diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index c869701..c67df3f 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -340,6 +340,7 @@ class CRUDComponent extends Component protected function setQuickFilters(array $params, \Cake\ORM\Query $query, array $quickFilterFields): \Cake\ORM\Query { $queryConditions = []; + $this->Controller->set('quickFilter', empty($quickFilterFields) ? [] : $quickFilterFields); if (!empty($params['quickFilter']) && !empty($quickFilterFields)) { $this->Controller->set('quickFilterValue', $params['quickFilter']); foreach ($quickFilterFields as $filterField) { diff --git a/templates/Individuals/index.php b/templates/Individuals/index.php index 0b92b4e..91520e1 100644 --- a/templates/Individuals/index.php +++ b/templates/Individuals/index.php @@ -23,7 +23,6 @@ echo $this->element('genericElements/IndexTable/index_table', [ 'button' => __('Filter'), 'placeholder' => __('Enter value to search'), 'data' => '', - 'value' => $quickFilterValue, 'searchKey' => 'value' ] ] diff --git a/templates/element/genericElements/ListTopBar/group_search.php b/templates/element/genericElements/ListTopBar/group_search.php index c05fd39..6347fa8 100644 --- a/templates/element/genericElements/ListTopBar/group_search.php +++ b/templates/element/genericElements/ListTopBar/group_search.php @@ -29,7 +29,7 @@ empty($data['placeholder']) ? '' : h($data['placeholder']), empty($data['id']) ? 'quickFilterField' : h($data['id']), empty($data['searchKey']) ? 'searchall' : h($data['searchKey']), - empty($data['value']) ? '' : h($data['value']) + empty($data['value']) ? (!empty($quickFilterValue) ? h($quickFilterValue) : '') : h($data['value']) ); echo sprintf( '
%s%s
', @@ -44,6 +44,7 @@ var controller = 'request->getParam('controller') ?>'; var action = 'request->getParam('action') ?>'; var additionalUrlParams = ''; + var quickFilter = ; var randomValue = ''; + $(`#quickFilterField-${randomValue}`).popover({ + title: '', + content: function() { return buildPopoverQuickFilterBody(quickFilter) }, + html: true, + sanitize: false, + trigger: 'manual', + }) $(`#quickFilterButton-${randomValue}`).click((e) => { doFilter($(e.target)) }); @@ -61,9 +69,14 @@ const $button = $(`#quickFilterButton-${randomValue}`) doFilter($button) } + }).on('focus', (e) => { + $(`#quickFilterField-${randomValue}`).popover('show') + }).on('focusout', (e) => { + $(`#quickFilterField-${randomValue}`).popover('hide') }); function doFilter($button) { + $(`#quickFilterField-${randomValue}`).popover('hide') const encodedFilters = encodeURIComponent($(`#quickFilterField-${randomValue}`).val()) const url = `/${controller}/${action}${additionalUrlParams}?quickFilter=${encodedFilters}` UI.reload(url, $(`#table-container-${randomValue}`), $(`#table-container-${randomValue} table.table`), [{ @@ -71,5 +84,35 @@ config: {} }]) } + + function buildPopoverQuickFilterBody(quickFilter) { + let tableData = [] + quickFilter.forEach(field => { + let fieldName, searchContain + if (typeof field === 'object') { + fieldName = Object.keys(field)[0]; + searchContain = field[fieldName] + } else { + fieldName = field + searchContain = false + } + $searchType = $('') + .text(searchContain ? '' : '') + .attr('title', searchContain ? '' : '') + tableData.push([fieldName, $searchType]) + }); + tableData.sort((a, b) => a[0] < b[0] ? -1 : 1) + $table = HtmlHelper.table( + ['', ''], + tableData, + { + small: true, + tableClass: ['mb-0'], + caption: '' + } + ) + return $table[0].outerHTML + } + }); diff --git a/webroot/js/bootstrap-helper.js b/webroot/js/bootstrap-helper.js index dd3e50e..a24bec2 100644 --- a/webroot/js/bootstrap-helper.js +++ b/webroot/js/bootstrap-helper.js @@ -649,7 +649,7 @@ class OverlayFactory { static defaultOptions = { text: '', variant: 'light', - opacity: 0.85, + opacity: 0.15, blur: '2px', rounded: false, auto: true, @@ -828,4 +828,74 @@ class FormValidationHelper { $(this.form).find('.invalid-feedback').remove() $(this.form).parent().find('.alert').remove() } + +} + +class HtmlHelper { + static table(head=[], body=[], options={}) { + const $table = $('') + const $thead = $('') + const $tbody = $('') + + $table.addClass('table') + if (options.striped) { + $table.addClass('table-striped') + } + if (options.bordered) { + $table.addClass('table-bordered') + } + if (options.borderless) { + $table.addClass('table-borderless') + } + if (options.hoverable) { + $table.addClass('table-hover') + } + if (options.small) { + $table.addClass('table-sm') + } + if (options.variant) { + $table.addClass(`table-${options.variant}`) + } + if (options.tableClass) { + $table.addClass(options.tableClass) + } + + const $caption = $('') + head.forEach(head => { + if (head instanceof jQuery) { + $theadRow.append($('') + row.forEach(item => { + if (item instanceof jQuery) { + $bodyRow.append($('
') + if (options.caption) { + if (options.caption instanceof jQuery) { + $caption = options.caption + } else { + $caption.text(options.caption) + } + } + + const $theadRow = $('
').append(head)) + } else { + $theadRow.append($('').text(head)) + } + }) + $thead.append($theadRow) + + body.forEach(row => { + const $bodyRow = $('
').append(item)) + } else { + $bodyRow.append($('').text(item)) + } + }) + $tbody.append($bodyRow) + }) + + $table.append($caption, $thead, $tbody) + if (options.responsive) { + options.responsiveBreakpoint = options.responsiveBreakpoint !== undefined ? options.responsiveBreakpoint : '' + $table = $('
').addClass(options.responsiveBreakpoint !== undefined ? `table-responsive-${options.responsiveBreakpoint}` : 'table-responsive').append($table) + } + return $table + } } \ No newline at end of file