UNPKG

metro4

Version:

The front-end framework for Build responsive, mobile-first projects on the web with the first front-end component library in Metro Style

479 lines (372 loc) 14.9 kB
/* global Metro */ (function(Metro, $) { 'use strict'; var Utils = Metro.utils; var ListViewDefaultConfig = { listviewDeferred: 0, selectable: false, checkStyle: 1, duration: 100, view: Metro.listView.LIST, selectCurrent: true, structure: {}, onNodeInsert: Metro.noop, onNodeDelete: Metro.noop, onNodeClean: Metro.noop, onCollapseNode: Metro.noop, onExpandNode: Metro.noop, onGroupNodeClick: Metro.noop, onNodeClick: Metro.noop, onNodeDblclick: Metro.noop, onListViewCreate: Metro.noop }; Metro.listViewSetup = function (options) { ListViewDefaultConfig = $.extend({}, ListViewDefaultConfig, options); }; if (typeof window["metroListViewSetup"] !== undefined) { Metro.listViewSetup(window["metroListViewSetup"]); } Metro.Component('listview', { init: function( options, elem ) { this._super(elem, options, ListViewDefaultConfig); return this; }, _create: function(){ var element = this.element; this._createView(); this._createEvents(); this._fireEvent("listview-create", { element: element }); }, _createIcon: function(data){ var icon, src; src = Utils.isTag(data) ? $(data) : $("<img>").attr("src", data); icon = $("<span>").addClass("icon"); icon.html(src.outerHTML()); return icon; }, _createCaption: function(data){ return $("<div>").addClass("caption").html(data); }, _createContent: function(data){ return $("<div>").addClass("content").html(data); }, _createToggle: function(){ return $("<span>").addClass("node-toggle"); }, _createNode: function(data){ var that = this, o = this.options; var node; node = $("<li>"); if (data.caption !== undefined || data.content !== undefined ) { var d = $("<div>").addClass("data"); node.prepend(d); if (data.caption !== undefined) d.append(that._createCaption(data.caption)); if (data.content !== undefined) d.append(that._createContent(data.content)); } if (data.icon !== undefined) { node.prepend(this._createIcon(data.icon)); } if (Utils.objectLength(o.structure) > 0) $.each(o.structure, function(key, val){ if (data[key] !== undefined) { $("<div>").addClass("node-data item-data-"+key).addClass(data[val]).html(data[key]).appendTo(node); } }); if (data.attributes && Utils.isObject(data.attributes)) { for(let key in data.attributes) { node.attr(`data-${key}`, data.attributes[key]) } } if (data.class) { node.addClass(data.class) } if (data.badge) { node.append( $("<span>").addClass("badge").html(data.badge) ) } if (data.badges) { const badges = $("<div>").addClass("badges").appendTo(node); data.badges.map(b => { if (!b) return; badges.append( $(b) ) }) } return node; }, _createView: function(){ var that = this, element = this.element, o = this.options; var nodes = element.find("li"); var struct_length = Utils.objectLength(o.structure); element.addClass("listview"); element.find("ul").addClass("listview"); $.each(nodes, function(){ var node = $(this); if (node.data("caption") !== undefined || node.data("content") !== undefined) { var data = $("<div>").addClass("data"); node.prepend(data); if (node.data("caption") !== undefined) data.append(that._createCaption(node.data("caption"))); if (node.data("content") !== undefined) data.append(that._createContent(node.data("content"))); } if (node.data('icon') !== undefined) { node.prepend(that._createIcon(node.data('icon'))); } if (node.children("ul").length > 0) { node.addClass("node-group"); node.append(that._createToggle()); if (node.data("collapsed") !== true) node.addClass("expanded"); } else { node.addClass("node"); } if (node.hasClass("node")) { var cb = $("<input type='checkbox' data-role='checkbox' data-style='"+o.checkStyle+"'>"); cb.data("node", node); node.prepend(cb); } if (struct_length > 0) $.each(o.structure, function(key){ if (node.data(key) !== undefined) { $("<div>").addClass("node-data item-data-"+key).addClass(node.data(key)).html(node.data(key)).appendTo(node); } }); if (node.data("class") !== undefined) { node.addClass(node.data("class")) } }); this.toggleSelectable(); this.view(o.view); }, _createEvents: function(){ var that = this, element = this.element, o = this.options; element.on(Metro.events.dblclick, ".node", function(){ var node = $(this); that._fireEvent("node-dblclick", { node: node }); }); element.on(Metro.events.click, ".node", function(){ var node = $(this); var href = $(this).attr("href"); if (href) { window.location.href = href; return; } element.find(".node").removeClass("current"); node.toggleClass("current"); if (o.selectCurrent === true) { element.find(".node").removeClass("current-select"); node.toggleClass("current-select"); } that._fireEvent("node-click", { node: node }); }); element.on(Metro.events.click, ".node-toggle", function(){ var node = $(this).closest("li"); that.toggleNode(node); }); element.on(Metro.events.click, ".node-group > .data > .caption", function(){ var node = $(this).closest("li"); element.find(".node-group").removeClass("current-group"); node.addClass("current-group"); that._fireEvent("group-node-click", { node: node }); }); element.on(Metro.events.dblclick, ".node-group > .data > .caption", function(){ var node = $(this).closest("li"); that.toggleNode(node); that._fireEvent("node-dbl-click", { node: node }); }); }, view: function(v){ var element = this.element, o = this.options; if (v === undefined) { return o.view; } o.view = v; $.each(Metro.listView, function(i, v){ element.removeClass("view-"+v); element.find("ul").removeClass("view-"+v); }); element.addClass("view-" + o.view); element.find("ul").addClass("view-" + o.view); }, toggleNode: function(node){ var o = this.options; var func; node=$(node); if (!node.hasClass("node-group")) { return ; } node.toggleClass("expanded"); func = node.hasClass("expanded") !== true ? "slideUp" : "slideDown"; this._fireEvent("collapse-node", { node: node }); node.children("ul")[func](o.duration); }, toggleSelectable: function(){ var element = this.element, o = this.options; var func = o.selectable === true ? "addClass" : "removeClass"; element[func]("selectable"); element.find("ul")[func]("selectable"); }, add: function(node, data){ var element = this.element, o = this.options; var target; var new_node; var toggle; if (node === null) { target = element; } else { node=$(node); if (!node.hasClass("node-group")) { return ; } target = node.children("ul"); if (target.length === 0) { target = $("<ul>").addClass("listview").addClass("view-"+o.view).appendTo(node); toggle = this._createToggle(); toggle.appendTo(node); node.addClass("expanded"); } } new_node = this._createNode(data); new_node.addClass("node").appendTo(target); var cb = $("<input type='checkbox'>"); cb.data("node", new_node); new_node.prepend(cb); Metro.makePlugin(cb, "checkbox", {}); this._fireEvent("node-insert", { newNode: new_node, parentNode: node, list: target }); return new_node; }, addGroup: function(data){ var element = this.element, o = this.options; var node; delete data['icon']; node = this._createNode(data); node.addClass("node-group").appendTo(element); node.append(this._createToggle()); node.addClass("expanded"); node.append($("<ul>").addClass("listview").addClass("view-"+o.view)); this._fireEvent("node-insert", { newNode: node, parentNode: null, list: element }) return node; }, insertBefore: function(node, data){ var new_node, parent_node, list; node=$(node); if (!node.length) {return;} new_node = this._createNode(data); new_node.addClass("node").insertBefore(node); parent_node = new_node.closest(".node"); list = new_node.closest("ul"); this._fireEvent("node-insert", { newNode: new_node, parentNode: parent_node, list: list }); return new_node; }, insertAfter: function(node, data){ var new_node, parent_node, list; node=$(node); if (!node.length) {return;} new_node = this._createNode(data); new_node.addClass("node").insertAfter(node); parent_node = new_node.closest(".node"); list = new_node.closest("ul"); this._fireEvent("node-insert", { newNode: new_node, parentNode: parent_node, list: list }); return new_node; }, del: function(node){ var element = this.element; node=$(node); if (!node.length) {return;} var parent_list = node.closest("ul"); var parent_node = parent_list.closest("li"); node.remove(); if (parent_list.children().length === 0 && !parent_list.is(element)) { parent_list.remove(); parent_node.removeClass("expanded"); parent_node.children(".node-toggle").remove(); } this._fireEvent("node-delete", { node: node }); }, clean: function(node){ node=$(node); if (!node.length) {return;} node.children("ul").remove(); node.removeClass("expanded"); node.children(".node-toggle").remove(); this._fireEvent("node-clean", { node: node }); }, getSelected: function(){ var element = this.element; var nodes = []; $.each(element.find(":checked"), function(){ var check = $(this); nodes.push(check.closest(".node")[0]) }); return nodes; }, clearSelected: function(){ this.element.find(":checked").prop("checked", false); this.element.trigger('change'); }, selectAll: function(mode){ this.element.find(".node > .checkbox input").prop("checked", mode !== false); this.element.trigger('change'); }, selectByAttribute: function(attributeName, attributeValue, select) { if (select !== false) { select = true; } this.element.find('li[' + attributeName + '="' + attributeValue + '"]' + ' > .checkbox input').prop("checked", select); this.element.trigger('change'); }, changeAttribute: function(attributeName){ var that = this, element = this.element, o = this.options; var changeView = function(){ var new_view = "view-"+element.attr("data-view"); that.view(new_view); }; var changeSelectable = function(){ o.selectable = JSON.parse(element.attr("data-selectable")) === true; that.toggleSelectable(); }; switch (attributeName) { case "data-view": changeView(); break; case "data-selectable": changeSelectable(); break; } }, destroy: function(){ var element = this.element; element.off(Metro.events.click, ".node"); element.off(Metro.events.click, ".node-toggle"); element.off(Metro.events.click, ".node-group > .data > .caption"); element.off(Metro.events.dblclick, ".node-group > .data > .caption"); return element; } }); }(Metro, m4q));