onClick does not workon first click

Viewed 244

I'm trying to let a button element switch its text between 'Follow' and 'Unfollow', but why isn't the Javascript reacting on the first click on the button?

HTML:

<form method="post">
    <button class="follow" onclick="this.innerHTML = follow_test(this.innerHTML)">

        Follow

    </button>
</form>

JavaScript:

    function follow_test(string) {
        if (string === 'Follow') { return ('Unfollow'); } else { return('Follow'); }
    }
6 Answers

As @Slaks pointed out, the reason was because of the white-space in your button text which caused the else statement to run instead since " string " is not strictly equal ( === ) to "string".

You can just use the innerText property which ignores white-space instead of the innerHTML property like this:

/* JavaScript */
var btn = document.querySelector("button");

function follow_test(string) { 
    let text = string.target;

    if (text.innerText === "Follow") {
        text.innerText = "Unfollow";
    } else {
        text.innerText = "Follow";
    }    
}

btn.addEventListener("click", follow_test);
<!-- HTML -->
<form method="post">
    <button type="button" class="follow"> // added 'type="button"' to prevent page reload for example's sake
        Follow
    </button>
</form>


Or if you prefer sticking with the innerHTML property or want to use the textContent property instead, you can just use the trim() method on the button string to remove all white-space before and after the string like this:

/* JavaScript */
var btn = document.querySelector("button");

function follow_test(string) { 
    let text = string.target;
    
    if ((text.innerHTML).trim() === "Follow") {
        text.innerHTML = "Unfollow"; 
    } else {
        text.innerHTML = "Follow";
    }
    
}

btn.addEventListener("click", follow_test);
<!-- HTML -->
<form method="post">
    <button type="button" class="follow"> // added 'type="button"' to prevent page reload for example's sake
        Follow
    </button>
</form>

There are two issues here;

First, the default "submit" behaivor of the <button> element will be taking affect during user click, which in the case of the <button> will cause the browser to reload and refresh the page. As a result, the expected behaivor won't be observed due to the page reload.

To prevent the page reload behavior you can simply return false; in the event handler:

<button onclick="return false;">
Return false stops page reload on button click
</button>

The second issue is that the input string passed to follow_test() needs to be santized (ie removing whitespaces) to ensure that that string === 'Follow' evaluates true so that Unfollow is shown immediatly after the first click. This can be achieved via the trim() method:

function follow_test(string) {
  if (string.trim() === 'Follow') {
    return ('Unfollow');
  } else {
    return ('Follow');
  }
}
<form method="post">
  <button class="follow" onclick="this.innerHTML = follow_test(this.innerHTML); return false;">

        Follow

    </button>
</form>

You can use .onclick. In a way, it's easier to understand :

var button = document.getElementsByClassName("follow")[0];

button.onclick = function(e) { 
  if(button.textContent == "Follow") { button.innerText = "Unfollow" } 
  else { button.innerText = "Follow" }

}
<button class="follow">Follow</button>

The problem is whitespace, try

Javascript

function follow_test(string) {
   if (string.indexOf('Follow')!== -1) { 
      return ('Unfollow'); 
   } else { 
      return('Follow');
   }
}

or you could change your HTML to the following and use innerText which will remove the white space and make your current function work:

HTML

<form method="post">
   <button class="follow" onclick="this.innerText = follow_test(this.innerText)">
   Follow
   </button>
</form>

OR

It might be better to use a class (or function with closure) to check the state of the button in order to toggle as checking the state or the HTML is dangerous, anything else in the code could ultimately alter it and break the functionality

Something like this:

Javascript

class toggleFollowState {
   toggle(){
      this.state = !this.state
      return this.getState()
   }
   getState(){
      return this.state ? 'Unfollow' : 'Follow'
   }
}

const followState = new toggleFollowState()
console.log(followState.toggle())
// logs true
console.log(followState.toggle())
// logs false
console.log(followState.getState())
// logs false

now you can set the HTML up like this

HTML

<form method="post">
   <button class="follow" onclick="this.innerHTML = followState.toggle()">
   Follow
   </button>
</form>

Happy coding!

Please try this below code.

<form method="post">
    <button class="follow" type="button" onclick="if(this.innerHTML == 'unFollow'){ this.innerHTML='Follow';}else{this.innerHTML='unFollow';};return false">
        Follow
    </button>
</form>

Try this :

<!DOCTYPE html>
<html>
    <body>

        <button id="toggle" onclick="myFunction()">Follow</button>

        <script>

            function myFunction() {
                var change = document.getElementById("toggle");
                if (change.innerHTML == "Follow")
                {
                    change.innerHTML = "Unfollow";
                }
                else {
                    change.innerHTML = "Follow";
                }
            }

        </script>
    </body>
</html>
Related