rewrite most of code into separate angular directive file

This commit is contained in:
vitam 2017-07-29 14:42:06 +02:00
parent 286cc301fe
commit 4fa683b4ee
3 changed files with 98 additions and 97 deletions

View File

@ -1040,7 +1040,7 @@
<!--click to toggle show the subfolders and files--> <!--click to toggle show the subfolders and files-->
<div class="checkbox" data-ng-click="folder.show=!folder.show"> <div class="checkbox" data-ng-click="folder.show=!folder.show">
<!-- The value of indeterminate="" can be bound to any angular expression --> <!-- 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 expand the folder' | translate }}</span>
<span ng-show="folder.show" class="control-label">{{ 'click the text to collapse the folder' | translate }}</span> <span ng-show="folder.show" class="control-label">{{ 'click the text to collapse the folder' | translate }}</span>
</div> </div>
@ -1055,7 +1055,7 @@
<div class="controls"> <div class="controls">
<label class="checkbox"> <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> </label>
</div> </div>
<br/> <br/>

View File

@ -118,47 +118,8 @@ angular
this.dirs = {}; this.dirs = {};
this.files = []; this.files = [];
this.show = false; 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; var folder = new OrganizedFolder(), tmp;
for (var i = 0; i < files.length; i++) { for (var i = 0; i < files.length; i++) {
tmp = folder; tmp = folder;
@ -172,7 +133,6 @@ angular
} }
tmp.files.push(files[i]); tmp.files.push(files[i]);
} }
folder.change();
return folder; return folder;
}; };
this.groupedFiles = groupFiles(this.files); this.groupedFiles = groupFiles(this.files);

View File

@ -1,57 +1,98 @@
// watches changes in the file upload control (input[file]) and // watches changes in the file upload control (input[file]) and
// puts the files selected in an attribute // puts the files selected in an attribute
var app = angular.module("webui.directives.fileselect", []); var app = angular.module("webui.directives.fileselect", ["webui.services.deps"]);
app.directive("indeterminate", function () { app.directive("indeterminate", [
return { "$parse", function syncInput (parse) {
// Restrict the directive so it can only be used as an attribute return {
restrict : "A", require : "ngModel",
// Restrict the directive so it can only be used as an attribute
restrict : "A",
link : function link (scope, elem, attr) { link : function link (scope, elem, attr, ngModelCtrl) {
// Whenever the bound value of the attribute changes we update // 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
// use upward emit notification for change to prevent the performance penalty bring by $scope.$watch var getter = parse(attr["ngModel"]);
elem[0].indeterminate = scope.$eval(attr.indeterminate); var setter = getter.assign;
scope.$on("childSelectedChange", function (event, options) { var children = []; // cache children input
elem[0].indeterminate = scope.$eval(attr.indeterminate); var get = function () {
}); return getter(scope);
};
/* var watcher = scope.$watch(attr.indeterminate, function (value) { // the internal 'indeterminate' flag on the attached dom element
elem[0].indeterminate = value; var setIndeterminateState = function (newValue) {
}); elem.prop("indeterminate", newValue);
};
// Remove the watcher when the directive is destroyed var setModelValueWithoutSideEffect = function (newVal) {
scope.$on("$destroy", function () { setter(scope, newVal);
watcher(); ngModelCtrl.$modelValue = newVal;
}); */ ngModelCtrl.$viewValue = newVal;
} ngModelCtrl.$render();
}; };
}); var setWithSideEffect = function (newVal) {
ngModelCtrl.$setViewValue(newVal);
app.directive("monitor", function () { ngModelCtrl.$render();
return { };
// Restrict the directive so it can only be used as an attribute var passIfLeafChild = function (callback) {
restrict : "A", return function () {
if (children.length > 0) {
link : function link (scope, elem, attr) { callback.apply(this, arguments);
// 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"); var passIfNotIsLeafChild = function (callback) {
}); return function () {
} if (children.length === 0) {
}; callback.apply(this, arguments);
}); }
};
app.directive("selected", function () { };
return { var passThroughThisScope = function (callback) {
// Restrict the directive so it can only be used as an attribute return function (event) {
restrict : "A", if (event.targetScope !== event.currentScope) {
return callback.apply(this, arguments);
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); 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)));
}
}
};
}
]);