syncfusion / ej2-vue-ui-components

Syncfusion Vue UI component library offer more than 50+ cross-browser, responsive, and lightweight vue UI controls for building modern web applications.
https://www.syncfusion.com/vue-ui-components
Other
295 stars 63 forks source link

Mention component not filtering after space when allowSpaces is true. #108

Closed willwarrenOZK closed 2 months ago

willwarrenOZK commented 6 months ago

I believe I have found an issue with the Syncfusion Vue Mention component. When allowSpaces is true, the popup with options stays open, but no filtering is done. So if you have two users with the same first name, Andrew Smith and Andrew Dodd, searching "@Andrew S" will show both Andrews. You can notice in Syncfusion's documentation the filtering is not happening after the space because the popup is not flickering from the update: https://ej2.syncfusion.com/vue/documentation/mention/filtering-data#allow-spacing-between-search

I believe I have found the cause of the issue within the Mention Components onKeyUp function, within the second-to-last else if: else if (this.allowSpaces && this.queryString !== "" && currentRange && currentRange.trim() !== "" && currentRange.replace(" ", " ").lastIndexOf(" ") < currentRange.length - 1 && e.keyCode !== 38 && e.keyCode !== 40 && e.keyCode !== 8 && this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0)) {

I believe that this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0)) needs to be changed to this.mentionChar.charCodeAt(0) !== lastWordRange.charCodeAt(0)). This appears to fix the issue when I change it in the browser's dev tools. Without this change, the searchLists() function is never called after you type a space. The way the code appears now, it seems it only passes into this else if when searching something like @John @Doe which does not seem intended.

For context, the above code block was pulled from the Mention Component's onKeyUp method which I will provide here: Mention2.prototype.onKeyUp = function(e) { var rangetextContent; if (this.isUpDownKey && this.isPopupOpen && e.keyCode === 229) { this.isUpDownKey = false; return; } this.isTyped = e.code !== "Enter" && e.code !== "Space" && e.code !== "ArrowDown" && e.code !== "ArrowUp" ? true : false; if (document.activeElement != this.inputElement) { this.inputElement.focus(); } if (this.isContentEditable(this.inputElement)) { this.range = this.getCurrentRange(); rangetextContent = this.range.startContainer.textContent.split(""); } var currentRange = this.getTextRange(); var lastWordRange = this.getLastLetter(currentRange); var Regex = new RegExp(this.mentionChar.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"), "g"); var charRegex = new RegExp("[a-zA-Z]", "g"); if (e.key === "Shift" || e.keyCode === 37 || e.keyCode === 39) { return; } if (!currentRange || !lastWordRange || e.code === "Enter" || e.keyCode === 27 || lastWordRange.match(Regex) && lastWordRange.match(Regex).length > 1 || this.isContentEditable(this.inputElement) && this.range.startContainer && this.range.startContainer.previousElementSibling && this.range.startContainer.textContent.split("").length > 0 && (rangetextContent.length === 1 || rangetextContent[rangetextContent.length - 2].indexOf("") === -1 || this.range.startContainer.nodeType === 1)) { if (this.allowSpaces && currentRange && currentRange.trim() !== "" && charRegex.test(currentRange) && currentRange.indexOf(this.mentionChar) !== -1 && !this.isMatchedText() && (currentRange.length > 1 && currentRange.replace(/\u00A0/g, " ").charAt(currentRange.length - 2) !== " ") && (this.list && this.list.querySelectorAll("ul").length > 0)) { this.queryString = currentRange.substring(currentRange.lastIndexOf(this.mentionChar) + 1).replace(" ", " "); this.searchLists(e); } else if (this.isPopupOpen && (!this.allowSpaces || !lastWordRange) && (e.code !== "ArrowDown" && e.code !== "ArrowUp")) { this.hidePopup(); this.lineBreak = true; } return; } this.queryString = lastWordRange.replace(this.mentionChar, ""); if (this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0) && this.queryString !== "" && e.keyCode !== 38 && e.keyCode !== 40 && !this.lineBreak) { this.searchLists(e); if (!this.isPopupOpen && this.queryString.length >= this.minLength) { if (!this.isContentEditable(this.inputElement)) { this.showPopup(); } else if (this.isContentEditable(this.inputElement) && this.range && this.range.startContainer !== this.inputElement && e.keyCode !== 9) { this.showPopup(); } } } else if (lastWordRange.indexOf(this.mentionChar) === 0 && !this.isPopupOpen && e.keyCode !== 8 && (!this.popupObj || (isNullOrUndefined(this.target) && !document.body.contains(this.popupObj.element) || !isNullOrUndefined(this.target) && document.body.contains(this.popupObj.element)))) { if (this.initRemoteRender && this.list && this.list.classList.contains("e-nodata")) { this.searchLists(e); } this.resetList(this.dataSource, this.fields); if (isNullOrUndefined(this.list)) { this.initValue(); } if (!this.isPopupOpen && e.keyCode !== 38 && e.keyCode !== 40) { this.didPopupOpenByTypingInitialChar = true; this.showPopup(); if (this.initRemoteRender && this.list.querySelectorAll("li").length === 0) { this.showWaitingSpinner(); } this.lineBreak = false; } } else if (this.allowSpaces && this.queryString !== "" && currentRange && currentRange.trim() !== "" && currentRange.replace(" ", " ").lastIndexOf(" ") < currentRange.length - 1 && e.keyCode !== 38 && e.keyCode !== 40 && e.keyCode !== 8 && this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0)) { this.queryString = currentRange.substring(currentRange.lastIndexOf(this.mentionChar) + 1).replace(" ", " "); this.searchLists(e); } else if (this.queryString === "" && this.isPopupOpen && e.keyCode !== 38 && e.keyCode !== 40 && this.mentionChar.charCodeAt(0) === lastWordRange.charCodeAt(0)) { this.searchLists(e); if (!this.isListResetted) { this.resetList(this.dataSource, this.fields); } } this.isListResetted = false; }

YohapujaSelvakumaran commented 5 months ago

We have considered the reported issue “When setting allowSpace as true, the filtering is not working properly" as a bug from our end and the fix for the issue will be included with our upcoming weekly release on April 10th, 2024.

Now you can track the status of the reported issue through the feedback below, Feedback Link: https://www.syncfusion.com/feedback/51909/when-setting-allowspace-as-true-the-filtering-is-not-working-properly

Disclaimer: “Inclusion of this solution in the weekly release may change due to other factors including but not limited to QA checks and works reprioritization.”

YohapujaSelvakumaran commented 4 months ago

We would like to inform you that we have resolved the reported issue "When setting allowSpace as true, the filtering is not working properly" in our latest version “25.1.39”. Therefore, we recommend upgrading to our latest version to resolve the current issue.

Root cause:

The issue arises when adding spaces during a search operation, causing the last word in the search term to be displaced if its character code doesn't match the character code of the first character after the space. This prevents the search list method from being triggered properly. To address this, enabling the allowSpace option when the list contains li values seems necessary. This option would likely accommodate searches with spaces, ensuring that the search list method is triggered correctly in such cases.

Sample: https://stackblitz.com/edit/u3f4iz-ggypcd?file=src%2FApp.vue,package.json

gsumankumar commented 2 months ago

The reported issue has been successfully addressed in release version (v25.1.39). Consequently, we are closing this ticket for administrative purposes. Should you have any additional questions or concerns, please feel free to reopen the ticket, and we will be more than happy to assist you further.