Your IP : 18.219.40.177


Current Path : /usr/local/mgr5/skins/orion/src/
Upload File :
Current File : //usr/local/mgr5/skins/orion/src/App.MultiSelect.js

/**
 * Модуль кастомного мультиселекта
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 */
App.MultiSelect = function(window, $, EventMgr, App) {
  'use strict';
  var init = function() {
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__view-value',
        'click', listOpenHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-choose li',
        'click', chooseElemHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-view .b-mselect__unselect',
        'click', unChooseElemHandler);
   // EventMgr.on('#main-wrapper', '.mselect-av .b-input-btn_type_plus',
   //     'click', selectAllHandler);
   // EventMgr.on('#main-wrapper', '.mselect-av .b-input-btn_type_minus',
   //     'click', unSelectAllHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__item_select-all',
        'dblclick', unSelectAllHandler);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__ul-view .b-mselect__item',
        'mouseover', checkSize);
    EventMgr.on('#main-wrapper', '.mselect-av .b-mselect__view-value',
        'keydown', keydownHandler);
    EventMgr.bind('selectValues', selectValues);
    EventMgr.bind('multiSelectUnselect', unSelectAllFromOut);
    EventMgr.bind('mselectUnselectByDepend', unselectByDepend);
  },

      listWrapperIdPostfix = '-ms-list-wrapper',

      listIdPostfix = '-ms-list',

      chooseListIdPostfix = '-ms-view',

      appDom = App.Dom,

      $body = function() {
        return $('body');
      },
      //show select options
      listOpenHandler = function(e) {
        var id = this.getAttribute('data-id'),
            list = appDom.byId(id + listWrapperIdPostfix),
            bodyHeight, elemHeight, formTop, elemTop, tabId, form;
        if (e.target && e.target.className.match('scrlbr')) {
          return;
        }
        if (list) {
          if (list.offsetWidth === 0) {
            //for close other list
            $('body').trigger('click');
            bodyHeight = window.document.body.offsetHeight;
            appDom.removeClass(list, 'closed');
            //calculate list options position
            elemHeight = list.offsetHeight;
            list.style.top = '';
            elemTop = $(list).offset().top;
            if ((bodyHeight - elemTop) < elemHeight) {
              tabId = list.getAttribute('data-tabid');
              form = $('#form-scroll-' + tabId);
              formTop = form.offset().top;
              if (formTop > (elemTop - elemHeight - appDom.byId(id + '-ms-view').offsetHeight)) {
                list.style.top = '-' + (elemHeight / 2) + 'px';
              } else {
                list.style.top = '-' + elemHeight + 'px';
              }
            }
            $body().on('click', listCloseHandler);
            e.stopPropagation();
            EventMgr.trigger('updateScroll', { id: id + listIdPostfix });
          } else {
            appDom.addClass(list, 'closed');
            EventMgr.off('body', 'click');
            $body().off('click', listCloseHandler);
          }
        }
      },
      //close select options
      listCloseHandler = function(e) {
        if (e.target) {
          if (!appDom.hasClass(e.target, 'b-mselect__item') &&
              !appDom.hasClass(e.target, 'scrlbr')) {
            closeList();
          } else {
            return;
          }
        }
        $body().off('click', listCloseHandler);
        e.stopPropagation();
      },
      //
      closeList = function(id) {
        var elems, selected;
        if (typeof id === 'string') {
          elems = $('#' + id + '-ms-list-wrapper');
        } else {
          elems = $('.b-mselect__options');
        }
        elems.addClass('closed');
        //remove selected hightlight
        if (typeof id === 'string') {
          selected = $('#' + id + '-ms-list-ul')
              .find('.b-mselect__item_st_selected');
        } else {
          selected = $('.b-mselect__item_st_selected');
        }
        selected.removeClass('b-mselect__item_st_selected');
      },

      checkAllSelectedElem = function(id) {
        var $items = $('#' + id + '-ms-list-ul'),
            selectedCount = $items.find('.chosen').length,
            allCount = $items.find('.b-mselect__item').length - 1;
        return {
          selectedCount: selectedCount,
          allCount: allCount,
          allSelected: allCount === selectedCount
        };
      },

      chooseElemHandler = function(e, data) {
        var clone = this.cloneNode(true),
            id = this.parentNode.getAttribute('data-id'),
            clist = App.Dom.byId(id + chooseListIdPostfix),
            maxSelect = clist.getAttribute('data-maxselect'),
            selectedObj = checkAllSelectedElem(id),
            selectedCount = selectedObj.selectedCount,
            preventChange = data ? data.preventChange ?  true : false : false;
        maxSelect = (maxSelect === '') ? 9999 : parseInt(maxSelect, 10);
        if (selectedCount === maxSelect) {
          //closeList(id);
          return;
        }

        //check for selected
        if (appDom.hasClass(this, 'b-mselect__item_select-all')) {
          if (selectedObj.allSelected) {
            unSelectAllValues(id);
          } else {
            selectAllValues(id);
          }
        } else if (appDom.hasClass(this, 'chosen')) {
          appDom.removeClass(this, 'chosen');
          $('.b-mselect__item[data-s-id="' + clone.id + '"] .b-mselect__unselect').trigger('click');
        } else {
          clone.setAttribute('data-s-id', clone.id);
          clone.id = '';
          if (!clist) { return; }
          appDom.addClass(this, 'chosen');
          appDom.addClass(clone, 'chosen');
          clist.appendChild(clone);
          setValue(id, preventChange);
        }
      },

      unChooseElemHandler = function(e) {
        var elem = this.parentNode,
            sid = elem.getAttribute('data-s-id'),
            sElem = appDom.byId(sid),
            id = sElem.parentNode.getAttribute('data-id');
        elem.parentNode.removeChild(elem);
        appDom.removeClass(sElem, 'chosen');
        setValue(id);
       // closeList(id);
        e.stopPropagation();
      },

      unSelectAllHandler = function(e) {
        var id = this.getAttribute('data-id');
        unSelectAllValues(id);
        e.preventDefault();
      },

      unSelectAllFromOut = function(e, data) {
        var id = data.id;
        unSelectAllValues(id);
      },
      //unselect all values
      unSelectAllValues = function(id) {
        $('#' + id + '-ms-view .b-mselect__item.chosen').remove();
        $('#' + id + '-ms-list-ul .chosen').removeClass('chosen');
        setValue(id);
      },

      selectAllHandler = function(e) {
        var id = this.getAttribute('data-id');
        selectAllValues(id);
        e.preventDefault();
      },
      //select all values
      selectAllValues = function(id) {
        var elems = $('#' + id + '-ms-list-ul .b-mselect__item'),
            l = elems.length, clone,
            clist = App.Dom.byId(id + chooseListIdPostfix),
            maxSelect = clist.getAttribute('data-maxselect'),
            selectedCount = $('#' + id + '-ms-list-ul li.chosen').length;
        maxSelect = (maxSelect === '') ? 9999 : parseInt(maxSelect, 10);
        for (var i = 0; i < l; i++) {
          if (selectedCount === maxSelect) {
            break;
          }
          if (appDom.hasClass(elems[i], 'dependelem') &&
             !appDom.hasClass(elems[i], 'b-myselect__select-li_show_yes')) {
            continue;
          }
          if (appDom.hasClass(elems[i], 'b-mselect__item_select-all')) {
            continue;
          }
          if (!appDom.hasClass(elems[i], 'chosen')) {
            clone = elems[i].cloneNode(true);
            clone.setAttribute('data-s-id', clone.id);
            clone.id = '';
            appDom.addClass(elems[i], 'chosen');
            appDom.addClass(clone, 'chosen');
            clist.appendChild(clone);
            selectedCount++;
          }
        }
        setValue(id);
      },

      //setvalue when change
      setValue = function(id, preventChange) {
        var elem = appDom.byId(id + chooseListIdPostfix),
            cElems = elem.children,
            l = cElems.length,
            val,
            value = '',
            input = appDom.byId(id + '-ms-value'),
            wrapper = appDom.byId(id + '-ms'),
            scrollId = $(wrapper).find('.b-mselect__view-value').attr('id'),
            tabId = elem.getAttribute('data-tabId');
        if (l !== 1) {
          while (l--) {
            val = cElems[l].getAttribute('data-val');
            value += val;
            if (l !== 1) {
              value += ',';
            } else {
              break;
            }
          }
        } else {
          value = '';
        }

        input.value = value;
        if (value === '') {
          appDom.removeClass(wrapper, 'selected');
        } else {
          appDom.addClass(wrapper, 'selected');
        }
        if (!preventChange) {
          $(input).trigger('change');
        }
        EventMgr.trigger('updateScroll', { id: 'form-scroll-' + tabId });
        EventMgr.trigger('updateScroll', { id: scrollId });
      },
      //apply setvalues
      selectValues = function(e, data) {
        var id = data.id,
            slist = data.sElems.slist,
            values = data.sElems.value !== undefined ? data.sElems.value : data.sElems,
            l = values.length,
            elem,
            maxSelect = $('#' + id + '-ms-view').attr('data-maxselect');
        maxSelect = (maxSelect === '') ? 9999 : parseInt(maxSelect, 10);
        if (slist) {
          $('#' + id + '-ms-list-ul').html(renderMultiSelectValues(slist, id));
        }
        $('#' + id + '-ms').removeClass('selected');
        $('#' + id + '-ms-list-ul li.chosen').removeClass('chosen');
        $('#' + id + '-ms-view li.chosen').remove();
        if (typeof values === 'string' && values !== '') {
          elem = $('#' + id + '-ms-list-ul li[data-val="' + values + '"]')
              .trigger('click');
        } else {
          if (maxSelect < l) { l = maxSelect; }
          for (var i = 0; i < l; i++) {
            if (i === l - 1) {
              elem = $('#' + id + '-ms-list-ul li[data-val="' + values[i] + '"]')
                .trigger('click', { 'preventChange': false });
            } else {
               elem = $('#' + id + '-ms-list-ul li[data-val="' + values[i] + '"]')
                .trigger('click', { 'preventChange': true });
            }
          }
        }

      },

      unselectByDepend = function(e, data) {
        var self = data.self;
        $(self).find('.b-mselect__ul-view .dependelem:not(".b-myselect__select-li_show_yes") .b-mselect__unselect').each(function() {
          $(this).trigger('click');
        });

      },
      //render options for setvalues
      renderMultiSelectValues = function(slist, id) {
        var html = '',
            l = slist.length;

        html += '<li class="b-mselect__item b-mselect__item_select-all">' + pageInfo.messages.msg_select_all + '</li>';
        for (var i = 0; i < l; i++) {
          html += '<li class="b-mselect__item" data-val="' +
              slist[i].key + '" unselectable="on" data-handler-val="' +
              hash(slist[i].key) + '"  data-dependkey="' +
              slist[i].depend + '" id="' + id + '-' + i + '">' +
              slist[i].value + '<span class="b-mselect__unselect"></span></li>';
        }
        return html;
      },

      UPKEY = 38,
      DOWNKEY = 40,
      LEFTKEY = 37,
      RIGHTKEY = 39,
      ENTERKEY = 13,
      TABKEY = 9,
      ESCKEY = 27,
      SPACE = 32,

      keydownHandler = function(e) {
        var codeKey = e.which || e.keyCode,
            ctrlKey = e.metaKey || e.ctrlKey,
            closed = appDom.hasClass(appDom.byId(this.getAttribute('data-id') +
                listWrapperIdPostfix), 'closed');
        //go up
        if (codeKey === UPKEY && !closed) {
          selectPrevOption.apply(this, []);
          //go down
        } else if (codeKey === DOWNKEY && !closed) {
          selectNextOption.apply(this, []);
          //close tab
        } else if (codeKey === TABKEY && !closed) {
          closeList();
          //choose selected value & close select or not?
        } else if ((codeKey === ENTERKEY || codeKey === SPACE) && !ctrlKey) {
          if (closed) {
            listOpenHandler.apply(this, [e]);
          } else {
            chooseSelected.apply(this, [e]);
          }
          //close list
        } else if (codeKey === ESCKEY && !closed) {
          e.stopPropagation();
          closeList();
        }
      },

      selectPrevOption = function() {
        var id = this.getAttribute('data-id'),
            $list = $('#' + id + '-ms-list-ul'),
            selElem = $list.find('.b-mselect__item_st_selected'),
            prev = true,
            prevElem = selElem;
        if (selElem.length > 0) {
          while (prev) {
            prevElem = prevElem.prev();
            if (prevElem.length > 0) {
              prev = prevElem.hasClass('chosen');
            } else {
              prevElem = null;
              prev = false;
            }
          }
          if (prevElem) {
            selElem.removeClass('b-mselect__item_st_selected');
            prevElem.addClass('b-mselect__item_st_selected');
          }
        } else {
          selElem = $list.find('.b-mselect__item:first:not(".chosen")');
          selElem.addClass('b-mselect__item_st_selected');
        }
      },

      selectNextOption = function() {
        var id = this.getAttribute('data-id'),
            $list = $('#' + id + '-ms-list-ul'),
            selElem = $list.find('.b-mselect__item_st_selected'),
            nextElem = selElem,
            next = true;
        if (selElem.length > 0) {
          while (next) {
            nextElem = nextElem.next();
            if (nextElem.length > 0) {
              next = nextElem.hasClass('chosen');
            } else {
              nextElem = null;
              next = false;
            }
          }
          if (nextElem) {
            selElem.removeClass('b-mselect__item_st_selected');
            nextElem.addClass('b-mselect__item_st_selected');
          }
        } else {
          selElem = findFirst($list);
          if (selElem) {
            selElem.addClass('b-mselect__item_st_selected');
          }
        }
      },

      findFirst = function($list) {
        var finding = true,
            first = $list.find('.b-mselect__item:first');
        while (finding) {
          if (first.length > 0) {
            if (first.hasClass('chosen')) {
              first = first.next();
              finding = true;
            } else {
              return first;
            }
          } else {
            return false;
          }
        }
      },

      chooseSelected = function(e) {
        var id = this.getAttribute('data-id'),
            selected = $('#' + id + '-ms-list-ul')
              .find('.b-mselect__item_st_selected');
        if (selected.length > 0) {
          selected.trigger('click');
        } else {
          closeList(id);
        }
      },

      checkSize = function() {
        if (App.Dom.hasClass(this, 'overwidth') ||
            App.Dom.hasClass(this, 'notoverwidth')) {
          return;
        }
        if (this.scrollWidth > this.offsetWidth) {
          App.Dom.addClass(this, 'overwidth');
          $(this).trigger('mouseover');
        } else {
          App.Dom.addClass(this, 'notoverwidth');
        }
      };

  return {
    init: init
  };
}(window, $, EventMgr, App);