MDL-69454 core_search: consistent navbar search

This commit is contained in:
Bas Brands
2020-09-23 17:36:14 +02:00
committed by Eloy Lafuente (stronk7)
parent 2d502fd749
commit 1fdb4fda4a
13 changed files with 358 additions and 181 deletions
+1
View File
@@ -2096,6 +2096,7 @@ $string['today'] = 'Today';
$string['todaylogs'] = 'Today\'s logs';
$string['toeveryone'] = 'to everyone';
$string['toggleemojipicker'] = 'Toggle emoji picker';
$string['togglesearch'] = 'Toggle search input';
$string['toomanybounces'] = 'That email address has had too many bounces. You <b>must</b> change it to continue.';
$string['toomanytags'] = 'This search included too many tags; some will have been ignored.';
$string['toomanytoshow'] = 'There are too many users to show.';
+7 -25
View File
@@ -3222,31 +3222,13 @@ EOD;
return '';
}
if ($id == false) {
$id = uniqid();
} else {
// Needs to be cleaned, we use it for the input id.
$id = clean_param($id, PARAM_ALPHANUMEXT);
}
// JS to animate the form.
$this->page->requires->js_call_amd('core/search-input', 'init', array($id));
$searchicon = html_writer::tag('div', $this->pix_icon('a/search', get_string('search', 'search'), 'moodle'),
array('role' => 'button', 'tabindex' => 0));
$formattrs = array('class' => 'search-input-form', 'action' => $CFG->wwwroot . '/search/index.php');
$inputattrs = array('type' => 'text', 'name' => 'q', 'placeholder' => get_string('search', 'search'),
'size' => 13, 'tabindex' => -1, 'id' => 'id_q_' . $id, 'class' => 'form-control');
$contents = html_writer::tag('label', get_string('enteryoursearchquery', 'search'),
array('for' => 'id_q_' . $id, 'class' => 'accesshide')) . html_writer::empty_tag('input', $inputattrs);
if ($this->page->context && $this->page->context->contextlevel !== CONTEXT_SYSTEM) {
$contents .= html_writer::empty_tag('input', ['type' => 'hidden',
'name' => 'context', 'value' => $this->page->context->id]);
}
$searchinput = html_writer::tag('form', $contents, $formattrs);
return html_writer::tag('div', $searchicon . $searchinput, array('class' => 'search-input-wrapper nav-link', 'id' => $id));
$data = [
'action' => new moodle_url('/search/index.php'),
'hiddenfields' => (object) ['name' => 'context', 'value' => $this->page->context->id],
'inputname' => 'q',
'searchstring' => get_string('search'),
];
return $this->render_from_template('core/search_input_navbar', $data);
}
/**
+1 -1
View File
@@ -36,7 +36,7 @@
<div class="popover-region collapsed {{$classes}}{{/classes}}"
{{$attributes}}{{/attributes}}
data-region="popover-region">
<div class="popover-region-toggle nav-link"
<div class="popover-region-toggle nav-link icon-no-margin"
data-region="popover-region-toggle"
role="button"
aria-controls="popover-region-container-{{uniqid}}"
+116
View File
@@ -0,0 +1,116 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core/search_input_navbar
Navbar search input template.
Example context (json):
{
"action": "https://moodle.local/admin/search.php",
"inputname": "search",
"searchstring": "Search",
"hiddenfields": [
{
"name": "cmid",
"value": "11"
}
]
}
}}
<div id="searchinput-navbar-{{uniqid}}" class="simplesearchform">
<div class="collapse" id="searchform-navbar">
<form autocomplete="off" action="{{{ action }}}" method="get" accept-charset="utf-8" class="mform form-inline searchform-navbar">
{{#hiddenfields}}
<input type="hidden" name="{{ name }}" value="{{ value }}">
{{/hiddenfields}}
<div class="input-group">
<label for="searchinput-{{uniqid}}">
<span class="sr-only">{{{ searchstring }}}</span>
</label>
<input type="text"
id="searchinput-{{uniqid}}"
class="form-control withclear"
placeholder="{{{ searchstring }}}"
aria-label="{{{ searchstring }}}"
name="{{{ inputname }}}"
data-region="input"
autocomplete="off"
>
<a class="btn btn-close"
data-action="closesearch"
data-toggle="collapse"
href="#searchform-navbar"
role="button"
>
{{#pix}} e/cancel, core {{/pix}}
<span class="sr-only">{{#str}} closebuttontitle {{/str}}</span>
</a>
<div class="input-group-append">
<button type="submit" class="btn btn-submit" data-action="submit">
{{#pix}} a/search, core {{/pix}}
<span class="sr-only">{{{ searchstring }}}</span>
</button>
</div>
</div>
</form>
</div>
<a
class="btn btn-open"
data-toggle="collapse"
data-action="opensearch"
href="#searchform-navbar"
role="button"
aria-expanded="false"
aria-controls="searchform-navbar"
>
<i class="icon fa fa-search fa-fw " aria-hidden="true"></i>
<span class="sr-only">{{#str}} togglesearch {{/str}}</span>
</a>
</div>
{{#js}}
require(
[
'jquery',
],
function(
$
) {
var uniqid = "{{uniqid}}";
var container = $('#searchinput-navbar-' + uniqid);
var opensearch = container.find('[data-action="opensearch"]');
var input = container.find('[data-region="input"]');
var submit = container.find('[data-action="submit"');
submit.on('click', function(e) {
if (input.val() === '') {
e.preventDefault();
}
});
container.on('hidden.bs.collapse', function() {
opensearch.removeClass('d-none');
input.val('');
});
container.on('show.bs.collapse', function() {
opensearch.addClass('d-none');
});
container.on('shown.bs.collapse', function() {
input.focus();
});
});
{{/js}}
+1 -1
View File
@@ -36,7 +36,7 @@
}}
<div class="popover-region collapsed" data-region="popover-region-messages">
<a id="message-drawer-toggle-{{uniqid}}" class="nav-link d-inline-block popover-region-toggle position-relative" href="#"
<a id="message-drawer-toggle-{{uniqid}}" class="nav-link d-inline-block popover-region-toggle position-relative icon-no-margin" href="#"
role="button">
{{#pix}} t/message, core, {{#str}} togglemessagemenu, message {{/str}} {{/pix}}
<div class="count-container {{^unreadcount}}hidden{{/unreadcount}}" data-region="count-container"
+3 -3
View File
@@ -44,14 +44,14 @@ class behat_search extends behat_base {
* @param string $query Query to search for
*/
public function i_search_for_using_the_header_global_search_box($query) {
// Hover over the search icon.
$this->execute('behat_general::i_hover', ['.icon[title=Search]', 'css_element']);
// Click the search icon.
$this->execute("behat_general::i_click_on", [get_string('togglesearch', 'core'), 'button']);
// Set the field.
$this->execute('behat_forms::i_set_the_field_to', ['q', $query]);
// Submit the form.
$this->execute_script('return document.querySelector(".search-input-form.expanded").submit();');
$this->execute_script('return document.querySelector(".searchform-navbar").submit();');
}
/**
+9
View File
@@ -2042,6 +2042,15 @@ nav.navbar .logo img {
max-height: 35px;
}
.nav.usernav {
.nav-item {
display: flex;
}
.usermenu .dropdown-toggle {
padding: 0 0.5rem;
}
}
/** Header-bar styles **/
.page-context-header {
// We need to be explicit about the height of the header.
@@ -1,4 +1,3 @@
$toggle-width: 25px;
$standard-border: 1px solid #ddd;
$region-container-height: 500px;
$region-container-width: 380px;
@@ -176,9 +175,6 @@ $content-header-footer-height: $region-header-height + $region-footer-height;
.navbar {
.popover-region {
float: left;
margin-right: 10px;
&.collapsed {
.popover-region-container {
@include invisible();
@@ -190,10 +186,6 @@ $content-header-footer-height: $region-header-height + $region-footer-height;
}
}
.popover-region-toggle {
width: $toggle-width;
}
.count-container {
padding: 2px;
border-radius: 2px;
+59 -43
View File
@@ -11,54 +11,70 @@
font-style: italic;
}
.search-input-wrapper {
margin: 0 $spacer 0 0;
overflow: hidden;
float: right;
width: 24px;
transition: width 0.5s ease, left 0.5s ease;
padding-top: 0;
padding-bottom: 0;
}
.search-input-wrapper > div {
float: left;
margin: 0;
.icon {
margin-right: 0;
margin-top: 10px;
.simplesearchform {
.btn {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.btn .icon {
margin: 0;
}
.btn-submit {
border-color: $input-border-color;
color: $gray-600;
}
.btn-close,
.btn-clear {
position: absolute;
top: 0;
right: 0;
color: $gray-600;
z-index: 4;
}
.btn-close {
right: 2.2rem;
}
.btn-submit {
background-color: $gray-100;
}
.withclear {
padding-right: 2rem;
}
.searchinput {
display: flex;
flex: 1 1 auto;
}
.collapsing {
height: inherit;
transition: none;
width: inherit;
}
}
.search-input-wrapper > form {
opacity: 0;
margin-left: 25px;
transition: opacity 0.5s ease-in-out;
}
.search-input-wrapper > form > input {
margin: 0;
}
.search-input-wrapper form.expanded {
opacity: 1;
}
.search-input-wrapper.expanded {
width: 162px;
}
@include media-breakpoint-down(xs) {
.search-input-wrapper {
> div {
margin: 0;
@include media-breakpoint-down(md) {
.simplesearchform .collapse.show,
.simplesearchform .collapsing {
position: absolute;
left: 0;
top: 0;
width: 100%;
display: flex;
background-color: $white;
z-index: $zindex-popover;
height: $navbar-height;
.form-inline {
width: auto;
margin-left: auto;
margin-right: auto;
}
> form {
display: none;
}
}
.navbar.navbar-light {
.simplesearchform .btn-open {
color: $navbar-light-color;
&:hover {
color: $navbar-light-hover-color;
}
margin: 0 $spacer 0 0;
}
}
+65 -44
View File
@@ -11308,6 +11308,12 @@ img#persona_signin {
nav.navbar .logo img {
max-height: 35px; }
.nav.usernav .nav-item {
display: flex; }
.nav.usernav .usermenu .dropdown-toggle {
padding: 0 0.5rem; }
/** Header-bar styles **/
.page-context-header {
overflow: hidden;
@@ -16196,43 +16202,64 @@ body.path-question-type .mform fieldset.hidden {
.search-results .result .filename {
font-style: italic; }
.search-input-wrapper {
margin: 0 1rem 0 0;
overflow: hidden;
float: right;
width: 24px;
transition: width 0.5s ease, left 0.5s ease;
padding-top: 0;
padding-bottom: 0; }
.simplesearchform .btn {
padding-left: 0.5rem;
padding-right: 0.5rem; }
.search-input-wrapper > div {
float: left;
margin: 0; }
.search-input-wrapper > div .icon {
margin-right: 0;
margin-top: 10px; }
.search-input-wrapper > form {
opacity: 0;
margin-left: 25px;
transition: opacity 0.5s ease-in-out; }
.search-input-wrapper > form > input {
.simplesearchform .btn .icon {
margin: 0; }
.search-input-wrapper form.expanded {
opacity: 1; }
.simplesearchform .btn-submit {
border-color: #ced4da;
color: #6c757d; }
.search-input-wrapper.expanded {
width: 162px; }
.simplesearchform .btn-close,
.simplesearchform .btn-clear {
position: absolute;
top: 0;
right: 0;
color: #6c757d;
z-index: 4; }
@media (max-width: 575.98px) {
.search-input-wrapper {
margin: 0 1rem 0 0; }
.search-input-wrapper > div {
margin: 0; }
.search-input-wrapper > form {
display: none; } }
.simplesearchform .btn-close {
right: 2.2rem; }
.simplesearchform .btn-submit {
background-color: #f8f9fa; }
.simplesearchform .withclear {
padding-right: 2rem; }
.simplesearchform .searchinput {
display: flex;
flex: 1 1 auto; }
.simplesearchform .collapsing {
height: inherit;
transition: none;
width: inherit; }
@media (max-width: 991.98px) {
.simplesearchform .collapse.show,
.simplesearchform .collapsing {
position: absolute;
left: 0;
top: 0;
width: 100%;
display: flex;
background-color: #fff;
z-index: 1060;
height: 50px; }
.simplesearchform .collapse.show .form-inline,
.simplesearchform .collapsing .form-inline {
width: auto;
margin-left: auto;
margin-right: auto; } }
.navbar.navbar-light .simplesearchform .btn-open {
color: rgba(0, 0, 0, 0.5); }
.navbar.navbar-light .simplesearchform .btn-open:hover {
color: rgba(0, 0, 0, 0.9); }
.search-areas-actions {
margin-bottom: 1rem; }
@@ -18745,18 +18772,12 @@ body {
.popover-region-content-container.loading .empty-message {
display: none; }
.navbar .popover-region {
float: left;
margin-right: 10px; }
.navbar .popover-region.collapsed .popover-region-container {
opacity: 0;
visibility: hidden;
height: 0;
overflow: hidden;
transition: height 0.25s, opacity 101ms 0.25s, visibility 101ms 0.25s; }
.navbar .popover-region-toggle {
width: 25px; }
.navbar .popover-region.collapsed .popover-region-container {
opacity: 0;
visibility: hidden;
height: 0;
overflow: hidden;
transition: height 0.25s, opacity 101ms 0.25s, visibility 101ms 0.25s; }
.navbar .count-container {
padding: 2px;
+26 -7
View File
@@ -15,7 +15,27 @@
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
Page navbar.
@template theme_boost/navbar
This template renders the top navbar.
Example context (json):
{
"output": {
"should_display_navbar_logo": true,
"get_compact_logo_url": "http://placekitten.com/50/50",
"custom_menu": "<li>..</li>",
"page_heading_menu": "<li>..</li>",
"search_box": "<div><input type='text'></div>",
"navbar_plugin_output": "<div class='dropdown'>Messaging</div>",
"user_menu": "<div class='dropdown'>John Doe</div>"
},
"config": {
"wwwroot": "#"
},
"sitename": "Moodle Site"
}
}}
<nav class="fixed-top navbar navbar-light bg-white navbar-expand moodle-has-zindex" aria-label="{{#str}}sitemenubar, admin{{/str}}">
@@ -42,19 +62,18 @@
<!-- page_heading_menu -->
{{{ output.page_heading_menu }}}
</ul>
<ul class="nav navbar-nav ml-auto">
<li class="d-none d-lg-block">
{{{ output.search_box }}}
</li>
<div class="ml-auto">
{{{ output.search_box }}}
</div>
<ul class="nav navbar-nav usernav">
<!-- navbar_plugin_output -->
<li class="nav-item">
{{{ output.navbar_plugin_output }}}
</li>
<!-- user_menu -->
<li class="nav-item d-flex align-items-center">
<li class="nav-item align-items-center pl-2">
{{{ output.user_menu }}}
</li>
</ul>
<!-- search_box -->
</nav>
+65 -44
View File
@@ -11518,6 +11518,12 @@ img#persona_signin {
nav.navbar .logo img {
max-height: 35px; }
.nav.usernav .nav-item {
display: flex; }
.nav.usernav .usermenu .dropdown-toggle {
padding: 0 0.5rem; }
/** Header-bar styles **/
.page-context-header {
overflow: hidden;
@@ -16421,43 +16427,64 @@ body.path-question-type .mform fieldset.hidden {
.search-results .result .filename {
font-style: italic; }
.search-input-wrapper {
margin: 0 1rem 0 0;
overflow: hidden;
float: right;
width: 24px;
transition: width 0.5s ease, left 0.5s ease;
padding-top: 0;
padding-bottom: 0; }
.simplesearchform .btn {
padding-left: 0.5rem;
padding-right: 0.5rem; }
.search-input-wrapper > div {
float: left;
margin: 0; }
.search-input-wrapper > div .icon {
margin-right: 0;
margin-top: 10px; }
.search-input-wrapper > form {
opacity: 0;
margin-left: 25px;
transition: opacity 0.5s ease-in-out; }
.search-input-wrapper > form > input {
.simplesearchform .btn .icon {
margin: 0; }
.search-input-wrapper form.expanded {
opacity: 1; }
.simplesearchform .btn-submit {
border-color: #ced4da;
color: #6c757d; }
.search-input-wrapper.expanded {
width: 162px; }
.simplesearchform .btn-close,
.simplesearchform .btn-clear {
position: absolute;
top: 0;
right: 0;
color: #6c757d;
z-index: 4; }
@media (max-width: 575.98px) {
.search-input-wrapper {
margin: 0 1rem 0 0; }
.search-input-wrapper > div {
margin: 0; }
.search-input-wrapper > form {
display: none; } }
.simplesearchform .btn-close {
right: 2.2rem; }
.simplesearchform .btn-submit {
background-color: #f8f9fa; }
.simplesearchform .withclear {
padding-right: 2rem; }
.simplesearchform .searchinput {
display: flex;
flex: 1 1 auto; }
.simplesearchform .collapsing {
height: inherit;
transition: none;
width: inherit; }
@media (max-width: 991.98px) {
.simplesearchform .collapse.show,
.simplesearchform .collapsing {
position: absolute;
left: 0;
top: 0;
width: 100%;
display: flex;
background-color: #fff;
z-index: 1060;
height: 50px; }
.simplesearchform .collapse.show .form-inline,
.simplesearchform .collapsing .form-inline {
width: auto;
margin-left: auto;
margin-right: auto; } }
.navbar.navbar-light .simplesearchform .btn-open {
color: rgba(0, 0, 0, 0.5); }
.navbar.navbar-light .simplesearchform .btn-open:hover {
color: rgba(0, 0, 0, 0.9); }
.search-areas-actions {
margin-bottom: 1rem; }
@@ -18926,18 +18953,12 @@ body {
.popover-region-content-container.loading .empty-message {
display: none; }
.navbar .popover-region {
float: left;
margin-right: 10px; }
.navbar .popover-region.collapsed .popover-region-container {
opacity: 0;
visibility: hidden;
height: 0;
overflow: hidden;
transition: height 0.25s, opacity 101ms 0.25s, visibility 101ms 0.25s; }
.navbar .popover-region-toggle {
width: 25px; }
.navbar .popover-region.collapsed .popover-region-container {
opacity: 0;
visibility: hidden;
height: 0;
overflow: hidden;
transition: height 0.25s, opacity 101ms 0.25s, visibility 101ms 0.25s; }
.navbar .count-container {
padding: 2px;
+5 -5
View File
@@ -57,16 +57,16 @@
<!-- page_heading_menu -->
{{{ output.page_heading_menu }}}
</ul>
<ul class="nav navbar-nav ml-auto">
<li class="d-none d-lg-block">
{{{ output.search_box }}}
</li>
<div class="ml-auto">
{{{ output.search_box }}}
</div>
<ul class="nav navbar-nav usernav">
<!-- navbar_plugin_output -->
<li class="nav-item">
{{{ output.navbar_plugin_output }}}
</li>
<!-- user_menu -->
<li class="nav-item d-flex align-items-center">
<li class="nav-item align-items-center">
{{{ output.user_menu }}}
</li>
</ul>