html 来自表单输入的JavaScript预测文本-显示选项列表并在选择选项时覆盖提示

n3schb8v  于 2023-10-14  发布在  Java
关注(0)|答案(1)|浏览(149)

我正在研究一个预测文本功能,该功能可以分析输入中的文本-如果用户即将触发预测通配符来填充提示文本,并在需要时根据用户的选择进行覆盖。它应该在提示文本下显示可用选项的列表。
不过,现在出了点故障。在后来的版本中,它重复重复的单词,而不是覆盖用户的选择。

  1. function getHint(transcript){
  2. console.log("GET HINT1");
  3. let triggerOne = "(?:\\b|')(to)(?:\\b|')";
  4. const found = transcript.match(triggerOne);
  5. //let last2 = transcript.slice(-2);
  6. console.log("found", found);
  7. //console.log("last2", last2);
  8. //console.log("found.length", found?.length);
  9. let hint = "";
  10. if(found){
  11. //if(found && (last2 !== "to") ){
  12. //found?.length > 0
  13. hint = "<span>jupiter moons</span>";
  14. }
  15. return transcript + " " +hint;
  16. }

替代

  1. getHint(transcript) {
  2. // Define an array of dynamic keywords
  3. const dynamicKeywords = ['to', 'from', 'a']
  4. // Create a regular expression pattern to match any of the dynamic keywords
  5. const dynamicKeywordRegex = new RegExp(
  6. `\\b(${dynamicKeywords.join('|')})\\b`,
  7. 'gi',
  8. )
  9. // Find all matches in the input text
  10. const matches = transcript.match(dynamicKeywordRegex)
  11. if (matches) {
  12. const uniqueMatches = [...new Set(matches)] // Remove duplicate matches
  13. let hints = {} // Create an object to store hints
  14. uniqueMatches.forEach((match) => {
  15. hints[match] = this.state.data[match]
  16. })
  17. this.setState({
  18. suggestions: hints, // Update suggestions with the hint object
  19. transcriptLength: transcript.length,
  20. transcript: transcript,
  21. })
  22. } else {
  23. this.setState({
  24. transcriptLength: 0,
  25. })
  26. }
  27. }
  28. handleChange(data) {
  29. let transcript = data.command
  30. // Get the dynamic keywords from your state data
  31. const dynamicKeywords = Object.keys(this.state.data)
  32. // Create a regular expression pattern to match any dynamic keyword
  33. const dynamicKeywordRegex = new RegExp(
  34. `\\b(${dynamicKeywords.join('|')})\\b`,
  35. 'gi',
  36. )
  37. // // Find all matches in the input text
  38. const matches = transcript.match(dynamicKeywordRegex)
  39. if (matches) {
  40. // Replace all dynamic keywords with highlighting in the transcript
  41. let highlightedText = transcript.replace(
  42. dynamicKeywordRegex,
  43. (match) =>
  44. ` ${match} <span className="highlighted-text">${this.state.data[match][0].key}</span>`,
  45. )
  46. // Set the highlighted text in the ref
  47. this.myRef.current.innerHTML = highlightedText
  48. // Update the hinted text
  49. this.getHint(transcript)
  50. } else {
  51. // No dynamic keywords found, reset the highlighting
  52. this.myRef.current.innerHTML = transcript
  53. // Update the hinted text
  54. this.getHint(transcript)
  55. }
  56. // Remove duplicates within the ref
  57. const currentText = this.myRef.current.textContent
  58. const newText = this.removeDuplicateWordsAcrossSegments(currentText)
  59. this.myRef.current.textContent = newText
  60. this.myRef.current.textContent = currentText
  61. }

阶段1
https://jsfiddle.net/9kxdnpL6/7/

  1. var to = [
  2. {
  3. "key": "home",
  4. "details": "20 Glenbrook Dr, Hillsborough CA 92591"
  5. },
  6. {
  7. "key": "work",
  8. "details": "400 S El Camino Real San Mateo, CA 92591"
  9. }
  10. ];
  11. var from = [
  12. {
  13. "key": "Wimpole Pharmacy",
  14. "details": "pharmacies"
  15. },
  16. {
  17. "key": "JP Pharmacy",
  18. "details": "pharmacies"
  19. },
  20. {
  21. "key": "Morrisons Pharmacy",
  22. "details": "pharmacies"
  23. }
  24. ]
  25. function submitLoginForm(event){
  26. event.preventDefault();
  27. console.log(event.target['command'].value);
  28. var transcript = event.target['command'].value;
  29. var s = document.getElementById("textHolder");
  30. s.innerHTML = getHint(transcript);
  31. }
  32. function getHint(transcript){
  33. console.log("GET HINT1");
  34. let triggerOne = "(?:\\b|')(to)(?:\\b|')";
  35. const found = transcript.match(triggerOne);
  36. //let last2 = transcript.slice(-2);
  37. console.log("found", found);
  38. //console.log("last2", last2);
  39. //console.log("found.length", found?.length);
  40. let hint = "";
  41. if(found){
  42. //if(found && (last2 !== "to") ){
  43. //found?.length > 0
  44. hint = "<span>jupiter moons</span>";
  45. }
  46. return transcript + " " +hint;
  47. }
  1. <form onsubmit="submitLoginForm(event)">
  2. <input type="text" name="command">
  3. <input type="submit" value="submit">
  4. </form>
  5. <div id="textHolder"></div>

