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

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

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

function getHint(transcript){
    console.log("GET HINT1");

    let triggerOne = "(?:\\b|')(to)(?:\\b|')";
    const found = transcript.match(triggerOne);
    //let last2 = transcript.slice(-2);
    console.log("found", found);
    //console.log("last2", last2);
    //console.log("found.length", found?.length);

    let hint = "";
    if(found){
    //if(found && (last2 !== "to") ){
      //found?.length > 0
      hint = "<span>jupiter moons</span>";
    }
  
    return transcript + " " +hint;
  }

替代

getHint(transcript) {
    // Define an array of dynamic keywords
    const dynamicKeywords = ['to', 'from', 'a']

    // Create a regular expression pattern to match any of the dynamic keywords
    const dynamicKeywordRegex = new RegExp(
      `\\b(${dynamicKeywords.join('|')})\\b`,
      'gi',
    )

    // Find all matches in the input text
    const matches = transcript.match(dynamicKeywordRegex)

    if (matches) {
      const uniqueMatches = [...new Set(matches)] // Remove duplicate matches

      let hints = {} // Create an object to store hints
      uniqueMatches.forEach((match) => {
        hints[match] = this.state.data[match]
      })

      this.setState({
        suggestions: hints, // Update suggestions with the hint object
        transcriptLength: transcript.length,
        transcript: transcript,
      })
    } else {
      this.setState({
        transcriptLength: 0,
      })
    }
  }

  handleChange(data) {
    let transcript = data.command

    // Get the dynamic keywords from your state data
    const dynamicKeywords = Object.keys(this.state.data)
    // Create a regular expression pattern to match any dynamic keyword
    const dynamicKeywordRegex = new RegExp(
      `\\b(${dynamicKeywords.join('|')})\\b`,
      'gi',
    )

    //   // Find all matches in the input text
    const matches = transcript.match(dynamicKeywordRegex)

    if (matches) {
      // Replace all dynamic keywords with highlighting in the transcript
      let highlightedText = transcript.replace(
        dynamicKeywordRegex,
        (match) =>
          ` ${match} <span className="highlighted-text">${this.state.data[match][0].key}</span>`,
      )

      // Set the highlighted text in the ref
      this.myRef.current.innerHTML = highlightedText

      // Update the hinted text
      this.getHint(transcript)
    } else {
      // No dynamic keywords found, reset the highlighting
      this.myRef.current.innerHTML = transcript

      // Update the hinted text
      this.getHint(transcript)
    }
    // Remove duplicates within the ref
    const currentText = this.myRef.current.textContent
    const newText = this.removeDuplicateWordsAcrossSegments(currentText)
    this.myRef.current.textContent = newText

    this.myRef.current.textContent = currentText
  }

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

var to = [
            {
              "key": "home",
              "details": "20 Glenbrook Dr, Hillsborough CA 92591"
            },
            {
              "key": "work",
              "details": "400 S El Camino Real San Mateo, CA 92591"
            }
          ];
          
          var from = [
            {
              "key": "Wimpole Pharmacy",
              "details": "pharmacies"
            },
            {
              "key": "JP Pharmacy",
              "details": "pharmacies"
            },
            {
              "key": "Morrisons Pharmacy",
              "details": "pharmacies"
            }
          ]
        

        function submitLoginForm(event){
            event.preventDefault();

            console.log(event.target['command'].value);
            var transcript = event.target['command'].value;

          var s = document.getElementById("textHolder");
          s.innerHTML = getHint(transcript);
            
        }      
        
        
      
      function getHint(transcript){
        console.log("GET HINT1");

        let triggerOne = "(?:\\b|')(to)(?:\\b|')";
        const found = transcript.match(triggerOne);
        //let last2 = transcript.slice(-2);
        console.log("found", found);
        //console.log("last2", last2);
        //console.log("found.length", found?.length);

        let hint = "";
        if(found){
        //if(found && (last2 !== "to") ){
          //found?.length > 0
          hint = "<span>jupiter moons</span>";
        }
      
        return transcript + " " +hint;
      }
<form onsubmit="submitLoginForm(event)">
        <input type="text" name="command">
        <input type="submit" value="submit">
    </form>

    <div id="textHolder"></div>

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

kxe2p93d

kxe2p93d1#

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

