JAVASCRIPT   8

picker.js

Guest on 20th July 2021 03:36:39 PM

  1. /*!
  2.  * pickadate.js v3.5.6
  3.  * By Amsul, http://amsul.ca
  4.  * Hosted on http://amsul.github.io/pickadate.js
  5.  * Licensed under MIT
  6.  */
  7.  
  8. (function ( factory ) {
  9.  
  10.     // AMD.
  11.     if ( typeof define == 'function' && define.amd )
  12.         define( 'picker', ['jquery'], factory )
  13.  
  14.     // Node.js/browserify.
  15.     else if ( typeof exports == 'object' )
  16.         module.exports = factory( require('jquery') )
  17.  
  18.     // Browser globals.
  19.     else this.Picker = factory( jQuery )
  20.  
  21. }(function( $ ) {
  22.  
  23. var $window = $( window )
  24. var $document = $( document )
  25. var $html = $( document.documentElement )
  26. var supportsTransitions = document.documentElement.style.transition != null
  27.  
  28.  
  29. /**
  30.  * The picker constructor that creates a blank picker.
  31.  */
  32. function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
  33.  
  34.     // If there’s no element, return the picker constructor.
  35. tor.
  36.     if ( !ELEMENT ) return PickerConstructor
  37.  
  38.  
  39.     var
  40.         IS_DEFAULT_THEME = false,
  41.  
  42.  
  43.    // The state of the picker.
  44. ker.
  45.         STATE = {
  46.             id: ELEMENT.id || 'P' + Math.abs( ~~(Math.random() * new Date()) )
  47.         },
  48.  
  49.  
  50.    // Merge the defaults and options passed.
  51. sed.
  52.         SETTINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS ) : OPTIONS || {},
  53.  
  54.  
  55.    // Merge the default classes with the settings classes.
  56. ses.
  57.         CLASSES = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass ),
  58.  
  59.  
  60.    // The element node wrapper into a jQuery object.
  61. ect.
  62.         $ELEMENT = $( ELEMENT ),
  63.  
  64.  
  65.    // Pseudo picker constructor.
  66. tor.
  67.         PickerInstance = function() {
  68.             return this.start()
  69.         },
  70.  
  71.  
  72.    // The picker prototype.
  73. ype.
  74.         P = PickerInstance.prototype = {
  75.  
  76.             constructor: PickerInstance,
  77.  
  78.             $node: $ELEMENT,
  79.  
  80.  
  81.        /**
  82.              * Initialize everything
  83.              */   */
  84.             start: function() {
  85.  
  86.            // If it’s already started, do nothing.
  87.  nothing.
  88.                 if ( STATE && STATE.start ) return P
  89.  
  90.  
  91.       // Update the picker states.
  92. r states.
  93.                 STATE.methods = {}
  94.                 STATE.start = true
  95.                 STATE.open = false
  96.                 STATE.type = ELEMENT.type
  97.  
  98.  
  99.       // Confirm focus state, convert into text input to remove UA stylings,
  100. stylings,
  101.       // and set as readonly to prevent keyboard popup.
  102. rd popup.
  103.                 ELEMENT.autofocus = ELEMENT == getActiveElement()
  104.                 ELEMENT.readOnly = !SETTINGS.editable
  105.                 ELEMENT.id = ELEMENT.id || STATE.id
  106.                 if ( ELEMENT.type != 'text' ) {
  107.                     ELEMENT.type = 'text'
  108.                 }
  109.  
  110.  
  111.       // Create a new picker component with the settings.
  112. settings.
  113.                 P.component = new COMPONENT(P, SETTINGS)
  114.  
  115.  
  116.       // Create the picker root and then prepare it.
  117. epare it.
  118.                 P.$root = $( '<div class="' + CLASSES.picker + '" id="' + ELEMENT.id + ' )
  119.                prepareElementRoot()
  120.  
  121.  
  122.                // Create the picker holder and then prepare it.
  123.                P.$holder = $( createWrappedComponent() ).appendTo( P.$root )
  124.                prepareElementHolder()
  125.  
  126.  
  127.                // If there’s a format for the hidden input element, create the element.
  128.                if ( SETTINGS.formatSubmit ) {
  129.                    prepareElementHidden()
  130.                }
  131.  
  132.  
  133.                // Prepare the input element.
  134.                prepareElement()
  135.  
  136.  
  137.                // Insert the hidden input as specified in the settings.
  138.                if ( SETTINGS.containerHidden ) $( SETTINGS.containerHidden ).append( P._hidden )
  139.                else $ELEMENT.after( P._hidden )
  140.  
  141.  
  142.                // Insert the root as specified in the settings.
  143.                if ( SETTINGS.container ) $( SETTINGS.container ).append( P.$root )
  144.                else $ELEMENT.after( P.$root )
  145.  
  146.  
  147.                // Bind the default component and settings events.
  148.                P.on({
  149.                    start: P.component.onStart,
  150.                    render: P.component.onRender,
  151.                    stop: P.component.onStop,
  152.                    open: P.component.onOpen,
  153.                    close: P.component.onClose,
  154.                    set: P.component.onSet
  155.                }).on({
  156.                    start: SETTINGS.onStart,
  157.                    render: SETTINGS.onRender,
  158.                    stop: SETTINGS.onStop,
  159.                    open: SETTINGS.onOpen,
  160.                    close: SETTINGS.onClose,
  161.                    set: SETTINGS.onSet
  162.                })
  163.  
  164.  
  165.                // Once we’re all set, check the theme in use.
  166.                IS_DEFAULT_THEME = isUsingDefaultTheme( P.$holder[0] )
  167.  
  168.  
  169.                // If the element has autofocus, open the picker.
  170.                if ( ELEMENT.autofocus ) {
  171.                    P.open()
  172.                }
  173.  
  174.  
  175.                // Trigger queued the “start” and “render” events.
  176.                return P.trigger( '
  177.                 return P.trigger( 'start' )//start
  178. ( 'render' )
  179.  /**
  180.              * Render a new picker
  181.              */ Render a new picker
  182.              */
  183.             render: function( e// Insert a new component holder in the root or box.
  184. omponent holder in the root or box.
  185.                 if ( entireComponent ) {
  186.                     P.$holder = $( createWrappedComponent() )
  187.                     prepareElementHolder()
  188.                     P.$root.html( P.$holder )
  189.                 }
  190.                 else P.$root.find( '.' + CLASSES.box ).html( P.component.nod// Trigger the queued “render” events.
  191. ger the queued “render” events.
  192.                 //render
  193. trigger( 'rend/**
  194.              * Destroy everything
  195.              */        * Destroy everything
  196.              */
  197.     // If it’s already stopped, do nothing.
  198.   // If it’s already stopped, do nothing.
  199.              // Then close the picker.
  200. urn P
  201.  
  202.                 // Then close the pi// Remove the hidden field.
  203. e()
  204.  
  205.                 // Remove the hidden field.
  206.                 if ( P._hidden ) {
  207.                     P._hidden.parentNode.removeChild// Remove the root.
  208.           }
  209.  
  210.                 // Remove the root.
  211.  // Remove the input class, remove the stored data, and unbind
  212.  input class, re// the events (after a tick for IE - see `P.close`).
  213. he events (after a tick for IE - see `P.close`).
  214.                 $ELEMENT.removeClass( CLASSES.input ).removeData( NAME )
  215.                 setTimeout( function() {
  216.                     $ELEMENT.off( '.' + S// Restore the element state
  217. 0)
  218.  
  219.                 // Restore the element state
  220.                 ELEMENT.type = STATE.type
  221.          // Trigger the queued “stop” events.
  222.         // Trigger the queued “stop” even// Reset the picker states.
  223. r( 'stop' )
  224.  
  225.                 // Reset the picker states.
  226.                 STATE.methods = {}
  227.                 STAT//stop
  228.  = false
  229.  
  230.     /**
  231.              * Open up the picker
  232.              */    /**
  233.              * Open up the picker
  234.              */
  235.       // If it’s already open, do nothing.
  236.  
  237.  
  238.                 // If it’s already open, do nothing// Add the “active” class.
  239. en ) return P
  240.  
  241.                 // Add the “active” class.
  242.                 $ELEMENT.addClass( CLASSES.active// * A Firefox bug, when `html` has `overflow:hidden`, results in
  243.     // * A Firef//   killing transitions :(. So add the “opened” state on the next tick.
  244. lling transition//   Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
  245.                 //   Bug: https://bugzilla.mozilla.org/show_bu// Add the “opened” class to the picker root.
  246. on() {
  247.  
  248.                     // Add the “opened” class to the picker root.
  249.                     P.$root.addClass( CLASSES.opened )
  250.            // If we have to give focus, bind the element and doc events.
  251. }, 0 )
  252.  
  253.                 // If we have to give focus, bind the element // Set it as open.
  254.              if ( dontGiveFocus !== false ) {
  255.  
  256.             // Prevent the page from scrolling.
  257.            STATE.open = true
  258.  
  259.                     // Prevent the page from scrolling.
  260.                     if ( IS_DEFAULT_THEME ) {
  261.                         $html.
  262.                             css( 'overflow', 'hidden' ).
  263.                             css( 'pa// Pass focus to the root element’s jQuery object.
  264.           }
  265.  
  266.                     // Pass focus to the root elemen// Bind the document events.
  267.                  focusPickerOnceOpened()
  268.  
  269.                     // Bind the document events.
  270.                     $document.on( 'click.' + STATE.id + ' focusin.' + STATE.id, funct// If the target of the event is not the element, close the picker picker.
  271.                 // If th// * Don’t worry about clicks or focusins on the root because those don’t bubble up.
  272.   // * Don’t worr//   Also, for Firefox, a click on an `option` element bubbles up directly
  273. .
  274.                       //   to the doc. So make sure the target wasn't the doc.
  275. bubbles up directly
  276.     // * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
  277.                // * In F//   which causes the picker to unexpectedly close when right-clicking it. So make
  278.                        ///   sure the event wasn’t a right-click.
  279. close when right-clicking it. So make
  280.                         //   sure the event wasn’t a right-click.
  281.            // If the target was the holder that covers the screen,
  282. t && event.which != 3 ) {
  283.  
  284.  // keep the element focused to maintain tabindex.
  285. e holder that covers the screen,
  286.                             // keep the element focused to maintain tabindex.
  287.                             P.close( target === P.$holder[0] )
  288.                         }
  289.  
  290.                 // Get the keycode.
  291. ' + STATE.id, function( event ) {
  292.  
  293.                         var
  294.                    // Translate that to a selection change.
  295.                 keycode = event.keyCode,
  296.  
  297.                             // Translate that to a selectio// Grab the target.
  298.                   keycodeToMove = P.component.key[ keycode ],
  299.  
  300.              // On escape, close the picker and give focus.
  301.                 target = event.target
  302.  
  303.  
  304.                         // On escape, close the picker and give focus.
  305.                         if ( key// Check if there is a key movement or “enter” keypress on the element.
  306.        }
  307.  
  308.  
  309.                         // Check if there is a key movement or “enter” keypress on the element.
  310.          // Prevent the default action to stop page movement.
  311. keycodeToMove || keycode == 13 ) ) {
  312.  
  313.                             // Prevent the// Trigger the key movement action.
  314. t.
  315.                             event.preventDefault()
  316.  
  317.                             // Trigger the key movement action.
  318.                             if ( keycodeToMove ) {
  319.                                 PickerConstructor._.trigger( P.component.ke// On “enter”, if the highlighted item isn’t disabled, set the value and close.
  320.   }
  321.  
  322.                             // On “enter”, if the highlighted item isn’t disabled, set the value and close.
  323.                             else if ( !P.$root.find( '.' + CLASSES.highlighted ).hasClass( CLASSES.disabled ) ) {
  324.                                 P.set( 'select', P.component.item.highlight )
  325.                                 if ( SETTINGS.closeOnSelect ) {
  326.                                     // If the target is within the root and “enter” is pressed,
  327.               }
  328.         // prevent the default action and trigger a click on the target instead.
  329. e root and “enter” is pressed,
  330.                         // prevent the default action and trigger a click on the target instead.
  331.                         else if ( $.contains( P.$root[0], target ) && keycode == 13 ) {
  332.                             event.prev// Trigger the queued “open” events.
  333. target.click()
  334.                         }
  335.                  //open
  336.               /**
  337.              * Close the picker
  338.              */en” events.
  339.                 return P.trigger( 'open' )
  340. // If we need to give focus, do it before changing states.
  341. e the picker
  342.              */
  343.             close: function( giveFocus ) {
  344.  
  345.                 // If we need to give focus, do it before changing states.
  346.                 if ( giveFocus ) {
  347.             // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
  348.              }
  349.          // The focus is triggered *after* the close has completed - causing it
  350. ve been incomplete wit// to open again. So unbind and rebind the event at the next tick.
  351. cus is triggered *after* the close has completed - causing it
  352.                         // to open again. So unbind and rebind the event at the next tick.
  353.                         P.$holder.off( 'focus.toOpen' ).focus()
  354.                         setTimeout( function() {
  355.                   // Remove the “active” class.
  356. pen', handleFocusToOpenEvent )
  357.                         }, 0 )
  358.                     }
  359.                 }
  360.  
  361.                 // R// * A Firefox bug, when `html` has `overflow:hidden`, results in
  362. oveClass( CLASSE//   killing transitions :(. So remove the “opened” state on the next tick.
  363. / * A Firefox bu//   Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
  364.    //   killing transitions :(. So remove the “openedâ// Remove the “opened” and “focused” class from the picker root.
  365. ozilla.org/show_bug.cgi?id=625289
  366.                 setTimeout( function() {
  367.  
  368.                     // Remove the “opened” and “focused” class from the picker// If it’s already closed, do nothing more.
  369. ( CLASSES.opened + ' ' + CLASSES.focused )
  370.                   // Set it as closed.
  371. hidden', true )
  372.  
  373.                 }, 0 )
  374.  
  375.            // Allow the page to scroll.
  376. y closed, do nothing more.
  377.                 if ( !STATE.open ) return P
  378.  
  379.                 // Set it as closed.
  380.                 STATE.open = false
  381.  
  382.                 // Allow the page to scroll.
  383.                 if ( IS_DEFAULT_THEM// Unbind the document events.
  384. .
  385.                         css( '.'erflow', '' ).
  386.                 // Trigger the queued “close” events.
  387. rollbarWidth() )
  388.                 }
  389.  
  390.                 // Unbi//close
  391. ocument events/**
  392.              * Clear the values
  393.              */                // Trigger the queued “close” events.
  394.                 return P.trigger( 'close' )
  395.   //clear
  396.   }, //close
  397.  
  398. /**
  399.              * Set something
  400.              */
  401.              */
  402.             clear: function( options ) {
  403.                 return P.set( 'clear', null, options )
  404.             }, //clear
  405.  
  406.  
  407.             /**
  408.              * Set something
  409.              */
  410.             set: function( thing, value// Make sure we have usable options.
  411. ingItem, thingValue,
  412.                     thingIsObject = $.isPlainObject( thing ),
  413.                     thingObject = thingIsObject ? thing : {}
  414.  
  415. // If the thing isn’t an object, make it one.
  416. ons.
  417.                 options = thingIsObject && $.isPlainObject( value ) ? value : options || {}
  418.  
  419.                 if ( thing ) {
  420.  
  421.           // Go through the things of items to set.
  422. object, make it one.
  423.                     if ( !thingIsObject ) {
  424.                // Grab the value of the thing.
  425. value
  426.                     }
  427.  
  428.                     // Go through the things of items to s// First, if the item exists and there’s a value, set it.
  429.                         // Grab the value of the thing.
  430.                         thingValue = thingObject[ thingItem ]
  431.  
  432.                         // First, if the item exists and there’s a value, set it.
  433.                         if ( thingItem in P.component.item ) {// Then, check to update the element value and broadcast a change.
  434. alue = null
  435.                             P.component.set( thingItem, thingValue, options )
  436.                         }
  437.  
  438.                         // Then, check to update the element value and broadcast a change.
  439.                         if ( thingItem == 'select' || thingItem == 'clear' ) {
  440.                             $ELEMENT.
  441.                  // Render a new picker.
  442. gItem == 'clear' ? '' : P.get( thingItem, SETTINGS.format ) ).
  443.    // When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
  444.  }
  445.  
  446.                     // Render a new picker.
  447.                     P.render()
  448.            //set
  449.  
  450.  
  451.             /**
  452.              * Get something
  453.              */er queued “set” events and pass the `thingObject`.
  454. // Make sure there’s something to get.
  455. : P.trigger( 'set', thingObject )
  456.             }, //set
  457.  
  458.  
  459.  // If a picker state exists, return that.
  460. g
  461.              */
  462.             get: function( thing, format ) {
  463.  
  464.                 // Make sure there’s something to get.// Return the submission value, if that.
  465.  
  466.  
  467.                 // If a picker state exists, return that.
  468.                 if ( STATE[ thing ] != null ) {
  469.                     return STATE[ thing ]
  470.                 }
  471.  
  472.                 // Return the submission value, if that.
  473.  // Return the value, if that.
  474. valueSubmit' ) {
  475.                     if ( P._hidden ) {
  476.                         return P._hidden.value
  477.                // Check if a component item exists, return that.
  478.          }
  479.  
  480.                 // Return the value, if that.
  481.                 if ( thing == 'value' ) {
  482.                     return ELEMENT.value
  483.                 }
  484.  
  485.                 // Check if a component item exists, return that.
  486.                 if ( thing in P.component.item ) {
  487.                     if ( typeof format == 'string' ) {
  488.                         var thingValue = P.component.get( thing )
  489.                         return thingValue ?
  490.                             PickerConstructor._.trigger(
  491.                                 P.component.formats.toString,
  492.                 //get
  493.           P.com/**
  494.              * Bind events on the things.
  495.              */]
  496.                             ) : ''
  497.                     }
  498.                     return P.component.get( thing )
  499.                 }
  500.             }, //get
  501.  
  502.  
  503.  
  504.             /**
  505.              * Bind events on the things.
  506.              */
  507.             on: function( thing, method, internal// If the thing isn’t an object, make it one.
  508. ,
  509.                     thingIsObject = $.isPlainObject( thing ),
  510.                     thingObject = thingIsObject ? thing : {}
  511.  
  512.                // Go through the things to bind to.
  513. // If the thing isn’t an object, make it one.
  514.                     if ( !t// Grab the method of the thing.
  515.         thingObject[ thing ] = method
  516.                     }
  517.  
  518.                     // Go t// If it was an internal binding, prefix it.
  519.      for ( thingName in thingObject ) {
  520.  
  521.                         // Grab the method of the thing.
  522.                         thingMethod = thingObject[ // Make sure the thing methods collection exists.
  523. an internal binding, prefix it.
  524.                         if ( internal ) {
  525.                             thingName// Add the method to the relative method collection.
  526.                  // Make sure the thing methods collection exists.
  527.                         STATE.methods[ thingName ] = STATE.methods[ thingName ] || []//on
  528.                /**
  529.              * Unbind events on the things.
  530.              */                    STATE.methods[ thingName ].push( thingMethod )
  531.                     }
  532.                 }
  533.  
  534.                 return P
  535.             }, //on
  536.  
  537.  
  538.  
  539.             /**
  540.              * Unbind events on the things.
  541.              */
  542.             off: function() {
  543.                 var i, thingName,
  544.                     names = arguments;
  545.                 for ( i = 0, namesCount = names.length; i < namesCount; i += 1 ) {
  546.                 /**
  547.              * Fire off method events.
  548.              */e in STATE.methods ) {
  549.                         delete STATE.methods[thingName]
  550.                     }
  551.                 }
  552.                 return P
  553.             },
  554.  
  555.  
  556.             /**
  557.              * Fire off method events.
  558.              */
  559.             trigger: function( name, data ) {
  560.                 var _trigger = function( name ) {
  561.                     var methodList = STATE.methods[ name ]
  562.                     if ( methodList ) {
  563.                         methodList.map( function( method ) {
  564.                           //trigger
  565. nstructor.//PickerInstance.prototype
  566. a ] )
  567. /**
  568.      * Wrap the picker holder components together.
  569.      */   }
  570.                 _trigger( '_' + name )
  571.       // Create a picker wrapper holder
  572.          return P
  573.             } //trigger
  574.         } //PickerI// Create a picker wrapper node
  575.  * Wrap the picker holder components together.
  576.      */
  577.     fun// Create a picker frame
  578. ent() {
  579.  
  580.         // Create a picker wrapper holder
  581.         return Pick// Create a picker box node
  582.  
  583.  
  584.             // Create a picker wrapper node
  585.             PickerConstructor._.// Create the components nodes.
  586.  Create a picker frame
  587.                 PickerConstructor._.node( 'div',
  588.  
  589.          // The picker box class
  590. icker box node
  591.                     PickerConstructor._.node( 'div',
  592.  
  593.            // Picker wrap class
  594. e the components nodes.
  595.                         P.component.nodes( ST// Picker frame class
  596.                // The picker box class
  597.                    // Picker holder class
  598.               ),
  599.  
  600.                     // Picker wrap class
  601.         //endreturn
  602. CLASSE//createWrappedComponent
  603.  
  604.  
  605.      /**
  606.      * Prepare the input element with all bindings.
  607.      */            ),
  608.  
  609.             // Picker holder class
  610.             CL// Store the picker data by component name.
  611.        ) //endreturn
  612.     } //createWrapp// Add the “input” class name.
  613. re the input element with all bindings.
  614.      */
  615.   // If there’s a `data-value`, update the value of the element.
  616. Store the picker data by component name.
  617.             data(NAME, P).
  618.  
  619.             // Add the “input” class name.
  620.             addClass(CL// Only bind keydown events if the element isn’t editable.
  621. `, update the value of the element.
  622.             val( $ELEMENT.data('value') // On focus/click, open the picker.
  623. TTINGS.format) :
  624.                 ELEMENT.value
  625.             )
  626.  
  627.  
  628.         // Only bind keydown events if the element isn’t editable.
  629.         if ( !SETTINGS.editable ) {
  630.  
  631.             $ELEM// Handle keyboard event based on the picker being opened or not.
  632.         on( 'focus.' + STATE.id + ' click.' + STATE.id, function(event) {
  633.           // Update the aria attributes.
  634. )
  635.                     P.open()
  636.                 }).
  637.  
  638.                 // Handle keyboard event based on the picker being opened or not.
  639.                 on( 'keydown.' + STATE/**
  640.      * Prepare the root picker element with all bindings.
  641.      */ibutes.
  642.         aria(ELEMENT, {
  643.             haspopup: true,
  644.             expanded: false,
  645.     /**
  646.       * Prepare the holder picker element with all bindings.
  647.       */)
  648.     }
  649.  
  650.  
  651.     /**
  652.      * Prepare the root picker element with all bindings.
  653.      */
  654.     functi// For iOS8.
  655. mentRoot() {
  656.         aria( P.$root[0], 'hidden', true )
  657.     }
  658.  
  659.  
  660.      /**
  661.       * Prepare the holder picker element with all bindings.
  662.       */
  663.     function pr// Remove the “target” class.
  664. $holder.
  665.  
  666.             on({
  667.  
  668.                 // For iOS8.
  669.                 keydown: handleKeydown// When something within the holder is focused, stop from bubbling
  670.               bl// to the doc and remove the “focused” state from the root.
  671. ” class.
  672.                     $ELEMENT.removeClass( CLASSES.target )
  673.                 },
  674.  
  675.                 // When something within the holder is focused, stop from bubbling
  676.        // When something within the holder is clicked, stop it
  677.  state from t// from bubbling to the doc.
  678. sin: function( event ) {
  679.                     P.$root.removeClass( CLASSES.focused )
  680.                     event.stopPropagati// Make sure the target isn’t the root holder so it can bubble up.
  681.  holder is clicked, stop it
  682.                 // from bubbling to the doc.
  683.                 'mousedown click': function( event ) // * For mousedown events, cancel the default action in order to
  684.      // Make sure the ta//   prevent cases where focus is shifted onto external elements
  685.           if ( target !=//   when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
  686.              // * For mo//   Also, for Firefox, don’t prevent action on the `option` element.
  687.       //   prevent cases where focus is shifted onto external elements
  688.                         //   when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
  689.                         //   // Re-focus onto the holder so that users can click away
  690. tion` element.
  691.              // from elements focused within the picker.
  692.  !$( target ).is( 'input, select, textarea, button, option' )) {
  693.  
  694.                             event.preventDefault()
  695.  
  696.                            // If there’s a click on an actionable element, carry out the actions.
  697.              // from elements focused within the picker.
  698.                             P.$holder[0].focus()
  699.                         }
  700.                     }
  701.                 }
  702.  
  703.             }).
  704.  
  705.             // If there’s a click on an actionable element, carry out the actions.
  706.             on( 'click', '[data-pick], [dat// * For IE, non-focusable elements can be active elements as well
  707. var $target = $( thi//   (http://stackoverflow.com/a/2684561).
  708. et.data(),
  709.                     targetDisabled = $target.hasClass( CLASSES.navDisabled ) || $target.hasClass( CLASSES.disabled ),
  710.  
  711.                     // * For IE, non-foc// If it’s disabled or nothing inside is actively focused, re-focus the element.
  712. ckoverflow.com/a/2684561).
  713.                     activeElement = getActiveElement()
  714.                     activeElement = activeElement && ( activeElement.type || activeElement.href// If something is superficially changed, update the `highlight` based on the `nav`.
  715.  re-focus the element.
  716.                 if ( targetDisabled || activeElement && !$.contains( P.$root[0], activeElement ) ) {
  717.                     P.$holder[0].focus()
  718.                 }
  719.  
  720.     // If something is picked, set `select` then close with focus.
  721. e `highlight` based on the `nav`.
  722.                 if ( !targetDisabled && targetData.nav ) {
  723.                     P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } )
  724.                 }
  725.  
  726.                 // If something is picked, set `select` then close w// If a “clear” button is pressed, empty the values and close with focus.
  727.  {
  728.                     P.set( 'select', targetData.pick )
  729.                     if ( SETTINGS.closeOnSelect ) {
  730.                         P.close( true )
  731.                     }
  732.                 }
  733.  
  734.                 // If a “clear” button is pressed, empty the values and close with focus.
  735.                 else if ( targetD//P.$holder
  736. {
  737.             /**
  738.       * Prepare the hidden input element along with all bindings.
  739.       */               P.close( true )
  740.                     }
  741.                 }
  742.  
  743.                 else if ( targetData.close ) {
  744.                     P.close( true )
  745.                 }
  746.  
  747.             }) //P.$holder
  748.  
  749.     }
  750.  
  751.  
  752.      /**
  753.       * Prepare the hidden input element along with all bindings.
  754.       */
  755.     function prepareElementHidden() {
  756.  
  757.         var name
  758.  
  759.         if ( SETTINGS.hiddenName === true ) {
  760.             name = ELEMENT.name
  761.             ELEMENT.name = ''
  762.         }
  763.         else {
  764.             name = [
  765.                 typeof SETTINGS.hiddenPrefix == 'stri// Create the name using the original input’s with a prefix and suffix.
  766. ffix == 'string' ? SETTINGS.hiddenSuffix : '_subm// If the element has a value, set the hidden value as well.
  767.  name[1]
  768.         }
  769.  
  770.         P._hidden = $(
  771.             '<input ' +
  772.             'type=hidden ' value="'       // Create the name using the original input’s with a prefix and suffix.
  773.             'name="' + name + '"' +
  774.  
  775.             // If the eleme// If the value changes, update the hidden input with the correct format.
  776.   $ELEMENT.data('value') || ELEMENT.value ?
  777.                     ' value="' + P.get('select', SETTINGS.formatSubmit) + '"' :
  778.                     ''
  779.             ) +
  780.             '>'
  781.         )[0]
  782.  
  783.         $ELEMENT.
  784. // Wait for transitions to end before focusing the holder. Otherwise, while
  785. ct f// using the `container` option, the view jumps to the container.
  786.        P._hidden.value = ELEMENT.value ?
  787.                     P.get('select', SETTINGS.formatSubmit) :
  788.                     '.'            })
  789.     }
  790.  
  791.  
  792.     // Wait for transitions to end before focusing the holder. Otherwise, while
  793.     // using the `container` option, the view jumps to the container.
  794.     function focusPickerOnceOpened() {
  795.  
  796.         if (IS_DEFAUL// Stop the event from propagating to the doc.
  797. .$holder.find('.' + CLASSES.frame).one('t// Add the “target” class.
  798.              P.$holder[0].focus()
  799.             })
  800.     // Add the “focused” class to the root.
  801. ].focus()
  802.         }
  803.     }
  804.  
  805.  
  806.     function handleFocusT// And then finally open the picker.
  807. the event from propagating to// For iOS8.
  808.      event.stopPropagation()
  809.  
  810.         // Add the “target” class.
  811.         $ELEMENT.// Check if one of the delete keys was pressed.
  812. €œfocused” class to the root.
  813.         P.$root.addClass// For some reason IE clears the input value on “escape”.
  814. er.
  815.         P.open()
  816.     }
  817.  
  818.  
  819.     // For iOS8.
  820.     function handleKeydownEvent( event ) {
  821.  
  822.         var k// Check if `space` or `delete` was pressed or the picker is closed with a key movement.
  823.         isKeycodeDelete = || isKeyc.test(keycode)
  824.  
  825.         // For some reason IE clears the input value o// Prevent it from moving the page and bubbling to doc.
  826.            P.close( true )
  827.             return false
  828.         }
  829.  
  830.         // Check if `// If `delete` was pressed, clear the values and close the picker.
  831. ovement.
  832.    // Otherwise open the picker.
  833. eycodeDelete || !STATE.open && P.component.key[keycode] ) {
  834.  
  835.             // Prevent it from moving the page a// Return a new picker instance.
  836. vent.preventDefault()
  837.             //PickerConstructor
  838. n()/**
  839.  * The default classes and prefix to use for the HTML classes.
  840.  */he picker.
  841.             // Otherwise open the picker.
  842.             if ( isKeycodeDelete ) { P.clear().close() }
  843.             else { P.open() }
  844.         }
  845.     }
  846.  
  847.  
  848.     // Return a new picker instance.
  849.     return new PickerInstance()
  850. } //PickerConstructor
  851.  
  852.  
  853.  
  854. /**
  855.  * The default classes and prefix to use for the HTML classes.
  856.  */
  857. PickerConstructor.klasses = function( prefix ) {
  858.     prefix = prefix || 'picker'
  859.     return {
  860.  
  861.         picker: prefix,
  862.         opened: prefix +//PickerConstructor.klasses
  863. : p/**
  864.  * Check if the default theme is being used.
  865.  */ut',
  866.         active: prefix + '__input--active',
  867.         target: prefix + 'position'target// For IE.
  868.  holder: prefix + '__holder',
  869.  
  870.         frame: prefix + '__frame',
  871.         wrap: prefix +// For normal browsers.
  872.  prefix + '__box'
  873.     }
  874. } //PickerConstructor.klasses
  875.  
  876.  
  877.  
  878. /**
  879.  * Check if the default theme is being used.
  880.  */
  881. function isUsingDefaul/**
  882.  * Get the width of the browser’s scrollbar.
  883.  * Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
  884.  */ntStyle[prop]
  885.     }
  886.  
  887.     // For normal browsers.
  888.     else if ( window.getComputedStyle ) {
  889.         theme = getComputedStyle( element )[prop]
  890.     }
  891.  
  892.     return theme == 'fixed'
  893. }
  894.  
  895.  
  896.  
  897. /**
  898.  * Get the width of the// Get the width without scrollbars.
  899.  from: https://github.com/VodkaBears/Remodal/blob/master// Force adding scrollbars.
  900. unction getScrollbarWidth() {
  901.  
  902.     if ( $htm// Add the inner div.
  903. height() ) {
  904.         return 0
  905.     }
  906.  
  907.     var $outer = $( '<div style="visib// Get the width with scrollbars.
  908.        appendTo( 'body' )
  909.  
  910.     // Get the width witho// Remove the divs.
  911. ar widthWithoutScroll = $// Return the difference between the widths.
  912. ollbars.
  913.     $outer.css( 'overflow', 'scroll' )
  914.  
  915.     /**
  916.  * PickerConstructor helper methods.
  917.  */div style="width:100%" />' ).a/**
  918.      * Create a group of nodes. Expects:
  919.      * `
  920.         {
  921.             min:    {Integer},
  922.             max:    {Integer},
  923.             i:      {Integer},
  924.             node:   {String},
  925.             item:   {Function}
  926.         }
  927.      * `
  928.      */oll
  929. }
  930.  
  931.  
  932.  
  933. /**
  934.  * PickerConstructor helper methods.
  935.  */
  936. PickerCon// Scope for the looped object
  937. Create a group of nodes. Expects:
  938.      * `// Create the nodes list
  939. n:    {Integer},
  940.             max:    {Int// The counter starts from the `min`
  941.  
  942.             node:   {String},
  943.             item:   {Function}
  944.         }
  945.      * `
  946.      */
  947.    // Loop from the `min` to `max`, incrementing by `i`
  948.       // Scope for the looped object
  949.             loopObjectScope,
  950.  
  951.             // Create the nodes list
  952.             nodesList = '',
  953.  
  954.           // Trigger the `item` function within scope of the object
  955.  = PickerConstructor._.trigger( groupObject.min, groupObject )
  956.  
  957.  
  958.         // Loop from the `min` to `max`, incrementin// Splice the subgroup and create nodes out of the sub nodes
  959. er( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) {
  960.  
  961.             // Trigger the `item` function wit// the node
  962.  the object
  963.             loopObjectScope // the classes
  964. ctor._.trigger( groupObject.item, groupO// the attributes
  965.  )
  966.  
  967.             // Splice the sub// Return the list of nodes
  968. f the sub nodes
  969.             node//group
  970.  Picke/**
  971.      * Create a dom node string
  972.      */bject.node,
  973.                 loopObjectScope[ 0 ],   // the node
  974.   // If the item is false-y, just return an empty string
  975.               loopObjectScope[ 2 ]    //// If the item is an array, do a join
  976. }
  977.  
  978.         // Return the list of nodes
  979.         return nodesList
  980.    // Check for the class
  981.     * Create a dom node string
  982.      */
  983.     node: function( wrap// Check for any attributes
  984. ) {
  985.  
  986.         // If the item is false-y, just return an empty s// Return the wrapped item
  987. return ''
  988.  
  989.         // If the item is an array, do a join
  990.         item = $.isArray( item ) ? //node
  991. in( ''/**
  992.      * Lead numbers below 10 with a zero.
  993.      */ss = klass ? ' class="' + klass + '"' : ''
  994.  
  995.         // Check for any attributes
  996.         attribu/**
  997.      * Trigger a function otherwise return the value.
  998.      */ped item
  999.         return '<' + wrapper + klass + attribute + '>' + item + '</' + wrapper + '>'
  1000.     }, //node
  1001.  
  1002.  
  1003.     /**
  1004.      * Lead numbers below 10 with a zer/**
  1005.      * If the second character is a digit, length is 2 otherwise 1.
  1006.      */' ) + number
  1007.     },
  1008.  
  1009.  
  1010.     /**
  1011.      * Trigger a function otherwise return the value.
  1012.      */
  1013.     tri/**
  1014.      * Tell if something is a date object.
  1015.      */rn typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback
  1016.     },
  1017.  
  1018.  
  1019.     /**
  1020.      * If the second character is a digit, lengt/**
  1021.      * Tell if something is an integer.
  1022.      */tring ) {
  1023.         return ( alue ).test( string[ 1 ] ) ? 2 : 1
  1024.     },
  1025.  
  1026.  
  1027.     /**
  1028.      * Tell if something is a date object.
  1029.      */
  1030.     /**
  1031.      * Create ARIA attribute strings.
  1032.      */tring.call( value ).indexO//PickerConstructor._
  1033. is./**
  1034.  * Extend the picker with a component and defaults.
  1035.  */f something is an integer.
  1036.      */
  1037.     isInteger: function( val// Extend jQuery.
  1038. urn {}.toString.call( value ).indexOf( 'Number' ) > -1 && // Grab the component data.
  1039.  /**
  1040.      * Create ARIA attribute strings.
  1041.      */
  1042.     // If the picker is requested, return the data object.
  1043. tend the picker with a component and defaults.
  1044.  */
  1045. PickerConstructor.extend = function( n// If the component data exists and `options` is a string, carry out the action.
  1046. ction ) {
  1047.  
  1048.         // Grab the component data.
  1049.         var componentData = this.data( name )
  1050.  
  1051.         // If the picker is requested, return the data object.
  1052.         if ( options == '// Otherwise go through each matched element and if the component
  1053.  If the // doesn’t exist, create a new picker using `this` element
  1054. e action// and merging the defaults and options with a deep copy.
  1055.  ) {
  1056.             return PickerConstructor._.trigger( componentData[ options ], componentData, [ action ] )
  1057.         }
  1058.  
  1059.         // Otherwise go through each matched element and if the component
  1060.         // doesn’t exis// Set the defaults.
  1061. r using `this` element
  1062.         // and merging the//PickerConstructor.extend
  1063. a deep copy.
  1064.         return this.each( function() {
  1065.             var $this = $( this )
  1066.             if ( !$this.data( name ) ) {
  1067.                 new PickerConstructor( this, name, Component, options )
  1068.             }
  1069.         })
  1070.     }
  1071.  
  1072.     // Set the defaults.
  1073.     $.fn[ name ].defaults = Component.defaults
  1074. } //PickerConstructor.extend
  1075.  
  1076.  
  1077.  
  1078. function aria(element, attribute, value) {
  1079.     if ( $.isPlainObject(attribute) ) {
  1080.         for ( var key in attribute ) {
  1081.             ariaSet(element, key, attribute[key])
  1082.         }
  1083.     }
  1084.     else {
  1085.         ariaSet(element, attribute, value)
  1086.     }
  1087. }
  1088. function ariaSet(element, attribute, value) {
  1089.     element.setAttribute(
  1090.         (attribute == 'role' ? '' : 'aria-') + attribute,
  1091.         value
  1092.     )
  1093. }
  1094. function ariaAttr(attribute, data)// IE8 bug throws an error for activeElements within iframes.
  1095. = { attribute: data }
  1096.     }
  1097.     data = ''
  1098.     for ( var key in attribute ) {
  1099.         var attr = (key == 'ro// Expose the picker constructor.
  1100.      attrVal = attribute[key]
  1101.  

Raw Paste


Login or Register to edit or fork this paste. It's free.