From eef86746b2ed194b9bbd72cf9ac28768f766147d Mon Sep 17 00:00:00 2001 From: Mick Ryan Date: Wed, 28 Oct 2015 23:52:26 -0700 Subject: [PATCH 1/3] BIG-22371 * Add validation to quicksearch box * Add Validation to search box on Advanced search page. --- assets/js/theme/global/quick-search.js | 42 +++++++++++++++++++++++++- assets/js/theme/search.js | 39 +++++++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/assets/js/theme/global/quick-search.js b/assets/js/theme/global/quick-search.js index f0c9e12ab3..25eb962c55 100644 --- a/assets/js/theme/global/quick-search.js +++ b/assets/js/theme/global/quick-search.js @@ -2,11 +2,41 @@ import $ from 'jquery'; import _ from 'lodash'; import utils from 'bigcommerce/stencil-utils'; import stencilDropDown from './stencil-dropdown'; +import nod from '../common/nod'; + +let internals = { + initValidaition($form) { + this.validator = nod({ + submit: $form + }); + + return this; + }, + bindValidation($form) { + if (this.validator) { + this.validator.add({ + selector: $form, + validate: 'presence', + errorMessage: 'Search field cannot be blank' + }); + } + + return this; + }, + checkElement() { + if (this.validator) { + this.validator.performCheck(); + return this.validator.areAll('valid'); + } + return false; + } +}; export default function() { const TOP_STYLING = 'top: 49px;'; const $quickSearchResults = $('.quickSearchResults'); const $quickSearchDiv = $('#quickSearch'); + let validator = internals.initValidaition($quickSearchDiv).bindValidation($quickSearchDiv.find('#search_query')); stencilDropDown.bind($('[data-search="quickSearch"]'), $quickSearchDiv, TOP_STYLING); @@ -14,8 +44,9 @@ export default function() { const doSearch = _.debounce((searchQuery) => { utils.api.search.search(searchQuery, {template: 'search/quick-results'}, (err, response) => { if (err) { - throw new Error(err); + return false; } + $quickSearchResults.html(response); }); }, 200); @@ -30,4 +61,13 @@ export default function() { doSearch(searchQuery); }); + + // Catch the submission of the quick-search + $quickSearchDiv.on('submit', (event) => { + if (!validator.checkElement()) { + return event.preventDefault(); + } + + return true; + }); } diff --git a/assets/js/theme/search.js b/assets/js/theme/search.js index 623529ff10..349e2d956c 100644 --- a/assets/js/theme/search.js +++ b/assets/js/theme/search.js @@ -2,6 +2,7 @@ import PageManager from '../page-manager'; import FacetedSearch from './common/faceted-search'; import collapsible from './common/collapsible'; import 'vakata/jstree'; +import nod from './common/nod'; export default class Search extends PageManager { constructor() { @@ -69,6 +70,8 @@ export default class Search extends PageManager { const $categoryTreeContainer = $searchForm.find('[data-search-category-tree]'); const treeData = []; + let validator = this.initValidaition($searchForm).bindValidation('#search_query_adv'); + collapsible(); this.context.categoryTree.forEach((node) => { @@ -78,9 +81,13 @@ export default class Search extends PageManager { this.categoryTreeData = treeData; this.createCategoryTree($categoryTreeContainer); - $searchForm.submit(() => { + $searchForm.submit((event) => { const selectedCategoryIds = $categoryTreeContainer.jstree().get_selected(); + if (!validator.check()) { + return event.preventDefault(); + } + $searchForm.find('input[name="category\[\]"]').remove(); for (const categoryId of selectedCategoryIds) { @@ -140,4 +147,34 @@ export default class Search extends PageManager { $container.jstree(treeOptions); } + + initValidaition($form) { + this.$form = $form; + this.validator = nod({ + submit: $form + }); + + return this; + } + + bindValidation(element) { + if (this.validator) { + this.validator.add({ + selector: this.$form.find(element), + validate: 'presence', + errorMessage: 'Search field cannot be blank' + }); + } + + return this; + } + + check() { + if (this.validator) { + this.validator.performCheck(); + return this.validator.areAll('valid'); + } + + return false; + } } From 00cd417c079da0915aea900ceaa27e29603a449a Mon Sep 17 00:00:00 2001 From: Mick Ryan Date: Thu, 29 Oct 2015 10:57:36 -0700 Subject: [PATCH 2/3] BIG-22371 * Fixed spelling * Added translation for error message * optimized the variable name and element that gets passed to bindValidation --- assets/js/theme/global/quick-search.js | 10 +++++----- assets/js/theme/search.js | 10 +++++----- lang/en.json | 3 +++ templates/components/common/quick-search.html | 2 +- templates/components/search/advanced-search.html | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/assets/js/theme/global/quick-search.js b/assets/js/theme/global/quick-search.js index 25eb962c55..458585a8b9 100644 --- a/assets/js/theme/global/quick-search.js +++ b/assets/js/theme/global/quick-search.js @@ -5,19 +5,19 @@ import stencilDropDown from './stencil-dropdown'; import nod from '../common/nod'; let internals = { - initValidaition($form) { + initValidation($form) { this.validator = nod({ submit: $form }); return this; }, - bindValidation($form) { + bindValidation(element) { if (this.validator) { this.validator.add({ - selector: $form, + selector: element, validate: 'presence', - errorMessage: 'Search field cannot be blank' + errorMessage: element.data('error-message') }); } @@ -36,7 +36,7 @@ export default function() { const TOP_STYLING = 'top: 49px;'; const $quickSearchResults = $('.quickSearchResults'); const $quickSearchDiv = $('#quickSearch'); - let validator = internals.initValidaition($quickSearchDiv).bindValidation($quickSearchDiv.find('#search_query')); + let validator = internals.initValidation($quickSearchDiv).bindValidation($quickSearchDiv.find('#search_query')); stencilDropDown.bind($('[data-search="quickSearch"]'), $quickSearchDiv, TOP_STYLING); diff --git a/assets/js/theme/search.js b/assets/js/theme/search.js index 349e2d956c..165c8c343b 100644 --- a/assets/js/theme/search.js +++ b/assets/js/theme/search.js @@ -70,7 +70,7 @@ export default class Search extends PageManager { const $categoryTreeContainer = $searchForm.find('[data-search-category-tree]'); const treeData = []; - let validator = this.initValidaition($searchForm).bindValidation('#search_query_adv'); + let validator = this.initValidation($searchForm).bindValidation($searchForm.find('#search_query_adv')); collapsible(); @@ -148,7 +148,7 @@ export default class Search extends PageManager { $container.jstree(treeOptions); } - initValidaition($form) { + initValidation($form) { this.$form = $form; this.validator = nod({ submit: $form @@ -157,12 +157,12 @@ export default class Search extends PageManager { return this; } - bindValidation(element) { + bindValidation($element) { if (this.validator) { this.validator.add({ - selector: this.$form.find(element), + selector: $element, validate: 'presence', - errorMessage: 'Search field cannot be blank' + errorMessage: $element.data('error-message') }); } diff --git a/lang/en.json b/lang/en.json index f13f7462f9..20f641fac2 100644 --- a/lang/en.json +++ b/lang/en.json @@ -697,6 +697,9 @@ "show-filters": "Show Filters", "hide-filters": "Hide Filters", "browse-by": "Browse by" + }, + "error": { + "empty_field": "Search field cannot be empty." } }, "page_not_found": { diff --git a/templates/components/common/quick-search.html b/templates/components/common/quick-search.html index c28db2912a..658dd1b16b 100644 --- a/templates/components/common/quick-search.html +++ b/templates/components/common/quick-search.html @@ -3,7 +3,7 @@
- +
diff --git a/templates/components/search/advanced-search.html b/templates/components/search/advanced-search.html index af0cc15909..78668334f1 100644 --- a/templates/components/search/advanced-search.html +++ b/templates/components/search/advanced-search.html @@ -8,7 +8,7 @@ {{lang 'forms.search.query' }} {{lang 'common.required' }} - +
From 86b2a272da9ba5a21594aa97c1ae4628d2030892 Mon Sep 17 00:00:00 2001 From: Mick Ryan Date: Thu, 29 Oct 2015 11:08:48 -0700 Subject: [PATCH 3/3] BIG-22371 * Moved chained calls to seperate lines for legibility. --- assets/js/theme/global/quick-search.js | 3 ++- assets/js/theme/search.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/assets/js/theme/global/quick-search.js b/assets/js/theme/global/quick-search.js index 458585a8b9..23f48ab50f 100644 --- a/assets/js/theme/global/quick-search.js +++ b/assets/js/theme/global/quick-search.js @@ -36,7 +36,8 @@ export default function() { const TOP_STYLING = 'top: 49px;'; const $quickSearchResults = $('.quickSearchResults'); const $quickSearchDiv = $('#quickSearch'); - let validator = internals.initValidation($quickSearchDiv).bindValidation($quickSearchDiv.find('#search_query')); + let validator = internals.initValidation($quickSearchDiv) + .bindValidation($quickSearchDiv.find('#search_query')); stencilDropDown.bind($('[data-search="quickSearch"]'), $quickSearchDiv, TOP_STYLING); diff --git a/assets/js/theme/search.js b/assets/js/theme/search.js index 165c8c343b..b4b0a32079 100644 --- a/assets/js/theme/search.js +++ b/assets/js/theme/search.js @@ -70,7 +70,8 @@ export default class Search extends PageManager { const $categoryTreeContainer = $searchForm.find('[data-search-category-tree]'); const treeData = []; - let validator = this.initValidation($searchForm).bindValidation($searchForm.find('#search_query_adv')); + let validator = this.initValidation($searchForm) + .bindValidation($searchForm.find('#search_query_adv')); collapsible();