Search field for tasks

Fixes #2103
pull/7/head
Francis Lachapelle 2012-12-05 14:47:28 -05:00
parent 3606601c39
commit 8ca79d9a17
13 changed files with 145 additions and 116 deletions

View File

@ -211,11 +211,11 @@ static NSArray *tasksFields = nil;
user = [context activeUser]; user = [context activeUser];
userLogin = [user login]; userLogin = [user login];
title = [request formValueForKey: @"search"];
param = [request formValueForKey: @"filterpopup"]; param = [request formValueForKey: @"filterpopup"];
if ([param length]) if ([param length])
{ {
[self _setupDatesWithPopup: param andUserTZ: userTimeZone]; [self _setupDatesWithPopup: param andUserTZ: userTimeZone];
title = [request formValueForKey: @"search"];
} }
else else
{ {

View File

@ -5,17 +5,16 @@
xmlns:const="http://www.skyrix.com/od/constant" xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label" xmlns:label="OGo:label"
> >
<div class="menu" id="searchMenu"> <div class="filterPanel" data-search="admin">
<ul id="searchOptions" class="choiceMenu"> <div class="menu" id="searchMenu">
<li id="name_or_address"><var:string <ul class="choiceMenu">
label:value="Name or Email"/></li> <li data-option="name_or_address"><var:string
</ul> label:value="Name or Email"/></li>
</div> </ul>
</div>
<div id="filterPanel">
<span class="searchBox" style="float: right;"> <span class="searchBox" style="float: right;">
<input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" /> <input name="criteria" type="hidden" var:value="searchCriteria" />
<input id="searchValue" class="textField" autocomplete="off" name="search" <input name="search" class="textField" autocomplete="off"
menuid="searchMenu" menuid="searchMenu"
type="text" var:value="searchText" /> type="text" var:value="searchText" />
</span> </span>

View File

@ -5,21 +5,20 @@
xmlns:const="http://www.skyrix.com/od/constant" xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label" xmlns:label="OGo:label"
> >
<div class="menu" id="searchMenu"> <div class="filterPanel" data-search="contacts">
<ul id="searchOptions" class="choiceMenu"> <div class="menu" id="searchMenu">
<li id="name_or_address"><var:string <ul id="searchOptions" class="choiceMenu">
label:value="Name or Email"/></li> <li data-option="name_or_address"><var:string
<li id="category"><var:string label:value="Category"/></li> label:value="Name or Email"/></li>
<li id="organization"><var:string label:value="Organization"/></li> <li data-option="category"><var:string label:value="Category"/></li>
</ul> <li data-option="organization"><var:string label:value="Organization"/></li>
</div> </ul>
</div>
<div id="filterPanel">
<span class="searchBox" style="float: right;"> <span class="searchBox" style="float: right;">
<input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" /> <input name="criteria" type="hidden" var:value="searchCriteria" />
<input id="searchValue" class="textField" autocomplete="off" name="search" <input name="search" class="textField" autocomplete="off"
menuid="searchMenu" menuid="searchMenu"
type="text" var:value="searchText" /> type="text" var:value="searchText" />
</span> </span>
</div> </div>
</container> </container>

View File

@ -5,25 +5,24 @@
xmlns:const="http://www.skyrix.com/od/constant" xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label" xmlns:label="OGo:label"
> >
<div class="menu" id="searchMenu"> <div class="filterPanel" data-search="mail">
<ul id="searchOptions" class="choiceMenu"> <div class="menu" id="searchMenu">
<li id="subject"><var:string label:value="Subject"/></li> <ul class="choiceMenu">
<li id="sender"><var:string label:value="Sender"/></li> <li data-option="subject"><var:string label:value="Subject"/></li>
<li id="subject_or_sender"><var:string <li data-option="sender"><var:string label:value="Sender"/></li>
label:value="Subject or Sender"/></li> <li data-option="subject_or_sender"><var:string
<li id="to_or_cc"><var:string label:value="To or Cc"/></li> label:value="Subject or Sender"/></li>
<li id="entire_message"><var:string <li data-option="to_or_cc"><var:string label:value="To or Cc"/></li>
label:value="Entire Message"/></li> <li data-option="entire_message"><var:string
</ul> label:value="Entire Message"/></li>
</div> </ul>
</div>
<div id="filterPanel">
<var:if condition="hideFrame" const:negate="YES" <var:if condition="hideFrame" const:negate="YES"
><span class="searchBox" style="float: right"> ><span class="searchBox" style="float: right">
<input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" /> <input name="criteria" type="hidden" var:value="searchCriteria" />
<input id="searchValue" <input name="search"
class="textField" class="textField"
autocomplete="off" name="search" type="text" var:value="searchText" autocomplete="off" type="text" var:value="searchText"
menuid="searchMenu" /> menuid="searchMenu" />
</span> </span>
</var:if> </var:if>

View File

@ -5,19 +5,18 @@
xmlns:const="http://www.skyrix.com/od/constant" xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label" xmlns:label="OGo:label"
> >
<div class="menu" id="searchMenu"> <div class="filterPanel" data-search="events">
<ul id="searchOptions" class="choiceMenu"> <div class="menu" id="eventSearchMenu">
<li><var:string label:value="Title or Description"/></li> <ul class="choiceMenu">
</ul> <li data-option="title"><var:string label:value="Title or Description"/></li>
</div> </ul>
</div>
<div id="filterPanel">
<span class="searchBox" style="float: right"> <span class="searchBox" style="float: right">
<input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" /> <input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" />
<input id="searchValue" <input id="searchValue"
class="textField" class="textField"
autocomplete="off" name="search" type="text" var:value="searchText" autocomplete="off" name="search" type="text" var:value="searchText"
menuid="searchMenu" /> menuid="eventSearchMenu" />
</span> </span>
<var:string label:value="View:" /> <var:string label:value="View:" />

View File

@ -170,9 +170,20 @@
</table> </table>
</div> </div>
<div id="tasksListView" class="tab"> <div id="tasksListView" class="tab">
<label> <div class="filterPanel" data-search="tasks">
<div class="menu" id="taskSearchMenu">
<ul class="choiceMenu">
<li data-option="title"><var:string label:value="Title or Description"/></li>
</ul>
</div>
<span class="searchBox" style="float: right">
<input name="criteria" type="hidden" />
<input name="search" class="textField"
autocomplete="off" type="text"
menuid="taskSearchMenu" />
</span>
<input id="showHideCompletedTasks" type="checkbox" class="checkBox"/><var:string label:value="Show completed tasks"/> <input id="showHideCompletedTasks" type="checkbox" class="checkBox"/><var:string label:value="Show completed tasks"/>
</label> </div>
<table id="tasksList" cellspacing="0"> <table id="tasksList" cellspacing="0">
<thead> <thead>
<tr> <tr>

View File

@ -6,8 +6,8 @@ var usersRightsWindowWidth = 450;
/* ACLs module */ /* ACLs module */
function onSearchFormSubmit() { function onSearchFormSubmit(panel) {
var searchValue = $("searchValue"); var searchValue = panel.down('[name="search"]');
var encodedValue = encodeURI(searchValue.value); var encodedValue = encodeURI(searchValue.value);
if (encodedValue.blank()) { if (encodedValue.blank()) {
@ -61,20 +61,18 @@ function buildUsersTree(treeDiv, response) {
var isUserDialog = false; var isUserDialog = false;
var multiplier = ((isUserDialog) ? 1 : 2); var multiplier = ((isUserDialog) ? 1 : 2);
if (response.length > 0) { for (var i = 0; i < response.length; i++)
for (var i = 0; i < response.length; i++) addUserLineToTree(d, 1 + i * multiplier, response[i]);
addUserLineToTree(d, 1 + i * multiplier, response[i]); treeDiv.innerHTML = "";
treeDiv.innerHTML = ""; treeDiv.appendChild(d.domObject());
treeDiv.appendChild(d.domObject ()); treeDiv.clean = false;
treeDiv.clean = false; for (var i = 0; i < response.length; i++) {
for (var i = 0; i < response.length; i++) { if (!isUserDialog) {
if (!isUserDialog) { var toggle = $("tgd" + (1 + i * 2));
var toggle = $("tgd" + (1 + i * 2)); toggle.observe ("click", onUserNodeToggle);
toggle.observe ("click", onUserNodeToggle);
}
var sd = $("sd" + (1 + i * multiplier));
sd.observe("click", onTreeItemClick);
} }
var sd = $("sd" + (1 + i * multiplier));
sd.observe("click", onTreeItemClick);
} }
} }
@ -220,7 +218,7 @@ function initAdministration() {
$("helpDialog").hide(); $("helpDialog").hide();
}); });
var searchValue = $("searchValue"); var searchValue = $$('[data-search="admin"] [name="search"]').first();
searchValue.focus(); searchValue.focus();
} }

