Commit 3699b36b4f94803e2cd4adf3a8d8b03c18f9f505

Authored by Felipe Henrique de Almeida Bormann
1 parent 615652db

added select field and javascript libraries quicksearch and multiselect.js to our project

amadeus/static/css/base/amadeus.css
... ... @@ -113,6 +113,11 @@
113 113 border: 0px;
114 114 }
115 115  
  116 +.category-search-users{
  117 + width: 100%;
  118 + margin-bottom: 15px;
  119 +}
  120 +
116 121 /* category app ends */
117 122  
118 123 .clearfix{
... ...
amadeus/static/css/multi-select.css 0 → 100755
... ... @@ -0,0 +1,93 @@
  1 +.ms-container{
  2 + background: transparent url('../img/switch.png') no-repeat 50% 50%;
  3 + width: 370px;
  4 +}
  5 +
  6 +.ms-container:after{
  7 + content: ".";
  8 + display: block;
  9 + height: 0;
  10 + line-height: 0;
  11 + font-size: 0;
  12 + clear: both;
  13 + min-height: 0;
  14 + visibility: hidden;
  15 +}
  16 +
  17 +.ms-container .ms-selectable, .ms-container .ms-selection{
  18 + background: #fff;
  19 + color: #555555;
  20 + float: left;
  21 + width: 45%;
  22 +}
  23 +.ms-container .ms-selection{
  24 + float: right;
  25 +}
  26 +
  27 +.ms-container .ms-list{
  28 + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  29 + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  30 + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  31 + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
  32 + -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
  33 + -ms-transition: border linear 0.2s, box-shadow linear 0.2s;
  34 + -o-transition: border linear 0.2s, box-shadow linear 0.2s;
  35 + transition: border linear 0.2s, box-shadow linear 0.2s;
  36 + border: 1px solid #ccc;
  37 + -webkit-border-radius: 3px;
  38 + -moz-border-radius: 3px;
  39 + border-radius: 3px;
  40 + position: relative;
  41 + height: 200px;
  42 + padding: 0;
  43 + overflow-y: auto;
  44 +}
  45 +
  46 +.ms-container .ms-list.ms-focus{
  47 + border-color: rgba(82, 168, 236, 0.8);
  48 + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
  49 + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
  50 + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
  51 + outline: 0;
  52 + outline: thin dotted \9;
  53 +}
  54 +
  55 +.ms-container ul{
  56 + margin: 0;
  57 + list-style-type: none;
  58 + padding: 0;
  59 +}
  60 +
  61 +.ms-container .ms-optgroup-container{
  62 + width: 100%;
  63 +}
  64 +
  65 +.ms-container .ms-optgroup-label{
  66 + margin: 0;
  67 + padding: 5px 0px 0px 5px;
  68 + cursor: pointer;
  69 + color: #999;
  70 +}
  71 +
  72 +.ms-container .ms-selectable li.ms-elem-selectable,
  73 +.ms-container .ms-selection li.ms-elem-selection{
  74 + border-bottom: 1px #eee solid;
  75 + padding: 2px 10px;
  76 + color: #555;
  77 + font-size: 14px;
  78 +}
  79 +
  80 +.ms-container .ms-selectable li.ms-hover,
  81 +.ms-container .ms-selection li.ms-hover{
  82 + cursor: pointer;
  83 + color: #fff;
  84 + text-decoration: none;
  85 + background-color: #08c;
  86 +}
  87 +
  88 +.ms-container .ms-selectable li.disabled,
  89 +.ms-container .ms-selection li.disabled{
  90 + background-color: #eee;
  91 + color: #aaa;
  92 + cursor: text;
  93 +}
0 94 \ No newline at end of file
... ...
amadeus/static/js/jquery.multi-select.js 0 → 100755
... ... @@ -0,0 +1,544 @@
  1 +/*
  2 +* MultiSelect v0.9.12
  3 +* Copyright (c) 2012 Louis Cuny
  4 +*
  5 +* This program is free software. It comes without any warranty, to
  6 +* the extent permitted by applicable law. You can redistribute it
  7 +* and/or modify it under the terms of the Do What The Fuck You Want
  8 +* To Public License, Version 2, as published by Sam Hocevar. See
  9 +* http://sam.zoy.org/wtfpl/COPYING for more details.
  10 +*/
  11 +
  12 +!function ($) {
  13 +
  14 + "use strict";
  15 +
  16 +
  17 + /* MULTISELECT CLASS DEFINITION
  18 + * ====================== */
  19 +
  20 + var MultiSelect = function (element, options) {
  21 + this.options = options;
  22 + this.$element = $(element);
  23 + this.$container = $('<div/>', { 'class': "ms-container" });
  24 + this.$selectableContainer = $('<div/>', { 'class': 'ms-selectable' });
  25 + this.$selectionContainer = $('<div/>', { 'class': 'ms-selection' });
  26 + this.$selectableUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
  27 + this.$selectionUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
  28 + this.scrollTo = 0;
  29 + this.elemsSelector = 'li:visible:not(.ms-optgroup-label,.ms-optgroup-container,.'+options.disabledClass+')';
  30 + };
  31 +
  32 + MultiSelect.prototype = {
  33 + constructor: MultiSelect,
  34 +
  35 + init: function(){
  36 + var that = this,
  37 + ms = this.$element;
  38 +
  39 + if (ms.next('.ms-container').length === 0){
  40 + ms.css({ position: 'absolute', left: '-9999px' });
  41 + ms.attr('id', ms.attr('id') ? ms.attr('id') : Math.ceil(Math.random()*1000)+'multiselect');
  42 + this.$container.attr('id', 'ms-'+ms.attr('id'));
  43 + this.$container.addClass(that.options.cssClass);
  44 + ms.find('option').each(function(){
  45 + that.generateLisFromOption(this);
  46 + });
  47 +
  48 + this.$selectionUl.find('.ms-optgroup-label').hide();
  49 +
  50 + if (that.options.selectableHeader){
  51 + that.$selectableContainer.append(that.options.selectableHeader);
  52 + }
  53 + that.$selectableContainer.append(that.$selectableUl);
  54 + if (that.options.selectableFooter){
  55 + that.$selectableContainer.append(that.options.selectableFooter);
  56 + }
  57 +
  58 + if (that.options.selectionHeader){
  59 + that.$selectionContainer.append(that.options.selectionHeader);
  60 + }
  61 + that.$selectionContainer.append(that.$selectionUl);
  62 + if (that.options.selectionFooter){
  63 + that.$selectionContainer.append(that.options.selectionFooter);
  64 + }
  65 +
  66 + that.$container.append(that.$selectableContainer);
  67 + that.$container.append(that.$selectionContainer);
  68 + ms.after(that.$container);
  69 +
  70 + that.activeMouse(that.$selectableUl);
  71 + that.activeKeyboard(that.$selectableUl);
  72 +
  73 + var action = that.options.dblClick ? 'dblclick' : 'click';
  74 +
  75 + that.$selectableUl.on(action, '.ms-elem-selectable', function(){
  76 + that.select($(this).data('ms-value'));
  77 + });
  78 + that.$selectionUl.on(action, '.ms-elem-selection', function(){
  79 + that.deselect($(this).data('ms-value'));
  80 + });
  81 +
  82 + that.activeMouse(that.$selectionUl);
  83 + that.activeKeyboard(that.$selectionUl);
  84 +
  85 + ms.on('focus', function(){
  86 + that.$selectableUl.focus();
  87 + });
  88 + }
  89 +
  90 + var selectedValues = ms.find('option:selected').map(function(){ return $(this).val(); }).get();
  91 + that.select(selectedValues, 'init');
  92 +
  93 + if (typeof that.options.afterInit === 'function') {
  94 + that.options.afterInit.call(this, this.$container);
  95 + }
  96 + },
  97 +
  98 + 'generateLisFromOption' : function(option, index, $container){
  99 + var that = this,
  100 + ms = that.$element,
  101 + attributes = "",
  102 + $option = $(option);
  103 +
  104 + for (var cpt = 0; cpt < option.attributes.length; cpt++){
  105 + var attr = option.attributes[cpt];
  106 +
  107 + if(attr.name !== 'value' && attr.name !== 'disabled'){
  108 + attributes += attr.name+'="'+attr.value+'" ';
  109 + }
  110 + }
  111 + var selectableLi = $('<li '+attributes+'><span>'+that.escapeHTML($option.text())+'</span></li>'),
  112 + selectedLi = selectableLi.clone(),
  113 + value = $option.val(),
  114 + elementId = that.sanitize(value);
  115 +
  116 + selectableLi
  117 + .data('ms-value', value)
  118 + .addClass('ms-elem-selectable')
  119 + .attr('id', elementId+'-selectable');
  120 +
  121 + selectedLi
  122 + .data('ms-value', value)
  123 + .addClass('ms-elem-selection')
  124 + .attr('id', elementId+'-selection')
  125 + .hide();
  126 +
  127 + if ($option.prop('disabled') || ms.prop('disabled')){
  128 + selectedLi.addClass(that.options.disabledClass);
  129 + selectableLi.addClass(that.options.disabledClass);
  130 + }
  131 +
  132 + var $optgroup = $option.parent('optgroup');
  133 +
  134 + if ($optgroup.length > 0){
  135 + var optgroupLabel = $optgroup.attr('label'),
  136 + optgroupId = that.sanitize(optgroupLabel),
  137 + $selectableOptgroup = that.$selectableUl.find('#optgroup-selectable-'+optgroupId),
  138 + $selectionOptgroup = that.$selectionUl.find('#optgroup-selection-'+optgroupId);
  139 +
  140 + if ($selectableOptgroup.length === 0){
  141 + var optgroupContainerTpl = '<li class="ms-optgroup-container"></li>',
  142 + optgroupTpl = '<ul class="ms-optgroup"><li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li></ul>';
  143 +
  144 + $selectableOptgroup = $(optgroupContainerTpl);
  145 + $selectionOptgroup = $(optgroupContainerTpl);
  146 + $selectableOptgroup.attr('id', 'optgroup-selectable-'+optgroupId);
  147 + $selectionOptgroup.attr('id', 'optgroup-selection-'+optgroupId);
  148 + $selectableOptgroup.append($(optgroupTpl));
  149 + $selectionOptgroup.append($(optgroupTpl));
  150 + if (that.options.selectableOptgroup){
  151 + $selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
  152 + var values = $optgroup.children(':not(:selected, :disabled)').map(function(){ return $(this).val();}).get();
  153 + that.select(values);
  154 + });
  155 + $selectionOptgroup.find('.ms-optgroup-label').on('click', function(){
  156 + var values = $optgroup.children(':selected:not(:disabled)').map(function(){ return $(this).val();}).get();
  157 + that.deselect(values);
  158 + });
  159 + }
  160 + that.$selectableUl.append($selectableOptgroup);
  161 + that.$selectionUl.append($selectionOptgroup);
  162 + }
  163 + index = index === undefined ? $selectableOptgroup.find('ul').children().length : index + 1;
  164 + selectableLi.insertAt(index, $selectableOptgroup.children());
  165 + selectedLi.insertAt(index, $selectionOptgroup.children());
  166 + } else {
  167 + index = index === undefined ? that.$selectableUl.children().length : index;
  168 +
  169 + selectableLi.insertAt(index, that.$selectableUl);
  170 + selectedLi.insertAt(index, that.$selectionUl);
  171 + }
  172 + },
  173 +
  174 + 'addOption' : function(options){
  175 + var that = this;
  176 +
  177 + if (options.value !== undefined && options.value !== null){
  178 + options = [options];
  179 + }
  180 + $.each(options, function(index, option){
  181 + if (option.value !== undefined && option.value !== null &&
  182 + that.$element.find("option[value='"+option.value+"']").length === 0){
  183 + var $option = $('<option value="'+option.value+'">'+option.text+'</option>'),
  184 + $container = option.nested === undefined ? that.$element : $("optgroup[label='"+option.nested+"']"),
  185 + index = parseInt((typeof option.index === 'undefined' ? $container.children().length : option.index));
  186 +
  187 + if (option.optionClass) {
  188 + $option.addClass(option.optionClass);
  189 + }
  190 +
  191 + if (option.disabled) {
  192 + $option.prop('disabled', true);
  193 + }
  194 +
  195 + $option.insertAt(index, $container);
  196 + that.generateLisFromOption($option.get(0), index, option.nested);
  197 + }
  198 + });
  199 + },
  200 +
  201 + 'escapeHTML' : function(text){
  202 + return $("<div>").text(text).html();
  203 + },
  204 +
  205 + 'activeKeyboard' : function($list){
  206 + var that = this;
  207 +
  208 + $list.on('focus', function(){
  209 + $(this).addClass('ms-focus');
  210 + })
  211 + .on('blur', function(){
  212 + $(this).removeClass('ms-focus');
  213 + })
  214 + .on('keydown', function(e){
  215 + switch (e.which) {
  216 + case 40:
  217 + case 38:
  218 + e.preventDefault();
  219 + e.stopPropagation();
  220 + that.moveHighlight($(this), (e.which === 38) ? -1 : 1);
  221 + return;
  222 + case 37:
  223 + case 39:
  224 + e.preventDefault();
  225 + e.stopPropagation();
  226 + that.switchList($list);
  227 + return;
  228 + case 9:
  229 + if(that.$element.is('[tabindex]')){
  230 + e.preventDefault();
  231 + var tabindex = parseInt(that.$element.attr('tabindex'), 10);
  232 + tabindex = (e.shiftKey) ? tabindex-1 : tabindex+1;
  233 + $('[tabindex="'+(tabindex)+'"]').focus();
  234 + return;
  235 + }else{
  236 + if(e.shiftKey){
  237 + that.$element.trigger('focus');
  238 + }
  239 + }
  240 + }
  241 + if($.inArray(e.which, that.options.keySelect) > -1){
  242 + e.preventDefault();
  243 + e.stopPropagation();
  244 + that.selectHighlighted($list);
  245 + return;
  246 + }
  247 + });
  248 + },
  249 +
  250 + 'moveHighlight': function($list, direction){
  251 + var $elems = $list.find(this.elemsSelector),
  252 + $currElem = $elems.filter('.ms-hover'),
  253 + $nextElem = null,
  254 + elemHeight = $elems.first().outerHeight(),
  255 + containerHeight = $list.height(),
  256 + containerSelector = '#'+this.$container.prop('id');
  257 +
  258 + $elems.removeClass('ms-hover');
  259 + if (direction === 1){ // DOWN
  260 +
  261 + $nextElem = $currElem.nextAll(this.elemsSelector).first();
  262 + if ($nextElem.length === 0){
  263 + var $optgroupUl = $currElem.parent();
  264 +
  265 + if ($optgroupUl.hasClass('ms-optgroup')){
  266 + var $optgroupLi = $optgroupUl.parent(),
  267 + $nextOptgroupLi = $optgroupLi.next(':visible');
  268 +
  269 + if ($nextOptgroupLi.length > 0){
  270 + $nextElem = $nextOptgroupLi.find(this.elemsSelector).first();
  271 + } else {
  272 + $nextElem = $elems.first();
  273 + }
  274 + } else {
  275 + $nextElem = $elems.first();
  276 + }
  277 + }
  278 + } else if (direction === -1){ // UP
  279 +
  280 + $nextElem = $currElem.prevAll(this.elemsSelector).first();
  281 + if ($nextElem.length === 0){
  282 + var $optgroupUl = $currElem.parent();
  283 +
  284 + if ($optgroupUl.hasClass('ms-optgroup')){
  285 + var $optgroupLi = $optgroupUl.parent(),
  286 + $prevOptgroupLi = $optgroupLi.prev(':visible');
  287 +
  288 + if ($prevOptgroupLi.length > 0){
  289 + $nextElem = $prevOptgroupLi.find(this.elemsSelector).last();
  290 + } else {
  291 + $nextElem = $elems.last();
  292 + }
  293 + } else {
  294 + $nextElem = $elems.last();
  295 + }
  296 + }
  297 + }
  298 + if ($nextElem.length > 0){
  299 + $nextElem.addClass('ms-hover');
  300 + var scrollTo = $list.scrollTop() + $nextElem.position().top -
  301 + containerHeight / 2 + elemHeight / 2;
  302 +
  303 + $list.scrollTop(scrollTo);
  304 + }
  305 + },
  306 +
  307 + 'selectHighlighted' : function($list){
  308 + var $elems = $list.find(this.elemsSelector),
  309 + $highlightedElem = $elems.filter('.ms-hover').first();
  310 +
  311 + if ($highlightedElem.length > 0){
  312 + if ($list.parent().hasClass('ms-selectable')){
  313 + this.select($highlightedElem.data('ms-value'));
  314 + } else {
  315 + this.deselect($highlightedElem.data('ms-value'));
  316 + }
  317 + $elems.removeClass('ms-hover');
  318 + }
  319 + },
  320 +
  321 + 'switchList' : function($list){
  322 + $list.blur();
  323 + this.$container.find(this.elemsSelector).removeClass('ms-hover');
  324 + if ($list.parent().hasClass('ms-selectable')){
  325 + this.$selectionUl.focus();
  326 + } else {
  327 + this.$selectableUl.focus();
  328 + }
  329 + },
  330 +
  331 + 'activeMouse' : function($list){
  332 + var that = this;
  333 +
  334 + this.$container.on('mouseenter', that.elemsSelector, function(){
  335 + $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');
  336 + $(this).addClass('ms-hover');
  337 + });
  338 +
  339 + this.$container.on('mouseleave', that.elemsSelector, function () {
  340 + $(this).parents('.ms-container').find(that.elemsSelector).removeClass('ms-hover');
  341 + });
  342 + },
  343 +
  344 + 'refresh' : function() {
  345 + this.destroy();
  346 + this.$element.multiSelect(this.options);
  347 + },
  348 +
  349 + 'destroy' : function(){
  350 + $("#ms-"+this.$element.attr("id")).remove();
  351 + this.$element.off('focus');
  352 + this.$element.css('position', '').css('left', '');
  353 + this.$element.removeData('multiselect');
  354 + },
  355 +
  356 + 'select' : function(value, method){
  357 + if (typeof value === 'string'){ value = [value]; }
  358 +
  359 + var that = this,
  360 + ms = this.$element,
  361 + msIds = $.map(value, function(val){ return(that.sanitize(val)); }),
  362 + selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable').filter(':not(.'+that.options.disabledClass+')'),
  363 + selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection').filter(':not(.'+that.options.disabledClass+')'),
  364 + options = ms.find('option:not(:disabled)').filter(function(){ return($.inArray(this.value, value) > -1); });
  365 +
  366 + if (method === 'init'){
  367 + selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),
  368 + selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection');
  369 + }
  370 +
  371 + if (selectables.length > 0){
  372 + selectables.addClass('ms-selected').hide();
  373 + selections.addClass('ms-selected').show();
  374 +
  375 + options.prop('selected', true);
  376 +
  377 + that.$container.find(that.elemsSelector).removeClass('ms-hover');
  378 +
  379 + var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
  380 + if (selectableOptgroups.length > 0){
  381 + selectableOptgroups.each(function(){
  382 + var selectablesLi = $(this).find('.ms-elem-selectable');
  383 + if (selectablesLi.length === selectablesLi.filter('.ms-selected').length){
  384 + $(this).find('.ms-optgroup-label').hide();
  385 + }
  386 + });
  387 +
  388 + var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
  389 + selectionOptgroups.each(function(){
  390 + var selectionsLi = $(this).find('.ms-elem-selection');
  391 + if (selectionsLi.filter('.ms-selected').length > 0){
  392 + $(this).find('.ms-optgroup-label').show();
  393 + }
  394 + });
  395 + } else {
  396 + if (that.options.keepOrder && method !== 'init'){
  397 + var selectionLiLast = that.$selectionUl.find('.ms-selected');
  398 + if((selectionLiLast.length > 1) && (selectionLiLast.last().get(0) != selections.get(0))) {
  399 + selections.insertAfter(selectionLiLast.last());
  400 + }
  401 + }
  402 + }
  403 + if (method !== 'init'){
  404 + ms.trigger('change');
  405 + if (typeof that.options.afterSelect === 'function') {
  406 + that.options.afterSelect.call(this, value);
  407 + }
  408 + }
  409 + }
  410 + },
  411 +
  412 + 'deselect' : function(value){
  413 + if (typeof value === 'string'){ value = [value]; }
  414 +
  415 + var that = this,
  416 + ms = this.$element,
  417 + msIds = $.map(value, function(val){ return(that.sanitize(val)); }),
  418 + selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),
  419 + selections = this.$selectionUl.find('#' + msIds.join('-selection, #')+'-selection').filter('.ms-selected').filter(':not(.'+that.options.disabledClass+')'),
  420 + options = ms.find('option').filter(function(){ return($.inArray(this.value, value) > -1); });
  421 +
  422 + if (selections.length > 0){
  423 + selectables.removeClass('ms-selected').show();
  424 + selections.removeClass('ms-selected').hide();
  425 + options.prop('selected', false);
  426 +
  427 + that.$container.find(that.elemsSelector).removeClass('ms-hover');
  428 +
  429 + var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
  430 + if (selectableOptgroups.length > 0){
  431 + selectableOptgroups.each(function(){
  432 + var selectablesLi = $(this).find('.ms-elem-selectable');
  433 + if (selectablesLi.filter(':not(.ms-selected)').length > 0){
  434 + $(this).find('.ms-optgroup-label').show();
  435 + }
  436 + });
  437 +
  438 + var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
  439 + selectionOptgroups.each(function(){
  440 + var selectionsLi = $(this).find('.ms-elem-selection');
  441 + if (selectionsLi.filter('.ms-selected').length === 0){
  442 + $(this).find('.ms-optgroup-label').hide();
  443 + }
  444 + });
  445 + }
  446 + ms.trigger('change');
  447 + if (typeof that.options.afterDeselect === 'function') {
  448 + that.options.afterDeselect.call(this, value);
  449 + }
  450 + }
  451 + },
  452 +
  453 + 'select_all' : function(){
  454 + var ms = this.$element,
  455 + values = ms.val();
  456 +
  457 + ms.find('option:not(":disabled")').prop('selected', true);
  458 + this.$selectableUl.find('.ms-elem-selectable').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').hide();
  459 + this.$selectionUl.find('.ms-optgroup-label').show();
  460 + this.$selectableUl.find('.ms-optgroup-label').hide();
  461 + this.$selectionUl.find('.ms-elem-selection').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').show();
  462 + this.$selectionUl.focus();
  463 + ms.trigger('change');
  464 + if (typeof this.options.afterSelect === 'function') {
  465 + var selectedValues = $.grep(ms.val(), function(item){
  466 + return $.inArray(item, values) < 0;
  467 + });
  468 + this.options.afterSelect.call(this, selectedValues);
  469 + }
  470 + },
  471 +
  472 + 'deselect_all' : function(){
  473 + var ms = this.$element,
  474 + values = ms.val();
  475 +
  476 + ms.find('option').prop('selected', false);
  477 + this.$selectableUl.find('.ms-elem-selectable').removeClass('ms-selected').show();
  478 + this.$selectionUl.find('.ms-optgroup-label').hide();
  479 + this.$selectableUl.find('.ms-optgroup-label').show();
  480 + this.$selectionUl.find('.ms-elem-selection').removeClass('ms-selected').hide();
  481 + this.$selectableUl.focus();
  482 + ms.trigger('change');
  483 + if (typeof this.options.afterDeselect === 'function') {
  484 + this.options.afterDeselect.call(this, values);
  485 + }
  486 + },
  487 +
  488 + sanitize: function(value){
  489 + var hash = 0, i, character;
  490 + if (value.length == 0) return hash;
  491 + var ls = 0;
  492 + for (i = 0, ls = value.length; i < ls; i++) {
  493 + character = value.charCodeAt(i);
  494 + hash = ((hash<<5)-hash)+character;
  495 + hash |= 0; // Convert to 32bit integer
  496 + }
  497 + return hash;
  498 + }
  499 + };
  500 +
  501 + /* MULTISELECT PLUGIN DEFINITION
  502 + * ======================= */
  503 +
  504 + $.fn.multiSelect = function () {
  505 + var option = arguments[0],
  506 + args = arguments;
  507 +
  508 + return this.each(function () {
  509 + var $this = $(this),
  510 + data = $this.data('multiselect'),
  511 + options = $.extend({}, $.fn.multiSelect.defaults, $this.data(), typeof option === 'object' && option);
  512 +
  513 + if (!data){ $this.data('multiselect', (data = new MultiSelect(this, options))); }
  514 +
  515 + if (typeof option === 'string'){
  516 + data[option](args[1]);
  517 + } else {
  518 + data.init();
  519 + }
  520 + });
  521 + };
  522 +
  523 + $.fn.multiSelect.defaults = {
  524 + keySelect: [32],
  525 + selectableOptgroup: false,
  526 + disabledClass : 'disabled',
  527 + dblClick : false,
  528 + keepOrder: false,
  529 + cssClass: ''
  530 + };
  531 +
  532 + $.fn.multiSelect.Constructor = MultiSelect;
  533 +
  534 + $.fn.insertAt = function(index, $parent) {
  535 + return this.each(function() {
  536 + if (index === 0) {
  537 + $parent.prepend(this);
  538 + } else {
  539 + $parent.children().eq(index - 1).after(this);
  540 + }
  541 + });
  542 +};
  543 +
  544 +}(window.jQuery);
