Skip to content
Advertisement

JavaScript function is always returning true where it should be false

My JavaScript function is always returning true whatever I write. The problem given wants me to validate that:

  1. space at beginning or at end are Not allowed.
  2. every character in the field must be a letter or a space (at most 1 space!) to seperate the words in the field (it’s about palindrome words, i already wrote its function estPalindrome(word)).
  3. the button “chercher” must be enabled once 1 word is valid.

I have also tried to replace phrase and len inside and outside the function. The results are terrible:

Inside it only alerts “true” when I blur out with empty field outside it alerts “true” every time, whatever I write.

Note: I am NOT allowed to change anything in HTML code.

var phrase = document.getElementById('phrase').value;
var len = phrase.length;

function estPhrase() {
  var verify = true;

  for (i = 0; i < len; i++) {
    let ch = phrase.charAt(i);
    let isLetter = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == ' ';
    
    if (!isLetter || (ch == ' ' && phrase.charAt(i + 1) == ' ') || phrase.charAt(0) == ' ' || phrase.charAt(len - 1) == ' ')

      verify = false;
  }

  if (len > 0)
    butt.removeAttribute('disabled');

  var words = new Array();

  for (i = 0, j = 0; i < len; i++, j++) {
    ch = phrase.charAt(i);
    words[j] = "";

    while (ch != ' ') {
      words[j] += ch;
      i++;
    }

    if (estPalindrome(words[j]) == true)
      count++;
  }

  console.log(verify);
}
<div> Phrase: <input type="text" id="phrase" onblur="estPhrase()" size="50" /></div>

Advertisement

Answer

As the html can’t be changed and the function estPhrase() is called directly from the <input> element, then the phrase and len variables should be moved into the function body.

It was quite hard to refactor and debug your current code based on your current requirements. Certain segments of code were in need of simplification. Whilst I would not normally do this, it was just easier to re-write the majority of the function. I know this may not be desirable but doing so may introduce you to new techniques and Javascript functions whilst also improving code readability at the same time.

Not knowing the inner workings of your estPalindrome() function, for testing purposes I have return true in all cases. Returning false would only prevent the counter from incrementing.

One thing of note is what ‘should’ happen if verify becomes false. Should the verify flag be tested prior to splitting the phrase into individual words? If so, then it would abort the remainder of the function and not cause an error in your estPalindrone() function.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>title</title>
    </head>

    <body>
        <div> Phrase: <input type="text" id="phrase" onblur="estPhrase()" size="50"/></div>

        <button id="chercher" disabled>Chercher Button</button>
    </body>

    <script>
        function estPhrase() {
            let phrase = document.getElementById('phrase').value;
            let chercher = document.getElementById('chercher');
            let verify = true;

            // Check phrase does not contain a leading or trailing edge space.
            if (phrase.length !== phrase.trim().length) {
                verify = false;
            }

            // Check phrase does not contain more than one sequential space.
            if (phrase.includes('  ')) {
                verify = false;
            }

            // Check phrase only contains valid characters (a-z, A-Z, space).
            if (/[^a-zA-Z ]/.test(phrase)) {
                verify = false;
            }

            // Bail early on failure. It could also be performed within the above 'if' statements.
            // if (verify === false) {
            //     return;
            // }

            // Now the phrase has been validated, splitting the phrase
            // into words for individual consumption should be error free.
            let words = phrase.split(' ');
            let count = 0;

            // Pass the words one by one into the 'estPalindrone' function.
            for (let word in words) {
                if (estPalindrome(word) === true) {
                    count++;
                }
            }

            // Disable button if count is 0.
            if (count === 0) {
                chercher.setAttribute('disabled', '');
            } else {
                chercher.removeAttribute('disabled');
            }

            // Testing.
            console.log('Phrase: ' + phrase);
            console.log('Verify: ' + verify);
            console.log('Words: ' + words);
            console.log('Count: ' + count);
        }

        function estPalindrome(word) {
            // Do stuff with word...
            return true;
        }
    </script>
</html>
Advertisement