Patron reg field validation (WIP)
authorBill Erickson <berickxx@gmail.com>
Thu, 3 Mar 2016 03:12:49 +0000 (22:12 -0500)
committerBill Erickson <berickxx@gmail.com>
Thu, 3 Mar 2016 03:12:49 +0000 (22:12 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/templates/staff/circ/patron/reg_actions.tt2
Open-ILS/src/templates/staff/circ/patron/t_edit.tt2
Open-ILS/src/templates/staff/css/circ.css.tt2
Open-ILS/web/js/ui/default/staff/circ/patron/regctl.js

index a533ba8..3640961 100644 (file)
 <div>
   <span class="pad-all-min">
     <button type="button" class="btn btn-default" 
+      ng-disabled="edit_passthru.has_invalid_fields()"
       ng-click="edit_passthru.save()">[% l('Save') %]</button>
   </span>
   <span class="pad-all-min">
     <button type="button" class="btn btn-default"
+      ng-disabled="edit_passthru.has_invalid_fields()"
       ng_click="edit_passthru.save({clone:true})">[% l('Save & Clone') %]</button>
   </span>
 </div>
index 84e3ab5..76a24b1 100644 (file)
@@ -101,7 +101,6 @@ MACRO draw_form_input(cls, field, path, type, required) BLOCK;
       ng-required="field_required('[% cls %]', '[% field %]')"
       ng-blur="handle_field_changed([% base_obj %], '[% field %]')"
       ng-pattern="field_pattern('[% cls %]', '[% field %]')"
-      ng-class="{'patron-reg-invalid-field' : field_is_invalid('[% model %]')}"
       ng-model="[% model %]"/>
   </div>
 [% END %]
@@ -132,7 +131,8 @@ This div wraps the entire form so we can hide it until all needed data
 has been loaded.  Setting ng-form and a name lets us refer to fields
 within the "form" by name for validation.
 -->
-<div ng-form name="reg_form" ng-show="page_data_loaded">
+<div ng-form id="patron-reg-container" 
+  name="reg_form" ng-show="page_data_loaded">
 
 <!-- BARCODE -->
 
@@ -142,13 +142,11 @@ within the "form" by name for validation.
       <input type="text" 
         name="barcode"
         ng-model="patron.card.barcode"
-        ng-class="{'patron-reg-invalid-field' : field_is_invalid('barcode')}"
         ng-pattern="field_pattern('ac', 'barcode')"
         ng-required="field_required('ac', 'barcode')"
         focus-me="focus_bc"
         ng-change="field_modified()" 
         ng-disabled="disable_bc"
-        ng-blur="handle_field_changed(patron.card, 'barcode')"
         class="form-control" 
         ng-blur="handle_field_changed(patron.card, 'barcode')"/>
   </div>
@@ -167,7 +165,6 @@ within the "form" by name for validation.
   <div class="col-md-3 reg-field-input">
     <input type="text" 
       name='usrname'
-      ng-class="{'patron-reg-invalid-field' : field_is_invalid('usrname')}"
       ng-required="field_required('au', 'usrname')"
       focus-me="focus_usrname"
       ng-change="field_modified()" 
@@ -263,7 +260,6 @@ within the "form" by name for validation.
       name="dob"
       ng-change="field_modified()" 
       ng-blur="handle_field_changed(patron, 'dob')"
-      ng-class="{'patron-reg-invalid-field' : field_is_invalid('dob')}"
       class="form-control" ng-model="patron.dob"/>
   </div>
   <div class="col-md-6 patron-reg-example">
@@ -275,7 +271,7 @@ within the "form" by name for validation.
 
 <div class="row reg-field-row" ng-show="show_field('au.juvenile')">
   [% draw_field_label('au', 'juvenile') %]
-  [% draw_form_input('au', 'alias', '', 'checkbox'); %]
+  [% draw_form_input('au', 'juvenile', '', 'checkbox'); %]
 </div>
 
 <!-- ident_type -->
@@ -283,21 +279,13 @@ within the "form" by name for validation.
 <div class="row reg-field-row" ng-show="show_field('au.ident_type')">
   [% draw_field_label('au', 'ident_type') %]
   <div class="col-md-3 reg-field-input">
-    <div class="btn-group" dropdown>
-      <button type="button" class="btn btn-default dropdown-toggle">
-        <span style="padding-right: 5px;">
-          {{patron.ident_type.name() || "[% l('Primary Ident Type') %]"}}
-        </span>
-        <span class="caret"></span>
-      </button>
-      <ul class="dropdown-menu">
-        <li ng-repeat="type in ident_types">
-          <a href ng-click="patron.ident_type = type; handle_field_changed(patron, 'ident_type')">
-            {{type.name()}}
-          </a>
-        </li>
-      </ul>
-    </div>
+    <select 
+      class="form-control" 
+      ng-model="patron.ident_type"
+      ng-required="field_required('au', 'ident_type')"
+      ng-blur="handle_field_changed(patron, 'ident_type')"
+      ng-options="type.name() for type in ident_types track by type.id()">
+    </select>
   </div>
 </div>
 
@@ -406,14 +394,16 @@ within the "form" by name for validation.
   [% draw_field_label('au', 'profile') %]
   <div class="col-md-3 reg-field-input">
     <div class="btn-group" dropdown>
-      <button type="button" class="btn btn-default dropdown-toggle">
+      <button type="button" class="btn btn-default dropdown-toggle"
+          ng-class="{'ng-invalid' : invalid_profile()}">
         <span style="padding-right: 5px;">
           {{patron.profile.name() || "[% l('Profile Group') %]"}}
         </span>
         <span class="caret"></span>
       </button>
       <ul class="dropdown-menu">
-        <li ng-repeat="grp in edit_profiles">
+        <li ng-repeat="grp in edit_profiles" 
+          ng-class="{disabled : grp.usergroup() == 'f'}">
           <a href 
             style="padding-left: {{pgt_depth(grp) * 10 + 5}}px"
             ng-click="set_profile(grp)">{{grp.name()}}</a>
index 8e69dfe..c676744 100644 (file)
@@ -158,7 +158,10 @@ but the ones I'm finding aren't quite cutting it..*/
   color: red;
 }
 
