Ciasto piekarz
Ciasto piekarz

Reputation: 8277

show hide html element and update button text

I am not sure if this question has been asked before but I am pretty new to Javascript and I was trying this example:

I am trying to change text of button on show/hide of the fieldSet but button setting button text doesnt work properly.

$(window).on("load", function() {
  $('.indoor').slideDown();
  $('.outdoor').slideDown();
});

$(document).ready(function(){
    $(".togOutBtn").click(function(){
        $(".outdoor").toggle(1000);
    });
    $(".togIndorBtn").click(function(){
        $(".indoor").toggle(1000);
    });
});

function btnToggle(elem, text) {
  if (elem.value == "") {
    elem.value = "Hide " + text;
  }

  if (elem.value == "Hide") {
    elem.value = "Show " + text;
    document.getElementById("togOutBtn").innerHTML = elem.value;
  } else {
    elem.value = "Hide " + text;
    document.getElementById("togOutBtn").innerHTML = elem.value;
  }


}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<button onclick="return btnToggle(this, 'Outdoors');" class="togOutBtn" id="togOutBtn">Hide Outdoors</button>
<fieldset class="outdoor" style="display: none;">
  <legend>Outdoors</legend>
  Temperature:
  <div id="Outtemp"></div>
  Humidity:
  <div id="Outhumid"></div>
  Feels lile:
  <div id="OutheadIndex"></div>
  <button onclick="waterPlant1()">Water the Plant</button>
</fieldset>
<br>
<button onclick="btnToggle(this, 'Indoors');" class="togIndorBtn">Hide Indoors</button>
<fieldset class="indoor" style="display: none;">
  <legend>Drawing Room</legend>
  Temperature: 23* C
  <br>Humidity: 12%
  <br>Feels lile:18* C
  <br>
</fieldset>

Also the first field set of Outdoors jitters while show hide compared to the lower one of indoor goes very smooth.

Upvotes: 1

Views: 213

Answers (4)

KOSSENTINI Anis
KOSSENTINI Anis

Reputation: 36

Try this one with Regex

$(window).on("load", function() {
  $('.indoor').slideDown();
  $('.outdoor').slideDown();
});

$(document).ready(function(){
	var btnOutState = 0;
	var btnInState = 0;
    $(".togOutBtn").click(function(){
        $(".outdoor").toggle(1000, function(){btnOutState = !btnOutState; btnChangeValue(".togOutBtn", btnOutState)});
    });
    $(".togIndorBtn").click(function(){
        $(".indoor").toggle(1000, function(){btnInState = !btnInState; btnChangeValue(".togIndorBtn", btnInState)});
    });
});

function btnChangeValue(elem, state) {
var pattern = "";
var replace = "";
	if(state){
		pattern = /Hide/g;
		replace = "Show";
	}else {
		pattern = /Show/g;
		replace = "Hide";
	}
	
	newText = $(elem).html();
	$(elem).html(newText.replace(pattern, replace));
}
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<button class="togOutBtn" id="togOutBtn">Hide Outdoors</button>
<fieldset class="outdoor" style="display: none;">
  <legend>Outdoors</legend>
  Temperature:
  <div id="Outtemp"></div>
  Humidity:
  <div id="Outhumid"></div>
  Feels lile:
  <div id="OutheadIndex"></div>
  <button onclick="waterPlant1()">Water the Plant</button>
</fieldset>
<br>
<button class="togIndorBtn">Hide Indoors</button>
<fieldset class="indoor" style="display: none;">
  <legend>Drawing Room</legend>
  Temperature: 23* C
  <br>Humidity: 12%
  <br>Feels lile:18* C
  <br>
</fieldset>

Upvotes: 0

Lucas Shanley
Lucas Shanley

Reputation: 406

This should help you get much closer to what you are looking to accomplish! Please let me know if you have any questions.

The advantage with this method is that you bind the two elements by setting the id of the button to the data-bind of the fieldset. You should never need to change the javascript this will simple scale indefinitely.

