Skip to content

Commit

Permalink
Move global search to a single search input. Display results in a gri…
Browse files Browse the repository at this point in the history
…d within accordions. (CFM-220) (#63)
  • Loading branch information
arlen authored Dec 13, 2022
1 parent 1f8a4d9 commit 16fd9b6
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 168 deletions.
9 changes: 9 additions & 0 deletions app/resources/locales/en_US/field.po
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,15 @@ msgstr "Required"
msgid "room"
msgstr "Room"

msgid "search.global"
msgstr "Global search"

msgid "search.global.submit"
msgstr "Submit global search"

msgid "search.global.clear"
msgstr "Clear global search"

msgid "search.placeholder"
msgstr "Search..."

Expand Down
174 changes: 67 additions & 107 deletions app/templates/Dashboards/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,65 +40,10 @@

<div class="pageTitleContainer">
<div class="pageTitle">
<h1><?= __d('operation','search.global'); ?></h1>
<h1><?= $vv_title; ?></h1>
</div>
</div>

<div id="search-container" aria-labelledby="global-search-toggle">
<?php
print $this->Form->create(null, $options);
print $this->Form->hidden('co_id', ['default' => $vv_cur_co->id]);
?>
<div class="input-group">
<?php
print $this->Form->label(
'q',
__d('operation','search'),
[
'class' => 'visually-hidden'
]
);
print $this->Form->input(
'q',
[
'id' => 'q',
'class' => 'form-control',
'placeholder' => __d('field','search.placeholder')
]
);
print $this->Form->button(
'<span class="material-icons-outlined">close</span>',
['type' => 'button', 'escapeTitle' => false, 'id' => 'search-clear', 'class' => 'btn btn-link']
);
print $this->Form->button(
__d('operation','search'),
['type' => 'submit', 'escapeTitle' => false, 'class' => 'btn btn-primary btn-sm']
);
?>
</div>
<?php
print $this->Form->end();
?>

<?php /* keep the following temporarily:
<div id="global-search-type">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="gs-type-basic" name="gs-type">
<label class="form-check-label" for="gs-type-basic">
basic
</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="gs-type-advanced" name="gs-type">
<label class="form-check-label" for="gs-type-advanced">
advanced
</label>
</div>
</div> */ ?>
</div>

<h2><?= $vv_title; ?></h2>

<!-- Flash Messages and defined Info Banners -->
<div class="alert-container" id="flash-messages">
<?= $this->Flash->render() ?>
Expand Down Expand Up @@ -126,69 +71,84 @@
<li class="search-results-found"><?= __d('result', 'search.result.found') ?></li>
<?php if($peopleResultsCount): ?>
<li>
<?= __d('result','search.result.found.modelCount', [$peopleResultsCount, __d('controller', "People", [$peopleResultsCount])]); ?>
<a href="#search-results-people" class="nospin">
<?= __d('result','search.result.found.modelCount', [$peopleResultsCount, __d('controller', "People", [$peopleResultsCount])]); ?>
</a>
</li>
<?php endif; ?>
<?php if($groupsResultsCount): ?>
<li>
<?= __d('result','search.result.found.modelCount', [$groupsResultsCount, __d('controller', "Groups", [$groupsResultsCount])]); ?>
<a href="#search-results-groups" class="nospin">
<?= __d('result','search.result.found.modelCount', [$groupsResultsCount, __d('controller', "Groups", [$groupsResultsCount])]); ?>
</a>
</li>
<?php endif; ?>
</ul>
<?php endif; ?>

<div id="search-results">
<div id="search-results" class="accordion">
<!-- Start with the Primary Registry objects -->
<?php foreach(['People', 'Groups'] as $pm): ?>
<?php if(!empty($vv_results[$pm])): ?>
<div class="search-results-group-container">
<h3><?= __d('controller', $pm, 2); ?></h3>
<ul class="search-results-group">

<?php foreach($vv_results[$pm] as $pkey => $matches): ?>
<?php
$url = [
'controller' => \Cake\Utility\Inflector::dasherize($pm),
'action' => 'edit',
$pkey
];
// The same entity can match on more than one searchable model
?>

<?php foreach($matches as $m => $entity): ?>
<?php
$displayField = $vv_supported_models[$m]['displayField'];
$displayLabel = __d('field', $displayField);
$displayString = $entity->$displayField;

// If we match on a related model (for example PersonRoles for People)
// indicate what actually matched
$matchInfo = __d('result', 'search.result.id', $pkey);

// Do we have a more informative string to render?
if(!empty($entity->person->primary_name->full_name)) {
$displayString = $entity->person->primary_name->full_name;

$matchInfo = __d('result', 'search.result.related', $displayLabel, $entity->$displayField, $pkey);
} elseif(!empty($entity->group->name)) {
$displayString = $entity->group->name;

$matchInfo = __d('result', 'search.result.related', $displayLabel, $displayString, $pkey);
}
?>
<li class="search-result">
<a href="<?= $this->Url->build($url) ?>">
<div class="search-result-name">
<?= $displayString ?>
</div>
<div class="search-result-match-info">
<?= filter_var($matchInfo, FILTER_SANITIZE_SPECIAL_CHARS) ?>
</div>
</a>
</li>
<?php endforeach; ?>
<?php endforeach; ?>
</ul>
<div id="search-results-<?= strtolower($pm) ?>" class="search-results-group-container accordion-item">
<div id="search-results-<?= strtolower($pm) ?>-header" class="search-results-group-title accordion-header">
<button class="accordion-button"
data-bs-toggle="collapse"
data-bs-target="#search-results-<?= strtolower($pm) ?>-body"
aria-expanded="true"
aria-controls="search-results-<?= strtolower($pm) ?>-body">
<?= __d('controller', $pm, 2); ?>
</button>
</div>
<div id="search-results-<?= strtolower($pm) ?>-body" class="accordion-collapse collapse show">
<div class="accordion-body">
<ul class="search-results-group">
<?php foreach($vv_results[$pm] as $pkey => $matches): ?>
<?php
$url = [
'controller' => \Cake\Utility\Inflector::dasherize($pm),
'action' => 'edit',
$pkey
];
// The same entity can match on more than one searchable model
?>

<?php foreach($matches as $m => $entity): ?>
<?php
$displayField = $vv_supported_models[$m]['displayField'];
$displayLabel = __d('field', $displayField);
$displayString = $entity->$displayField;

// If we match on a related model (for example PersonRoles for People)
// indicate what actually matched
$matchInfo = __d('result', 'search.result.id', $pkey);

// Do we have a more informative string to render?
if(!empty($entity->person->primary_name->full_name)) {
$displayString = $entity->person->primary_name->full_name;

$matchInfo = __d('result', 'search.result.related', $displayLabel, $entity->$displayField, $pkey);
} elseif(!empty($entity->group->name)) {
$displayString = $entity->group->name;

$matchInfo = __d('result', 'search.result.related', $displayLabel, $displayString, $pkey);
}
?>
<li class="search-result">
<a href="<?= $this->Url->build($url) ?>">
<div class="search-result-name">
<?= $displayString ?>
</div>
<div class="search-result-match-info">
<?= filter_var($matchInfo, FILTER_SANITIZE_SPECIAL_CHARS) ?>
</div>
</a>
</li>
<?php endforeach; ?>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<?php endif; ?>
<?php endforeach; ?>
Expand Down
29 changes: 14 additions & 15 deletions app/templates/element/javascript.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,29 @@

// SEARCH
// Persistent search bar form:
$('#global-search form').submit(function () {
// Disallow submit on blank
if($.trim($('#global-search-q').val()) == '') {
return false;
}
});
// Select search text on focus
$('#global-search-q').focus(function() {
$('#global-search-q').select();
});

// Search page form:
$('#search').submit(function () {
$('#global-search form').submit(function() {
// Disallow submit on blank
if($.trim($('#q').val()) == '') {
return false;
}
});
$('#search-clear').click(function () {
$('#global-search-clear').click(function(e) {
e.stopPropagation();
$('#q').val('');
$('#q').removeClass('hasValue');
$('#q').focus();
});
// Select search text on focus
$('#q').focus(function() {
$('#q').select();
$(this).select();
});
// Hide and reveal clear button
$('#q').on('input', function(e) {
if($(this).val() != '') {
$(this).addClass('hasValue');
} else {
$(this).removeClass('hasValue');
}
});

// TOP FILTER FORM
Expand Down
37 changes: 34 additions & 3 deletions app/templates/element/searchGlobal.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,42 @@
<?php
print $this->Form->create(null, $options);
print $this->Form->hidden('co_id', ['default' => $vv_cur_co->id]);
print $this->Form->label('global-search-q', __d('field','search.placeholder'), ['class' => 'visually-hidden']);
print $this->Form->input('global-search-q',['id' => 'global-search-q', 'placeholder' => __d('field','search.placeholder')]);
print $this->Form->label(
'q',
__d('field','search.global'),
['class' => 'visually-hidden']
);
$globalSearchInputClass = '';
if(!empty($this->request->getData('q'))) {
$globalSearchInputClass = 'hasValue';
}
print $this->Form->input(
'q',
[
'id' => 'q',
'class' => $globalSearchInputClass,
'placeholder' => __d('field','search.placeholder')
]
);
print $this->Form->button(
'<span class="material-icons">close</span>',
[
'type' => 'button',
'escapeTitle' => false,
'id' => 'global-search-clear',
'class' => 'btn btn-link',
'aria-label' => __d('field','search.global.clear')
]
);
print $this->Form->button(
'<em class="material-icons">search</em>',
['type' => 'submit', 'escapeTitle' => false, 'id' => 'global-search-button', 'class' => 'btn btn-link btn-sm']
[
'type' => 'submit',
'escapeTitle' => false,
'id' => 'global-search-button',
'class' => 'btn btn-link btn-sm',
'aria-label' => __d('field','search.global.submit')
]
);
print $this->Form->end();
?>
Expand Down
Loading

0 comments on commit 16fd9b6

Please sign in to comment.