View File

@ -18,9 +18,9 @@ function openContactsFolder(contactsFolder, reload, idx) {
var url = URLForFolderID(Contact.currentAddressBook, "Contacts") + var url = URLForFolderID(Contact.currentAddressBook, "Contacts") +
"/view?noframe=1"; "/view?noframe=1";
var searchValue = search["value"]; var searchValue = search["contacts"]["value"];
if (searchValue && searchValue.length > 0) if (searchValue && searchValue.length > 0)
url += ("&search=" + search["criteria"] url += ("&search=" + search["contacts"]["criteria"]
+ "&value=" + escape(searchValue.utf8encode())); + "&value=" + escape(searchValue.utf8encode()));
var sortAttribute = sorting["attribute"]; var sortAttribute = sorting["attribute"];
if (sortAttribute && sortAttribute.length > 0) if (sortAttribute && sortAttribute.length > 0)
@ -613,7 +613,7 @@ function onFolderSelectionChange(event) {
} }
else { else {
search = {}; search = {};
$("searchValue").value = ""; $$('[name="search"]').each(function(input) { input.value = "" });
initCriteria(); initCriteria();
openContactsFolder(nodes[0].getAttribute("id")); openContactsFolder(nodes[0].getAttribute("id"));
} }

View File

@ -784,9 +784,9 @@ function openMailbox(mailbox, reload) {
lastClickedRow = -1; // from generic.js lastClickedRow = -1; // from generic.js
} }
var searchValue = search["value"]; var searchValue = search["mail"]["value"];
if (searchValue && searchValue.length > 0) { if (searchValue && searchValue.length > 0) {
urlParams.set("search", search["criteria"]); urlParams.set("search", search["mail"]["criteria"]);
urlParams.set("value", escape(searchValue.utf8encode())); urlParams.set("value", escape(searchValue.utf8encode()));
} }
var sortAttribute = sorting["attribute"]; var sortAttribute = sorting["attribute"];