-.patron-reg-invalid-field {
+/* Angular applies these classes based on the field's 
+ * required and pattern settings */
+#patron-reg-container .ng-invalid,
+#patron-reg-container .ng-invalid-required {
   background-color: yellow;
   color: red;
 }
index 02e7575..2dd04b9 100644 (file)
@@ -1202,6 +1202,12 @@ function PatronRegCtrl($scope, $routeParams,
     // See $scope.show_field().
     // A field with visbility level 3 means it's required.
     $scope.field_required = function(cls, field) {
+
+        // Value in the password field is not required
+        // for existing patrons.
+        if (field == 'passwd' && $scope.patron && !$scope.patron.isnew) 
+          return false;
+
         return (field_visibility[cls + '.' + field] == 3);
     }
 
@@ -1226,6 +1232,14 @@ function PatronRegCtrl($scope, $routeParams,
         $scope.field_modified();
     }
 
+    $scope.invalid_profile = function() {
+        return !(
+            $scope.patron && 
+            $scope.patron.profile && 
+            $scope.patron.profile.usergroup() == 't'
+        );
+    }
+
     $scope.new_address = function() {
         var addr = egCore.idl.toHash(new egCore.idl.aua());
         patronRegSvc.ingest_address($scope.patron, addr);
@@ -1549,6 +1563,9 @@ function PatronRegCtrl($scope, $routeParams,
         $scope.field_modified();
     }
 
+    /* NOTE: this function is not necessary since angular applies
+     * the needed classes as each field becomes valid/invalid.
+     * Leaving it here for now for reference.
     // Returns true if a required field has no value or a field's
     // value does not match its configured regex pattern.
     // Tests angular's form field validation toggles.
@@ -1560,6 +1577,12 @@ function PatronRegCtrl($scope, $routeParams,
             $scope.reg_form[field_name].$valid === false
         );
     }
+    */
+
+    // Returns true if any input elements are tagged as invalid
+    $scope.edit_passthru.has_invalid_fields = function() {
+        return $('#patron-reg-container.ng-invalid').length > 0;
+    }
 
     $scope.edit_passthru.save = function(save_args) {
         if (!save_args) save_args = {};