diff --git a/include/ajax.forms.php b/include/ajax.forms.php index 69da6ec54787e352ce32244a8c7e5f176faa941a..0e440573c8532e544afef4cc9192e8c809430eb8 100644 --- a/include/ajax.forms.php +++ b/include/ajax.forms.php @@ -206,6 +206,38 @@ class DynamicFormsAjaxAPI extends AjaxController { ))); } + function searchListItems($list_id) { + global $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Login required'); + elseif (!($list = DynamicList::lookup($list_id))) + Http::response(404, 'No such list'); + elseif (!($q = $_GET['q'])) + Http::response(400, '"q" query arg is required'); + + $items = clone $list->getAllItems(); + $items->filter(Q::any(array( + 'value__startswith' => $q, + 'extra__contains' => $q, + 'properties__contains' => '"'.$q, + ))); + + $results = array(); + foreach ($items as $I) { + $display = $I->value; + if ($I->extra) + $display .= " ({$I->extra})"; + $results[] = array( + 'value' => $I->value, + 'display' => $display, + 'id' => $I->id, + 'list_id' => $I->list_id, + ); + } + return $this->encode($results); + } + function addListItem($list_id) { global $thisstaff; diff --git a/include/class.list.php b/include/class.list.php index 82142b90ea86c50b822c926512284fed8a43b739..b6c8c7327147441b74357fcac7e479193769f239 100644 --- a/include/class.list.php +++ b/include/class.list.php @@ -135,6 +135,11 @@ class DynamicList extends VerySimpleModel implements CustomList { 'table' => LIST_TABLE, 'ordering' => array('name'), 'pk' => array('id'), + 'joins' => array( + 'items' => array( + 'reverse' => 'DynamicListItem.list', + ), + ), ); // Required fields diff --git a/include/staff/templates/list-item-properties.tmpl.php b/include/staff/templates/list-item-properties.tmpl.php index 61ef1b8f6ba3c0d25c3cfed5ceefd3040a1b8f18..35895173e86bc61d1d864a781360a90abe737f9f 100644 --- a/include/staff/templates/list-item-properties.tmpl.php +++ b/include/staff/templates/list-item-properties.tmpl.php @@ -1,8 +1,14 @@ +<?php + $properties_form = $item ? $item->getConfigurationForm($_POST ?: null) + : $list->getConfigurationForm(); + $hasProperties = count($properties_form->getFields()) > 0; +?> <h3 class="drag-handle"><?php echo $list->getName(); ?> — <?php echo $item ? $item->getValue() : __('Add New List Item'); ?></h3> <a class="close" href=""><i class="icon-remove-circle"></i></a> <hr/> +<?php if ($hasProperties) { ?> <ul class="tabs" id="item_tabs"> <li class="active"> <a href="#value"><i class="icon-reorder"></i> @@ -12,6 +18,7 @@ <?php echo __('Item Properties'); ?></a> </li> </ul> +<?php } ?> <form method="post" id="item_tabs_container" action="<?php echo $action; ?>"> <?php @@ -28,9 +35,10 @@ <div class="tab_content hidden" id="properties"> <?php - $form = $item ? $item->getConfigurationForm($_POST ?: null) - : $list->getConfigurationForm(); - include 'dynamic-form-simple.tmpl.php'; + if ($hasProperties) { + $form = $properties_form; + include 'dynamic-form-simple.tmpl.php'; + } ?> </div> diff --git a/include/staff/templates/list-items.tmpl.php b/include/staff/templates/list-items.tmpl.php index c1df5299910bdd514d015b4f163df6c089fa76bc..a2dbb1630e683ffd794b021a45fcfc2f87deceb6 100644 --- a/include/staff/templates/list-items.tmpl.php +++ b/include/staff/templates/list-items.tmpl.php @@ -13,19 +13,10 @@ ?> <div style="margin: 5px 0"> <div class="pull-left"> - <input type="search" size="25" id="search" value="<?php + <input type="text" placeholder="<?php echo __('Search items'); ?>" + data-url="ajax.php/list/<?php echo $list->getId(); ?>/items/search" + size="25" id="items-search" value="<?php echo Format::htmlchars($_POST['search']); ?>"/> - <button type="submit" onclick="javascript: - event.preventDefault(); - $.pjax({type: 'POST', data: { search: $('#search').val() }, container: '#pjax-container'}); - return false; -"><?php echo __('Search'); ?></button> - <?php if ($_POST['search']) { ?> - <a href="#" onclick="javascript: - $.pjax.reload('#pjax-container'); return false; " - ><i class="icon-remove-sign"></i> <?php - echo __('clear'); ?></a> - <?php } ?> </div> <?php if ($list) { ?> <div class="pull-right"> @@ -102,14 +93,6 @@ if ($list) { $icon = ($list->get('sort_mode') == 'SortCol') ? '<i class="icon-sort"></i> ' : ''; $items = $list->getAllItems(); - if ($_POST['search']) { - $items->filter(Q::any(array( - 'value__contains'=>$_POST['search'], - 'extra__contains'=>$_POST['search'], - 'properties__contains'=>$_POST['search'], - ))); - $search = true; - } $items = $pageNav->paginate($items); // Emit a marker for the first sort offset ?> <input type="hidden" id="sort-offset" value="<?php echo @@ -125,3 +108,39 @@ if ($list) { <div><?php echo __('Page').':'.$pageNav->getPageLinks('items', $pjax_container); ?></div> <?php } ?> </div> +<script type="text/javascript"> +$(function() { + var last_req; + $('input#items-search').typeahead({ + source: function (typeahead, query) { + if (last_req) + last_req.abort(); + var $el = this.$element; + var url = $el.data('url')+'?q='+query; + last_req = $.ajax({ + url: url, + dataType: 'json', + success: function (data) { + typeahead.process(data); + } + }); + }, + onselect: function (obj) { + var $el = this.$element, + url = 'ajax.php/list/{0}/item/{1}/update' + .replace('{0}', obj.list_id) + .replace('{1}', obj.id); + $.dialog(url, [201], function (xhr, resp) { + var json = $.parseJSON(resp); + if (json && json.success) { + if (json.id && json.row) { + $('#list-item-' + json.id).replaceWith(json.row); + } + } + }); + this.$element.val(''); + }, + property: "display" + }); +}); +</script> diff --git a/scp/ajax.php b/scp/ajax.php index 6971008a6eeafa87e576ec48f01c205d207c6332..c2ff371d5aa6a898a05036bc23d9c20f3221f565 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -68,6 +68,7 @@ $dispatcher = patterns('', )), url('^/list/', patterns('ajax.forms.php:DynamicFormsAjaxAPI', url_get('^(?P<list>\w+)/items$', 'getListItems'), + url_get('^(?P<list>\w+)/items/search$', 'searchListItems'), url_get('^(?P<list>\w+)/item/(?P<id>\d+)/update$', 'getListItem'), url_post('^(?P<list>\w+)/item/(?P<id>\d+)/update$', 'saveListItem'), url('^(?P<list>\w+)/item/add$', 'addListItem'),