阶段2 -它找到提示,但复制单词,并且不覆盖用户的选择。https://codesandbox.io/s/compassionate-elgamal-4h4f2f?file=/src/_globals/PredictiveText/PredictiveText.js:4402-4622

kxe2p93d

kxe2p93d1#

我对你的代码做了一点尝试,但发现正则表达式模式并没有真正做到我认为它应该做的事情,最后使用了一种不同的方法,我认为工作正常。
下面的代码不是使用正则表达式来匹配输入文本,而是使用includes来确定输入的文本是否是预定义关键字的一部分。

  1. const d=document;
  2. const q=(e,n=d)=>n.querySelector(e);
  3. const lookup={
  4. locations:[
  5. {
  6. "key": "home",
  7. "details": "20 Glenbrook Dr, Hillsborough CA 92591"
  8. },
  9. {
  10. "key": "work",
  11. "details": "400 S El Camino Real San Mateo, CA 92591"
  12. },
  13. {
  14. "key": "pub",
  15. "details": "421 Sauchiehall St, Glasgow G2 3LG"
  16. }
  17. ],
  18. suppliers:[
  19. {
  20. "key": "Wimpole Pharmacy",
  21. "details": "18 Wimpole St, London W1G 8GD"
  22. },
  23. {
  24. "key": "JP Pharmacy",
  25. "details": "139 Camden High Street, London, NW1 7JR"
  26. },
  27. {
  28. "key": "Morrisons Pharmacy",
  29. "details": "4 ALBION WAY RIVERSIDE RETAIL PARK NORWICH NORFOLK NR1 1WU"
  30. },
  31. {
  32. "key": "Lloyds Pharmacy",
  33. "details": "280b Lower Farnham Road, Aldershot, UK, GU11 3RD"
  34. },
  35. {
  36. "key": "Waitrose & Partners Pharmacy",
  37. "details": "Stonneyland Dr, Lichfield WS13 6RX"
  38. },
  39. {
  40. "key": "The Stag",
  41. "details": "140 Castle St, Forfar DD8 3HX"
  42. },
  43. {
  44. "key": "The Osnaburg",
  45. "details": "23 Osnaburg St, Forfar DD8 2AA"
  46. },
  47. {
  48. "key": "The Zoar",
  49. "details": "20 Muir St, Forfar DD8 3JY"
  50. }
  51. ]
  52. };
  53. const keyuphandler=(e)=>{
  54. if( e.target instanceof HTMLInputElement ){
  55. let list=q('datalist',e.target.parentNode);
  56. list.innerHTML='';
  57. if( e.target.value.length >= 2 ){
  58. let hints=getHints( e.target.name, e.target.value );
  59. hints.forEach( hint=>{
  60. list.appendChild( new Option( hint, hint ) );
  61. });
  62. return true;
  63. }
  64. list.innerHTML='';
  65. }
  66. };
  67. const getHints=(key,str)=>{
  68. let matches=[];
  69. let source=lookup[key];
  70. source.forEach(obj=>{
  71. if( obj.key.toLowerCase().includes( str.toLowerCase() ) ) {
  72. /* modify format of displayed hint here */
  73. matches.push( obj.key+': '+obj.details )
  74. }
  75. });
  76. return matches.sort((a,b)=>a.localeCompare(b));
  77. };
  78. const clickhandler=(e)=>{
  79. e.stopPropagation();
  80. if( e.target instanceof SVGSVGElement ){
  81. q('input',e.target.closest('label')).value='';
  82. }
  83. };
  84. d.addEventListener('keyup',keyuphandler);
  85. d.addEventListener('click',clickhandler);
  1. body{font-family:monospace;}
  2. label{display:flex;flex-direction:row;margin:1rem;justify-content:space-between;width:50%;}
  3. label > input{flex:2;padding:0.5rem}
  4. label > span{flex:1;padding:0.5rem}
  5. svg{width:20px;height:20px;margin:0.5rem;fill:rgba(255,0,0,0.25);cursor:pointer}
  1. <form>
  2. <label>
  3. <span>Deliver to:</span>
  4. <input type="text" list='loc' name="locations" />
  5. <datalist id='loc' class='hint'></datalist>
  6. <svg>
  7. <use href="#closer" />
  8. </svg>
  9. </label>
  10. <label>
  11. <span>Supplier:</span>
  12. <input type="text" list='sup' name="suppliers" />
  13. <datalist id='sup' class='hint'></datalist>
  14. <svg>
  15. <use href="#closer" />
  16. </svg>
  17. </label>
  18. <input type="submit" />
  19. </form>
  20. <svg>
  21. <defs>
  22. <symbol id="closer" viewBox="0 0 612 612" pointer-events="none">
  23. <path d="M444.644,306l138.644-138.644c38.284-38.284,
  24. 38.284-100.36,0-138.644c-38.283-38.284-100.359-38.284-138.644,
  25. 0 L306,167.356L167.356,28.713c-38.284-38.284-100.36-38.284-138.644,
  26. 0s-38.284,100.36,0,138.644L167.356,306L28.713,444.644 c-38.284,
  27. 38.283-38.284,100.36,0,138.644c38.284,38.284,100.36,38.284,138.644,0L306,
  28. 444.644l138.644,138.644 c38.283,38.284,100.36,38.284,138.644,
  29. 0c38.284-38.283,38.284-100.36,0-138.644L444.644,306z" />
  30. </symbol>
  31. </defs>
  32. </svg>
展开查看全部

相关问题