rewrite most of code into separate angular directive file
This commit is contained in:
parent
286cc301fe
commit
4fa683b4ee
|
@ -1040,7 +1040,7 @@
|
|||
<!--click to toggle show the subfolders and files-->
|
||||
<div class="checkbox" data-ng-click="folder.show=!folder.show">
|
||||
<!-- The value of indeterminate="" can be bound to any angular expression -->
|
||||
<input type="checkbox" ng-model="folder.selected" data-ng-click="$event.stopPropagation()" indeterminate="folder.indeterminate" monitor/>{{folderName}}
|
||||
<input type="checkbox" data-ng-model="folder.selected" data-ng-click="$event.stopPropagation()" indeterminate/>{{folderName}}
|
||||
<span ng-show="!folder.show" class="control-label">{{ 'click the text to expand the folder' | translate }}</span>
|
||||
<span ng-show="folder.show" class="control-label">{{ 'click the text to collapse the folder' | translate }}</span>
|
||||
</div>
|
||||
|
@ -1055,7 +1055,7 @@
|
|||
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" ng-model="file.selected" monitor/>{{file.relpath}}
|
||||
<input type="checkbox" data-ng-model="file.selected" indeterminate="false"/>{{file.relpath}}
|
||||
</label>
|
||||
</div>
|
||||
<br/>
|
||||
|
|
|
@ -118,47 +118,8 @@ angular
|
|||
this.dirs = {};
|
||||
this.files = [];
|
||||
this.show = false;
|
||||
this._selected = false;
|
||||
this.selected = true;
|
||||
}
|
||||
OrganizedFolder.prototype.change = function () {
|
||||
for (var i = 0; i < this.files.length; i++) {
|
||||
this.files[i].selected = this.selected;
|
||||
}
|
||||
for (var folder in this.dirs) {
|
||||
if (this.dirs.hasOwnProperty(folder)) {
|
||||
this.dirs[folder].selected = this.selected;
|
||||
}
|
||||
}
|
||||
};
|
||||
Object.defineProperty(OrganizedFolder.prototype, "selected", {
|
||||
get : function () {
|
||||
return this._selected;
|
||||
},
|
||||
set : function (newValue) {
|
||||
this._selected = newValue;
|
||||
this.change();
|
||||
}
|
||||
});
|
||||
Object.defineProperty(OrganizedFolder.prototype, "indeterminate", {
|
||||
get : function () {
|
||||
var allSeleted = true;
|
||||
var allNotSelected = true;
|
||||
for (var p in this.dirs) {
|
||||
if (this.dirs.hasOwnProperty(p)) {
|
||||
if (this.dirs[p].indeterminate) {
|
||||
return true;
|
||||
}
|
||||
allSeleted &= this.dirs[p].selected;
|
||||
allNotSelected &= !this.dirs[p].selected;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < this.files.length; i++) {
|
||||
allSeleted &= this.files[i].selected;
|
||||
allNotSelected &= !this.files[i].selected;
|
||||
}
|
||||
return !allSeleted && !allNotSelected;// is not determinate when either all selected either all not selected;
|
||||
}
|
||||
});
|
||||
var folder = new OrganizedFolder(), tmp;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
tmp = folder;
|
||||
|
@ -172,7 +133,6 @@ angular
|
|||
}
|
||||
tmp.files.push(files[i]);
|
||||
}
|
||||
folder.change();
|
||||
return folder;
|
||||
};
|
||||
this.groupedFiles = groupFiles(this.files);
|
||||
|
|
|
@ -1,57 +1,98 @@
|
|||
// watches changes in the file upload control (input[file]) and
|
||||
// puts the files selected in an attribute
|
||||
var app = angular.module("webui.directives.fileselect", []);
|
||||
app.directive("indeterminate", function () {
|
||||
return {
|
||||
// Restrict the directive so it can only be used as an attribute
|
||||
restrict : "A",
|
||||
var app = angular.module("webui.directives.fileselect", ["webui.services.deps"]);
|
||||
app.directive("indeterminate", [
|
||||
"$parse", function syncInput (parse) {
|
||||
return {
|
||||
require : "ngModel",
|
||||
// Restrict the directive so it can only be used as an attribute
|
||||
restrict : "A",
|
||||
|
||||
link : function link (scope, elem, attr) {
|
||||
// Whenever the bound value of the attribute changes we update
|
||||
// the internal 'indeterminate' flag on the attached dom element
|
||||
// use upward emit notification for change to prevent the performance penalty bring by $scope.$watch
|
||||
elem[0].indeterminate = scope.$eval(attr.indeterminate);
|
||||
scope.$on("childSelectedChange", function (event, options) {
|
||||
elem[0].indeterminate = scope.$eval(attr.indeterminate);
|
||||
});
|
||||
|
||||
/* var watcher = scope.$watch(attr.indeterminate, function (value) {
|
||||
elem[0].indeterminate = value;
|
||||
});
|
||||
|
||||
// Remove the watcher when the directive is destroyed
|
||||
scope.$on("$destroy", function () {
|
||||
watcher();
|
||||
}); */
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive("monitor", function () {
|
||||
return {
|
||||
// Restrict the directive so it can only be used as an attribute
|
||||
restrict : "A",
|
||||
|
||||
link : function link (scope, elem, attr) {
|
||||
// Whenever the bound value of the attribute changes we update
|
||||
// the internal 'indeterminate' flag on the attached dom element
|
||||
elem.change(function () {
|
||||
scope.$emit("childSelectedChange");
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive("selected", function () {
|
||||
return {
|
||||
// Restrict the directive so it can only be used as an attribute
|
||||
restrict : "A",
|
||||
|
||||
link : function link (scope, elem, attr) {
|
||||
elem[0].value = scope.$eval(attr.selected);
|
||||
scope.$on("childSelectedChange", function (event, options) {
|
||||
elem[0].value = scope.$eval(attr.selected);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
link : function link (scope, elem, attr, ngModelCtrl) {
|
||||
// Whenever the bound value of the attribute changes we update
|
||||
// use upward emit notification for change to prevent the performance penalty bring by $scope.$watch
|
||||
var getter = parse(attr["ngModel"]);
|
||||
var setter = getter.assign;
|
||||
var children = []; // cache children input
|
||||
var get = function () {
|
||||
return getter(scope);
|
||||
};
|
||||
// the internal 'indeterminate' flag on the attached dom element
|
||||
var setIndeterminateState = function (newValue) {
|
||||
elem.prop("indeterminate", newValue);
|
||||
};
|
||||
var setModelValueWithoutSideEffect = function (newVal) {
|
||||
setter(scope, newVal);
|
||||
ngModelCtrl.$modelValue = newVal;
|
||||
ngModelCtrl.$viewValue = newVal;
|
||||
ngModelCtrl.$render();
|
||||
};
|
||||
var setWithSideEffect = function (newVal) {
|
||||
ngModelCtrl.$setViewValue(newVal);
|
||||
ngModelCtrl.$render();
|
||||
};
|
||||
var passIfLeafChild = function (callback) {
|
||||
return function () {
|
||||
if (children.length > 0) {
|
||||
callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
};
|
||||
var passIfNotIsLeafChild = function (callback) {
|
||||
return function () {
|
||||
if (children.length === 0) {
|
||||
callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
};
|
||||
var passThroughThisScope = function (callback) {
|
||||
return function (event) {
|
||||
if (event.targetScope !== event.currentScope) {
|
||||
return callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
};
|
||||
if (attr["indeterminate"] && parse(attr["indeterminate"]).constant && !scope.$eval(attr["indeterminate"])) {
|
||||
// is leaf input, Only receive parent change and emit child change event
|
||||
setIndeterminateState(scope.$eval(attr["indeterminate"]));
|
||||
ngModelCtrl.$viewChangeListeners.push(passIfNotIsLeafChild(function () {
|
||||
scope.$emit("childSelectedChange");
|
||||
}));
|
||||
scope.$on("ParentSelectedChange", passThroughThisScope(
|
||||
function (event, newVal) {
|
||||
setWithSideEffect(newVal);
|
||||
}));
|
||||
scope.$emit("i'm child input", get);
|
||||
setWithSideEffect(get());
|
||||
scope.$emit("childSelectedChange");
|
||||
} else {
|
||||
// init first time and only once
|
||||
// establish parent-child's relation
|
||||
scope.$on("i'm child input", passThroughThisScope(
|
||||
function (event, child) {
|
||||
children.push(child);
|
||||
})
|
||||
);
|
||||
var updateBaseOnChildrenState = function () {
|
||||
var allSelected = children.every(function (child) {
|
||||
return child();
|
||||
});
|
||||
var anySeleted = children.some(function (child) {
|
||||
return child();
|
||||
});
|
||||
setIndeterminateState(allSelected !== anySeleted);
|
||||
setWithSideEffect(allSelected);
|
||||
};
|
||||
// is not leaf input, Only receive child change and parent change event
|
||||
ngModelCtrl.$viewChangeListeners.push(passIfLeafChild(function () {
|
||||
if (!elem.prop("indeterminate")) { // emit when prop indeterminate is set to false
|
||||
scope.$broadcast("ParentSelectedChange", get());
|
||||
}
|
||||
}));
|
||||
// reset input state base on children inputs
|
||||
scope.$on("childSelectedChange", passThroughThisScope(passIfLeafChild(updateBaseOnChildrenState)));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
|
Loading…
Reference in New Issue
Block a user