mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-08 00:54:50 +01:00
* Selected favorite highlighting
Now highlights if the current application state matches a favorite, either by click or manually setting the filters.
This commit is contained in:
parent
9d5d2944c4
commit
01939c6bf6
@ -1283,6 +1283,12 @@ app.classes.calendar = AppJS.extend(
|
||||
jQuery.extend(state, this._super.apply(this, arguments)); // call default implementation
|
||||
}
|
||||
|
||||
// Make sure date is consitantly a string, in case it needs to be passed to server
|
||||
if(state.date.toJSON)
|
||||
{
|
||||
state.state = state.date.toJSON();
|
||||
}
|
||||
|
||||
// Don't store current user in state to allow admins to create favourites for all
|
||||
// Should make no difference for normal users.
|
||||
if(state.owner == egw.user('account_id'))
|
||||
@ -1291,6 +1297,10 @@ app.classes.calendar = AppJS.extend(
|
||||
// it will work for other users too.
|
||||
state.owner = 0;
|
||||
}
|
||||
// Don't store first and last
|
||||
delete state.first;
|
||||
delete state.last;
|
||||
|
||||
return state;
|
||||
},
|
||||
|
||||
|
@ -412,6 +412,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
|
||||
*/
|
||||
applyFilters: function(_set) {
|
||||
var changed = false;
|
||||
var keep_selection = false;
|
||||
|
||||
// Avoid loops cause by change events
|
||||
if(this.update_in_progress) return;
|
||||
@ -464,6 +465,17 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s === 'selected')
|
||||
{
|
||||
changed = true;
|
||||
keep_selection = true;
|
||||
this.controller._selectionMgr.resetSelection();
|
||||
for(var i in _set.selected)
|
||||
{
|
||||
this.controller._selectionMgr.setSelected(_set.selected[i].indexOf('::') > 0 ? _set.selected[i] : this.controller.dataStorePrefix + '::'+_set.selected[i],true);
|
||||
}
|
||||
delete _set.selected;
|
||||
}
|
||||
else if (this.activeFilters[s] !== _set[s])
|
||||
{
|
||||
this.activeFilters[s] = _set[s];
|
||||
@ -475,7 +487,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
|
||||
this.egw().debug("info", "Changing nextmatch filters to ", this.activeFilters);
|
||||
|
||||
// Keep the selection after applying filters, but only if unchanged
|
||||
if(!changed)
|
||||
if(!changed || keep_selection)
|
||||
{
|
||||
this.controller.keepSelection();
|
||||
}
|
||||
@ -509,6 +521,19 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput, et2_IPrin
|
||||
// Trigger an update
|
||||
this.controller.update(true);
|
||||
|
||||
if(changed)
|
||||
{
|
||||
// Highlight matching favorite in sidebox
|
||||
if(this.getInstanceManager().app)
|
||||
{
|
||||
var app = this.getInstanceManager().app;
|
||||
if(window.app[app] && window.app[app].highlight_favorite)
|
||||
{
|
||||
window.app[app].highlight_favorite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.update_in_progress = false;
|
||||
},
|
||||
|
||||
|
@ -142,6 +142,9 @@ var AppJS = Class.extend(
|
||||
this.et2 = et2.widgetContainer;
|
||||
this._fix_iFrameScrolling();
|
||||
if (this.egw.is_popup()) this._set_Window_title();
|
||||
|
||||
// Highlights the favorite based on initial list state
|
||||
this.highlight_favorite();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -363,9 +366,21 @@ var AppJS = Class.extend(
|
||||
sidebox
|
||||
.off()
|
||||
// removed .on("mouse(enter|leave)" (wrapping trash icon), as it stalls delete in IE11
|
||||
.on("click","div.ui-icon-trash", this, this.delete_favorite)
|
||||
.on("click.sidebox","div.ui-icon-trash", this, this.delete_favorite)
|
||||
// need to install a favorite handler, as we switch original one off with .off()
|
||||
.on('click','li[data-id]', this, function(event) {
|
||||
.on('click.sidebox','li[data-id]', this, function(event) {
|
||||
var li = $j(this);
|
||||
li.siblings().removeClass('ui-state-highlight');
|
||||
|
||||
// Wait an arbitrary 50ms to avoid having the class removed again
|
||||
// by the change handler.
|
||||
if(li.attr('data-id') !== 'blank')
|
||||
{
|
||||
window.setTimeout(function() {
|
||||
li.addClass('ui-state-highlight');
|
||||
},50);
|
||||
}
|
||||
|
||||
var href = jQuery('a[href^="javascript:"]', this).prop('href');
|
||||
var matches = href ? href.match(/^javascript:([^\(]+)\((.*)?\);?$/) : null;
|
||||
if (matches && matches.length > 1 && matches[2] !== undefined)
|
||||
@ -401,6 +416,18 @@ var AppJS = Class.extend(
|
||||
self._refresh_fav_nm();
|
||||
}
|
||||
});
|
||||
|
||||
// Bind favorite de-select
|
||||
var egw_fw = egw_getFramework();
|
||||
if(egw_fw && egw_fw.applications[this.appname] && egw_fw.applications[this.appname].browser
|
||||
&& egw_fw.applications[this.appname].browser.baseDiv)
|
||||
{
|
||||
$j(egw_fw.applications[this.appname].browser.baseDiv)
|
||||
.off('.sidebox')
|
||||
.on('change.sidebox', function() {
|
||||
self.highlight_favorite();
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -721,6 +748,102 @@ var AppJS = Class.extend(
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark the favorite closest matching the current state
|
||||
*
|
||||
* Closest matching takes into account not set values, so we pick the favorite
|
||||
* with the most matching values without a value that differs.
|
||||
*/
|
||||
highlight_favorite: function() {
|
||||
if(!this.sidebox) return;
|
||||
|
||||
var state = this.getState();
|
||||
var best_match = false;
|
||||
var best_count = 0;
|
||||
|
||||
$j('li[data-id]',this.sidebox).removeClass('ui-state-highlight');
|
||||
|
||||
$j('li[data-id] a[href^="javascript:"]',this.sidebox).each(function(i,href) {
|
||||
|
||||
var matches = href.href ? href.href.match(/^javascript:([^\(]+)\((.*)?\);?$/) : null;
|
||||
var favorite = {}
|
||||
if (matches && matches.length > 1 && matches[2] !== undefined)
|
||||
{
|
||||
favorite = JSON.parse(decodeURI(matches[2]));
|
||||
}
|
||||
if(!favorite || jQuery.isEmptyObject(favorite)) return;
|
||||
|
||||
var match_count = 0;
|
||||
for(var state_key in state)
|
||||
{
|
||||
if(state[state_key] == favorite.state[state_key] || !state[state_key] && !favorite.state[state_key])
|
||||
{
|
||||
match_count++;
|
||||
}
|
||||
else if (state[state_key] && typeof state[state_key] === 'object' && favorite.state[state_key] && typeof favorite.state[state_key] === 'object')
|
||||
{
|
||||
if((typeof state[state_key].length !== 'undefined' || typeof state[state_key].length !== 'undefined')
|
||||
&& (state[state_key].length || Object.keys(state[state_key]).length) != (favorite.state[state_key].length || Object.keys(favorite.state[state_key]).length ))
|
||||
{
|
||||
// State or favorite has a length, but the other does not
|
||||
if((state[state_key].length === 0 || Object.keys(state[state_key]).length === 0) &&
|
||||
(favorite.state[state_key].length == 0 || Object.keys(favorite.state[state_key]).length === 0))
|
||||
{
|
||||
// Just missing, or one is an array and the other is an object
|
||||
continue;
|
||||
}
|
||||
// One has a value and the other doesn't, no match
|
||||
debugger;
|
||||
return;
|
||||
}
|
||||
// Consider sub-objects (column filters) individually
|
||||
for(var sub_key in state[state_key])
|
||||
{
|
||||
if(state[state_key][sub_key] == favorite.state[state_key][sub_key] || !state[state_key][sub_key] && !favorite.state[state_key][sub_key])
|
||||
{
|
||||
match_count++;
|
||||
}
|
||||
else if (state[state_key][sub_key] && favorite.state[state_key][sub_key] &&
|
||||
typeof state[state_key][sub_key] === 'object' && typeof favorite.state[state_key][sub_key] === 'object')
|
||||
{
|
||||
// Too deep to keep going, just string compare for perfect match
|
||||
if(JSON.stringify(state[state_key][sub_key]) === JSON.stringify(favorite.state[state_key][sub_key]))
|
||||
{
|
||||
match_count++;
|
||||
}
|
||||
}
|
||||
else if(state[state_key][sub_key] && state[state_key][sub_key] != favorite.state[state_key][sub_key])
|
||||
{
|
||||
// Different values, do not match
|
||||
debugger;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (state_key == 'selectcols')
|
||||
{
|
||||
// Skip, might be set, might not
|
||||
}
|
||||
else if (typeof state[state_key] !== 'undefined' && state[state_key] != favorite.state[state_key])
|
||||
{
|
||||
// Different values, do not match
|
||||
debugger;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(match_count > best_count)
|
||||
{
|
||||
best_match = href.parentNode.dataset.id;
|
||||
best_count = match_count;
|
||||
}
|
||||
});
|
||||
if(best_match)
|
||||
{
|
||||
$j('li[data-id="'+best_match+'"]',this.sidebox).addClass('ui-state-highlight');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fix scrolling iframe browsed by iPhone/iPod/iPad touch devices
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user