webui: hide empty fields and sections

Hide widgets without a value. Must be explicitly turned on. In widget by
`hidden_if_empty` flag. Or globally by `hide_empty_widgets` flag. Global
hiding can be individually turned off by `ignore_empty_hiding` flag.

https://fedorahosted.org/freeipa/ticket/4402

Reviewed-By: Endi Sukma Dewata <edewata@redhat.com>
This commit is contained in:
Petr Vobornik 2014-07-31 10:22:51 +02:00
parent 1f13e56ac6
commit 2b2f379811
2 changed files with 93 additions and 11 deletions

View File

@ -70,8 +70,19 @@ define([], function() {
dataType: 'json', dataType: 'json',
async: true, async: true,
processData: false processData: false
} },
/**
* Hide read-only widgets without value
* @property {boolean}
*/
hide_empty_widgets: false,
/**
* Hide sections without any visible widget
* @property {boolean}
*/
hide_empty_sections: true
}; };
return config; return config;

View File

@ -32,6 +32,7 @@ define(['dojo/_base/array',
'dojo/string', 'dojo/string',
'dojo/topic', 'dojo/topic',
'./builder', './builder',
'./config',
'./datetime', './datetime',
'./entity', './entity',
'./ipa', './ipa',
@ -44,7 +45,7 @@ define(['dojo/_base/array',
'./util', './util',
'exports' 'exports'
], ],
function(array, lang, construct, Evented, has, keys, on, string, topic, builder, function(array, lang, construct, Evented, has, keys, on, string, topic, builder, config,
datetime, entity_mod, IPA, $, navigation, phases, reg, rpc, text, util, exp) { datetime, entity_mod, IPA, $, navigation, phases, reg, rpc, text, util, exp) {
/** /**
@ -178,9 +179,23 @@ IPA.widget = function(spec) {
*/ */
that.visible = spec.visible === undefined ? true : spec.visible; that.visible = spec.visible === undefined ? true : spec.visible;
/**
* If true, widget visible is set to false when value is empty
* @property {boolean}
*/
that.hidden_if_empty = spec.hidden_if_empty === undefined ? config.hide_empty_widgets :
spec.hidden_if_empty;
/**
* Disable `hidden_if_empty`
* @property {boolean}
*/
that.ignore_empty_hiding = spec.ignore_empty_hiding === undefined ? config.hide_empty_sections :
spec.ignore_empty_hiding;
/** /**
* Default main element's css classes * Default main element's css classes
* @type {string} * @property {string}
*/ */
that.base_css_class = spec.base_css_class || 'widget'; that.base_css_class = spec.base_css_class || 'widget';
@ -189,7 +204,7 @@ IPA.widget = function(spec) {
* *
* Intended to be overridden in spec objects * Intended to be overridden in spec objects
* *
* @type {string} * @property {string}
*/ */
that.css_class = spec.css_class || ''; that.css_class = spec.css_class || '';
@ -234,22 +249,30 @@ IPA.widget = function(spec) {
/** /**
* Whether widget should be displayed. * Whether widget should be displayed.
* @param {boolean} value - True - visible; False - hidden * @param {boolean} [value] - True - visible; False - hidden,
* undefined - use previous (enforce state)
*/ */
that.set_visible = function(visible) { that.set_visible = function(visible) {
var changed = visible !== that.visible; var old = that._effective_visible;
visible = visible === undefined ? that.visible : visible;
that.visible = visible; that.visible = visible;
var current = that.get_visible();
that._effective_visible = current;
if (visible) { if (current) {
that.show(); that.show();
} else { } else {
that.hide(); that.hide();
} }
if (changed) { if (old !== current) {
that.emit('visible-change', { source: that, visible: visible }); that.emit('visible-change', { source: that, visible: current });
} }
}; };
that.get_visible = function() {
return that.visible;
};
that.hide = function() { that.hide = function() {
that.container.hide(); that.container.hide();
}; };
@ -378,6 +401,13 @@ IPA.input_widget = function(spec) {
*/ */
that.undo_clicked = IPA.observer(); that.undo_clicked = IPA.observer();
/**
* @inheritDoc
*/
that.ctor_init = function() {
on(that, 'value-change', that.hide_if_empty);
};
/** /**
* Creates HTML representation of error link * Creates HTML representation of error link
* @param {HTMLElement} container - node to place the error link * @param {HTMLElement} container - node to place the error link
@ -594,6 +624,26 @@ IPA.input_widget = function(spec) {
that.emit('value-change', { source: that, value: value, old: old }); that.emit('value-change', { source: that, value: value, old: old });
}; };
/**
* Hide widget if value is empty and widget is read_only.
* @protected
*/
that.hide_if_empty = function(event) {
var value = event.value !== undefined ? event.value : true;
that.has_value = !util.is_empty(value);
that.set_visible();
};
that.get_visible = function() {
var visible = that.visible;
if (that.has_value === false && !that.is_writable() && that.hidden_if_empty) {
visible = false;
}
return visible;
};
/** /**
* Widget is writable * Widget is writable
* @return {boolean} * @return {boolean}
@ -4394,10 +4444,30 @@ IPA.section = function(spec) {
var that = IPA.composite_widget(spec); var that = IPA.composite_widget(spec);
that.hidden_if_empty = spec.hidden_if_empty === undefined ? true : spec.hidden_if_empty;
that.show_header = spec.show_header === undefined ? true : spec.show_header; that.show_header = spec.show_header === undefined ? true : spec.show_header;
that.base_css_class = that.base_css_class + ' details-section'; that.base_css_class = that.base_css_class + ' details-section';
that.layout_css_class = spec.layout_css_class || 'col-sm-12'; that.layout_css_class = spec.layout_css_class || 'col-sm-12';
that.ctor_init = function() {
on(that.widgets, 'widget-add', that.on_widget_add);
};
that.on_widget_add = function(event) {
on(event.widget, 'visible-change', that.hide_if_empty);
};
that.hide_if_empty = function() {
if (!that.hidden_if_empty) return;
var widgets = that.widgets.get_widgets();
var any = false;
for (var i=0, l=widgets.length; i<l; i++) {
any = widgets[i].get_visible();
if (any) break;
}
that.set_visible(any);
};
that.create = function(container) { that.create = function(container) {
that.widget_create(container); that.widget_create(container);
@ -4583,7 +4653,7 @@ exp.fluid_layout = IPA.fluid_layout = function(spec) {
var group = $('<div/>', { 'class': that.group_cls }); var group = $('<div/>', { 'class': that.group_cls });
that.rows.put(widget.name, group); that.rows.put(widget.name, group);
if (!widget.visible) { if (!widget.get_visible()) {
group.css('display', 'none'); group.css('display', 'none');
} }
@ -5109,7 +5179,7 @@ IPA.widget_container = function(spec) {
spec = spec || {}; spec = spec || {};
var that = IPA.object(); var that = new Evented();
that.new_container_for_child = spec.new_container_for_child !== undefined ? that.new_container_for_child = spec.new_container_for_child !== undefined ?
spec.new_container_for_child : true; spec.new_container_for_child : true;
@ -5118,6 +5188,7 @@ IPA.widget_container = function(spec) {
that.add_widget = function(widget) { that.add_widget = function(widget) {
that.widgets.put(widget.name, widget); that.widgets.put(widget.name, widget);
that.emit('widget-add', { source: that, widget: widget });
}; };
that.get_widget = function(path) { that.get_widget = function(path) {