LP#1098685 html5 fix of Require OPAC patron holds phone/SMS alert info user/cesardv/hold_notify_html5_formval
authorCesar Velez <cesar.velez@equinoxinitiative.org>
Thu, 25 May 2017 18:34:12 +0000 (14:34 -0400)
committerCesar Velez <cesar.velez@equinoxinitiative.org>
Thu, 25 May 2017 18:34:12 +0000 (14:34 -0400)
Uses HTML5 input required attrib when Modernizr says it's supported otherwise uses IE8 compatible JS.
Client-side validates OPAC place hold form and highlights missing needed inputs.

Signed-off by: Cesar Velez <cesar.velez@equinoxinitiative.org>

Open-ILS/src/templates/opac/css/style.css.tt2
Open-ILS/src/templates/opac/parts/base.tt2
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]
Open-ILS/web/js/ui/default/opac/modernizr.3.5.0.min.input_setclasses.js [new file with mode: 0644]

index 3daeb49..a299f37 100644 (file)
@@ -156,6 +156,7 @@ div.select-box-wrapper {
 #dash_checked, #dash_e_checked { color: [% css_colors.text_attention %]; }
 #dash_holds, #dash_e_holds { color: [% css_colors.text_attention %]; }
 #dash_pickup, #dash_e_pickup { color: [% css_colors.text_goodnews %]; }
+.neededInput { background-color : [% css_colors.background_alert %]; }
 
 /*  
 #dash_fines { color: [% css_colors.text_badnews %]; }
index 8d7b07d..e0cfcc6 100644 (file)
@@ -41,6 +41,7 @@
             [% INCLUDE 'opac/parts/goog_analytics.tt2' %]
         [% END %]
         [% PROCESS 'opac/parts/stripe.tt2' %]
+        <script src="[% ctx.media_prefix %]/js/ui/default/opac/modernizr.3.5.0.min.input_setclasses.js"></script>
     </head>
     <body[% IF want_dojo; ' class="tundra"'; END %]>
         <h1 class="sr-only">[% l('Catalog') %]</h1>
index 845eed2..adec815 100644 (file)
@@ -132,6 +132,8 @@ var aou_hash = {
 
 <!-- Require radio parts selection 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"></script>
   <script type="text/javascript">
     function validateRadioSelection (radios) {
        for (i = 0; i < radios.length; ++ i)
@@ -152,32 +154,40 @@ var aou_hash = {
         }
      }
 
+ /* this only works on browsers that support html5 form validation, basically IE 10 or higher */
     function onHoldAlertMethodChanged(cbox){
-        
-        switch(cbox.id){
-            case "phone_notify_checkbox":
-                var phoneInput = document.getElementsByName("phone_notify")[0];
-                if(cbox.checked) {
-                    phoneInput.setAttribute("required","");
-                } else {
-                    phoneInput.removeAttribute("required");
-                }
-                break;
-            case "sms_notify_checkbox":
-                var smsInput = document.getElementsByName("sms_notify")[0];
-                var carrierInput = document.getElementsByName("sms_carrier")[0];
-                if(cbox.checked) {
-                    smsInput.setAttribute("required","");
-                    carrierInput.setAttribute("required","");
-                } else {
-                    smsInput.removeAttribute("required");
-                    carrierInput.removeAttribute("required");
-                }
-                break;
+    
+            
+        if (Modernizr.input.required){
+           switch(cbox.id){
+               case "phone_notify_checkbox":
+                   var phoneInput = document.getElementsByName("phone_notify")[0];
+                   if(cbox.checked) {
+                       phoneInput.setAttribute("required","");
+                   } else {
+                       phoneInput.removeAttribute("required");
+                   }
+                   break;
+               case "sms_notify_checkbox":
+                   var smsInput = document.getElementsByName("sms_notify")[0];
+                   var carrierInput = document.getElementsByName("sms_carrier")[0];
+                   if(cbox.checked) {
+                       smsInput.setAttribute("required","");
+                       carrierInput.setAttribute("required","");
+                   } else {
+                       smsInput.removeAttribute("required");
+                       carrierInput.removeAttribute("required");
+                   }
+                   break;
+            }
+        } else {
+            plainJSValidate();
         }
     }
+
         
   </script>
+
 [% END %]
 
 <script type="text/javascript">if ($('client_tz_id')) { $('client_tz_id').value = OpenSRF.tz }</script>
index 716b120..87e2f90 100644 (file)
@@ -22,8 +22,7 @@
                 SET some_holds_allowed = 0 IF some_holds_allowed == -1;
               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 (Modernizr.input.required || plainJSValidate())">
         <input type="hidden" name="hold_type" value="[% CGI.param('hold_type') | html %]" />
         [%  
             redirect = CGI.param('hold_source_page') || CGI.param('redirect_to') || CGI.referer;
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..1452673
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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 plainJSValidate() {
+    //var res = validateMethodSelections(document.getElementsByClassName("hold-alert-method"));
+    var res = validateMethodSelections(document.querySelectorAll(".hold-alert-method")); /* IE 8 hack */
+    if (res.isValid)
+    {
+        return true;
+    } else {
+        alert ("Please complete hold notification method info.");
+        // res.culpritNames.forEach(function(n){ /* can't do this in IE 8 grrr*/
+        for (var i = 0; i < res.culpritNames.length; i++){
+            document.forms["PlaceHold"].elements[res.culpritNames[i]].className = "neededInput";
+        }
+        return false;
+    }
+}
+
diff --git a/Open-ILS/web/js/ui/default/opac/modernizr.3.5.0.min.input_setclasses.js b/Open-ILS/web/js/ui/default/opac/modernizr.3.5.0.min.input_setclasses.js
new file mode 100644 (file)
index 0000000..90a3707
--- /dev/null
@@ -0,0 +1,3 @@
+/*! modernizr 3.5.0 (Custom Build) | MIT *\r
+ * https://modernizr.com/download/?-input-setclasses !*/\r
+!function(e,n,t){function s(e,n){return typeof e===n}function a(){var e,n,t,a,o,i,f;for(var c in r)if(r.hasOwnProperty(c)){if(e=[],n=r[c],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;t<n.options.aliases.length;t++)e.push(n.options.aliases[t].toLowerCase());for(a=s(n.fn,"function")?n.fn():n.fn,o=0;o<e.length;o++)i=e[o],f=i.split("."),1===f.length?Modernizr[f[0]]=a:(!Modernizr[f[0]]||Modernizr[f[0]]instanceof Boolean||(Modernizr[f[0]]=new Boolean(Modernizr[f[0]])),Modernizr[f[0]][f[1]]=a),l.push((a?"":"no-")+f.join("-"))}}function o(e){var n=c.className,t=Modernizr._config.classPrefix||"";if(u&&(n=n.baseVal),Modernizr._config.enableJSClass){var s=new RegExp("(^|\\s)"+t+"no-js(\\s|$)");n=n.replace(s,"$1"+t+"js$2")}Modernizr._config.enableClasses&&(n+=" "+t+e.join(" "+t),u?c.className.baseVal=n:c.className=n)}function i(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):u?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}var l=[],r=[],f={_version:"3.5.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){r.push({name:e,fn:n,options:t})},addAsyncTest:function(e){r.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=f,Modernizr=new Modernizr;var c=n.documentElement,u="svg"===c.nodeName.toLowerCase(),p=i("input"),m="autocomplete autofocus list placeholder max min multiple pattern required step".split(" "),d={};Modernizr.input=function(n){for(var t=0,s=n.length;s>t;t++)d[n[t]]=!!(n[t]in p);return d.list&&(d.list=!(!i("datalist")||!e.HTMLDataListElement)),d}(m),a(),o(l),delete f.addTest,delete f.addAsyncTest;for(var g=0;g<Modernizr._q.length;g++)Modernizr._q[g]();e.Modernizr=Modernizr}(window,document);
\ No newline at end of file