const d=document;
const q=(e,n=d)=>n.querySelector(e);

const lookup={
  locations:[
      {
        "key": "home",
        "details": "20 Glenbrook Dr, Hillsborough CA 92591"
      },
      {
        "key": "work",
        "details": "400 S El Camino Real San Mateo, CA 92591"
      },
      {
        "key": "pub",
        "details": "421 Sauchiehall St, Glasgow G2 3LG"
      }
  ],
  suppliers:[
      {
        "key": "Wimpole Pharmacy",
        "details": "18 Wimpole St, London W1G 8GD"
      },
      {
        "key": "JP Pharmacy",
        "details": "139 Camden High Street, London, NW1 7JR"
      },
      {
        "key": "Morrisons Pharmacy",
        "details": "4 ALBION WAY RIVERSIDE RETAIL PARK NORWICH NORFOLK NR1 1WU"
      },
      {
        "key": "Lloyds Pharmacy",
        "details": "280b Lower Farnham Road, Aldershot, UK, GU11 3RD"
      },
      {
        "key": "Waitrose & Partners Pharmacy",
        "details": "Stonneyland Dr, Lichfield WS13 6RX"
      },
      {
        "key": "The Stag",
        "details": "140 Castle St, Forfar DD8 3HX"
      },
      {
        "key": "The Osnaburg",
        "details": "23 Osnaburg St, Forfar DD8 2AA"
      },
      {
        "key": "The Zoar",
        "details": "20 Muir St, Forfar DD8 3JY"
      }
  ]
};

const keyuphandler=(e)=>{
  if( e.target instanceof HTMLInputElement ){
  
    let list=q('datalist',e.target.parentNode);
        list.innerHTML='';
    
    if( e.target.value.length >= 2 ){
      let hints=getHints( e.target.name, e.target.value );
          hints.forEach( hint=>{
            list.appendChild( new Option( hint, hint ) );
          });
          
      return true;
    }
    list.innerHTML='';
  }
};

const getHints=(key,str)=>{
  let matches=[];
  let source=lookup[key];
  
  source.forEach(obj=>{
    if( obj.key.toLowerCase().includes( str.toLowerCase() ) ) {
      /* modify format of displayed hint here */
      matches.push( obj.key+': '+obj.details )
    }
  });
  return matches.sort((a,b)=>a.localeCompare(b));
};

const clickhandler=(e)=>{
  e.stopPropagation();
  if( e.target instanceof SVGSVGElement ){
    q('input',e.target.closest('label')).value='';
  }
};



d.addEventListener('keyup',keyuphandler);
d.addEventListener('click',clickhandler);
body{font-family:monospace;}
label{display:flex;flex-direction:row;margin:1rem;justify-content:space-between;width:50%;}
label > input{flex:2;padding:0.5rem}
label > span{flex:1;padding:0.5rem}
svg{width:20px;height:20px;margin:0.5rem;fill:rgba(255,0,0,0.25);cursor:pointer}
<form>
  <label>
    <span>Deliver to:</span>
    <input type="text" list='loc' name="locations" />
    <datalist id='loc' class='hint'></datalist>
    <svg>
      <use href="#closer" />
    </svg>
  </label>
  
  <label>
    <span>Supplier:</span>
    <input type="text" list='sup' name="suppliers" />
    <datalist id='sup' class='hint'></datalist>
    <svg>
      <use href="#closer" />
    </svg>
  </label>
  
  <input type="submit" />
</form>

<svg>
  <defs>
    <symbol id="closer" viewBox="0 0 612 612" pointer-events="none">
      <path d="M444.644,306l138.644-138.644c38.284-38.284,
          38.284-100.36,0-138.644c-38.283-38.284-100.359-38.284-138.644,
          0 L306,167.356L167.356,28.713c-38.284-38.284-100.36-38.284-138.644,
          0s-38.284,100.36,0,138.644L167.356,306L28.713,444.644 c-38.284,
          38.283-38.284,100.36,0,138.644c38.284,38.284,100.36,38.284,138.644,0L306,
          444.644l138.644,138.644 c38.283,38.284,100.36,38.284,138.644, 
          0c38.284-38.283,38.284-100.36,0-138.644L444.644,306z" />
    </symbol>
  </defs>
</svg>

相关问题