better syncing of cart state
authorGalen Charlton <gmc@equinoxinitiative.org>
Fri, 15 Jun 2018 16:16:31 +0000 (12:16 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Fri, 15 Jun 2018 16:16:31 +0000 (12:16 -0400)
This patch improves how the display of the cart size and selected records
are handled when the back (and forward) buttons are used, and embeds
record_selectors.js on all pages. It also:

* adds more bullet-proofing of element existance in record_selectors.js
* adds an /eg/opac/api/mylist/retrieve API

Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm
Open-ILS/src/templates/opac/parts/js.tt2
Open-ILS/web/js/ui/default/opac/record_selectors.js

index df320a6..09afe3c 100644 (file)
@@ -133,6 +133,7 @@ sub load {
         $path =~ /opac\/my(opac\/lists|list)/ ||
         $path =~ m!opac/api/mylist!;
 
+    return $self->load_api_mylist_retrieve if $path =~ m|opac/api/mylist/retrieve|;
     return $self->load_api_mylist_add if $path =~ m|opac/api/mylist/add|;
     return $self->load_api_mylist_delete if $path =~ m|opac/api/mylist/delete|;
 
index 07f1aab..d17c0e2 100644 (file)
@@ -73,6 +73,26 @@ sub fetch_mylist {
     return ($cache_key, $list, $marc_xml);
 }
 
+sub load_api_mylist_retrieve {
+    my $self = shift;
+
+    # this has the effect of instantiating an empty one if need be
+    my ($cache_key, $list) = $self->fetch_mylist(0, 1);
+
+    $self->ctx->{json_response} = {
+        mylist => [ map { 0 + $_ } @$list ], # force integers
+    };
+    $self->ctx->{json_reponse_cookie} =
+        $self->cgi->cookie(
+            -name => (ref $self)->COOKIE_CART_CACHE,
+            -path => '/',
+            -value => ($cache_key) ? $cache_key : '',
+            -expires => ($cache_key) ? undef : '-1h'
+        );
+
+    return Apache2::Const::OK;
+}
+
 
 # Adds a record (by id) to My List, creating a new anon cache + list if necessary.
 sub load_mylist_add {
index a1dae3d..2fdf7ba 100644 (file)
@@ -68,9 +68,7 @@
 <script src='[% ctx.media_prefix %]/js/ui/default/opac/ac_google_books.js[% ctx.cache_key %]' async defer></script>
 [%- END %]
 
-[%- IF ctx.page == 'rresult' %]
 <script src='[% ctx.media_prefix %]/js/ui/default/opac/record_selectors.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' %]
index 0a6439e..327b7a0 100644 (file)
@@ -2,13 +2,54 @@
 
     var rec_selector_block = document.getElementById("record_selector_block");
     var rec_selectors = document.getElementsByClassName("result_record_selector");
+    var record_cart_count_el = document.getElementById('record_cart_count');
+    var selected_records_count_el = document.getElementById('selected_records_count');
+    var select_all_records_el = document.getElementById('select_all_records');
+    var clear_selected_records_el = document.getElementById('clear_selected_records');
     var mylist = [];
 
+    function initialize() {
+        var req = new window.XMLHttpRequest();
+        req.open('GET', '/eg/opac/api/mylist/retrieve');
+        if (('responseType' in req) && (req.responseType = 'json')) {
+            req.onload = function (evt) {
+                var result = req.response;
+                handleUpdate(result);
+                syncPageState();
+            }
+        } else {
+            // IE 10/11
+            req.onload = function (evt) {
+                var result = JSON.parse(req.responseText);
+                handleUpdate(result);
+                syncPageState();
+            }
+        }
+        req.send();
+    }
+    initialize();
+
+    function syncPageState() {
+        [].forEach.call(rec_selectors, function(el) {
+            el.checked = mylist.includes(parseInt(el.value));
+            if (el.checked) {
+                adjustLegacyControlsVis('checked', el.value);
+            } else {
+                adjustLegacyControlsVis('unchecked', el.value);
+            }
+            toggleRowHighlighting(el);
+        });
+    }
+
     function handleUpdate(result) {
         if (result) {
             mylist = result.mylist;
-            document.getElementById('selected_records_count').innerHTML = mylist.length;
-            document.getElementById('record_cart_count').innerHTML = mylist.length;
+            if (selected_records_count_el) {
+                selected_records_count_el.innerHTML = mylist.length;
+            }
+            if (record_cart_count_el) {
+                record_cart_count_el.innerHTML = mylist.length;
+            }
             checkMaxCartSize();
         }
     }
     }
 
     function adjustLegacyControlsVis(op, rec) {
-        if (op == 'add') {
+        if (op == 'add' || op == 'checked') {
             var t;
             if (t = document.getElementById('mylist_add_' + rec)) t.classList.add('hidden');
             if (t = document.getElementById('mylist_delete_' + rec)) t.classList.remove('hidden');
-        } else {
+        } else if (op == 'delete' || op == 'unchecked') {
             if (t = document.getElementById('mylist_add_' + rec)) t.classList.remove('hidden');
             if (t = document.getElementById('mylist_delete_' + rec)) t.classList.add('hidden');
         }
     }
 
     function checkMaxCartSize() {
-        if ((typeof max_cart_size === 'undefined') || !max_cart_size) return;
-        var current_size = parseInt(document.getElementById('selected_records_count').innerHTML);
+        if ((typeof max_cart_size === 'undefined') || !max_cart_size || !mylist.length) return;
+        var alertel = document.getElementById('hit_selected_record_limit');
         [].forEach.call(rec_selectors, function(el) {
-            if (!el.checked) el.disabled = (current_size >= max_cart_size);
+            if (!el.checked) el.disabled = (mylist.length >= max_cart_size);
         });
-        var alertel = document.getElementById('hit_selected_record_limit');
-        if (current_size >= max_cart_size) {
-            alertel.classList.remove('hidden');
-            if (!document.getElementById('select_all_records').checked) {
-                document.getElementById('select_all_records').disabled = true;
+        if (mylist.length >= max_cart_size) {
+            if (alertel) alertel.classList.remove('hidden');
+            if (select_all_records_el && !select_all_records_el.checked) {
+                select_all_records_el.disabled = true;
             }
         } else {
-            alertel.classList.add('hidden');
-            document.getElementById('select_all_records').disabled = false;
+            if (alertel) alertel.classList.add('hidden');
+            if (select_all_records_el) select_all_records_el.disabled = false;
         }
     }
 
                 mungeList('delete', this.value);
                 adjustLegacyControlsVis('delete', this.value);
             }
-            toggleRowHighlighting(this);
+            toggleRowHighlighting(el);
         }, false);
         el.classList.remove("hidden");
         if (!el.checked) all_checked = false;
     });