Edit: Added a validation so that it only attempts to operate on the fieldset IF it finds one. Whats neat is that now you an also bind multiple fieldsets to the single input if you set multiple data-binds to the same value.

$('fieldset[data-bind]').slideDown();

$('input[type="button"]').on('click',function(){
  let $id = this.id,
      $this = this;
      $bind= '[data-bind="' + $id + '"]';
  
  if($bind.length){
    $( $bind).toggle(1000,function(){
      $this.value.indexOf('Hide') > -1 ?
         $this.value = $this.value.replace('Hide','Show') :
         $this.value = $this.value.replace('Show','Hide');
    });
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<input type="button" id="outdoorBtn" value="Hide Outdoors">
<fieldset data-bind="outdoorBtn" style="display: none;">
  <legend>Outdoors</legend>
  Temperature:
  <div id="Outtemp"></div>
  Humidity:
  <div id="Outhumid"></div>
  Feels lile:
  <div id="OutheadIndex"></div>
  <button onclick="waterPlant1()">Water the Plant</button>
</fieldset>
<br>
<input type="button" id="indoorBtn" value="Hide Indoors">
<fieldset data-bind="indoorBtn" style="display: none;">
  <legend>Drawing Room</legend>
  Temperature: 23* C
  <br>Humidity: 12%
  <br>Feels lile:18* C
  <br>
</fieldset>

Upvotes: 1

KAD
KAD

Reputation: 11122

You can do this using callback of the toggle function and the visibility of the fieldset, no need to have a onclick attribute at the level of the button:

$(window).on("load", function() {
  $('.indoor').slideDown();
  $('.outdoor').slideDown();
});

$(document).ready(function(){
    $(".togOutBtn").click(function(){
        $(".outdoor").toggle(1000, function(){
           showHideFunc('togOutBtn', 'Out');
        });
    });

    $(".togIndorBtn").click(function(){
        $(".indoor").toggle(1000, function(){
           showHideFunc('togIndorBtn', 'In');
		});
	});
});

function showHideFunc(elementClass, inOut)
{
  $("." + elementClass).text(function(){ 
                return ($(this).next('fieldset').is(':visible') ) 
                ? 'Hide ' + inOut + 'doors' : 'Show ' + inOut + 'doors' 
			});
}
#container1
{
  margin-bottom:10px
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="container1">
<button  class="togOutBtn" id="togOutBtn">Hide Outdoors</button>
<fieldset class="outdoor" style="display: none;">
  <legend>Outdoors</legend>
  Temperature:
  <div id="Outtemp"></div>
  Humidity:
  <div id="Outhumid"></div>
  Feels lile:
  <div id="OutheadIndex"></div>
  <button onclick="waterPlant1()">Water the Plant</button>
</fieldset>
  </div>
  
<div id="container2">
<button class="togIndorBtn">Hide Indoors</button>
<fieldset class="indoor" style="display: none;">
  <legend>Drawing Room</legend>
  Temperature: 23* C
  <br>Humidity: 12%
  <br>Feels lile:18* C
  <br>
</fieldset>
  
   </div>

Upvotes: 0

CodeCabin
CodeCabin

Reputation: 166

Your problem is your if statement inside btnToggle:

if (elem.value == "Hide") {

Here you are saying "if the button value is "Hide". It's never going to be Hide. It's going to be "Hide Outdoors".

You fix that by going like this:

if (elem.value == "Hide " +text) {

You then get the statement "if value = 'Hide Outdoors'" instead of "if value= 'Hide'"

working function:

function btnToggle(elem, text) {
  if (elem.value == "") {
    elem.value = "Hide " + text;
  }
  alert(elem.value);
  if (elem.value == "Hide " +text) {
    elem.value = "Show " + text;
    document.getElementById("togOutBtn").innerHTML = elem.value;
  } else {
    elem.value = "Hide " + text;
    document.getElementById("togOutBtn").innerHTML = elem.value;
  }
}

Upvotes: 0

Related Questions