public/app.js
// Define the function that fires when the order by conjunctionSelector changes.
Define the function that fires when the order by conjunctionSelector changes.
Define the function that fires when the order by conjunctionSelector changes .
function onChangeBehaviorForOrderByConjunctionSelector (event)  
  {
    event.preventDefault();
    let orderByClauseWrapperCount = document.querySelectorAll(".orderByClauseWrapper").length;
    let previousSetting = event.target.getAttribute('data-previous');
    if (event.target.value == "") 
    {
      event.target.value = event.target.parentNode.parentNode.nextElementSibling.querySelectorAll(".orderByConjunctionSelector")[0].value;
      event.target.parentNode.parentNode.parentNode.removeChild(event.target.parentNode.parentNode.nextElementSibling);
      event.target.setAttribute('data-previous', event.target.value);
    }
    else if (event.target.value != "" && previousSetting == "")
    {
      event.target.setAttribute('data-previous','');
      let elmnt = document.querySelectorAll(".orderByClauseWrapper")[orderByClauseWrapperCount - 1];
      let cln = elmnt.cloneNode(true);
      cln.querySelectorAll(".resetElement").forEach(function(element){element.value = "";}); 
      cln.querySelectorAll(".fieldToOrderBy")[0].addEventListener("change", onChangeBehaviorForFieldToOrderBySelector);  
      cln.querySelectorAll(".orderByConjunctionSelector")[0].addEventListener("change", onChangeBehaviorForOrderByConjunctionSelector);
      document.querySelectorAll(".orderByClauseGroupWrapper")[0].appendChild(cln);     
      event.target.setAttribute('data-previous', event.target.value);
    }
  } 
function onChangeBehaviorForOrderByConjunctionSelector ( event ) { event . preventDefault ( ) ; let orderByClauseWrapperCount = document . querySelectorAll ( ".orderByClauseWrapper" ) . length ; let previousSetting = event . target . getAttribute ( 'data-previous' ) ; if ( event . target . value == "" ) { event . target . value = event . target . parentNode . parentNode . nextElementSibling . querySelectorAll ( ".orderByConjunctionSelector" ) [ 0 ] . value ; event . target . parentNode . parentNode . parentNode . removeChild ( event . target . parentNode . parentNode . nextElementSibling ) ; event . target . setAttribute ( 'data-previous' , event . target . value ) ; } else if ( event . target . value != "" && previousSetting == "" ) { event . target . setAttribute ( 'data-previous' , '' ) ; let elmnt = document . querySelectorAll ( ".orderByClauseWrapper" ) [ orderByClauseWrapperCount - 1 ] ; let cln = elmnt . cloneNode ( true ) ; cln . querySelectorAll ( ".resetElement" ) . forEach ( function ( element ) { element . value = "" ; } ) ; cln . querySelectorAll ( ".fieldToOrderBy" ) [ 0 ] . addEventListener ( "change" , onChangeBehaviorForFieldToOrderBySelector ) ; cln . querySelectorAll ( ".orderByConjunctionSelector" ) [ 0 ] . addEventListener ( "change" , onChangeBehaviorForOrderByConjunctionSelector ) ; document . querySelectorAll ( ".orderByClauseGroupWrapper" ) [ 0 ] . appendChild ( cln ) ; event . target . setAttribute ( 'data-previous' , event . target . value ) ; } }
Define the function that fires when the order by conjunctionSelector changes.
Define the function that fires when the order by conjunctionSelector changes .
// Stop it from redirecting anywhere // Start of: Delete the filter elements directly below or add new ones depending on user's input. // Get a count of how many order by expressions already exist. // Get the previous setting if any. // Check the value of the conjunction select element chosen by the user. // If the blank option was selected we will delete the filter below. // Get the value of the conjunction control we are about to delete because this value joins the next  // filter down the line (if one exists). We will move this value into the current conjuction selector. // Delete the filter below. // Store the new value as an attribute in case we need to work with this select element in the future. // otherwise if a conjunction was selected where it was previously blank we will add a new filter. // Blank out the attribute that tracks the previous setting so that the cloned control starts out clean. // Clone a new wrapper, the child select element, and children options from the previous and append it to the DOM // Set all the element values to "" // Create an event listener for the onchange event of the newly cloned select element and bind this function to it. // Append the new clone to the new where-clause group // Now that cloning is done we can use this attribute to keep track of the  // new value of the current conjunction control in case we need to change it again. // End of: Delete the filter elements directly below or add new ones depending on user's input. // End of: function onChangeBehaviorForOrderByConjunctionSelector (event)