LP#1098685: Require OPAC patron holds w/ phone/SMS notification to enter that info
authorCesar Velez <cesar.velez@equinoxinitiative.org>
Tue, 23 May 2017 20:36:44 +0000 (16:36 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Wed, 9 Aug 2017 13:54:34 +0000 (09:54 -0400)
This provides some plain vanilla JS form validation, and error feedback
using a yellow background color on the culprit input field.

Signed-off by: Cesar Velez <cesar.velez@equinoxinitiative.org>
Signed-off-by: Chris Sharp <csharp@georgialibraries.org>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/templates/opac/parts/js.tt2
Open-ILS/src/templates/opac/parts/place_hold.tt2
Open-ILS/web/js/ui/default/opac/holds-validation.js [new file with mode: 0644]

index a5c7082..e581b07 100644 (file)
 [%- IF ctx.page == 'record' AND ctx.google_books_preview %]
 <script src='[% ctx.media_prefix %]/js/ui/default/opac/ac_google_books.js[% ctx.cache_key %]' async defer></script>
 [%- END %]
 [%- IF ctx.page == 'record' AND ctx.google_books_preview %]
 <script src='[% ctx.media_prefix %]/js/ui/default/opac/ac_google_books.js[% ctx.cache_key %]' async defer></script>
 [%- END %]
+
+<!-- Require some inputs and selections for browsers that don't support required form field element -->
+[% IF ctx.page == 'place_hold' %]
+  <script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/holds-validation.js[% ctx.cache_key %]">
+  </script>
+[% END %]
+
 [%- IF want_dojo; -%]
 <script type="text/javascript">
      var djConfig = {
 [%- IF want_dojo; -%]
 <script type="text/javascript">
      var djConfig = {
@@ -130,29 +137,5 @@ var aou_hash = {
 };
 </script>
 
 };
 </script>
 
-<!-- Require radio parts selection for browsers that don't support required form field element -->
-[% IF ctx.page == 'place_hold' %]
-  <script type="text/javascript">
-    function validateRadioSelection (radios) {
-       for (i = 0; i < radios.length; ++ i)
-       {
-         if (radios[i].checked) return true;
-       }
-       return false;
-    }
-    function validateHoldForm() {
-      if (validateRadioSelection (document.getElementsByName("part")))
-      {
-        return true;
-       }
-       else
-       {
-          alert ("Please select a part");
-          return false;
-        }
-     }
-  </script>
-[% END %]
-
 <script type="text/javascript">if ($('client_tz_id')) { $('client_tz_id').value = OpenSRF.tz }</script>
 [%- END; # want_dojo -%]
 <script type="text/javascript">if ($('client_tz_id')) { $('client_tz_id').value = OpenSRF.tz }</script>
 [%- END; # want_dojo -%]
index a7e7441..c9f1d99 100644 (file)
@@ -45,7 +45,7 @@ function toggleActivationDate() {
               ELSE; some_holds_allowed = 1; END;
             END %]
       
               ELSE; some_holds_allowed = 1; END;
             END %]
       
-    <form method="post" name="PlaceHold" [% IF hdata.parts.size > 0 AND enable.radio.parts == 'true' %] onsubmit="return validateHoldForm()" [% END %] >
+    <form method="post" name="PlaceHold" onsubmit="return validateHoldForm()" >
         <input type="hidden" name="hold_type" value="[% CGI.param('hold_type') | html %]" />
         [%  
             redirect = CGI.param('hold_source_page') || CGI.param('redirect_to') || CGI.referer;
         <input type="hidden" name="hold_type" value="[% CGI.param('hold_type') | html %]" />
         [%  
             redirect = CGI.param('hold_source_page') || CGI.param('redirect_to') || CGI.referer;
@@ -197,7 +197,7 @@ function toggleActivationDate() {
         <p>
             [% l('Notify when hold is ready for pickup?') %]
             <blockquote>
         <p>
             [% l('Notify when hold is ready for pickup?') %]
             <blockquote>
-                <input type="checkbox" id="email_notify" name="email_notify" value="t"
+                <input class="hold-alert-method" type="checkbox" id="email_notify" name="email_notify" value="t"
                     [% IF !ctx.user.email %]disabled="true"[% ELSIF ctx.default_email_notify %]checked="checked"[% END %]/>
                     <label for="email_notify">[% l('Yes, by Email') %]</label><br/>
                 <blockquote>
                     [% IF !ctx.user.email %]disabled="true"[% ELSIF ctx.default_email_notify %]checked="checked"[% END %]/>
                     <label for="email_notify">[% l('Yes, by Email') %]</label><br/>
                 <blockquote>
@@ -205,7 +205,7 @@ function toggleActivationDate() {
                      ELSE; l('Email Address:') %] <span name="email_address">[% ctx.user.email %]</span>[% END %]
                 </blockquote>
                 [%- IF allow_phone_notifications == 'true' %]
                      ELSE; l('Email Address:') %] <span name="email_address">[% ctx.user.email %]</span>[% END %]
                 </blockquote>
                 [%- IF allow_phone_notifications == 'true' %]
-                <input type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox"
+                <input class="hold-alert-method" type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox"
                     [% IF ctx.default_phone_notify %]checked="checked"[% END %]/>
                     <label for="phone_notify_checkbox">[% l('Yes, by Phone') %]</label><br/>
                 <blockquote>
                     [% IF ctx.default_phone_notify %]checked="checked"[% END %]/>
                     <label for="phone_notify_checkbox">[% l('Yes, by Phone') %]</label><br/>
                 <blockquote>
@@ -215,7 +215,7 @@ function toggleActivationDate() {
                 </blockquote>
                 [%- END -%]
                 [% IF ctx.get_org_setting(ctx.search_ou, 'sms.enable') == 1 %]
                 </blockquote>
                 [%- END -%]
                 [% IF ctx.get_org_setting(ctx.search_ou, 'sms.enable') == 1 %]
-                <input type="checkbox" id="sms_notify_checkbox" name="sms_notify_checkbox"
+                <input class="hold-alert-method" type="checkbox" id="sms_notify_checkbox" name="sms_notify_checkbox"
                     [% IF ctx.default_sms_notify %]checked="checked"[% END %]/>
                     <label for="sms_notify_checkbox">[% l('Yes, by Text Messaging') %]</label><br/>
                 <blockquote>
                     [% IF ctx.default_sms_notify %]checked="checked"[% END %]/>
                     <label for="sms_notify_checkbox">[% l('Yes, by Text Messaging') %]</label><br/>
                 <blockquote>
diff --git a/Open-ILS/web/js/ui/default/opac/holds-validation.js b/Open-ILS/web/js/ui/default/opac/holds-validation.js
new file mode 100644 (file)
index 0000000..842366c
--- /dev/null
@@ -0,0 +1,76 @@
+/* JS form validation for holds page alert methods */
+function resetBackgrounds(names){
+    for (var key in names) {
+        if (names.hasOwnProperty(key)) {
+            var l = document.getElementsByName(names[key]);
+            if (l.length > 0) {
+                l[0].style.backgroundColor  = "";
+            }
+        }
+    }
+}
+
+function validateMethodSelections (alertMethodCboxes) {
+    var needsPhone = false;
+    var hasPhone = false;
+    
+    var needsEmail = false;
+    var hasEmail = false;
+    
+    var needsSms = false;
+    var hasSms = false;
+    var inputNames = { e: "email_address", ph: "phone_notify", sms: "sms_notify", carrier: "sms_carrier"};
+    resetBackgrounds(inputNames);
+
+    //Array.from(alertMethodCboxes).forEach(function(cbox){
+    for (var i = 0; i < alertMethodCboxes.length; i++){
+        var cbox = alertMethodCboxes[i];
+        if (cbox.checked && !cbox.disabled) {
+            switch(cbox.id){
+                case "email_notify_checkbox":
+                    needsEmail = true;
+                    hasEmail = document.getElementsByName(inputNames.e)[0].innerHTML !== "";
+                    break;
+                case "phone_notify_checkbox":
+                    needsPhone = true;
+                    hasPhone = document.getElementsByName(inputNames.ph)[0].value !== "";
+                    break;
+                case "sms_notify_checkbox":
+                    needsSms = true;
+                    var smsNumInput = document.getElementsByName(inputNames.sms)[0];
+                    hasSms = document.getElementsByName(inputNames.carrier)[0].value !== "" && smsNumInput.value !== ""; // todo: properly validate phone nums
+                break;
+            }
+        }
+    }
+    
+    var culprits = [];
+    var emailOK = (needsEmail && hasEmail) || (!needsEmail);
+    var phoneOK = needsPhone && hasPhone || (!needsPhone);
+    var smsOK = needsSms && hasSms || (!needsSms);
+    
+    if (!phoneOK) {
+        culprits.push("phone_notify");
+    }
+    if (!smsOK) {
+        culprits.push("sms_notify", "sms_carrier");
+    }
+    
+    var isFormOK = emailOK && phoneOK && smsOK;
+    return { isValid: isFormOK, culpritNames : culprits };
+}
+
+function validateHoldForm() {
+    var res = validateMethodSelections(document.getElementsByClassName("hold-alert-method"));
+    if (res.isValid)
+    {
+        return true;
+    } else {
+        alert ("Please complete hold notification method info.");
+        res.culpritNames.forEach(function(n){
+            document.getElementsByName(n)[0].style.backgroundColor  = "yellow";
+        });
+        return false;
+    }
+}
+