0

I want to detect a specific word or multiple words within the user's entered text and reply accordingly. I plan to add more words to detect but for now I've been using this. My result is finalKey.contains is not a function.

<html>
<div>
  <p1 id="iOut"></p1>
</div>
<div>
  <input id="uIn" value=""></input>
</div>
<button onclick="regis()">SUBMIT</button>

<script>
  var key = document.getElementById("uIn").value;
  var finalKey = key.toUpperCase();

  function regis() {
    if (finalKey.contains("Hi" || "H")) {
      document.getElementById("iOut").innerHTML = "HEY";

    } else if (finalKey.contains("Bye" || "Goodbye")) {
      document.getElementById("iOut").innerHTML = "Okay";

    } else {
      document.getElementById("iOut").innerHTML = " Try again";
    }
  }
</script>

</html>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
One Amaro
  • 25
  • 6

3 Answers3

1

There is no such thing as contains. It is .includes or indexOf != -1

Your gathering of values needs to be inside the function too

Also you cannot test two values in one statement unless you turn it around and use an array:

["Hi","H"].indexOf(finalKey) !=-1 

or

["HI","H"].filter(text => finalKey.startsWith(text)).length > 0

if you want finalkey to start with either - use .includes if you want to test the complete input

Lastly you uppercased the text so compare uppercase text

function regis() {
  var key = document.getElementById("uIn").value;
  var finalKey = key.toUpperCase();

  if (["HI","H"].filter(text => finalKey.includes(text)).length > 0) {
    document.getElementById("iOut").innerHTML = "HEY";
  } else 
    if (["BYE","GOODBYE"].filter(text => finalKey.includes(text)).length > 0) {
    document.getElementById("iOut").innerHTML = "Okay";
  } else // GOOD has to be AFTER GOODBYE to not catch it
    if (["GOOD","GREAT"].filter(text => finalKey.includes(text)).length > 0) {
    document.getElementById("iOut").innerHTML = "That's Good";
  } else {
    document.getElementById("iOut").innerHTML = " Try again";
  }
}
<div>
  <p1 id="iOut"></p1>
</div>
<div>
  <input id="uIn" value="" />
</div>
<button type="button" onclick="regis()">SUBMIT</button>

Using regular expression and word boundaries

Note I wrapped in a form, now you can just hit enter too

const wordList = [
  { list: ["HI", "H"], answer: "HEY" },
  { list: ["BYE", "GOODBYE"], answer: "Okay" },
  { list: ["GOOD", "GREAT"], answer: "That's good" }
];

const defaultText = " Try again";

document.getElementById("inputForm").addEventListener("submit", e => {
  e.preventDefault()
  const input = document.getElementById("uIn").value.trim().toUpperCase();
  let result = wordList
    .filter(({ list, answer }) => list
      .filter(word => new RegExp("\\b" + word + "\\b").test(input))
      .length > 0);
      
  console.log(result)
  document.getElementById("iOut").innerHTML = result.length > 0 ? result[0].answer : defaultText;
})
<div>
  <p1 id="iOut"></p1>
</div>
<form id="inputForm">
  <div>
    <input id="uIn" value="" />
  </div>
  <button>SUBMIT</button>
</form>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • I have another issue with the code. I have one code looking for GOOD and replies "That's good". Then there is another code looking for GOODBYE to reply "Bye" but instead it's replying "That's good". – One Amaro Aug 31 '21 at 06:27
  • It always help to post complete examples. Includes will find strings. Now you are taking words and we will need regular expressions – mplungjan Aug 31 '21 at 06:42
  • Or put the test for the longest word first. I'll update – mplungjan Aug 31 '21 at 06:44
  • I knew I could rearrange the order but I was hoping there was another way. I have the code in alphabetical order to make it easier to edit. Looks like I'll have to rearrange all 280 lines. – One Amaro Aug 31 '21 at 07:00
  • See updated version with an object and regular expression – mplungjan Aug 31 '21 at 09:30
1

You will want to use .includes() and not .contains().

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String

I'd recommend getting comfortable with Chrome's Developer Tools. For example, pull up a browser and enter "xyz". You will see various methods available, and contains() is not on the list.

Also, as @mplungjan pointed out, there are other problems here.

"Hi" || "H" evaluates to "Hi". So "HI" is entirely ignored here.

You could write finalKey.includes("Hi") || finalKey.includes("H")) instead, but this would get cumbersome as you add other conditions.

A better approach would be to use functional programming along these lines:

const wordsToTest = ['FOO', 'BAR'];
if (wordsToTest.find(word => finalKey.includes(word))) {
Scott Schafer
  • 487
  • 3
  • 14
0

I was made aware that i made a fundemental mistake in my previous answer, so i came up with another solution. With this approach you will not have to make multiple if/else statements, however simply add new object to the array, i hope it is pretty self explanatory when looking at it :)

<html>
<div>
  <p1 id="iOut"></p1>
</div>
<div>
  <input id="uIn" value=""></input>
</div>
<button onclick="regis()">SUBMIT</button>

<script>


  function regis() {

    let key = document.getElementById("uIn").value;
    let finalKey = key.toUpperCase();
    let match = false;

    // Words to test for 
    autoComplete = [
        { // Hey
            response: "hey",
            input: [
                'HI',
                'H',
            ]
        },
        { // Bye
            response: "Bye",
            input: [
                'BYE',
                'GOODBYE',
            ]
        }
    ]

    for (potentialMatch of autoComplete){
        for (input of potentialMatch.input){
            if (input === finalKey){
                document.getElementById("iOut").innerHTML = potentialMatch.response;
                match = true;
            }
        }
    }

    if (match === false)
        document.getElementById("iOut").innerHTML = " Try again";
    }
    
</script>

</html>
Noex98
  • 166
  • 6
  • If your goal is to learn/practice JavaScript, you're on your way. This is fine. But generally, the less code you have to write the better, and the more you can make your code data-driven the better. Your list of responses might eventually come from a database, etc. So you could more succinctly write this as: const inputToResponses = {'HI': 'hey, 'H': 'hey', 'BYE': 'Bye", 'GOODBYE': 'Bye'}; document.getElementById("iOut").innerHTML = inputToResponses[finalKey.toUpperCase()] || 'Try again'; Eventually you probably should look into a framework like React, Vue, etc. – Scott Schafer Aug 30 '21 at 00:25
  • Thank you. I tried out your code but I need it to be able to recognize the word within a sentence. If I type "They said hi", it doesn't recognize the "hi". – One Amaro Aug 31 '21 at 06:33