Malcolm Salvador
Malcolm Salvador

Reputation: 1566

jQuery .change() function must Fire only once

At my page I have a <select> tag named #boxID. next to it is a div named "wholeThingBody" that is hidden via jQuery.

<select id='boxID'>
  <option value='option1'> option1</option>
  <option value='option2'> option2</option> 
</select>

<div id='wholeThingBody'>
     Some content to permanently display once .change has been fired once
</div>

What I need is to have the user click on the <select> just once to show the hidden <DIV> the problem though is that when the user selects another option in the select, the DIV hides again. (it sort of toggles)

How can I make it so that when the user fires .change only once? I tried changing the ID but it doesn't work

$("#boxID").change(function () { 
        $(this).next().slideToggle(300); //show the content of div #wholeThingBody
        $(this).id = "okna"; //attempt to prevent wholeThingBody from toggle hiding
     });
    $("#wholeThingBody").hide(); 

Upvotes: 0

Views: 194

Answers (5)

Sven van den Boogaart
Sven van den Boogaart

Reputation: 12325

 //var to remember if its fired before.
 var fired = false;
 $("#boxID").change(function () { 
      if(!fired){
         $(this).next().slideToggle(300); //show the content of div #wholeThingBody
         $(this).id = "okna"; 
         fired = true;
    }
 });
$("#wholeThingBody").hide(); 

Upvotes: 4

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34234

There are several ways to do this:

  1. Use slideDown (the best way):

    $("#boxID").change(function () { 
        $(this).next().slideDown(300);
    });
    $("#wholeThingBody").hide(); 
    
  2. Remove listener:

    $("#boxID").on('change', function() {
        $(this).next().toggleSlide(300);
        $("#boxID").off('change');
    });
    $("#wholeThingBody").hide(); 
    
  3. As for me, I would do this with CSS classes.

    CSS:

    #wholeThingBody {
        display: none;
    }
    
    #wholeThingBody.active { 
        display: block;
    }
    

    JS:

    $("#boxID").on('change', function() {
        $(this).next().addClass('active'); // It will add a class only once
    });
    

By the way, for the future, if you want to change the ID of a DOM element, then do this

this.id = "okna";

instead of

$(this).id = "okna";

Because id is a property of DOM-element, not jQuery-property

Upvotes: 1

guest271314
guest271314

Reputation: 1

Try utilizing $.Callbacks("once") , callbacks.fireWith()

var callbacks = $.Callbacks("once");
var fn = function() {
  $(this).next().slideToggle(300); //show the content of div #wholeThingBody
};
callbacks.add(fn);
$("#boxID").change(function() {
  callbacks.fireWith(this);
});
$("#wholeThingBody").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id='boxID'>
  <option value='option1'>option1</option>
  <option value='option2'>option2</option>
</select>

<div id='wholeThingBody'>
  Some content to permanently display once .change has been fired once
</div>

Upvotes: 2

potatopeelings
potatopeelings

Reputation: 41075

Just use slideDown instead of slideToggle

$("#boxID").change(function () { 
    $(this).next().slideDown(300);
});

Upvotes: 2

Arun P Johny
Arun P Johny

Reputation: 388406

Use one() to register a handler which will be triggered only once, also since you want to display the element, instead of using slideToggle() use slideDown() like

$("#boxID").one('change', function() {
  $(this).next().slideDown(300); //show the content of div #wholeThingBody
});
$("#wholeThingBody").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id='boxID'>
  <option value='option1'>option1</option>
  <option value='option2'>option2</option>
</select>

<div id='wholeThingBody'>
  Some content to permanently display once .change has been fired once
</div>

Upvotes: 3

Related Questions