helo
helo

Reputation: 13

Javascript dynamicly created elements with events

I'm trying to create a form dynamically with javascript and jQuery. The form has some jQuery animations which are triggered by clicks on checkbox input elements.

Here's some of the page HTML after the page loads (before creating any dynamic elements):

<td id="escalationTimeout">
  <div>
    <div class="div-formContainer" style="width: 195px;">
      <label title="tooltip text">
        <input type="checkbox" style="position: relative; top: 2px;" onclick="cbtoggle(this); slideUpDown(this);"> checkbox text
      </label>
    </div>
    <div class="div-inline-block" style="display: none;">
      <input type="text" size="3" name="value1" id="value1" value="" style="background-color: AliceBlue;"> minutes
    </div>
    <div style="display: none;">
       <!-- some other stuff here, not so important for this question -->
    </div>
  </div>
</td>

Here are the two JS functions referenced in the above code:

function cbtoggle(obj) {
  if ( jQuery(obj).is(':checked') ) {
    jQuery(obj).parent().parent().next().fadeIn(300);
  } else {
    jQuery(obj).parent().parent().next().fadeOut(300);
  }
}
function slideUpDown(obj) {
  jQuery(obj).attr("disabled", true);
  if ( jQuery(obj).is(':checked') ) {
    jQuery(obj).parent().parent().next().next().slideDown(300,function() { jQuery(obj).removeAttr("disabled"); } );
  } else {
    jQuery(obj).parent().parent().next().next().slideUp(300,function() { jQuery(obj).removeAttr("disabled"); } );
  }
}

For the static section in the first code block, when the checkbox is clicked, a div fades in and another div under it slides into view. I used jQuery functions to make this work. For the staticly created verstion, it works completely as expected. Let me know if further explanation is required.

What I am trying to do is duplicate this section at run time via JS so that the user can have more sections like this to fill in if they want. See the code below which creates a duplicate of this section and appends it to the parent div (id="escalationTimeout"):

// This is where we will insert this whole thing when it's done being created
var appendToElement = document.getElementById("escalationTimeout");

// Create the master div wrapper for this new section
var newTopElement = document.createElement("DIV");

// Create the checkbox
var newChildElement = document.createElement("INPUT");
newChildElement.type = "checkbox";
jQuery(newChildElement).css("position", "relative");
jQuery(newChildElement).css("top", "2px");
newChildElement.onClick = function() { 
              cbtoggle(this); 
              slideUpDown(this);
               };

// Create the label for the checkbox
var newElement = document.createElement("LABEL");
jQuery(newElement).attr("title", "tooltip text");

// Append the checkbox and the text node to the label tags
newElement.appendChild(newChildElement);
newChildElement = document.createTextNode(" checkbox text");
newElement.appendChild(newChildElement);
newChildElement = newElement;

// Create the div wrapper for the label and its checkbox
newElement = document.createElement("DIV");
jQuery(newElement).addClass("div-formContainer");
jQuery(newElement).css("width", "195px");

// Append the label into the div wrapper
newElement.appendChild(newChildElement);
// Append the div wrapper into the master div wrapper
newTopElement.appendChild(newElement);

// Create the fade in-out section
newChildElement = document.createElement("INPUT");
newChildElement.type = "text";
newChildElement.size = "3";
jQuery(newChildElement).css("backgroundColor", "AliceBlue");

// Create the div wrapper for this text input box
newElement = document.createElement("DIV");
jQuery(newElement).addClass("div-inline-block");
jQuery(newElement).css("display", "none");
// Append into the div wrapper
newElement.appendChild(newChildElement);
newChildElement = document.createTextNode(" minutes");
newElement.appendChild(newChildElement);
// Append the div wrapper into the master div wrapper
newTopElement.appendChild(newElement);

// Create the slide up/down section
newElement = document.createElement("DIV");
jQuery(newElement).css("display", "none");
newChildElement = document.createTextNode("Some other stuff here");
newElement.appendChild(newChildElement);

// Append into the master div wrapper for this new section
newTopElement.appendChild(newElement);

// Finally, append into the existing div
appendToElement.appendChild(newTopElement);

If I run the above code, it results in the following HTML block:

<div>
  <div class="div-formContainer" style="width: 195px;">
    <label title="tooltip text">
      <input type="checkbox" style="position: relative; top: 2px;"> checkbox text
    </label>
  </div>
  <div class="div-inline-block" style="display: none;">
    <input type="text" size="3" style="background-color: rgb(240, 248, 255);"> minutes
  </div>
  <div style="display: none;">
    Some other stuff here
  </div>
</div>

It contains no onclick="cbtoggle(this); slideUpDown(this);" in the first input tag (checkbox) as I expect it to, and clicking the checkbox has no effect.

This section in particular does not work:

newChildElement.onClick = function() { 
                            cbtoggle(this); 
                            slideUpDown(this);
                           };

I also tried this instead of the above but not only does it NOT work, it also disables the checkbox:

newChildElement.addEventListener("click", cbtoggle(newChildElement));
newChildElement.addEventListener("click", slideUpDown(newChildElement));

Can anyone explain where I am going wrong? Thanks in advance.

Upvotes: 1

Views: 59

Answers (1)

Mouradif
Mouradif

Reputation: 2694

Try this :

newChildElement.addEventListener("click", function(){
    cbtoggle(this);
    slideUpDown(this);
});

the callback function of an addEventListener is not just any function you want to throw, it's a specific type that uses an Event as argument. Here, you don't need an argument but sometimes it comes handy to use it. For example you could see things like that :

formElement.addEventListener('submit', function(e){
    // Prevent the normal behavious of submitting the form (aka loading the action target page)
    e.preventDefault();
});

Upvotes: 1

Related Questions