File indexing completed on 2024-05-19 06:00:15

0001 /* ==========================================================
0002  * bootstrap-formhelpers-selectbox.js
0003  * https://github.com/vlamanna/BootstrapFormHelpers
0004  * ==========================================================
0005  * Copyright 2012 Vincent Lamanna
0006  *
0007  * Licensed under the Apache License, Version 2.0 (the "License");
0008  * you may not use this file except in compliance with the License.
0009  * You may obtain a copy of the License at
0010  *
0011  * http://www.apache.org/licenses/LICENSE-2.0
0012  *
0013  * Unless required by applicable law or agreed to in writing, software
0014  * distributed under the License is distributed on an "AS IS" BASIS,
0015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016  * See the License for the specific language governing permissions and
0017  * limitations under the License.
0018  * ========================================================== */
0019 
0020 
0021 !function ($) {
0022 
0023   "use strict"; // jshint ;_;
0024 
0025 
0026  /* SELECTBOX CLASS DEFINITION
0027   * ========================= */
0028 
0029   var toggle = '[data-toggle=bfh-selectbox]'
0030     , BFHSelectBox = function (element) {
0031       }
0032 
0033   BFHSelectBox.prototype = {
0034 
0035     constructor: BFHSelectBox
0036 
0037   , toggle: function (e) {
0038       var $this = $(this)
0039         , $parent
0040         , isActive
0041 
0042       if ($this.is('.disabled, :disabled')) return false
0043 
0044       $parent = getParent($this)
0045 
0046       isActive = $parent.hasClass('open')
0047 
0048       clearMenus()
0049 
0050       if (!isActive) {
0051         $parent.toggleClass('open')
0052         
0053         $parent.find('[role=option] > li > [data-option="' + $this.find('.bfh-selectbox-option').data('option') + '"]').focus()
0054       }
0055 
0056       return false
0057     }
0058 
0059   , filter: function(e) {
0060     var $this
0061       , $parent
0062       , $items
0063       
0064     $this = $(this)
0065     
0066     $parent = $this.closest('.bfh-selectbox')
0067     
0068     $items = $('[role=option] li a', $parent)
0069     
0070     $items.hide()
0071     
0072     $items.filter(function() { return ($(this).text().toUpperCase().indexOf($this.val().toUpperCase()) != -1) }).show()
0073   }
0074   
0075   , keydown: function (e) {
0076       var $this
0077         , $items
0078         , $active
0079         , $parent
0080         , isActive
0081         , index
0082 
0083       if (!/(38|40|27)/.test(e.keyCode) && !/[A-z]/.test(String.fromCharCode(e.which))) return
0084 
0085       $this = $(this)
0086 
0087       e.preventDefault()
0088       e.stopPropagation()
0089 
0090       if ($this.is('.disabled, :disabled')) return false
0091 
0092       $parent = $this.closest('.bfh-selectbox')
0093 
0094       isActive = $parent.hasClass('open')
0095 
0096       if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
0097 
0098       $items = $('[role=option] li a', $parent).filter(':visible')
0099 
0100       if (!$items.length) return
0101 
0102       $('body').off('mouseenter.bfh-selectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.mouseenter)
0103       
0104       index = $items.index($items.filter(':focus'))
0105 
0106       if (e.keyCode == 38 && index > 0) index--                                        // up
0107       if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
0108       if (/[A-z]/.test(String.fromCharCode(e.which))) {
0109         var $subItems = $items.filter(function() { return ($(this).text().charAt(0).toUpperCase() == String.fromCharCode(e.which)) })
0110         var selectedIndex = $subItems.index($subItems.filter(':focus'))
0111         if (!~selectedIndex) index = $items.index($subItems)
0112         else if (selectedIndex >= $subItems.length - 1) index = $items.index($subItems)
0113         else index++
0114       }
0115       if (!~index) index = 0
0116       
0117       $items
0118         .eq(index)
0119         .focus()
0120         
0121       $('body').on('mouseenter.bfh-selectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.mouseenter)
0122     }
0123     
0124     , mouseenter: function (e) {
0125           var $this
0126           
0127           $this = $(this)
0128           
0129           if ($this.is('.disabled, :disabled')) return false
0130           
0131           $this.focus()
0132     }
0133     
0134     , select: function (e) {
0135       var $this
0136         , $parent
0137         , $toggle
0138         , $input
0139       
0140       $this = $(this)
0141       
0142       e.preventDefault()
0143       e.stopPropagation()
0144       
0145       if ($this.is('.disabled, :disabled')) return false
0146       
0147       $parent = $this.closest('.bfh-selectbox')
0148       $toggle = $parent.find('.bfh-selectbox-option')
0149       $input = $parent.find('input[type="hidden"]')
0150       
0151       $toggle.data('option', $this.data('option'))
0152       $toggle.html($this.html())
0153       
0154       $input.removeData()
0155       $input.val($this.data('option'))
0156       $.each($this.data(), function(i,e) {
0157         $input.data(i,e);  
0158       });
0159       $input.change()
0160       
0161       clearMenus()
0162     }
0163 
0164   }
0165 
0166   function clearMenus() {
0167     getParent($(toggle))
0168       .removeClass('open')
0169   }
0170 
0171   function getParent($this) {
0172     var selector = $this.attr('data-target')
0173       , $parent
0174 
0175     if (!selector) {
0176       selector = $this.attr('href')
0177       selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
0178     }
0179 
0180     $parent = $(selector)
0181     $parent.length || ($parent = $this.parent())
0182 
0183     return $parent
0184   }
0185 
0186 
0187   /* SELECTBOX PLUGIN DEFINITION
0188    * ========================== */
0189 
0190   $.fn.bfhselectbox = function (option) {
0191     return this.each(function () {
0192       var $this = $(this)
0193         , data = $this.data('bfhselectbox')
0194       this.type = 'bfhselectbox';
0195       if (!data) $this.data('bfhselectbox', (data = new BFHSelectBox(this)))
0196       if (typeof option == 'string') data[option].call($this)
0197     })
0198   }
0199 
0200   $.fn.bfhselectbox.Constructor = BFHSelectBox
0201 
0202   var origHook
0203   // There might already be valhooks for the "text" type
0204   if ($.valHooks.div){
0205     // Preserve the original valhook function
0206     origHook = $.valHooks.div
0207   }
0208   $.valHooks.div = {
0209     get: function(el) {
0210       if($(el).hasClass("bfh-selectbox")){
0211         return $(el).find('input[type="hidden"]').val()
0212       }else if (origHook){
0213         return origHook.get(el)
0214       }
0215     },
0216     set: function(el, val) {
0217       if($(el).hasClass("bfh-selectbox")){
0218         var $el = $(el)
0219           , text = $el.find("li a[data-option='"+val+"']").text()
0220         $el.find('input[type="hidden"]').val(val)
0221 
0222         $el.find('.bfh-selectbox-option').text(text)
0223       }else if (origHook){
0224         return origHook.set(el,val)
0225       }
0226     }
0227   }
0228 
0229   /* APPLY TO STANDARD SELECTBOX ELEMENTS
0230    * =================================== */
0231 
0232   $(function () {
0233     $('html')
0234       .on('click.bfhselectbox.data-api', clearMenus)
0235     $('body')
0236       .on('click.bfhselectbox.data-api touchstart.bfhselectbox.data-api'  , toggle, BFHSelectBox.prototype.toggle)
0237       .on('keydown.bfhselectbox.data-api', toggle + ', [role=option]' , BFHSelectBox.prototype.keydown)
0238       .on('mouseenter.bfhselectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.mouseenter)
0239       .on('click.bfhselectbox.data-api', '[role=option] > li > a', BFHSelectBox.prototype.select)  
0240       .on('click.bfhselectbox.data-api', '.bfh-selectbox-filter', function (e) { return false })
0241       .on('propertychange.bfhselectbox.data-api change.bfhselectbox.data-api input.bfhselectbox.data-api paste.bfhselectbox.data-api', '.bfh-selectbox-filter', BFHSelectBox.prototype.filter)
0242   })
0243 
0244 }(window.jQuery);