summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2015-06-05 15:55:11 +0200
committerTomas Babej <tbabej@redhat.com>2015-07-03 10:42:16 +0200
commit114f11fe5a1229cf50d95b68e973e3f2dc2c27fb (patch)
tree62637cb1ed393d9b44873207cab3c69764eb7612
parentba0a1c6b33e2519a48754602413c8379fb1f0ff1 (diff)
downloadfreeipa-114f11fe5a1229cf50d95b68e973e3f2dc2c27fb.tar.gz
freeipa-114f11fe5a1229cf50d95b68e973e3f2dc2c27fb.tar.xz
freeipa-114f11fe5a1229cf50d95b68e973e3f2dc2c27fb.zip
webui: ListViewWidget
A widget for rendering a list of groups of items. Intended to be used in sidebar. Plan is to serve also as a base for FacetGroupsWidget. https://fedorahosted.org/freeipa/ticket/3129 Reviewed-By: Martin Kosek <mkosek@redhat.com> Reviewed-By: Tomas Babej <tbabej@redhat.com>
-rw-r--r--install/ui/src/freeipa/widgets/ListViewWidget.js233
1 files changed, 233 insertions, 0 deletions
diff --git a/install/ui/src/freeipa/widgets/ListViewWidget.js b/install/ui/src/freeipa/widgets/ListViewWidget.js
new file mode 100644
index 000000000..d378e2b1e
--- /dev/null
+++ b/install/ui/src/freeipa/widgets/ListViewWidget.js
@@ -0,0 +1,233 @@
+//
+// Copyright (C) 2015 FreeIPA Contributors see COPYING for license
+//
+
+define([
+ 'dojo/_base/declare',
+ 'dojo/_base/lang',
+ 'dojo/on',
+ 'dojo/Evented',
+ 'dojo/Stateful',
+ '../jquery',
+ '../ipa',
+ '../reg',
+ '../text',
+ '../util'
+], function(declare, lang, on, Evented, Stateful, $, IPA, reg, text, util) {
+
+var widgets = {};
+
+/**
+ * Widget for rendering a list of groups of items
+ * @class
+ */
+widgets.ListViewWidget = declare([Stateful, Evented], {
+
+ /**
+ * List of groups
+ * @type {Object[]}
+ */
+ groups: null,
+
+ /**
+ * Should be visible
+ * @type {Boolean}
+ */
+ visible: true,
+
+ /**
+ * Selected item
+ * @property {Object}
+ */
+ selected_item: null,
+
+ // behavior
+ select_on_click: true,
+
+ /**
+ * Raised when menu item is clicked
+ * @event item-click
+ */
+
+ // nodes
+ el: null,
+ group_els: null,
+ item_els: null,
+
+ // html and styling
+ css_class: '',
+ group_el_type: '<div/>',
+ group_class: '',
+ group_label_el_type: '<div/>',
+ group_label_class: 'nav-category',
+ group_label_title_el_type: '<h2/>',
+ group_label_title_class: '',
+ item_cont_el_type: '<div/>',
+ item_cont_class: '',
+ item_list_el_type: '<ul/>',
+ item_list_class: 'nav nav-pills nav-stacked',
+ item_el_type: '<li/>',
+ item_class: 't',
+ item_link_class: 'item-link',
+ selected_class: 'active',
+
+ _groupsSetter: function(value) {
+ this.groups = value;
+ this.render_groups();
+ },
+
+ _get_group_items: function(group) {
+ return group.items;
+ },
+
+ render: function() {
+
+ this.el = $('<div/>', { 'class': this.css_class });
+ this.render_groups();
+ return this.el;
+ },
+
+ render_groups: function() {
+ if (!this.el) return;
+
+ this.group_els = {};
+ this.item_els = {};
+
+ this.el.empty();
+ if (!this.groups) return;
+
+ for (var i=0; i<this.groups.length; i++) {
+ var group = this.groups[i];
+ var items = this._get_group_items(group);
+ if (items.length) {
+ var group_el = this.render_group(group);
+ this.el.append(group_el);
+ }
+ }
+ },
+
+ render_group: function(group) {
+
+ var gr = this.group_els[group.name] = { item_els: {}};
+
+ gr.group_el = $(this.group_el_type, {
+ 'class': this.group_class,
+ name: group.name
+ });
+
+ gr.label_el = $(this.group_label_el_type, {
+ 'class': this.group_label_class
+ }).appendTo(gr.group_el);
+
+ gr.label_title_el = $(this.group_label_title_el_type, {
+ 'class': this.group_label_title_class,
+ text: ' '
+ }).appendTo(gr.label_el);
+
+
+ var item_cont = $(this.item_cont_el_type, { 'class': this.item_cont_class });
+ var item_list = $(this.item_list_el_type, { 'class': this.item_list_class });
+ item_list.appendTo(item_cont);
+ var items = this._get_group_items(group);
+ for (var i=0,l=items.length; i<l; i++) {
+ var item = items[i];
+ var item_el = this.item_els[item.name] = this.render_item(item);
+ item_list.append(item_el);
+ }
+ gr.group_el.append(item_cont);
+
+ return gr.group_el;
+ },
+
+ render_item: function(item) {
+ var self = this;
+ var el = $(this.item_el_type, {
+ name: item.name,
+ 'class': this.item_class,
+ click: function() {
+ if (item.disabled || el.hasClass('entity-facet-disabled')) {
+ return false;
+ }
+ self.on_click(item);
+ return false;
+ }
+ });
+
+ $('<a/>', {
+ text: item.label || item.name || '',
+ 'class': 'item-link',
+ href: this.create_item_link(item),
+ name: item.name,
+ title: item.title
+ }).appendTo(el);
+
+ return el;
+ },
+
+ create_item_link: function(item) {
+ return '#';
+ },
+
+ on_click: function(item) {
+ this.emit('item-click', { source: this, context: item });
+ if (this.select_on_click) {
+ this.select(item);
+ }
+ },
+
+ update_group: function(group) {
+ if (!this.group_els[group.name]) return;
+ var label_el = this.group_els[group.name].label_title_el;
+ label_el.text(group.label);
+ if (group.title) label_el.attr('title', group.title);
+ },
+
+ update_item: function(item) {
+ var item_el = this.item_els[item.name];
+ var label_el = $('a', item_el);
+ label_el.text(item.label);
+ if (item.title) label_el.attr('title', item.title);
+ },
+
+ select: function(item) {
+ if (!this.el) return;
+ var cls = this.selected_class;
+ var item_el = this.item_els[item.name];
+
+ this.el.find(this.item_class).removeClass(cls);
+ this.el.find(this.item_link_class).removeClass(cls);
+
+ if (!item_el) return; // return if can't select
+
+ item_el.addClass(cls);
+ item_el.find(this.item_link_class).addClass(cls);
+ this.set('selected_item', item);
+ this.emit('select', { source: this, context: item });
+ },
+
+ select_first: function() {
+ if (!this.el) return;
+ this.el.find(this.item_link_class).removeClass(this.selected_class);
+ this.el.find(this.item_class).removeClass(this.selected_class);
+ var first = this.el.find(this.item_link_class + ':first');
+ first.addClass(this.selected_class);
+ first.parent().addClass(this.selected_class);
+ },
+
+ set_visible: function(visible) {
+ this.set('visible', visible);
+ this._apply_visible();
+ },
+
+ _apply_visible: function() {
+ if (!this.el) return;
+ this.el.css('display', this.visible ? '' : 'none');
+ },
+
+ constructor: function(spec) {
+ lang.mixin(this, spec);
+ }
+});
+
+ return widgets.ListViewWidget;
+}); \ No newline at end of file