... ...
amadeus/static/js/quicksearch.js 0 → 100755
... ... @@ -0,0 +1,181 @@
  1 +(function($, window, document, undefined) {
  2 + $.fn.quicksearch = function (target, opt) {
  3 +
  4 + var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({
  5 + delay: 100,
  6 + selector: null,
  7 + stripeRows: null,
  8 + loader: null,
  9 + noResults: '',
  10 + matchedResultsCount: 0,
  11 + bind: 'keyup',
  12 + onBefore: function () {
  13 + return;
  14 + },
  15 + onAfter: function () {
  16 + return;
  17 + },
  18 + show: function () {
  19 + this.style.display = "";
  20 + },
  21 + hide: function () {
  22 + this.style.display = "none";
  23 + },
  24 + prepareQuery: function (val) {
  25 + return val.toLowerCase().split(' ');
  26 + },
  27 + testQuery: function (query, txt, _row) {
  28 + for (var i = 0; i < query.length; i += 1) {
  29 + if (txt.indexOf(query[i]) === -1) {
  30 + return false;
  31 + }
  32 + }
  33 + return true;
  34 + }
  35 + }, opt);
  36 +
  37 + this.go = function () {
  38 +
  39 + var i = 0,
  40 + numMatchedRows = 0,
  41 + noresults = true,
  42 + query = options.prepareQuery(val),
  43 + val_empty = (val.replace(' ', '').length === 0);
  44 +
  45 + for (var i = 0, len = rowcache.length; i < len; i++) {
  46 + if (val_empty || options.testQuery(query, cache[i], rowcache[i])) {
  47 + options.show.apply(rowcache[i]);
  48 + noresults = false;
  49 + numMatchedRows++;
  50 + } else {
  51 + options.hide.apply(rowcache[i]);
  52 + }
  53 + }
  54 +
  55 + if (noresults) {
  56 + this.results(false);
  57 + } else {
  58 + this.results(true);
  59 + this.stripe();
  60 + }
  61 +
  62 + this.matchedResultsCount = numMatchedRows;
  63 + this.loader(false);
  64 + options.onAfter();
  65 +
  66 + return this;
  67 + };
  68 +
  69 + /*
  70 + * External API so that users can perform search programatically.
  71 + * */
  72 + this.search = function (submittedVal) {
  73 + val = submittedVal;
  74 + e.trigger();
  75 + };
  76 +
  77 + /*
  78 + * External API to get the number of matched results as seen in
  79 + * https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6
  80 + * */
  81 + this.currentMatchedResults = function() {
  82 + return this.matchedResultsCount;
  83 + };
  84 +
  85 + this.stripe = function () {
  86 +
  87 + if (typeof options.stripeRows === "object" && options.stripeRows !== null)
  88 + {
  89 + var joined = options.stripeRows.join(' ');
  90 + var stripeRows_length = options.stripeRows.length;
  91 +
  92 + jq_results.not(':hidden').each(function (i) {
  93 + $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
  94 + });
  95 + }
  96 +
  97 + return this;
  98 + };
  99 +
  100 + this.strip_html = function (input) {
  101 + var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
  102 + output = $.trim(output.toLowerCase());
  103 + return output;
  104 + };
  105 +
  106 + this.results = function (bool) {
  107 + if (typeof options.noResults === "string" && options.noResults !== "") {
  108 + if (bool) {
  109 + $(options.noResults).hide();
  110 + } else {
  111 + $(options.noResults).show();
  112 + }
  113 + }
  114 + return this;
  115 + };
  116 +
  117 + this.loader = function (bool) {
  118 + if (typeof options.loader === "string" && options.loader !== "") {
  119 + (bool) ? $(options.loader).show() : $(options.loader).hide();
  120 + }
  121 + return this;
  122 + };
  123 +
  124 + this.cache = function () {
  125 +
  126 + jq_results = $(target);
  127 +
  128 + if (typeof options.noResults === "string" && options.noResults !== "") {
  129 + jq_results = jq_results.not(options.noResults);
  130 + }
  131 +
  132 + var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults);
  133 + cache = t.map(function () {
  134 + return e.strip_html(this.innerHTML);
  135 + });
  136 +
  137 + rowcache = jq_results.map(function () {
  138 + return this;
  139 + });
  140 +
  141 + /*
  142 + * Modified fix for sync-ing "val".
  143 + * Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1
  144 + * */
  145 + val = val || this.val() || "";
  146 +
  147 + return this.go();
  148 + };
  149 +
  150 + this.trigger = function () {
  151 + this.loader(true);
  152 + options.onBefore();
  153 +
  154 + window.clearTimeout(timeout);
  155 + timeout = window.setTimeout(function () {
  156 + e.go();
  157 + }, options.delay);
  158 +
  159 + return this;
  160 + };
  161 +
  162 + this.cache();
  163 + this.results(true);
  164 + this.stripe();
  165 + this.loader(false);
  166 +
  167 + return this.each(function () {
  168 +
  169 + /*
  170 + * Changed from .bind to .on.
  171 + * */
  172 + $(this).on(options.bind, function () {
  173 +
  174 + val = $(this).val();
  175 + e.trigger();
  176 + });
  177 + });
  178 +
  179 + };
  180 +
  181 +}(jQuery, this, document));
