From 79659b30a76f20719c3d1ab1a3fc2f3d6e516a57 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 17 Jan 2017 16:25:27 -0500 Subject: Filtered search input click back at token Allows the user to click back around the filtered search input to change the previously searched terms --- .../filtered_search_dropdown_manager.js.es6 | 16 ++++++++++++++-- .../filtered_search/filtered_search_manager.js.es6 | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 1cd0483877a..1d5c3490f09 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -92,7 +92,7 @@ const filterIconPadding = 27; const offset = gl.text - .getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding; + .getTextWidth(this.getSearchInput(), this.font) + filterIconPadding; this.mapping[key].reference.setOffset(offset); } @@ -148,7 +148,7 @@ setDropdown() { const { lastToken, searchToken } = this.tokenizer - .processTokens(this.filteredSearchInput.value); + .processTokens(this.getSearchInput()); if (this.filteredSearchInput.value.split('').last() === ' ') { this.updateCurrentDropdownOffset(); @@ -169,6 +169,18 @@ } } + getSearchInput() { + const selectionStart = this.filteredSearchInput.selectionStart; + const inputValue = this.filteredSearchInput.value; + const rightPos = inputValue.slice(selectionStart).search(/\s/); + + if (rightPos < 0) { + return inputValue; + } + + return inputValue.slice(0, rightPos + selectionStart + 1).trim(); + } + resetDropdowns() { // Force current dropdown to hide this.mapping[this.currentDropdown].reference.hideDropdown(); 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 4e8a7cfc940..ca8a185a102 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -35,6 +35,7 @@ this.filteredSearchInput.addEventListener('input', this.toggleClearSearchButtonWrapper); this.filteredSearchInput.addEventListener('keydown', this.checkForEnterWrapper); this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper); + this.filteredSearchInput.addEventListener('click', this.setDropdownWrapper); this.clearSearchButton.addEventListener('click', this.clearSearchWrapper); } -- cgit v1.2.3 From ac080c6379e931572571fc7cfdc2a20bf626e14d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 18 Jan 2017 21:39:43 +0000 Subject: Opens dropdown correctly --- .../javascripts/filtered_search/dropdown_user.js.es6 | 2 +- .../javascripts/filtered_search/dropdown_utils.js.es6 | 12 ++++++++++++ .../filtered_search_dropdown_manager.js.es6 | 19 ++++--------------- .../filtered_search/filtered_search_manager.js.es6 | 11 ++++++++++- 4 files changed, 27 insertions(+), 17 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_user.js.es6 index e80d266ae89..2e9e53458fb 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_user.js.es6 @@ -37,7 +37,7 @@ } getSearchInput() { - const query = this.input.value.trim(); + const query = gl.DropdownUtils.getSearchInput(this.input).trim(); const { lastToken } = gl.FilteredSearchTokenizer.processTokens(query); return lastToken.value || ''; diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index c27ef3042d1..07d257ad8d9 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -72,6 +72,18 @@ // Return boolean based on whether it was set return dataValue !== null; } + + static getSearchInput(filteredSearchInput) { + const selectionStart = filteredSearchInput.selectionStart; + const inputValue = filteredSearchInput.value; + const rightPos = inputValue.slice(selectionStart).search(/\s/); + + if (rightPos < 0) { + return inputValue; + } + + return inputValue.slice(0, rightPos + selectionStart + 1).trim(); + } } window.gl = window.gl || {}; diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 1d5c3490f09..4577aa2c94e 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -59,7 +59,8 @@ const input = document.querySelector('.filtered-search'); const word = `${tokenName}:${tokenValue}`; - const { lastToken, searchToken } = gl.FilteredSearchTokenizer.processTokens(input.value); + const inputValue = gl.DropdownUtils.getSearchInput(input).trim(); + const { lastToken, searchToken } = gl.FilteredSearchTokenizer.processTokens(inputValue); const lastSearchToken = searchToken.split(' ').last(); const lastInputCharacter = input.value[input.value.length - 1]; const lastInputTrimmedCharacter = input.value.trim()[input.value.trim().length - 1]; @@ -92,7 +93,7 @@ const filterIconPadding = 27; const offset = gl.text - .getTextWidth(this.getSearchInput(), this.font) + filterIconPadding; + .getTextWidth(gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(), this.font) + filterIconPadding; this.mapping[key].reference.setOffset(offset); } @@ -148,7 +149,7 @@ setDropdown() { const { lastToken, searchToken } = this.tokenizer - .processTokens(this.getSearchInput()); + .processTokens(gl.DropdownUtils.getSearchInput(this.filteredSearchInput)); if (this.filteredSearchInput.value.split('').last() === ' ') { this.updateCurrentDropdownOffset(); @@ -169,18 +170,6 @@ } } - getSearchInput() { - const selectionStart = this.filteredSearchInput.selectionStart; - const inputValue = this.filteredSearchInput.value; - const rightPos = inputValue.slice(selectionStart).search(/\s/); - - if (rightPos < 0) { - return inputValue; - } - - return inputValue.slice(0, rightPos + selectionStart + 1).trim(); - } - resetDropdowns() { // Force current dropdown to hide this.mapping[this.currentDropdown].reference.hideDropdown(); 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 ca8a185a102..12b8cb4b4b1 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -30,12 +30,13 @@ this.checkForEnterWrapper = this.checkForEnter.bind(this); this.clearSearchWrapper = this.clearSearch.bind(this); this.checkForBackspaceWrapper = this.checkForBackspace.bind(this); + this.showOnClick = this.showOnClick.bind(this); this.filteredSearchInput.addEventListener('input', this.setDropdownWrapper); this.filteredSearchInput.addEventListener('input', this.toggleClearSearchButtonWrapper); this.filteredSearchInput.addEventListener('keydown', this.checkForEnterWrapper); this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper); - this.filteredSearchInput.addEventListener('click', this.setDropdownWrapper); + this.filteredSearchInput.addEventListener('click', this.showOnClick); this.clearSearchButton.addEventListener('click', this.clearSearchWrapper); } @@ -44,6 +45,7 @@ this.filteredSearchInput.removeEventListener('input', this.toggleClearSearchButtonWrapper); this.filteredSearchInput.removeEventListener('keydown', this.checkForEnterWrapper); this.filteredSearchInput.removeEventListener('keyup', this.checkForBackspaceWrapper); + this.filteredSearchInput.removeEventListener('click', this.showOnClick); this.clearSearchButton.removeEventListener('click', this.clearSearchWrapper); } @@ -189,6 +191,13 @@ } return usernamesById; } + + showOnClick() { + const currentDropdownRef = this.dropdownManager.mapping[this.dropdownManager.currentDropdown].reference; + + this.setDropdownWrapper(); + currentDropdownRef.dispatchInputEvent(); + } } window.gl = window.gl || {}; -- cgit v1.2.3 From c45dc8027ce934550efc6091237d94104397033b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 19 Jan 2017 10:10:53 +0000 Subject: Correctly replaces string when selecting in dropdown --- .../filtered_search/dropdown_utils.js.es6 | 18 +++++++++-- .../filtered_search_dropdown_manager.js.es6 | 35 ++++++++++------------ .../filtered_search/filtered_search_manager.js.es6 | 3 +- 3 files changed, 32 insertions(+), 24 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 07d257ad8d9..1bfcbd011b0 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -76,13 +76,25 @@ static getSearchInput(filteredSearchInput) { const selectionStart = filteredSearchInput.selectionStart; const inputValue = filteredSearchInput.value; - const rightPos = inputValue.slice(selectionStart).search(/\s/); + const { right } = gl.DropdownUtils.getInputSelectionPosition(filteredSearchInput); - if (rightPos < 0) { + if (right < 0) { return inputValue; } - return inputValue.slice(0, rightPos + selectionStart + 1).trim(); + return inputValue.slice(0, right + selectionStart + 1).trim(); + } + + static getInputSelectionPosition(input) { + const inputValue = input.value; + const selectionStart = input.selectionStart; + const left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); + const right = inputValue.slice(selectionStart).search(/\s/); + + return { + left, + right, + }; } } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 4577aa2c94e..95c8761638c 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -57,29 +57,23 @@ static addWordToInput(tokenName, tokenValue = '') { const input = document.querySelector('.filtered-search'); + const inputValue = input.value; const word = `${tokenName}:${tokenValue}`; - const inputValue = gl.DropdownUtils.getSearchInput(input).trim(); - const { lastToken, searchToken } = gl.FilteredSearchTokenizer.processTokens(inputValue); - const lastSearchToken = searchToken.split(' ').last(); - const lastInputCharacter = input.value[input.value.length - 1]; - const lastInputTrimmedCharacter = input.value.trim()[input.value.trim().length - 1]; - - // Remove the typed tokenName - if (word.indexOf(lastSearchToken) === 0 && searchToken !== '') { - // Remove spaces after the colon - if (lastInputCharacter === ' ' && lastInputTrimmedCharacter === ':') { - input.value = input.value.trim(); - } - - input.value = input.value.slice(0, -1 * lastSearchToken.length); - } else if (lastInputCharacter !== ' ' || (lastToken && lastToken.value[lastToken.value.length - 1] === ' ')) { - // Remove the existing tokenValue - const lastTokenString = `${lastToken.key}:${lastToken.symbol}${lastToken.value}`; - input.value = input.value.slice(0, -1 * lastTokenString.length); + // Get the string to replace + const selectionStart = input.selectionStart; + const { left } = gl.DropdownUtils.getInputSelectionPosition(input); + let { right } = gl.DropdownUtils.getInputSelectionPosition(input); + + if (right < 0) { + right = inputValue.length; } - input.value += word; + if (left !== -1) { + input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right + selectionStart)}`; + } else { + input.value += word; + } } updateCurrentDropdownOffset() { @@ -93,7 +87,8 @@ const filterIconPadding = 27; const offset = gl.text - .getTextWidth(gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(), this.font) + filterIconPadding; + .getTextWidth(gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(), this.font) + + filterIconPadding; this.mapping[key].reference.setOffset(offset); } 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 12b8cb4b4b1..b0cabf9d378 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -193,7 +193,8 @@ } showOnClick() { - const currentDropdownRef = this.dropdownManager.mapping[this.dropdownManager.currentDropdown].reference; + const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; + const currentDropdownRef = dropdown.reference; this.setDropdownWrapper(); currentDropdownRef.dispatchInputEvent(); -- cgit v1.2.3 From 658c6c26c384c64e3535e87b5c7bfd550632ff29 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 19 Jan 2017 10:30:29 +0000 Subject: Fixed filter issue --- app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 | 2 +- app/assets/javascripts/filtered_search/dropdown_utils.js.es6 | 3 ++- .../filtered_search/filtered_search_dropdown_manager.js.es6 | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 index f06c3fc9c6f..13cbec1be4a 100644 --- a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 @@ -15,7 +15,7 @@ loadingTemplate: this.loadingTemplate, }, droplabFilter: { - filterFunction: gl.DropdownUtils.filterWithSymbol.bind(null, this.symbol), + filterFunction: gl.DropdownUtils.filterWithSymbol.bind(null, this.symbol, input), }, }; } diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 1bfcbd011b0..dcab32fd38b 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -20,8 +20,9 @@ return escapedText; } - static filterWithSymbol(filterSymbol, item, query) { + static filterWithSymbol(filterSymbol, input, item) { const updatedItem = item; + const query = gl.DropdownUtils.getSearchInput(input).trim(); const { lastToken, searchToken } = gl.FilteredSearchTokenizer.processTokens(query); if (lastToken !== searchToken) { diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 95c8761638c..a64818497c1 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -85,10 +85,9 @@ this.font = window.getComputedStyle(this.filteredSearchInput).font; } + const inputText = gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(); const filterIconPadding = 27; - const offset = gl.text - .getTextWidth(gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(), this.font) - + filterIconPadding; + const offset = gl.text.getTextWidth(inputText, this.font) + filterIconPadding; this.mapping[key].reference.setOffset(offset); } @@ -146,7 +145,7 @@ const { lastToken, searchToken } = this.tokenizer .processTokens(gl.DropdownUtils.getSearchInput(this.filteredSearchInput)); - if (this.filteredSearchInput.value.split('').last() === ' ') { + if (this.currentDropdown) { this.updateCurrentDropdownOffset(); } -- cgit v1.2.3 From 91ad8c3c93ea5f558891e6302b04c378aa79d412 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 19 Jan 2017 10:37:54 +0000 Subject: Trigger filter on click --- .../filtered_search/filtered_search_manager.js.es6 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'app/assets') 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 b0cabf9d378..f1912a83e81 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -30,13 +30,14 @@ this.checkForEnterWrapper = this.checkForEnter.bind(this); this.clearSearchWrapper = this.clearSearch.bind(this); this.checkForBackspaceWrapper = this.checkForBackspace.bind(this); - this.showOnClick = this.showOnClick.bind(this); + this.tokenChange = this.tokenChange.bind(this); this.filteredSearchInput.addEventListener('input', this.setDropdownWrapper); this.filteredSearchInput.addEventListener('input', this.toggleClearSearchButtonWrapper); this.filteredSearchInput.addEventListener('keydown', this.checkForEnterWrapper); this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper); - this.filteredSearchInput.addEventListener('click', this.showOnClick); + this.filteredSearchInput.addEventListener('click', this.tokenChange); + this.filteredSearchInput.addEventListener('keyup', this.tokenChange); this.clearSearchButton.addEventListener('click', this.clearSearchWrapper); } @@ -45,7 +46,8 @@ this.filteredSearchInput.removeEventListener('input', this.toggleClearSearchButtonWrapper); this.filteredSearchInput.removeEventListener('keydown', this.checkForEnterWrapper); this.filteredSearchInput.removeEventListener('keyup', this.checkForBackspaceWrapper); - this.filteredSearchInput.removeEventListener('click', this.showOnClick); + this.filteredSearchInput.removeEventListener('click', this.tokenChange); + this.filteredSearchInput.removeEventListener('keyup', this.tokenChange); this.clearSearchButton.removeEventListener('click', this.clearSearchWrapper); } @@ -192,12 +194,17 @@ return usernamesById; } - showOnClick() { + tokenChange(e) { const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; const currentDropdownRef = dropdown.reference; this.setDropdownWrapper(); currentDropdownRef.dispatchInputEvent(); + + if (e.type === 'click') { + // If click event, we need to trigger filter + this.filteredSearchInput.dispatchEvent(new Event('keyup')); + } } } -- cgit v1.2.3 From ab1b8d5035c75e0613dd3fe5f027cd3e73102247 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 19 Jan 2017 15:36:38 +0000 Subject: Added tests Fixed edge cases with changing value --- .../filtered_search_dropdown_manager.js.es6 | 27 +++++++++++++++++----- .../filtered_search/filtered_search_manager.js.es6 | 7 +----- 2 files changed, 22 insertions(+), 12 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index a64818497c1..031e4f9b127 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -62,18 +62,33 @@ // Get the string to replace const selectionStart = input.selectionStart; - const { left } = gl.DropdownUtils.getInputSelectionPosition(input); - let { right } = gl.DropdownUtils.getInputSelectionPosition(input); + let { left, right } = gl.DropdownUtils.getInputSelectionPosition(input); if (right < 0) { right = inputValue.length; } - if (left !== -1) { - input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right + selectionStart)}`; - } else { - input.value += word; + if (left < 0) { + left += 1; } + + input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right + selectionStart)}`; + gl.FilteredSearchDropdownManager.updateInputCaretPosition(selectionStart, input); + } + + static updateInputCaretPosition(selectionStart, input) { + // Reset the position + // Sometimes can end up at end of input + input.setSelectionRange(selectionStart, selectionStart); + + const inputValue = input.value; + let { right } = gl.DropdownUtils.getInputSelectionPosition(input); + + if (right < 0) { + right = inputValue.length; + } + + input.setSelectionRange(selectionStart + right, selectionStart + right); } updateCurrentDropdownOffset() { 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 f1912a83e81..c7b72b36561 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -194,17 +194,12 @@ return usernamesById; } - tokenChange(e) { + tokenChange() { const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; const currentDropdownRef = dropdown.reference; this.setDropdownWrapper(); currentDropdownRef.dispatchInputEvent(); - - if (e.type === 'click') { - // If click event, we need to trigger filter - this.filteredSearchInput.dispatchEvent(new Event('keyup')); - } } } -- cgit v1.2.3 From a4789db98e6ad39e8b890ebe93ee91bb4531eec3 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 19 Jan 2017 18:43:38 +0000 Subject: Fixed bug replacing full input value --- app/assets/javascripts/filtered_search/dropdown_utils.js.es6 | 8 +++++++- .../filtered_search/filtered_search_dropdown_manager.js.es6 | 7 ++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index dcab32fd38b..0027f79aecb 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -89,9 +89,15 @@ static getInputSelectionPosition(input) { const inputValue = input.value; const selectionStart = input.selectionStart; - const left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); + let left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); const right = inputValue.slice(selectionStart).search(/\s/); + if (selectionStart === 0) { + left = 0; + } else if (selectionStart === inputValue.length && left < 0) { + left = inputValue.length; + } + return { left, right, diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 031e4f9b127..9edb6ade4f2 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -62,16 +62,13 @@ // Get the string to replace const selectionStart = input.selectionStart; - let { left, right } = gl.DropdownUtils.getInputSelectionPosition(input); + const { left } = gl.DropdownUtils.getInputSelectionPosition(input); + let { right } = gl.DropdownUtils.getInputSelectionPosition(input); if (right < 0) { right = inputValue.length; } - if (left < 0) { - left += 1; - } - input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right + selectionStart)}`; gl.FilteredSearchDropdownManager.updateInputCaretPosition(selectionStart, input); } -- cgit v1.2.3 From 80c0b877d966226a8f31ea199c6cfc5cf4bf9527 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 20 Jan 2017 13:59:26 +0000 Subject: Fixed issue when label or milestone had space --- .../javascripts/filtered_search/dropdown_utils.js.es6 | 17 +++++++++++++---- .../filtered_search_dropdown_manager.js.es6 | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 0027f79aecb..54792f987b0 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -83,14 +83,23 @@ return inputValue; } - return inputValue.slice(0, right + selectionStart + 1).trim(); + return inputValue.slice(0, right + 1).trim(); } static getInputSelectionPosition(input) { - const inputValue = input.value; + let inputValue = input.value; + // Replace all spaces inside quote marks with underscores + // This helps with matching the beginning & end of a token:key + inputValue = inputValue.replace(/"(.*?)"/g, str => str.replace(/\s/g, '_') ); + const selectionStart = input.selectionStart; - let left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); - const right = inputValue.slice(selectionStart).search(/\s/); + let right = inputValue.slice(selectionStart).search(/\s/); + + if (right >= 0) { + right += selectionStart; + } + + let left = inputValue.slice(0, right).search(/\S+$/); if (selectionStart === 0) { left = 0; diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 9edb6ade4f2..cd0f41eb8ef 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -69,7 +69,7 @@ right = inputValue.length; } - input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right + selectionStart)}`; + input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right)}`; gl.FilteredSearchDropdownManager.updateInputCaretPosition(selectionStart, input); } @@ -85,7 +85,7 @@ right = inputValue.length; } - input.setSelectionRange(selectionStart + right, selectionStart + right); + input.setSelectionRange(selectionStart + right, selectionStart); } updateCurrentDropdownOffset() { -- cgit v1.2.3 From 1980403c149f7ec59a8c215950c33fd4a81c024c Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 20 Jan 2017 14:06:34 +0000 Subject: Fixed caret not moving correctly --- app/assets/javascripts/filtered_search/dropdown_utils.js.es6 | 2 +- .../javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 54792f987b0..86fcc8f2612 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -99,7 +99,7 @@ right += selectionStart; } - let left = inputValue.slice(0, right).search(/\S+$/); + let left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); if (selectionStart === 0) { left = 0; diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index cd0f41eb8ef..fc00e77ae7f 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -85,7 +85,7 @@ right = inputValue.length; } - input.setSelectionRange(selectionStart + right, selectionStart); + input.setSelectionRange(right, right); } updateCurrentDropdownOffset() { -- cgit v1.2.3 From eb993dc5963fdec39ebbec813df0b3afb6e6fde2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 20 Jan 2017 15:09:36 +0000 Subject: Fixed bug with hint not showing when in middle of text --- .../filtered_search/dropdown_hint.js.es6 | 2 +- .../filtered_search/dropdown_user.js.es6 | 2 +- .../filtered_search/dropdown_utils.js.es6 | 21 ++++++++++++--------- .../filtered_search_dropdown_manager.js.es6 | 13 ++----------- 4 files changed, 16 insertions(+), 22 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 index 63c20f57520..f4ec3b206cc 100644 --- a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 @@ -9,7 +9,7 @@ this.config = { droplabFilter: { template: 'hint', - filterFunction: gl.DropdownUtils.filterHint, + filterFunction: gl.DropdownUtils.filterHint.bind(null, input), }, }; } diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_user.js.es6 index 2e9e53458fb..7bf199d9274 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_user.js.es6 @@ -37,7 +37,7 @@ } getSearchInput() { - const query = gl.DropdownUtils.getSearchInput(this.input).trim(); + const query = gl.DropdownUtils.getSearchInput(this.input); const { lastToken } = gl.FilteredSearchTokenizer.processTokens(query); return lastToken.value || ''; diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 86fcc8f2612..df4103b0e7f 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -22,7 +22,7 @@ static filterWithSymbol(filterSymbol, input, item) { const updatedItem = item; - const query = gl.DropdownUtils.getSearchInput(input).trim(); + const query = gl.DropdownUtils.getSearchInput(input); const { lastToken, searchToken } = gl.FilteredSearchTokenizer.processTokens(query); if (lastToken !== searchToken) { @@ -45,8 +45,9 @@ return updatedItem; } - static filterHint(item, query) { + static filterHint(input, item) { const updatedItem = item; + const query = gl.DropdownUtils.getSearchInput(input); let { lastToken } = gl.FilteredSearchTokenizer.processTokens(query); lastToken = lastToken.key || lastToken || ''; @@ -79,32 +80,34 @@ const inputValue = filteredSearchInput.value; const { right } = gl.DropdownUtils.getInputSelectionPosition(filteredSearchInput); - if (right < 0) { - return inputValue; - } - - return inputValue.slice(0, right + 1).trim(); + return inputValue.slice(0, right); } static getInputSelectionPosition(input) { + const selectionStart = input.selectionStart; let inputValue = input.value; // Replace all spaces inside quote marks with underscores // This helps with matching the beginning & end of a token:key inputValue = inputValue.replace(/"(.*?)"/g, str => str.replace(/\s/g, '_') ); - const selectionStart = input.selectionStart; + // Get the right position for the word selected let right = inputValue.slice(selectionStart).search(/\s/); if (right >= 0) { right += selectionStart; + } else if (right < 0) { + right = inputValue.length; } - let left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); + // Get the left position for the word selected + let left = inputValue.slice(0, right).search(/\S+$/); if (selectionStart === 0) { left = 0; } else if (selectionStart === inputValue.length && left < 0) { left = inputValue.length; + } else if (left < 0) { + left = selectionStart; } return { diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index fc00e77ae7f..f3750c2b23e 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -62,12 +62,7 @@ // Get the string to replace const selectionStart = input.selectionStart; - const { left } = gl.DropdownUtils.getInputSelectionPosition(input); - let { right } = gl.DropdownUtils.getInputSelectionPosition(input); - - if (right < 0) { - right = inputValue.length; - } + const { left, right } = gl.DropdownUtils.getInputSelectionPosition(input); input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right)}`; gl.FilteredSearchDropdownManager.updateInputCaretPosition(selectionStart, input); @@ -79,11 +74,7 @@ input.setSelectionRange(selectionStart, selectionStart); const inputValue = input.value; - let { right } = gl.DropdownUtils.getInputSelectionPosition(input); - - if (right < 0) { - right = inputValue.length; - } + const { right } = gl.DropdownUtils.getInputSelectionPosition(input); input.setSelectionRange(right, right); } -- cgit v1.2.3 From 4a797620e8dd92519bf43dfb36e7e09de0c9e739 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 20 Jan 2017 15:16:31 +0000 Subject: Added comments to regex --- app/assets/javascripts/filtered_search/dropdown_utils.js.es6 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index df4103b0e7f..f5d2eb9ae76 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -91,6 +91,7 @@ inputValue = inputValue.replace(/"(.*?)"/g, str => str.replace(/\s/g, '_') ); // Get the right position for the word selected + // Regex matches first space let right = inputValue.slice(selectionStart).search(/\s/); if (right >= 0) { @@ -100,6 +101,7 @@ } // Get the left position for the word selected + // Regex matches last non-whitespace character let left = inputValue.slice(0, right).search(/\S+$/); if (selectionStart === 0) { -- cgit v1.2.3 From 8198d49801d91510fe11c53ce184cf750bd06c49 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 20 Jan 2017 16:06:38 +0000 Subject: Places dropdown at cursor position --- .../filtered_search/filtered_search_dropdown_manager.js.es6 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index f3750c2b23e..42c673a5106 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -88,7 +88,8 @@ this.font = window.getComputedStyle(this.filteredSearchInput).font; } - const inputText = gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(); + const input = this.filteredSearchInput; + const inputText = input.value.slice(0, input.selectionStart); const filterIconPadding = 27; const offset = gl.text.getTextWidth(inputText, this.font) + filterIconPadding; -- cgit v1.2.3 From 317ef7b51c680503b01c88b8d8fdb09bd1a515e8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 20 Jan 2017 18:04:15 +0000 Subject: Fixed failing JS specs --- app/assets/javascripts/filtered_search/dropdown_utils.js.es6 | 3 +-- .../filtered_search/filtered_search_dropdown_manager.js.es6 | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index f5d2eb9ae76..6910cf171d4 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -76,7 +76,6 @@ } static getSearchInput(filteredSearchInput) { - const selectionStart = filteredSearchInput.selectionStart; const inputValue = filteredSearchInput.value; const { right } = gl.DropdownUtils.getInputSelectionPosition(filteredSearchInput); @@ -88,7 +87,7 @@ let inputValue = input.value; // Replace all spaces inside quote marks with underscores // This helps with matching the beginning & end of a token:key - inputValue = inputValue.replace(/"(.*?)"/g, str => str.replace(/\s/g, '_') ); + inputValue = inputValue.replace(/"(.*?)"/g, str => str.replace(/\s/g, '_')); // Get the right position for the word selected // Regex matches first space diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 42c673a5106..04873115580 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -73,7 +73,6 @@ // Sometimes can end up at end of input input.setSelectionRange(selectionStart, selectionStart); - const inputValue = input.value; const { right } = gl.DropdownUtils.getInputSelectionPosition(input); input.setSelectionRange(right, right); -- cgit v1.2.3 From e75c20fcff87f8f0de8daa556e7286659f111ab6 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Sat, 21 Jan 2017 19:30:51 +0000 Subject: Fixed issue with multiple words not filtering correctly --- app/assets/javascripts/filtered_search/dropdown_utils.js.es6 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'app/assets') diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 6910cf171d4..443ac222f70 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -28,10 +28,7 @@ if (lastToken !== searchToken) { const title = updatedItem.title.toLowerCase(); let value = lastToken.value.toLowerCase(); - - if ((value[0] === '"' || value[0] === '\'') && title.indexOf(' ') !== -1) { - value = value.slice(1); - } + value = value.replace(/"(.*?)"/g, str => str.slice(1).slice(0, -1)); // Eg. filterSymbol = ~ for labels const matchWithoutSymbol = lastToken.symbol === filterSymbol && title.indexOf(value) !== -1; -- cgit v1.2.3