summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClement Ho <ClemMakesApps@gmail.com>2017-01-30 16:53:18 -0600
committerClement Ho <ClemMakesApps@gmail.com>2017-02-23 22:29:54 -0600
commit0f8d7b73bc28b08df6a884ef2e8d99e0c0eff3e3 (patch)
tree4a3ba7498a20c9c8c23ac6bb8be2f3589e579051
parent8d4c4b3992ccb863dd8d32cc59594855c14b8b84 (diff)
downloadgitlab-ce-fix-filtered-search-input-placeholder.tar.gz
Auto hide filtered search input placeholderfix-filtered-search-input-placeholder
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js.es617
-rw-r--r--spec/features/merge_requests/reset_filters_spec.rb26
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js.es673
-rw-r--r--spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js.es62
-rw-r--r--spec/support/filtered_search_helpers.rb8
5 files changed, 117 insertions, 9 deletions
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
index 7a28963cb14..c1fc1111ecf 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
@@ -27,6 +27,7 @@
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.setDropdownWrapper = this.dropdownManager.setDropdown.bind(this.dropdownManager);
this.toggleClearSearchButtonWrapper = this.toggleClearSearchButton.bind(this);
+ this.handleInputPlaceholderWrapper = this.handleInputPlaceholder.bind(this);
this.handleInputVisualTokenWrapper = this.handleInputVisualToken.bind(this);
this.checkForEnterWrapper = this.checkForEnter.bind(this);
this.clearSearchWrapper = this.clearSearch.bind(this);
@@ -36,6 +37,7 @@
this.filteredSearchInput.form.addEventListener('submit', this.handleFormSubmit);
this.filteredSearchInput.addEventListener('input', this.setDropdownWrapper);
this.filteredSearchInput.addEventListener('input', this.toggleClearSearchButtonWrapper);
+ this.filteredSearchInput.addEventListener('input', this.handleInputPlaceholderWrapper);
this.filteredSearchInput.addEventListener('input', this.handleInputVisualTokenWrapper);
this.filteredSearchInput.addEventListener('keydown', this.checkForEnterWrapper);
this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper);
@@ -48,6 +50,7 @@
this.filteredSearchInput.form.removeEventListener('submit', this.handleFormSubmit);
this.filteredSearchInput.removeEventListener('input', this.setDropdownWrapper);
this.filteredSearchInput.removeEventListener('input', this.toggleClearSearchButtonWrapper);
+ this.filteredSearchInput.removeEventListener('input', this.handleInputPlaceholderWrapper);
this.filteredSearchInput.removeEventListener('input', this.handleInputVisualTokenWrapper);
this.filteredSearchInput.removeEventListener('keydown', this.checkForEnterWrapper);
this.filteredSearchInput.removeEventListener('keyup', this.checkForBackspaceWrapper);
@@ -101,12 +104,25 @@
}
}
+ handleInputPlaceholder() {
+ const query = gl.DropdownUtils.getSearchQuery();
+ const placeholder = 'Search or filter results...';
+ const currentPlaceholder = this.filteredSearchInput.placeholder;
+
+ if (query.length === 0 && currentPlaceholder !== placeholder) {
+ this.filteredSearchInput.placeholder = placeholder;
+ } else if (query.length > 0 && currentPlaceholder !== '') {
+ this.filteredSearchInput.placeholder = '';
+ }
+ }
+
clearSearch(e) {
e.preventDefault();
this.filteredSearchInput.value = '';
this.filteredSearchInput.parentElement.querySelector('.tokens-container').innerHTML = '';
this.clearSearchButton.classList.add('hidden');
+ this.handleInputPlaceholder();
this.dropdownManager.resetDropdowns();
}
@@ -214,6 +230,7 @@
if (hasFilteredSearch) {
this.clearSearchButton.classList.remove('hidden');
+ this.handleInputPlaceholder();
}
}
diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb
index 16fd15599e6..6fed1568fcf 100644
--- a/spec/features/merge_requests/reset_filters_spec.rb
+++ b/spec/features/merge_requests/reset_filters_spec.rb
@@ -24,67 +24,93 @@ feature 'Merge requests filter clear button', feature: true, js: true do
context 'when a milestone filter has been applied' do
it 'resets the milestone filter' do
visit_merge_requests(project, milestone_title: milestone.title)
+
expect(page).to have_css(merge_request_css, count: 1)
+ expect(get_filtered_search_placeholder).to eq('')
reset_filters
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
end
end
context 'when a label filter has been applied' do
it 'resets the label filter' do
visit_merge_requests(project, label_name: bug.name)
+
expect(page).to have_css(merge_request_css, count: 1)
+ expect(get_filtered_search_placeholder).to eq('')
reset_filters
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
end
end
context 'when a text search has been conducted' do
it 'resets the text search filter' do
visit_merge_requests(project, search: 'Bug')
+
expect(page).to have_css(merge_request_css, count: 1)
+ expect(get_filtered_search_placeholder).to eq('')
reset_filters
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
end
end
context 'when author filter has been applied' do
it 'resets the author filter' do
visit_merge_requests(project, author_username: user.username)
+
expect(page).to have_css(merge_request_css, count: 1)
+ expect(get_filtered_search_placeholder).to eq('')
reset_filters
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
end
end
context 'when assignee filter has been applied' do
it 'resets the assignee filter' do
visit_merge_requests(project, assignee_username: user.username)
+
expect(page).to have_css(merge_request_css, count: 1)
+ expect(get_filtered_search_placeholder).to eq('')
reset_filters
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
end
end
context 'when all filters have been applied' do
it 'clears all filters' do
visit_merge_requests(project, assignee_username: user.username, author_username: user.username, milestone_title: milestone.title, label_name: bug.name, search: 'Bug')
+
expect(page).to have_css(merge_request_css, count: 0)
+ expect(get_filtered_search_placeholder).to eq('')
reset_filters
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
end
end
context 'when no filters have been applied' do
it 'the clear button should not be visible' do
visit_merge_requests(project)
+
expect(page).to have_css(merge_request_css, count: 2)
+ expect(get_filtered_search_placeholder).to eq(default_placeholder)
expect(page).not_to have_css(clear_search_css)
end
end
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6
index 98959dda242..2440e55bb47 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6
@@ -7,14 +7,12 @@ require('~/filtered_search/filtered_search_manager');
(() => {
describe('Filtered Search Manager', () => {
+ let input;
+
describe('search', () => {
let manager;
const defaultParams = '?scope=all&utf8=✓&state=opened';
- function getInput() {
- return document.querySelector('.filtered-search');
- }
-
beforeEach(() => {
setFixtures(`
<input type='text' class='filtered-search' />
@@ -26,15 +24,16 @@ require('~/filtered_search/filtered_search_manager');
spyOn(gl.FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {});
spyOn(gl.utils, 'getParameterByName').and.returnValue(null);
+ input = document.querySelector('.filtered-search');
manager = new gl.FilteredSearchManager();
});
afterEach(() => {
- getInput().outerHTML = '';
+ input.outerHTML = '';
});
it('should search with a single word', () => {
- getInput().value = 'searchTerm';
+ input.value = 'searchTerm';
spyOn(gl.utils, 'visitUrl').and.callFake((url) => {
expect(url).toEqual(`${defaultParams}&search=searchTerm`);
@@ -44,7 +43,7 @@ require('~/filtered_search/filtered_search_manager');
});
it('should search with multiple words', () => {
- getInput().value = 'awesome search terms';
+ input.value = 'awesome search terms';
spyOn(gl.utils, 'visitUrl').and.callFake((url) => {
expect(url).toEqual(`${defaultParams}&search=awesome+search+terms`);
@@ -54,7 +53,7 @@ require('~/filtered_search/filtered_search_manager');
});
it('should search with special characters', () => {
- getInput().value = '~!@#$%^&*()_+{}:<>,.?/';
+ input.value = '~!@#$%^&*()_+{}:<>,.?/';
spyOn(gl.utils, 'visitUrl').and.callFake((url) => {
expect(url).toEqual(`${defaultParams}&search=~!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%3C%3E%2C.%3F%2F`);
@@ -63,5 +62,63 @@ require('~/filtered_search/filtered_search_manager');
manager.search();
});
});
+
+ describe('handleInputPlaceholder', () => {
+ const placeholder = 'Search or filter results...';
+ let tokensContainer;
+
+ beforeEach(() => {
+ setFixtures(`
+ <form>
+ <ul class="tokens-container list-unstyled"></ul>
+ <input type='text' class='filtered-search' placeholder='${placeholder}' />
+ <button class="clear-search" type="button">
+ <i class="fa fa-times"></i>
+ </button>
+ </form>
+ `);
+
+ spyOn(gl.FilteredSearchManager.prototype, 'cleanup').and.callFake(() => {});
+ spyOn(gl.FilteredSearchManager.prototype, 'loadSearchParamsFromURL').and.callFake(() => {});
+ spyOn(gl.FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {});
+ spyOn(gl.utils, 'getParameterByName').and.returnValue(null);
+
+ input = document.querySelector('.filtered-search');
+ tokensContainer = document.querySelector('.tokens-container');
+ return new gl.FilteredSearchManager();
+ });
+
+ afterEach(() => {
+ input.outerHTML = '';
+ tokensContainer.innerHTML = '';
+ });
+
+ it('should render placeholder when there is no input', () => {
+ expect(input.placeholder).toEqual(placeholder);
+ });
+
+ it('should not render placeholder when there is input', () => {
+ input.value = 'test words';
+
+ const event = new Event('input');
+ input.dispatchEvent(event);
+
+ expect(input.placeholder).toEqual('');
+ });
+
+ it('should not render placeholder when there are tokens and no input', () => {
+ tokensContainer.innerHTML = `
+ <li class="js-visual-token filtered-search-token">
+ <div class="name">label</div>
+ <div class="value">~bug</div>
+ </li>
+ `;
+
+ const event = new Event('input');
+ input.dispatchEvent(event);
+
+ expect(input.placeholder).toEqual('');
+ });
+ });
});
})();
diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js.es6
index 19f797a034e..4f07dfbd7d9 100644
--- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js.es6
@@ -12,7 +12,7 @@ require('~/filtered_search/filtered_search_visual_tokens');
});
afterEach(() => {
- document.querySelector('.tokens-container').innerHTML = '';
+ tokensContainer.innerHTML = '';
});
describe('getLastVisualToken', () => {
diff --git a/spec/support/filtered_search_helpers.rb b/spec/support/filtered_search_helpers.rb
index f43379f258e..62c40b431c7 100644
--- a/spec/support/filtered_search_helpers.rb
+++ b/spec/support/filtered_search_helpers.rb
@@ -52,4 +52,12 @@ module FilteredSearchHelpers
end
end
end
+
+ def default_placeholder
+ 'Search or filter results...'
+ end
+
+ def get_filtered_search_placeholder
+ find('.filtered-search')['placeholder']
+ end
end