... ...
categories/templates/categories/create.html
... ... @@ -63,5 +63,41 @@
63 63 $('.date-picker').datepicker({
64 64 language: locale,
65 65 });
  66 +
  67 + $('#id_coordinators').multiSelect({
  68 + selectableHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder='{% trans "try an username" %} '>",
  69 + selectionHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder='{% trans "try an username" %} '>",
  70 + afterInit: function(ms){
  71 + var that = this,
  72 + $selectableSearch = that.$selectableUl.prev(),
  73 + $selectionSearch = that.$selectionUl.prev(),
  74 + selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)',
  75 + selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected';
  76 +
  77 + that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
  78 + .on('keydown', function(e){
  79 + if (e.which === 40){
  80 + that.$selectableUl.focus();
  81 + return false;
  82 + }
  83 + });
  84 +
  85 + that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
  86 + .on('keydown', function(e){
  87 + if (e.which == 40){
  88 + that.$selectionUl.focus();
  89 + return false;
  90 + }
  91 + });
  92 + },
  93 + afterSelect: function(){
  94 + this.qs1.cache();
  95 + this.qs2.cache();
  96 + },
  97 + afterDeselect: function(){
  98 + this.qs1.cache();
  99 + this.qs2.cache();
  100 + }
  101 + });// Used to create multi-select css style
