LP#1117808: new egFmValueSelector directive
authorGalen Charlton <gmc@equinoxinitiative.org>
Fri, 23 Dec 2016 06:36:07 +0000 (01:36 -0500)
committerKathy Lussier <klussier@masslnc.org>
Fri, 17 Feb 2017 15:13:36 +0000 (10:13 -0500)
This directive supplies a select widget that draws its
values from a table specified by an IDL class code.  It
is meant to be used for tables containing a reasonably
small number of rows (i.e., dozens at most, not hundreds
or thousands).

The following attributes are available:

idl-class      : Code of IDL class to draw from, e.g., "vmp".
ng-model       : Model to bind the current selected value to.
filter         : JSON query filter to apply conditions on the set
                 of rows to be used. (optional)
sticky-setting : Local storage key to persist the last value
                 that was selected by the user. (optional)
ou-setting     : Name of library setting to use to set the default
                 selected value. If sticky-setting is used, any
                 previously-selected value will override the default
                 specified by the OU setting. (optional)

The list of values from the source table displayed in the select
widget are those that meet all of the following conditions:

- primary key is not null
- filter conditions (if supplied)
- logged-in user has PCRUD permissions to view the value

The option value is taken from the column in the source table
specified by the oils_persist:primary IDL attribute, while
the displayed label is taken from the column that has the
reporter:selector="name" IDL attribute.

Example:

<eg-fm-value-selector
  idl-class="vmp"
  ng-model="merge_profile"
  filter="{'preserve_spec':{'=':null}}"
  sticky-setting="eg.cat.z3950.selected_merge_profile"
  ou-setting="cat.default.merge_profile"
></eg-fm-value-selector>

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Open-ILS/src/templates/staff/share/t_fm_value_selector.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/services/ui.js

diff --git a/Open-ILS/src/templates/staff/share/t_fm_value_selector.tt2 b/Open-ILS/src/templates/staff/share/t_fm_value_selector.tt2
new file mode 100644 (file)
index 0000000..4306e5e
--- /dev/null
@@ -0,0 +1,5 @@
+<select
+  ng-options="item.id as item.name for item in linked_values"
+  ng-model="ngModel"
+  ng-change="handleChange(ngModel)"
+</select>
index 3ed6429..e4e4579 100644 (file)
@@ -559,6 +559,97 @@ function($window , egStrings) {
     }
 ])
 
+/*
+ *  egFmValueSelector - widget for selecting a value from list specified
+ *                      by IDL class
+ */
+.directive('egFmValueSelector', function() {
+    return {
+        restrict : 'E',
+        transclude : true,
+        scope : {
+            idlClass : '@',
+            ngModel : '=',
+
+            // optional filter for refining the set of rows that
+            // get returned. Example:
+            //
+            // filter="{'column':{'=':null}}"
+            filter : '=',
+
+            // optional name of settings key for persisting
+            // the last selected value
+            stickySetting : '@',
+
+            // optional OU setting for fetching default value;
+            // used only if sticky setting not set
+            ouSetting : '@'
+        },
+        require: 'ngModel',
+        templateUrl : './share/t_fm_value_selector',
+        controller : ['$scope','egCore', function($scope , egCore) {
+
+            $scope.org = egCore.org; // for use in the link function
+            $scope.auth = egCore.auth; // for use in the link function
+            $scope.hatch = egCore.hatch // for use in the link function
+
+            function flatten_linked_values(cls, list) {
+                var results = [];
+                var fields = egCore.idl.classes[cls].fields;
+                var id_field;
+                var selector;
+                angular.forEach(fields, function(fld) {
+                    if (fld.datatype == 'id') {
+                        id_field = fld.name;
+                        selector = fld.selector ? fld.selector : id_field;
+                        return;
+                    }
+                });
+                angular.forEach(list, function(item) {
+                    var rec = egCore.idl.toHash(item);
+                    results.push({
+                        id : rec[id_field],
+                        name : rec[selector]
+                    });
+                });
+                return results;
+            }
+
+            var search = {};
+            search[egCore.idl.classes[$scope.idlClass].pkey] = {'!=' : null};
+            if ($scope.filter) {
+                angular.extend(search, $scope.filter);
+            }
+            egCore.pcrud.search(
+                $scope.idlClass, search, {}, {atomic : true}
+            ).then(function(list) {
+                $scope.linked_values = flatten_linked_values($scope.idlClass, list);
+            });
+
+            $scope.handleChange = function(value) {
+                if ($scope.stickySetting) {
+                    egCore.hatch.setLocalItem($scope.stickySetting, value);
+                }
+            }
+
+        }],
+        link : function(scope, element, attrs) {
+            if (scope.stickySetting && (angular.isUndefined(scope.ngModel) || (scope.ngModel === null))) {
+                var value = scope.hatch.getLocalItem(scope.stickySetting);
+                scope.ngModel = value;
+            }
+            if (scope.ouSetting && (angular.isUndefined(scope.ngModel) || (scope.ngModel === null))) {
+                scope.org.settings([scope.ouSetting], scope.auth.user().ws_ou())
+                .then(function(set) {
+                    var value = parseInt(set[scope.ouSetting]);
+                    if (!isNaN(value))
+                        scope.ngModel = value;
+                });
+            }
+        }
+    }
+})
+
 .factory('egWorkLog', ['egCore', function(egCore) {
     var service = {};