I have some JS that dynamically creates a new div (inputs inside of a form). It works great. I separately have some jquery that checks a dropdown input, and shows a separate div if a specific selection is clicked. It works great.
If I try to use the jquery to show a separate div inside one of the dynamically created ones, it does not work. The first instance of it does work, but none of the dynamically created ones. After searching around, it looks like I need a delegation, but I can't seem to figure it out for my specific situation.
The JSFiddle: http://jsfiddle.net/Xyzeg/ (change the "CPI" dropdown in the first field, for the event to go off). The fiddle includes the other JS for dynamically creating the divs.
Any pointers would be appreciated.
<div style="float:left">
<div id='dynamicInput'>Pension 1: Amount: $<input type='text' name='adjustmentInputs[]' value='0' size='13' maxlength='20'>Start Year:
<input type='text' name='adjustmentInputs[]' value='2032' size='5' maxlength='6'>
<input type='hidden' name='adjustmentInputs[]' value='2100'>
<select name='adjustmentInputs[]'>
<option value='InflationAdjusted'>Inflation Adjusted</option>
<option value='NotInflationAdjusted'>Not Inflation Adjusted</option>
</select>by
<select name='adjustmentInputs[]' class='pensionAdjustment1'>
<option value='CPI'>CPI</option>
<option value='constantPercentage'>Constant %</option>
</select>
<div id='constantPercentageText1' style='display: none'># <input type='text' name='adjustmentInputs[]' value='3' size='5' maxlength='6'>%</div>
</div>
<input type="button" value="Add another Portfolio Adjustment" onClick="addInput('dynamicInput');">
</div>
<script>
$("[class*=pensionAdjustment]").change(function() {
var n = $(this).attr('class').replace('pensionAdjustment', '');
var newId = "constantPercentageText" + n;
var selectedItem = $(this).children('option:selected');
if ($(this).val() == 'constantPercentage') {
$("#constantPercentageText" + n).css('display', 'inline');
$("#constantPercentageText" + n).show();
} else {
$("#constantPercentageText" + n).css('display', 'none');
}
});
</script>
You need to delegate with newly created elements!
Change this line
$("[class*=pensionAdjustment]").change(function() {
to
$(document).on('change',"[class*=pensionAdjustment]", function() {
You can use
$(document).on('change', '[class*=pensionAdjustment]', function(){
// your code
});
It would be better if you use a parent div, instead of document.
Update : The elements you are injection dynamically to the DOM were not present when the event was registered, so new elements are not firing the event. Using event delegation, (registering the event on a parent element) this could be solved because when any element fires an event, the event bubbles up to the last element (upwards) it can find and this way the parent element is being triggered but behind the scene, something like following is happening
e = e || window.event;
var el = e.target || e.srcElement;
You may check this.
You have to bind the event to a parent element, then filter down to the one you want. This way it doesn't matter when the element is added, it will always work. This is called delegation. You delegate the task of handling the event to another element.
$(document).on('change', "[class*=pensionAdjustment]", function(){
var n = $(this).attr('class').replace('pensionAdjustment', '');
var newId = "constantPercentageText" + n;
var selectedItem = $(this).children('option:selected');
if ($(this).val() == 'constantPercentage') {
$("#constantPercentageText" + n).css('display', 'inline');
$("#constantPercentageText" + n).show();
} else {
$("#constantPercentageText" + n).css('display', 'none');
}
});
Related
I am working on JavaScript project and I am having a problem with click event and retrieving the correct information about the element clicked. I am relatively new to the JavaScript.
The real code I am working on is fairly complex however I am posting only a chunk of code to illustrate my problem.
function App(){
this.name = "New App";
}
App.prototype.createDIV = function() {
var h = "<div class='clickable' id='idToShow'><div class='name' id='notToShow'>" + this.name + "</div></div>";
$('#content').html(h);
}
App.prototype.showID = function(e) {
if (e.target.id == 'idToShow') {
alert(this.name); // this doesn't display, because incorrect ID is retrieved
}
}
$(document).ready(function() {
var newApp = new App();
$("input#btn").click(newApp.createDIV.bind(newApp));
$("div").on("click", ".clickable", newApp.showID.bind(newApp));
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<div id="content"></div>
<input type="button" id="btn" value="CLICK">
I have a object in the app with number of prototypes. On document load, object is constructed, events are attached to elements and bind to object. Clicking the button, new set of div results are created dynamically.
Now this is where it starts to go wrong for me. I attached an event to div with the class CLICKABLE and I would like to retrieve the id of that particular DIV element (id='idToShow'); however I keep retrieving the id of the following DIV (id='notToShow').
I might not fully understand why is this happening and what to do to prevent it in order to get the correct ID.
Try using if (e.currentTarget.id == 'idToShow') instead of if (e.target.id == 'idToShow').
How to add only selected class and remove other class which is selected before?
<html>
<select name="Button-Style" id="Button-Style" style="width:100%;">
<option value="Sun-Flower">Sun Flower</option>
<option value="orange-flat">orange-flat</option>
</select>
<script>
$(document).ready(function(){
$('#Button-Style').change(function(){
if($(this).val() == 'sun-flower'){
$("#$id>input").addClass('sun-flower-button');
}
else if($(this).val() == 'orange-flat'){
$("#" + id).addClass('orange-flat-button');
}
else{
}
});
});
</script>
</html>
I want to add only one class at a time.
You can do it like this with jquery.
$('.selected_check').change(function () {
if ($(this).is(":checked")) {
var x = $(this).closest('tr').prop('id');
var id = "#" + x;
$(id).removeClass('td_bgcolor');
$(id).addClass('highlight_row');
} else {
var y = $(this).closest('tr').prop('id');
var id = "#" + y;
$(id).removeClass('highlight_row');
$(id).addClass('td_bgcolor');
}
});
simply use removeClass and addClass cheers!!
Use removeClass() function in jQuery.
As for example;
HTML:
<div id="adiv" class="1st-class"></div>
Now jQuery;
$("#adiv").addClass("2nd-div"); // This 'll add 2nd-class with the div
$("#adiv").removeClass("1st-div"); //This 'll remove the 1st-class from the div.
Now if you want to remove all previous added class simply do;
$("#adiv").removeClass(); //removeClass without any argument removes all class
I'm having some difficulty understanding your question, but I think I get the gist of it.
Say you have the following HTML:
<div class="menu">
<div class="menu--option">Option 1</div>
<div class="menu--option">Option 2</div>
<div class="menu--option">Option 3</div>
</div>
Whenever someone clicks on an option, we want to add the class s-active to it, while making sure it is the only one with that class. You will want to do something like this:
// First, we listen to the click event.
$("menu--option").click(function () {
// When it fires, we select all of the menu options,
// and iterate over them, removing '.s-active' from it
// if the element has the class.
$("menu--option").each(function () {
$(this).removeClass("s-active");
});
// Finally, we add '.s-active' to the element that was clicked.
$(this).addClass("s-active");
}
Hopefully this was helpful!
You can code it in this way!
$('#Button-Style').change(function(){
$(this).removeClass();
if($(this).val()=="your_option_value"){
$(this).addClass("new_class");}
}
I am not sure to selection of element on which you are adding class but you can use removeClass() without supplying parameter to function to remove all previously applied class to item and then add your class as you are doing using addClass()
if($(this).val() == 'sun-flower'){
$("#$id>input").removeClass(); // Remove all classes .. although please check selector
$("#$id>input").addClass('sun-flower-button');
}
else if($(this).val() == 'orange-flat'){
$("#" + id).removeClass();
$("#" + id).addClass('orange-flat-button');
}
Also may I suggest passing class name directly from option values in select item. Then no need for extra if condition .
<select name="Button-Style" id="Button-Style" style="width:100%;">
<option value="Sun-Flower-button">Sun Flower</option>
<option value="orange-flat-button">orange-flat</option>
</select>
and in jquery
$('#Button-Style').change(function(){
var className = $(this).val();
$('#inputElement').removeClass();
$('#inputElement').addClass(className);
});
If you are trying to remove all previous classes and add a new one, you can use jQuery's toggleClass function.
I've been going through my dynamically added code and changing everything that was using .click() to use .on("click") and its been working great but now I've run into something that I am not sure how to convert to dynamically added compatible.
Here is the code: This is a function in javascript that is called when a button named "Add" or "Remove" is clicked (these buttons are also dynamically added after another button is clicked)
function row_add_remove(sname, snum, count, type) {
if (type == "add") {
var selectbox = '<select id="qty_'+snum+'_'+count+'" name="qty_'+snum+'_'+count+'">';
for (i=1;i<16;i++){selectbox += '<option value='+i+'>'+i+'</option>';}
selectbox += '</select>';
if (count > 1) {
$("#tr_"+sname+"_"+(count-1)).after('<tr id="tr_'+sname+'_'+count+'"><td>'+selectbox+' X <input type=text id="item_'+sname+'_'+count+'" name="item_'+snum+'_'+count+'" size="70" placeholder="Item '+count+'" /></td></tr>');
$("#toprow"+snum+"_count").html("("+count+")");
}
}
if (type == "remove") {
if (count == 1) {
$("#"+sname).hide();
$("#toprow"+snum+"_count").html("");
$("#td_"+sname+"_"+count).remove();
$("#ph_order_div").show();
count--;
}
if (count > 1) {
$("#tr_"+sname+"_"+count).remove();
count--;
$("#toprow"+snum+"_count").html("("+count+")");
}
if (count < 0) {count = 0;}
}
}
The problem (I think, maybe its more than this) is the .after() doesn't fire. Now i'm not sure if the problem lies with that or with the whole code but when I click the Add button its not adding another TR after the one that is shown by default.
This code works great when NOT dynamically added so can anyone help me with what I need to change to get the above function to work when the buttons that call it and the TR's that it tries to modify are dynamically added?
Here is the code that is fired when the buttons are clicked:
whatmeatfield = $("#meat_field_count").html();
$(document).on("click", "#add_btn_1", function() {
if (whatmeatfield <= 0) {whatmeatfield = 1;}
whatmeatfield++;
row_add_remove("meatseafood",1,whatmeatfield,"add");
});
$(document).on("click", "#remove_btn_1", function() {
row_add_remove("meatseafood",1,whatmeatfield,"remove");
whatmeatfield--;
if (whatmeatfield <=0) {whatmeatfield = 1;}
});
in your .after(), there is typo mistake in <input type=text there should be quote like <input type="text"
You have not define whatmeatfield variable. it should be
var whatmeatfield
Also you are directly passing html of some element id, you need to parse it to integer. like
var whatmeatfield = parseInt($("#meat_field_count").html()) ;
This may help you to solve your issues
The problem may occur becouse of two things.
You're using id selector and you're porobably adding another button with the same id and as far as html spec says id should be unique.
What can you do?
Change ID to CLASS.
The problem occurs becouse you're changing the id to schema like #remove_btn_1, #remove_btn_2, #remove_btn_3 and therefore you do not have any handler for this buttons.
What can you do?
Change selector from "#remove_btn_1" to "[id*=remove_btn_]"
Of course same with #add_btn_
Post me back if it was helpful.
Problem: Creating an Element on a button click then attaching a click event to the new element.
I've had this issue several times and I always seem to find a work around but never get to the root of the issue. Take a look a the code:
HTML:
<select>
<option>567</option>
<option>789</option>
</select>
<input id="Add" value="Add" type="button"> <input id="remove" value="Remove" type="button">
<div id="container">
<span class="item">123</span>
<br/>
<span class="item">456</span>
<br/>
</div>
JavaScript
$(".item").click(function () {
if ($("#container span").hasClass("selected")) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
$("add").click(function() {
//Finds Selected option from the Select
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = choice;//Value from Option
newSpan.className = "item";
var divList = $("#container");
divList.appendChild(newSpan);//I've tried using Jquery's Add method with no success
//Deletes the selected option from the select
})
Here are some methods I've already tried:
Standard jQuery click on elements with class "item"
Including using the `live()` and `on()` methods
Setting inline `onclick` event after element creation
jQuery change event on the `#Container` that uses Bind method to bind click event handler
Caveat: I can not create another select list because we are using MVC and have had issues retrieving multiple values from a list box. So there are hidden elements that are generated that MVC is actually tied to.
Use $.on instead of your standard $.click in this case:
$("#container").on("click", ".item", function(){
if ( $("#container span").hasClass("selected") ) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
It looks to me like you want to move the .selected class around between .item elements. If this is the case, I would suggest doing this instead:
$("#container").on("click", ".item", function(){
$(this)
.addClass("selected")
.siblings()
.removeClass("selected");
});
Also note your $("add") should be $("#add") if you wish to bind to the element with the "add" ID. This section could also be re-written:
$("#add").click(function() {
$("<span>", { html: $("select").val() })
.addClass("item")
.appendTo("#container");
});
I'm trying to make radio buttons that when you have them active, it displays a dropdown. I can already make it display, but when I click on another radio button, it shows one, but doesn't hide the other...
Code:
<input type='radio' name='op' onchange='$("#ban_length").fadeToggle();'/>
<input type='radio' name='op' onchange='$("#rank_list").fadeToggle();'/>
JavaScript section:
$(document).ready(function() {
$('#op1').change(function(){
$("#ban_length").fadeIn();
$("#rank_list").fadeOut();
});
$('#op2').change(function(){
$("#ban_length").fadeOut();
$("#rank_list").fadeIn();
});
});
HTML:
<input type='radio' name='op' id='op1'/>
<input type='radio' name='op' id='op2'/>
<div id="ban_length">demo</div>
<div id="rank_list">demo</div>
Demo:
http://jsfiddle.net/b2UPt/1/
<input type='radio' name='op' onchange='$("#ban_length").fadeIn();$("#rank_list").fadeOut();'/>
<input type='radio' name='op' onchange='$("#rank_list").fadeIn();$("#ban_length").fadeOut();'/>
Though I would suggest removing the javascript from the elements themselves, giving them ids and adding the javascript to a separate script with $(theID).change(function(){....
Alternatively, you can use hide instead of fadeOut if you would like them to hide immediately.
And one last suggestion. If there are many of these and not just 2, I would add a shared class to each of the elements you are fading in. Then instead of hide on each element, just call $(".className").hide() to hide any that might be visible.
The change event only fires on the element that was clicked (i.e. the radio button that is now enabled). It isn't fired when a radio button is automatically disabled.
So you need to check all the radio buttons every time one of them triggers the change event. You need to be able to tell them apart, though, so start by giving them ids:
<input type="radio" name="op" id="radio_ban_length" />
<input type="radio" name="op" id="radio_rank_list" />
After that, you can use them to toggle the correct dropdowns:
$('input:radio').change(function() {
var id = $(this).attr("id");
if (id === "radio_ban_length") {
$("ban_length").fadeIn();
$("rank_list").fadeOut();
} else {
$("rank_list").fadeIn();
$("ban_length").fadeOut();
}
});
Alternatively, if you like a challenge or if you might have more than two radio's, you could use filter() and :checked to do something like this:
function getDropdownId(radioId) {
return '#' + radioId.replace(/^radio_/, '');
}
var radios = $('input:radio');
radios.change(function() {
// Checked radio's:
radios.filter(':checked').each(function(){
var id = getDropdownId($(this).attr('id'));
$(id).fadeIn();
});
// Unchecked radio's:
radios.filter(':not(:checked)').each(function(){
var id = getDropdownId($(this).attr('id'));
$(id).fadeOut();
});
});
Note that this method does rely on the id's of the radio buttons matching those of the dropdowns (e.g. radio_ban_length for ban_length).
Update: here is a live example: http://jsfiddle.net/55ANB/1/
add id="ban" and id="rank" to your radios
in your jquery section, add the click handler to the radio buttons
$(':radio').click(function() {
if ($(this).attr("id") == "ban") $("ban_length").fadeToggle();
if ($(this).attr("id") == "rank") $("rank_length").fadeToggle();
});