Uploaded image for project: 'Sakai'
  1. Sakai
  2. SAK-30059

Consolidate JavaScript functions to disable controls and show a spinner into Reference (library)

    Details

      Description

      Currently, we're duplicating a lot of JavaScript across different tools to handle disabling of controls and showing spinners. The code now lives in assignments, authz, gradebook, site-manage, user and usermembership.

      The linked PR introduces a fancy new 'modern' spinner style into reference (library), for use across all projects in Sakai (sub-tasks of this ticket will rip out the old scattered JavaScript/spinners in favour of the new one). This new spinner style has two main incarnations:

      1) Overlay the spinner on top of a control the user has clicked or interacted with. This is for use with elements that have enough area for the spinner to be over-layed onto the control, such as buttons.
      2) Append a spinner as a sibling to a control the user has interacted with (or anywhere on the page if the override is specified). This is for use with elements that don't have enough area to over-lay a spinner on top of the control, such as a drop-down list.
      3) Apply the spinner to a pre-allocated div already in the DOM. This is for edge cases where dynamically adding a div to the DOM causes 'bouncing' effects when content is moved dynamically.

      With this in place in reference, it become simple to enable control disabling and spinners on user interaction on any page in Sakai:

      1) Add a reference to the JavaScript file in library on your page:

      <script type="text/javascript" src="/library/js/spinner.js"></script>

      2) Then, simply call one of the three methods provided in your onclick/onchange/etc event handler(s) on the elements a user can interact with:

      /**
       * This function is to be used with typical elements that have enough area to overlay
       * a spinner graphic on top. It will (clone and) disable all elements on the page,
       * and render a spinner graphic over top of the clicked element.
       * 
       * If no escapes are needed, pass in null for the escapeList parameter.
       * 
       * @param {DOM Element} clickedElement - the element being interacted with
       * @param {Array[String]} escapeList - array of IDs you do not wish to be disabled
       */
      SPNR.disableControlsAndSpin( clickedElement, escapeList );
      

      OR

      /**
       * This function is to be used with elements that don't have enough area to overlay
       * a spinner, such as a drop down. It will (clone and) disable all elements on the
       * page and render a spinner graphic beside (the sibling of) the element being
       * interacted with (by default).
       * 
       * If you want the spinner graphic to appear somewhere other than beside the element
       * being interacted with, supply the ID of the parent element where you want the
       * spinner to appear. The function will append the spinner graphic as a child of the
       * requested element.
       * 
       * If no escapes and/or no override spinner location is needed, pass in null for their
       * respective parameters.
       * 
       * @param {DOM Element} clickedElement
       * @param {Array[String]} escapeList
       * @param {String} overrideSpinnerLocation
       */
      SPNR.insertSpinnerAfter( clickedElement, escapeList, overrideSpinnerLocation );
      

      OR

       /**
       * This function is to be used in special cases where injecting an element into the DOM
       * causes 'bouncing' effects, where content is shifted dynamically.
       * 
       * In these special cases, you can add an empty div with a unique ID and the class
       * "allocatedSpinPlaceholder", so that the area is pre-allocated. This function will use
       * the pre-allocated div rather than injecting a div dynamically to avoid 'bouncing'.
       * 
       * If the div with the ID provided cannot be found, this will fallback to the
       * insertSpinnerAfter() algorithm.
       * 
       * If no escapes are needed, pass in null for the escapeList parameter.
       * 
       * @param {type} clickedElement - the element being interacted with
       * @param {type} escapeList - array of IDs you do not wish to be disabled
       * @param {type} allocatedID - the ID of the div manually added to the page to contain the spinner
       */
      SPNR.insertSpinnerInPreallocated = function( clickedElement, escapeList, allocatedID )
      

      NOTE: when using the insertSpinnerAfter/insertSpinnerInPreallocated functions, they relies on specific (flex-box) styles on the parent container in order to centre the spinner in line with the other elements in the container. Simply adding the class 'spinnerBesideContainer' to the container element should suffice to get it all lined up neatly.

        Gliffy Diagrams

          Zeplin

            Attachments

              Issue Links

                Activity

                  People

                  Assignee:
                  bjones86 Brian Jones
                  Reporter:
                  bjones86 Brian Jones
                  Votes:
                  0 Vote for this issue
                  Watchers:
                  2 Start watching this issue

                    Dates

                    Created:
                    Updated:
                    Resolved:

                      Git Integration