-    if (all_checked) {
-        document.getElementById('select_all_records').checked = true;
+    if (rec_selectors.length && all_checked && select_all_records_el) {
+        select_all_records_el.checked = true;
     }
-    checkMaxCartSize();
 
     function deselectSelectedOnPage() {
         var to_del = [];
         }
     }
 
-    document.getElementById('select_all_records').addEventListener('click', function() {
-        if (this.checked) {
-            // adding
-            var to_add = [];
-            [].forEach.call(rec_selectors, function(el) {
-                if (!el.checked) {
-                    el.checked = true;
-                    adjustLegacyControlsVis('add', el.value);
-                    toggleRowHighlighting(el);
-                    to_add.push(el.value);
+    if (select_all_records_el) {
+        select_all_records_el.addEventListener('click', function() {
+            if (this.checked) {
+                // adding
+                var to_add = [];
+                [].forEach.call(rec_selectors, function(el) {
+                    if (!el.checked) {
+                        el.checked = true;
+                        adjustLegacyControlsVis('add', el.value);
+                        toggleRowHighlighting(el);
+                        to_add.push(el.value);
+                    }
+                });
+                if (to_add.length > 0) {
+                    mungeList('add', to_add);
                 }
-            });
-            if (to_add.length > 0) {
-                mungeList('add', to_add);
+            } else {
+                // deleting
+                deselectSelectedOnPage();
             }
-        } else {
-            // deleting
-            deselectSelectedOnPage();
-        }
-    });
+        });
+    }
 
-    document.getElementById('clear_selected_records').addEventListener('click', function() {
-        deselectSelectedOnPage();
-        document.getElementById('select_all_records').checked = false;
-    });
+    if (clear_selected_records_el) {
+        clear_selected_records_el.addEventListener('click', function() {
+            deselectSelectedOnPage();
+            if (select_all_records_el) select_all_records_el.checked = false;
+        });
+    }
 
 
 })();