Skip to content

Instantly share code, notes, and snippets.

@maolion
Created August 15, 2016 00:26
Show Gist options
  • Select an option

  • Save maolion/36ecf888cb491f381cd1992d1073a26a to your computer and use it in GitHub Desktop.

Select an option

Save maolion/36ecf888cb491f381cd1992d1073a26a to your computer and use it in GitHub Desktop.
var $ = require("jquery");
var Event = require('common/utils/event.js');
var Helpers = require('common/utils/helpers.js');
var DEFAULT_OPTIONS = {
renderLeaf: _renderLeaf,
renderNode: _renderNode,
firstNode: null,
firstLeaf: null,
triggerEventType: "mouseenter"
};
var ROOT_KEY = 'R';
var $NOOP_EL = $(null);
function Cascader($el, options) {
Event.call(this);
this._options = $.extend({}, DEFAULT_OPTIONS, options);
this._source = this._options.source || [];
this._sourceIndexMap = {};
this._rendered = {};
this._opened = [];
this._$el = $el;
this._currentKey = null;
if (!this._source.length) {
_sourceMaybeFromDOM.call(this);
}
_generateSourceIndexMap.call(this, this._source, ROOT_KEY);
_init.call(this);
_initUIEvent.call(this);
}
////////////////////////////////////////////////////////////////////////////////
// private methods
function _init() {
this._$el.empty();
_render.call(this, this._source, this._$el, ROOT_KEY);
}
function _generateSourceIndexMap(list, prefix) {
for (var i = 0, l = list.length; i < l; i++) {
var item = list[i];
var key = prefix + '_' + i;
item.__cascader_key__ = key;
this._sourceIndexMap[key] = item;
if (item.children && item.children.length) {
_generateSourceIndexMap.call(this, item.children, key);
}
}
}
function _initUIEvent() {
var _this = this;
var map = _this._sourceIndexMap;
this._$el.on(this._options.triggerEventType, '.cascader-node', function() {
var $node = $(this);
var key = $node.attr('data-key');
if (!map[key]) {
return;
}
var $child = _render.call(_this, map[key].children, $node, key);
var item = [$node[0], $child[0]];
_this._opened[key] = item;
$(item).addClass('active');
_clearOpened.call(_this, key);
_this._currentKey = key;
_this.fireEvent('opened', [key, item[0], item[1]]);
});
}
function _renderNode(item) {
return item.content || item.name || item.label;
}
function _renderLeaf(item) {
return item.content || item.name || item.label;
}
function _generate(list, key) {
var output = '<div class="cascader-panel '+ (key == ROOT_KEY ? 'is-root' : 'is-child') +'" data-key="'+key+'">';
var nodes = [];
var leafs = [];
if (this._options.firstNode) {
nodes.push(
'<div class="cascader-node is-leaf" data-key="'+key+'">' +
this._options.renderNode.call(this, this._options.firstNode, key) +
'</div>'
);
}
if (this._options.firstLeaf) {
leafs.push(
'<div class="cascader-leaf" data-key="'+key+'">' +
this._options.renderLeaf.call(this, this._options.firstLeaf, key) +
'</div>'
);
}
for (var i = 0, l = list.length; i < l; i++) {
var item = list[i];
var itemKey = item.__cascader_key__;
if (item.children && item.children.length) {
nodes.push(
'<div class="cascader-node" data-key="'+itemKey+'">' +
this._options.renderNode.call(this, item, itemKey) +
'</div>'
);
} else {
leafs.push(
'<div class="cascader-leaf" data-key="'+itemKey+'">' +
this._options.renderLeaf.call(this, item, itemKey) +
'</div>'
);
}
}
output +=
(nodes.length ? '<div class="cascader-node-list">' + nodes.join('') + '</div>' : '')+
(leafs.length ? '<div class="cascader-leaf-list">' + leafs.join('') + '</div>' : '')+
'</div>';
return output;
}
function _render(list, $parent, key) {
if (list && list.length && this._rendered[key]) {
return this._rendered[key] || $NOOP_EL;
}
var $child = $(_generate.call(this, list, key))
this._$el.append($child);
this.fireEvent('rendered', [key, $parent, $child]);
return (
this._rendered[key] = $child
);
}
function _clearOpened(currentKey) {
for (var key in this._opened) {
if (!this._opened.hasOwnProperty(key)) {
continue;
}
if (currentKey.indexOf(key) != 0) {
var item = this._opened[key];
$(item).removeClass('active');
delete this._opened[key];
this.fireEvent('closed', [key, item[0], item[1]]);
}
}
}
function _sourceMaybeFromDOM() {
var $items = this._$el.find('.cascader-source-item');
if (!$items.length) {
return;
}
var rootChildrens = this._source;
var map = {
0: { children: rootChildrens }
};
for (var i = 0, l = $items.length; i < l; i++) {
var $item = $items.eq(i);
var id = $item.attr('data-id');
map[id] = {
id: id,
pid: $item.attr('data-pid'),
content: $item.html(),
children: []
};
}
for (var id in map) {
if (!map.hasOwnProperty(id)) {
continue;
}
var item = map[id];
if (map.hasOwnProperty(item.pid)) {
map[item.pid].children.push(item)
}
}
}
////////////////////////////////////////////////////////////////////////////////
// public methods
var api = Cascader.prototype = Helpers.create(Event.prototype, Cascader);
api.getItem = function(key) {
return this._sourceIndexMap[key];
};
api.getSource = function(key) {
return this._source;
};
api.getOpened = function() {
return this._opened;
};
api.getCurrent = function() {
return
};
api.close = function() {
_clearOpened.call(this, '');
this.fireEvent('close');
};
api.open = function() {
this.fireEvent('open');
};
module.exports = Cascader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment