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.SelectAutoComplete.js

/**
  Select Autocomplete
  provide select with options autocomplete
 *  @param {object} window  global object
 *  @param {function} $ jQuery library
 *  @param {object} EventMgr EventMgr library
 *  @param {object} App Application
 *  @param {object} ScrollHandler Scrollbar library
 *  @return {object}
 **/
App.SelectAutoComplete = function(window, $, EventMgr, App, ScrollHandler) {
  'use strict';

  var inputSelector = '.b-select-ac__input',
      chooseListItem = '.i-select-ac__list-item',
      keys = {
        '38': 'UPKEY',
        '40': 'DOWNKEY',
        '37': 'LEFTKEY',
        '39': 'RIGHTKEY',
        '13': 'ENTERKEY',
        '9': 'TABKEY'
      };

  function $content() {
    var content;
    return function() {
      if (!content || content.length === 0) {
        content = $('#main-wrapper');
      }
      return content;
    }();
  }

  function $body() {
    var content;
    return function() {
      if (!content || content.length === 0) {
        content = $('body');
      }
      return content;
    }();
  }

  function init() {
    EventMgr.on($content(), inputSelector, 'keyup', keyUpHandler);
    EventMgr.on($content(), inputSelector, 'keydown', tabUpHandler);
    EventMgr.on($content(), inputSelector, 'blur', checkValue);
    EventMgr.on($content(), inputSelector, 'click', getDefaultOptions);
    EventMgr.on($content(), inputSelector, 'click', preventDefault);
    EventMgr.bind('selectAutoCompleteResponse', makeChooseList);
    EventMgr.on($content(), chooseListItem, 'click', chooseListItemHandler);
  }

  var timer,
      lastValue;

  function preventDefault(e) {
    e.preventDefault();
    e.stopPropagation();
  }

  function getChooseList(elem, firstRun) {
    var name = elem.getAttribute('data-name'),
        tabId = elem.getAttribute('data-tabid'),
        url = window.pageInfo.url,
        param = $('#frm-' + tabId).serializeObject(),
        value = elem.value;
    param[name] = elem.value;
    /* jslint camelcase: false */
    param.sv_field = name;
    param.sv_autocomplete = 'yes';
    /* jslint camelcase: true */
    if ((value !== lastValue) || firstRun) {
      EventMgr.trigger('ajaxRequest', {
        url: url,
        param: param,
        trfunc: 'selectAutoCompleteResponse',
        invar: { tabId: tabId, sourceField: name, value: value },
        type: 'post', outtype: 'json', queue: 'noqueue' });
    }
    lastValue = value;
  }

  function getDefaultOptions() {
    // close others list
    $body().trigger('click');
    var elem = this;
    getChooseList(elem, true);
  }

  /**
   * KeyUp handler
   * get choose list or set value from choose list
   * @param {object} e
   * @this {Node}
   */
  function keyUpHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode;
    if (keys[codeKey]) {
      keyChooseListItem(e, keys[codeKey], this);
      return;
    }
    var elem = this;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function() {
      getChooseList(elem);
    }, 200);
  }

  /**
   * Choose value by up/down key
   * @param {Object} e Event object
   * @param {String} key Name of key
   * @param {HTMLElement} elem
   * @param {Boolean} dontPrevent Don't prevent default action
   */
  function keyChooseListItem(e, key, elem, dontPrevent) {
    var name = elem.getAttribute('data-name'),
        tabId = elem.getAttribute('data-tabid'),
        $selected = $('#b-select-ac-list__' + name + '-' + tabId +
            ' .b-select-ac__list-item_selected_yes');
    if ($selected.length === 0) {
      $selected = $('#b-select-ac-list__' + name + '-' + tabId +
          ' .i-select-ac__list-item:first');
      if ($selected.length === 0) {
        return;
      } else {
        $selected.addClass('b-select-ac__list-item_selected_yes');
        chooseListItemHandler.apply($selected[0], [e, true, dontPrevent]);
        return;
      }
    }

    if (key === 'UPKEY') {
      var prev = $selected.prev();
      if (prev.length !== 0) {
        $selected.removeClass('b-select-ac__list-item_selected_yes');
        prev.addClass('b-select-ac__list-item_selected_yes');
        chooseListItemHandler.apply(prev[0], [e, true, dontPrevent]);
      }
    } else if (key === 'DOWNKEY') {
      var next = $selected.next();
      if (next.length !== 0) {
        $selected.removeClass('b-select-ac__list-item_selected_yes');
        next.addClass('b-select-ac__list-item_selected_yes');
        chooseListItemHandler.apply(next[0], [e, true, dontPrevent]);
      }
    } else if (key === 'ENTERKEY') {
      chooseListItemHandler.apply($selected[0], [e, false, dontPrevent]);
    } else if (key === 'TABKEY') {
      //choose only when selected 1st elem
      if ($selected.index() === 0) {
        chooseListItemHandler.apply($selected[0], [e, true, dontPrevent]);
      }
    }
  }
  var chooseListStorage = {},
      VALUESCACHE = {};

  /**
   * Build choose list from response
   * @param {Object} e
   * @param {Object} data
   * @return {Boolean}
   */
  function makeChooseList(e, data) {
    var tabId = data.tabId,
        fieldName = data.sourceField,
        commonId = fieldName + '-' + tabId,
        listElem = App.Dom.byId('b-select-ac-list__' + commonId),
        listElemWrapperId = 'cont-b-select-ac-list__' + commonId,
        listElemWrapper = App.Dom.byId(listElemWrapperId),
        chooseList = data.setvalues[fieldName],
        defValue = data.value,
        l, html = '', value, re,
        options = {}, id = (new Date()).getTime(),
        focusedElem = document.activeElement;
    //show only if element is focused
    if (focusedElem) {
      if (focusedElem.getAttribute('data-name') !== fieldName) {
        return false;
      }
    }

    //trigger setvalues if somebody add other field values
    if (data[data.sourceField]) {
      data[data.sourceField] = null;
      EventMgr.trigger('formSetValues', data);
    }

    if (chooseList && chooseList.slist) {
      l = chooseList.slist.length;
      for (var i = 0; i < l; i++) {
        value = chooseList.slist[i].value;
        if (typeof value === 'string') {
          re = new RegExp('(' + App.u.escapeRegExp(defValue) + ')', 'i');
          value = value
              .replace(re, '<span class="b-select-ac__font-normal">$1</span>');
          html += '<li data-id="' + i + '" data-lid="' + id + '"' +
              ' class="b-select-ac__list-item i-select-ac__list-item">' + value + '</li>';
          options[String(i)] = {
            key: chooseList.slist[i].key,
            value: chooseList.slist[i].value
          };
        }
      }
      chooseListStorage[String(id)] = {
        options: options
      };
      listElem.innerHTML = html;
    } else {
      listElem.innerHTML =
          '<li class="b-select-ac__list-item i-select-ac__list-item ' +
              'b-select-ac__list-item_notfound_yes" data-lid="' + id + '">' +
          pageInfo.notfound + '</li>';
    }
    if (listElemWrapper.style.display !== 'block') {
      listElemWrapper.style.display = 'block';
      $body().on('click.closeChooseList',
          $.proxy(closeChooseList, listElem));
    } else {
      $body().off('click.closeChooseList');
      $body().on('click.closeChooseList',
          $.proxy(closeChooseList, listElem));
    }
    EventMgr.trigger('updateScroll', listElemWrapperId);
    App.Common.setOptionListPosition('#opt-', commonId);
  }

  function setValue(opt) {
    opt = opt || {};
    var inputValue = App.Dom.byId(opt.id),
        inputKey = App.Dom.byId('key-' + opt.id);
    if (inputValue) {
      inputValue.value = opt.value;
    }
    if (inputKey) {
      inputKey.value = opt.key;
      $(inputKey).trigger('change');
      VALUESCACHE[opt.id] = {
        key: opt.key,
        value: opt.value
      };
    }
  }

  /**
   * Set choosen value to element
   * @param {Object} e
   * @param {Boolean|Undefined} dontclose Don't close flag
   * @param {Boolean|Undefined} dontPrevent Don't prevent default action
   * @this {Node}
   */
  function chooseListItemHandler(e, dontclose, dontPrevent) {
    if (!dontPrevent) {
      e.preventDefault();
    }
    var elem = this,
        id = elem.getAttribute('data-id'),
        lid = elem.getAttribute('data-lid'),
        parentNode = elem.parentNode,
        inputId = parentNode.getAttribute('data-id');
    if (chooseListStorage[lid] && chooseListStorage[lid].options) {
      if (chooseListStorage[lid].options[id] !== undefined) {
        setValue({
          id: inputId,
          key: chooseListStorage[lid].options[id].key,
          value: chooseListStorage[lid].options[id].value
        });
      }
    }
    if (!dontclose) {
      closeChooseList.apply(parentNode, [{}, true]);
    }
  }
  function tabUpHandler(e) {
    e = e || window.event;
    var codeKey = e.which || e.keyCode;
    if (keys[codeKey] === 'TABKEY') {
      if (this.value !== '') {
        keyChooseListItem(e, 'TABKEY', this, true);
      }
      //close list
      $body().trigger('click');
    }
  }
  /**
   * check congruence for value & key
   */
  function checkValue(e, force) {
    var id = this.getAttribute('id'),
        optListWrapper = App.Dom.byId('cont-b-select-ac-list__' + id),
        optList = App.Dom.byId('b-select-ac-list__' + id);
    if (force || (optListWrapper && optListWrapper.style.display === 'none' ||
         $(optList).find('.b-select-ac__list-item_notfound_yes').length)) {
      var inputKey = App.Dom.byId('key-' + id);
      if (VALUESCACHE[id] && inputKey &&
           VALUESCACHE[id].key === inputKey.value) {
        if (this.value !== '') {
          this.value = VALUESCACHE[id].value;
        } else {
          setValue({id: id, key: '', value: ''});
        }
      } else {
        this.value = '';
      }
    }
  }

  /**
   * check fullmatch value & options
   */
  function checkFullmatch(options, value) {
    var fullmatch = false,
        fullmatchKey;
    if (options && value !== undefined) {
      var l = options.length;
      for (var key in options) {
        if (options.hasOwnProperty(key)) {
          fullmatchKey = key;
          if (options[key].value === value) {
            fullmatch = true;
            break;
          }
        }
      }
    }
    return {
        yes: fullmatch,
        key: options[fullmatchKey].key
    };
  }
  /**
   * close Choose list
   * @param {Boolean|Undefined} chosen
   * @param {Object} e
   * @this {Node}
   */
  function closeChooseList(e, chosen) {
    var listItem = $(this).find('.i-select-ac__list-item');
    var listElemWrapper = this.parentNode;

    if (listItem[0] && !chosen) {
      var lid = listItem[0].getAttribute('data-lid'),
          id = this.getAttribute('data-id');
      if (id && chooseListStorage && chooseListStorage[lid]) {
        var inputValue = App.Dom.byId(id),
            fullmatch = checkFullmatch(chooseListStorage[lid].options, inputValue.value);
        //if (chooseListStorage[lid].fullmatchKey !== false) {
        if (fullmatch.yes) {
          //set valuesCache
          setValue({
            id: id,
            key: fullmatch.key,
            value: inputValue.value
          });
        } else {
          //check for valid value in value field
          checkValue.apply(inputValue, [{}, true]);
        }
      }
    }
    listElemWrapper.style.display = 'none';
    this.innerHTML = '';
    $body().off('click');
    chooseListStorage = {};
  }

  var api = {
    init: init
  };

  return api;
} (window, $, EventMgr, App, ScrollHandler);