66 102 </script>
67 103 {% endblock %}
68 104 \ No newline at end of file
... ...
categories/templates/categories/home.html
... ... @@ -7,6 +7,15 @@
7 7 {% breadcrumb 'Home' 'categories:index' %}
8 8 {% endblock %}
9 9  
  10 +{% block style %}
  11 + <link rel="stylesheet" type="text/css" href="{% static "css/multi-select.css" %}">
  12 +{% endblock style %}
  13 +
  14 +{% block javascript %}
  15 + {{super.block}}
  16 + <script src="{% static "js/jquery.multi-select.js" %} " type="text/javascript"></script>
  17 + <script type="text/javascript" src="{% static "js/quicksearch.js" %}"></script>
  18 +{% endblock javascript %}
10 19  
11 20 {% block render_breadcrumbs %}
12 21 {% render_breadcrumbs %}
... ...
categories/templates/categories/update.html
... ... @@ -64,5 +64,41 @@
64 64 $('.date-picker').datepicker({
65 65 language: locale,
66 66 });
  67 +
  68 + $('#id_coordinators').multiSelect({
  69 + selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='{% trans "try an username" %} '>",
  70 + selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='{% trans "try an username" %} '>",
  71 + afterInit: function(ms){
  72 + var that = this,
  73 + $selectableSearch = that.$selectableUl.prev(),
  74 + $selectionSearch = that.$selectionUl.prev(),
  75 + selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)',
  76 + selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected';
  77 +
  78 + that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
  79 + .on('keydown', function(e){
  80 + if (e.which === 40){
  81 + that.$selectableUl.focus();
  82 + return false;
  83 + }
  84 + });
  85 +
  86 + that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
  87 + .on('keydown', function(e){
  88 + if (e.which == 40){
  89 + that.$selectionUl.focus();
  90 + return false;
  91 + }
  92 + });
  93 + },
  94 + afterSelect: function(){
  95 + this.qs1.cache();
  96 + this.qs2.cache();
  97 + },
  98 + afterDeselect: function(){
  99 + this.qs1.cache();
  100 + this.qs2.cache();
  101 + }
  102 + });// Used to create multi-select css style
67 103 </script>
68 104 {% endblock %}
69 105 \ No newline at end of file
... ...