View File

@ -277,11 +277,11 @@ TABLE#eventsList THEAD TD:last-child,
TABLE#tasksList THEAD TD:last-child TABLE#tasksList THEAD TD:last-child
{ border-right: 0px; } { border-right: 0px; }
#filterPanel, .filterPanel,
#schedulerTabs .tab label #schedulerTabs .tab label
{ display: block; { display: block;
margin: 0; margin: 0;
padding: 5px; padding: 0 0 5px 5px;
background-color: #eee; background-color: #eee;
background-color: #E6E7E6; } background-color: #E6E7E6; }

View File

@ -2169,14 +2169,17 @@ function onHeaderClick(event) {
Event.stop(event); Event.stop(event);
} }
function refreshCurrentFolder() { function refreshCurrentFolder(id) {
refreshEvents(); if (id == 'tasks')
refreshTasks();
else
refreshEvents();
} }
/* refreshes the "unifinder" list */ /* refreshes the "unifinder" list */
function refreshEvents() { function refreshEvents() {
var titleSearch; var titleSearch;
var value = search["value"]; var value = search["events"]["value"];
if (value && value.length) if (value && value.length)
titleSearch = "&search=" + escape(value.utf8encode()); titleSearch = "&search=" + escape(value.utf8encode());
@ -2193,7 +2196,15 @@ function refreshEvents() {
} }
function refreshTasks(setUserDefault) { function refreshTasks(setUserDefault) {
var titleSearch;
var value = search["tasks"]["value"];
var setud; var setud;
if (value && value.length)
titleSearch = "&search=" + escape(value.utf8encode());
else
titleSearch = "";
/* TODO: the logic behind this should be reimplemented properly: /* TODO: the logic behind this should be reimplemented properly:
the "taskslist" method should save the status when the 'show-completed' the "taskslist" method should save the status when the 'show-completed'
is set to true and revert to the current status when that parameter is is set to true and revert to the current status when that parameter is
@ -2201,10 +2212,13 @@ function refreshTasks(setUserDefault) {
setud = ""; setud = "";
if (setUserDefault == 1) if (setUserDefault == 1)
setud = "&setud=1"; setud = "&setud=1";
refreshAlarms(); refreshAlarms();
return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks
+ "&asc=" + sorting["task-ascending"] + "&asc=" + sorting["task-ascending"]
+ "&sort=" + sorting["task-attribute"]); + "&sort=" + sorting["task-attribute"]
+ titleSearch);
} }
function refreshEventsAndDisplay() { function refreshEventsAndDisplay() {
@ -2700,11 +2714,12 @@ function getMenus() {
onCalendarNew, onCalendarRemove, onCalendarNew, onCalendarRemove,
"-", onCalendarExport, onCalendarImport, "-", onCalendarExport, onCalendarImport,
null, "-", null, "-", onMenuSharing); null, "-", null, "-", onMenuSharing);
menus["searchMenu"] = new Array(setSearchCriteria); menus["eventSearchMenu"] = new Array(setSearchCriteria);
menus["tasksListMenu"] = new Array (editEvent, newTask, "-", menus["tasksListMenu"] = new Array (editEvent, newTask, "-",
marksTasksAsCompleted, deleteEvent, "-", marksTasksAsCompleted, deleteEvent, "-",
onMenuRawTask); onMenuRawTask);
menus["taskSearchMenu"] = new Array(setSearchCriteria);
var calendarsMenu = $("calendarsMenu"); var calendarsMenu = $("calendarsMenu");
if (calendarsMenu) if (calendarsMenu)
@ -3361,4 +3376,4 @@ function initScheduler() {
Event.observe(window, "resize", onWindowResize); Event.observe(window, "resize", onWindowResize);
} }
document.observe("dom:loaded", initScheduler); document.observe("generic:loaded", initScheduler);

View File

@ -443,7 +443,7 @@ DIV.dragHandle:active
{ background-color: #99a; } { background-color: #99a; }
/* search fields */ /* search fields */
DIV#filterPanel DIV.filterPanel
{ height: 2em; { height: 2em;
vertical-align: middle; vertical-align: middle;
width: 100%; width: 100%;
@ -770,7 +770,7 @@ BUTTON.comboBoxButton:active
background-color: #d6d7d6; background-color: #d6d7d6;
} }
INPUT#searchValue INPUT[name="search"]
{ margin-right: 1em; { margin-right: 1em;
width: 20em; width: 20em;
padding-left: 24px; padding-left: 24px;

View File

@ -1073,14 +1073,15 @@ function popupSearchMenu(event) {
} }
function setSearchCriteria(event) { function setSearchCriteria(event) {
var searchValue = $("searchValue"); var panel = $(this).up('.filterPanel');
var searchCriteria = $("searchCriteria"); var searchValue = panel.down('[name="search"]');
var searchCriteria = panel.down('[name="criteria"]');
if (searchValue.ghostPhrase == searchValue.value) if (searchValue.ghostPhrase == searchValue.value)
searchValue.value = ""; searchValue.value = "";
searchValue.ghostPhrase = this.innerHTML; searchValue.ghostPhrase = this.innerHTML;
searchCriteria.value = this.getAttribute('id'); searchCriteria.value = this.readAttribute('data-option');
if (this.parentNode.chosenNode) if (this.parentNode.chosenNode)
this.parentNode.chosenNode.removeClassName("_chosen"); this.parentNode.chosenNode.removeClassName("_chosen");
@ -1092,20 +1093,18 @@ function setSearchCriteria(event) {
searchValue.lastSearch = ""; searchValue.lastSearch = "";
this.parentNode.chosenNode = this; this.parentNode.chosenNode = this;
onSearchFormSubmit(); onSearchFormSubmit(panel);
} }
} }
function configureSearchField() { function configureSearchField() {
var searchValue = $("searchValue"); $$('.searchBox [name="search"]').each(function(searchValue) {
searchValue.on("click", popupSearchMenu);
if (searchValue) { searchValue.on("blur", onSearchBlur);
searchValue.observe("click", popupSearchMenu); searchValue.on("focus", onSearchFocus);
searchValue.observe("blur", onSearchBlur); searchValue.on("keydown", onSearchKeyDown);
searchValue.observe("focus", onSearchFocus); searchValue.on("mousedown", onSearchMouseDown);
searchValue.observe("keydown", onSearchKeyDown); });
searchValue.observe("mousedown", onSearchMouseDown);
}
} }
function onSearchMouseDown(event) { function onSearchMouseDown(event) {
@ -1118,7 +1117,7 @@ function onSearchMouseDown(event) {
} }
function onSearchFocus(event) { function onSearchFocus(event) {
ghostPhrase = this.ghostPhrase; var ghostPhrase = this.ghostPhrase;
if (this.value == ghostPhrase) { if (this.value == ghostPhrase) {
this.value = ""; this.value = "";
this.setAttribute("modified", ""); this.setAttribute("modified", "");
@ -1130,15 +1129,16 @@ function onSearchFocus(event) {
function onSearchBlur(event) { function onSearchBlur(event) {
if (!this.value || this.value.blank()) { if (!this.value || this.value.blank()) {
var id = $(this).up('[data-search]').readAttribute('data-search');
this.setAttribute("modified", ""); this.setAttribute("modified", "");
this.setStyle({ color: "#909090" }); this.setStyle({ color: "#909090" });
this.value = this.ghostPhrase; this.value = this.ghostPhrase;
if (this.timer) if (this.timer)
clearTimeout(this.timer); clearTimeout(this.timer);
search["value"] = ""; search[id]["value"] = "";
if (this.lastSearch != "") { if (this.lastSearch != "") {
this.lastSearch = ""; this.lastSearch = "";
refreshCurrentFolder(); refreshCurrentFolder(id);
} }
} else if (this.value == this.ghostPhrase) { } else if (this.value == this.ghostPhrase) {
this.setAttribute("modified", ""); this.setAttribute("modified", "");
@ -1160,43 +1160,47 @@ function IsCharacterKey(keyCode) {
function onSearchKeyDown(event) { function onSearchKeyDown(event) {
if (event.keyCode == Event.KEY_RETURN) { if (event.keyCode == Event.KEY_RETURN) {
var panel = $(this).up('.filterPanel');
if (this.timer) if (this.timer)
clearTimeout(this.timer); clearTimeout(this.timer);
onSearchFormSubmit(); onSearchFormSubmit(panel);
preventDefault(event); preventDefault(event);
} }
else if (event.keyCode == Event.KEY_BACKSPACE else if (event.keyCode == Event.KEY_BACKSPACE
|| IsCharacterKey(event.keyCode)) { || IsCharacterKey(event.keyCode)) {
var panel = $(this).up('.filterPanel');
if (this.timer) if (this.timer)
clearTimeout(this.timer); clearTimeout(this.timer);
this.timer = setTimeout("onSearchFormSubmit()", 500); this.timer = onSearchFormSubmit.delay(0.5, panel);
} }
} }
function onSearchFormSubmit(event) { function onSearchFormSubmit(filterPanel) {
var searchValue = $("searchValue"); var id = filterPanel.readAttribute('data-search');
var searchCriteria = $("searchCriteria"); var searchValue = filterPanel.down('[name="search"]');
var searchCriteria = filterPanel.down('[name="criteria"]');
if (searchValue.value != searchValue.ghostPhrase if (searchValue.value != searchValue.ghostPhrase
&& (searchValue.value != searchValue.lastSearch && (searchValue.value != searchValue.lastSearch
&& (searchValue.value.strip().length > minimumSearchLength && (searchValue.value.strip().length > minimumSearchLength
|| searchValue.value.strip() == "." ))) { || searchValue.value.strip() == "." ))) {
search["criteria"] = searchCriteria.value; search[id]["criteria"] = searchCriteria.value;
search["value"] = searchValue.value; search[id]["value"] = searchValue.value;
searchValue.lastSearch = searchValue.value; searchValue.lastSearch = searchValue.value;
refreshCurrentFolder(); refreshCurrentFolder(id);
} }
} }
function initCriteria() { function initCriteria() {
var searchCriteria = $("searchCriteria"); $$('[data-search]').each(function(element) {
var searchValue = $("searchValue"); var box = $(element);
var searchOptions = $("searchOptions"); var id = box.readAttribute('data-search');
var searchCriteria = box.down('[name="criteria"]');
if (searchValue && searchOptions) { var searchValue = box.down('[name="search"]');
var searchOptions = box.down('.choiceMenu');
var firstOption = searchOptions.down("li"); var firstOption = searchOptions.down("li");
if (firstOption) { if (firstOption) {
searchCriteria.value = firstOption.getAttribute('id'); searchCriteria.value = firstOption.readAttribute('data-option');
searchValue.ghostPhrase = firstOption.innerHTML; searchValue.ghostPhrase = firstOption.innerHTML;
searchValue.lastSearch = ""; searchValue.lastSearch = "";
if (searchValue.value == '') { if (searchValue.value == '') {
@ -1209,9 +1213,11 @@ function initCriteria() {
searchOptions.chosenNode.removeClassName("_chosen"); searchOptions.chosenNode.removeClassName("_chosen");
firstOption.addClassName("_chosen"); firstOption.addClassName("_chosen");
searchOptions.chosenNode = firstOption; searchOptions.chosenNode = firstOption;
// Initialize global array
search[id] = {};
} }
searchValue.blur(); searchValue.blur();
} });
} }
/* toolbar buttons */ /* toolbar buttons */
@ -1657,6 +1663,9 @@ function onLoadHandler(event) {
progressImage.parentNode.removeChild(progressImage); progressImage.parentNode.removeChild(progressImage);
$(document.body).observe("contextmenu", onBodyClickContextMenu); $(document.body).observe("contextmenu", onBodyClickContextMenu);
// Some module are initialized only once this method is completed
document.fire('generic:loaded');
onFinalLoadHandler(); onFinalLoadHandler();
} }
@ -1862,7 +1871,7 @@ function parent$(element) {
} }
/* stubs */ /* stubs */
function refreshCurrentFolder() { function refreshCurrentFolder(id) {
} }
function configureDragHandles() { function configureDragHandles() {