r450 - in trunk/faxtomail-ui-web/src/main/webapp: WEB-INF WEB-INF/content/admin css js
Author: echatellier Date: 2014-07-28 18:19:59 +0200 (Mon, 28 Jul 2014) New Revision: 450 Url: http://forge.codelutin.com/projects/faxtomail/repository/revisions/450 Log: Add search support using select2 with angular Added: trunk/faxtomail-ui-web/src/main/webapp/js/select2.js Modified: trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/wro.xml trunk/faxtomail-ui-web/src/main/webapp/css/faxtomail.css trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js Modified: trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp 2014-07-28 15:20:27 UTC (rev 449) +++ trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/content/admin/configuration-input.jsp 2014-07-28 16:19:59 UTC (rev 450) @@ -451,15 +451,16 @@ </tbody> </table> - <div class="form-inline"> + <div class="form"> <div class="form-group"> <label for="newCustomerResponsibleField" class="control-label">Nouveau :</label> - <select id="newCustomerResponsibleField" class="form-control" ng-model="newCustomerResponsible" + <select id="newCustomerResponsibleField" ui-select2 ng-model="newCustomerResponsible" ng-options="user as user.firstName + ' ' + user.lastName for user in users|filter:filterByAlreadyInCollection(selectedMailFolder.customerResponsibles)"></select> + + <a class="btn btn-success btn-xs" ng-click="addCustomerResponsible()" ng-disabled="!newCustomerResponsible"> + <span class="glyphicon glyphicon-plus"></span> + </a> </div> - <a class="btn btn-success btn-xs" ng-click="addCustomerResponsible()" ng-disabled="!newCustomerResponsible"> - <span class="glyphicon glyphicon-plus"></span> - </a> </div> </div> </div> @@ -840,10 +841,10 @@ </tr> </tbody> </table> - <div class="form-inline"> + <div class="form"> <div class="form-group"> <label for="newRightUserField" class="control-label">Nouveau utilisateur :</label> - <select id="newRightUserField" class="form-control" + <select id="newRightUserField" ui-select2 ng-model="newRightUser" ng-options="user as user.firstName + ' ' + user.lastName for user in users|filter:filterByAlreadyInCollection(selectedMailFolder.rightUsers)"> </select> @@ -853,10 +854,10 @@ </div> </div> - <div class="form-inline"> + <div class="form"> <div class="form-group"> <label for="newRightGroupField" class="control-label">Nouveau groupe :</label> - <select id="newRightGroupField" class="form-control" + <select id="newRightGroupField" ui-select2 ng-model="newRightGroup" ng-options="group as group.completeName for group in groups|filter:filterByAlreadyInCollection(selectedMailFolder.rightGroups)"> </select> @@ -922,10 +923,10 @@ </tr> </tbody> </table> - <div class="form-inline"> + <div class="form"> <div class="form-group"> <label for="newRightUserField" class="control-label">Nouveau utilisateur :</label> - <select id="newRightUserField" class="form-control" + <select id="newRightUserField" ui-select2 ng-model="newRightUser" ng-options="user as user.firstName + ' ' + user.lastName for user in users|filter:filterByAlreadyInCollection(selectedMailFolder.rightUsers)"> </select> @@ -935,10 +936,10 @@ </div> </div> - <div class="form-inline"> + <div class="form"> <div class="form-group"> <label for="newRightGroupField" class="control-label">Nouveau groupe :</label> - <select id="newRightGroupField" class="form-control" + <select id="newRightGroupField" ui-select2 ng-model="newRightGroup" ng-options="group as group.completeName for group in groups|filter:filterByAlreadyInCollection(selectedMailFolder.rightGroups)"> </select> @@ -1144,10 +1145,10 @@ <div class="col-md-8" ng-show="selectedGroupChef"> <h3>Édition du chef de groupe</h3> - <div class="form-inline"> + <div class="form"> <div class="form-group required"> <label for="groupChefUserGroupField" class="control-label">Chef du groupe : </label> - <select id="groupChefUserGroupField" class="form-control" ng-required="selectedGroupChef" + <select id="groupChefUserGroupField" ui-select2 ng-required="selectedGroupChef" ng-model="selectedGroupChef.userGroup" ng-options="group as group.completeName for group in groups|filter:availableNewGroupChef"> <option value=""></option> @@ -1177,12 +1178,13 @@ </tr> </tbody> </table> - <div class="form-inline"> + <div class="form"> <div class="form-group"> <label for="newManagedGroupField" class="control-label">Nouveau groupe :</label> - <select id="newManagedGroupField" class="form-control" - ng-model="newManagedGroup" width="'100%'" searchContains="true" - ng-options="group as group.completeName for group in groups|filter:filterByAlreadyInCollection(selectedGroupChef.managedGroups)" > + <select id="newManagedGroupField" ui-select2 + ng-model="newManagedGroup" + ng-options="group as group.completeName for group in groups|filter:filterByAlreadyInCollection(selectedGroupChef.managedGroups)"> + <option value=""></option> </select> <a class="btn btn-success btn-xs" ng-click="addManagedGroup()" ng-disabled="!newManagedGroup"> <span class="glyphicon glyphicon-plus"></span> Modified: trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/wro.xml =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/wro.xml 2014-07-28 15:20:27 UTC (rev 449) +++ trunk/faxtomail-ui-web/src/main/webapp/WEB-INF/wro.xml 2014-07-28 16:19:59 UTC (rev 450) @@ -45,6 +45,11 @@ <js>classpath:META-INF/resources/webjars/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.js</js> </group> + <group name='select2' abstract="true"> + <group-ref>webjar-select2</group-ref> + <js>/js/select2.js</js> + </group> + <group name='select2sortable' abstract="true"> <group-ref>webjar-select2</group-ref> <js>/js/select2sortable.js</js> @@ -79,6 +84,7 @@ </group> <group name='faxtomail-configuration'> + <group-ref>select2</group-ref> <group-ref>select2sortable</group-ref> <group-ref>angular-chosen</group-ref> <group-ref>webjar-angular-ui-sortable</group-ref> Modified: trunk/faxtomail-ui-web/src/main/webapp/css/faxtomail.css =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/css/faxtomail.css 2014-07-28 15:20:27 UTC (rev 449) +++ trunk/faxtomail-ui-web/src/main/webapp/css/faxtomail.css 2014-07-28 16:19:59 UTC (rev 450) @@ -57,6 +57,14 @@ } .select2-container { + width: 70%; +} + +.select2-offscreen { + position: fixed !important; +} +/* select 2 sortable */ +.select2-container-multi { width: 100%; } Modified: trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js 2014-07-28 15:20:27 UTC (rev 449) +++ trunk/faxtomail-ui-web/src/main/webapp/js/configuration.js 2014-07-28 16:19:59 UTC (rev 450) @@ -22,7 +22,7 @@ * #L% */ -var ConfigurationModule = angular.module('ConfigurationModule', ['FaxToMail', 'ui.tree', 'ui.sortable', 'localytics.directives', 'ui.select2.sortable']); +var ConfigurationModule = angular.module('ConfigurationModule', ['FaxToMail', 'ui.tree', 'ui.select2', 'ui.sortable', 'localytics.directives', 'ui.select2.sortable']); /** * Global configuration controller. Added: trunk/faxtomail-ui-web/src/main/webapp/js/select2.js =================================================================== --- trunk/faxtomail-ui-web/src/main/webapp/js/select2.js (rev 0) +++ trunk/faxtomail-ui-web/src/main/webapp/js/select2.js 2014-07-28 16:19:59 UTC (rev 450) @@ -0,0 +1,193 @@ +/** %%Ignore-License + * + * C'est une version patché de ui.select2 pour supporter le ng-options. + * En attendant https://github.com/angular-ui/ui-select2/issues/46 + */ +(function () { + "use strict"; + var module = angular.module('ui.select2', []); + + module.value('uiSelect2Config', {}) + + module.directive('uiSelect2', ['uiSelect2Config', '$timeout', '$compile', '$parse', '$q', '$rootScope', + function (uiSelect2Config, $timeout, $compile, $parse, $q, $rootScope) { + var options = {}; + if (uiSelect2Config) { + angular.extend(options, uiSelect2Config); + } + return { + require: '?ngModel', + link: function(scope, element, attrs, ngModel) { + + // instance-specific options + var opts = setupOptions(); + setupAttributeAndClassSynchronization(); + setupCleanupOnDestroy(); + + if (attrs.isOpen) { + setupIsOpenBinding(); + } + + if (attrs.query) { + setupQueryHandler(); + } else { + scheduleResyncAfterEveryDigest(); + } + + element.select2(opts); + return; + + + //Privates + function setupOptions() { + return angular.extend({}, options, scope.$eval(attrs.uiSelect2)); + } + + function scheduleResyncAfterEveryDigest() { + //After every digest make sure that select2's value is in sync + var scheduledValue = false; + scope.$watch(function() { + //Only schedule once per digest cycle regardles of times watch is called; + if (!scheduledValue) { + scheduledValue = true; + $timeout(function() { + element.select2('val', element.val()); + scheduledValue = false; + }, 0, false); + } + }); + } + + + function setupIsOpenBinding() { + var isOpen = false; + var isOpenExpression = $parse(attrs.isOpen); + scope.$watch(isOpenExpression, function(value) { + if (value && !isOpen) { + $timeout(function() { + isOpen = true; + element.select2('open'); + }, 0, false); + + } + if (!value && isOpen) { + $timeout(function() { + element.select2('close'); + isOpen = false; + element.select2('close'); + }, 0, false); + } + }); + + element.on('select2-open.select2', function() { + scope.$apply(function() { + isOpen = true; + isOpenExpression.assign(scope, true); + }); + }); + + element.on('select2-close.select2', function() { + scope.$apply(function() { + isOpen = false; + isOpenExpression.assign(scope, false); + }); + }); + } + + + function setupCleanupOnDestroy() { + element.on("$destroy", function() { + element.select2("destroy"); + element.off('.select2'); + }); + } + + + function setupAttributeAndClassSynchronization() { + attrs.$observe('disabled', function(value) { + element.select2('enable', !value); + }); + + attrs.$observe('readonly', function(value) { + element.select2('readonly', !!value); + }); + + // Update valid and dirty statuses + if (ngModel) { + ngModel.$parsers.push(function(value) { + var div = element.select2("container"); + div + .toggleClass('ng-invalid', !ngModel.$valid) + .toggleClass('ng-valid', ngModel.$valid) + .toggleClass('ng-invalid-required', !ngModel.$valid) + .toggleClass('ng-valid-required', ngModel.$valid) + .toggleClass('ng-dirty', ngModel.$dirty) + .toggleClass('ng-pristine', ngModel.$pristine); + return value; + }); + } + } + + + function setupQueryHandler() { + var queryResults = []; + ngModel.$parsers.unshift(function(value) { + var result = queryResults[value]; + return result; + }); + + ngModel.$formatters.push(function(value) { + if (value) { + var label = scope.$eval(attrs.queryLabel, { + option: value + }); + element.select2('data', { + text: label + }); + } + }); + + opts.query = function(query) { + if (query.page === 1) { + queryResults = []; + } + + var queryOptions = { + term: query.term, + page: query.page, + context: query.context + }; + var resultPromiseOrObject = scope.$eval(attrs.query, { + query: queryOptions + }); + + $q.when(resultPromiseOrObject).then(function(result) { + var select2Results = []; + var i = queryResults.length; + + angular.forEach(result.results, function(option) { + var context = { + option: option + }; + var label = scope.$eval(attrs.queryLabel, context); + select2Results.push({ + id: i, + text: label + }); + i++; + }); + + queryResults = queryResults.concat(result.results); + query.callback({ + results: select2Results, + more: result.more + }); + }); + }; + } + + } + }; + } + ]); +})();
participants (1)
-
echatellier@users.forge.codelutin.com