Dynamic add divs to html using js - javascript

I am trying to add html divs( with textfields) using button click.My form look like this :
On add size button click it add one row (Price and size ) and one add More item button click i want to add new area with name,price and size and so on.
HTML Code is :
<div class="clearfix"></div>
<div class="moreitems form-group" style="border:1px solid #ccc;height:200px;display:none;">
</div>
My js code is :
jQuery("#addmoreitems").click(function () {
var options = jQuery("#select1").html();
jQuery('.moreitems').css("display","block");
var fld = '<div class="clearfix"></div><div class="form-group"><div class="col-sm-3"><label for="" class="text-left control-label">Product Name :</label></div><div class="col-sm-4"><input type="text" class="required-entry form-control" name="pname[]" id="pname"></div></div></div>';
fld += '<div class="clearfix"></div><div class="form-group"><div class="col-sm-3"><label for="" class="text-left control-label">Price :</label></div><div class="col-sm-4"><input type="text" class="required-entry form-control" name="more_prices[]" id="prices"><select name="more_size[]" class="mysize">'+options+'</select></div></div>';
fld += '<div class="col-sm-4"><div class="col-sm-3" style="margin-top:15px;"><button type="button" id="addsize" class="btn btn-info">Add Size</button></div></div>';
jQuery('.moreitems').html(fld);
jQuery('.mysize').html(options);
});
});
But this code add first time.I want to add as many times the add more items button.Also on add more size button want to add price and size fields.

The problem is that you're using html() function which replaces the entire html contents, where in your situation you want to append() the HTML every time you click the button.
Change:
jQuery('.moreitems').html(fld);
To:
jQuery('.moreitems').append(fld);

Hi as i know the may the problem is in appending the using the .html() method.
here the difference between this two methods reference link given
http://www.slideshare.net/umarali1981/jqueryappend-vs-jqueryhtml
cause .html() overwrites the contents of the DIV. while .append() will add to the contents of the DIV. so use this and another thing to notify is that you should bind the 'click' event in-spite of using the only 'click' method like.
$("#addmoreitems").unbind('click').bind('click',function () {
// write your code here
});

Related

Jquery not detect click after append of element

i've made a sortable list with html5sortable library, where user have a category, where can add products inside, and can add other categories where to add products too.
The first one category is already displayed, and work fine when adding products, but if I add another category I can't add product on this category.
I've tried with "on" method instead of "click", as it should work on element created dinamically, but I think I'm using it in the wrong way.
Here is the HTML
<div class="container-categorie">
//THIS IS A CATEGORY ITEM, WITH ADD PRODUCT BUTTON INSIDE
<div class="category" id="categoria-1">
<input type="text" class="input-categoria" placeholder="NAME CATEGORY" autofocus="autofocus">
<div class="list" id="list-1">
//products will be added here
</div>
<div class="item-products add-product-container">
<div align="center" class="add-product-btn" id="addproduct-1">
+ add product
</div>
</div>
</div>
//END OF CATEGORY ITEM
<div class="add-categoria-container">
Nuova categoria
</div>
</div>
And here is the js code:
var i = 2;
$(".categoria").on('click', function() {
//to delegate the click I applied this event to "add product" button's container
});
//This add a product inside category div
$(".add-product-btn").click(function() {
var id_btn = $(this).attr("id");
var single_id = id_btn.substring(id_btn.indexOf("-") + 1);
$("#list-"+single_id).append('<div class="item-products">prova</div>');
sortable('.list');
});
//This should add a new category inside "container-categorie", with an "add product"
//button inside, to add products inside this new category
$(".add-categoria-container").click(function() {
$(".sortable-categorie").append('<div class="categoria"><input type="text" class="input-categoria" placeholder="NOME CATEGORIA PRODOTTI" autofocus="autofocus"><div class="list" id="list-'+i+'"></div><div class="item-products add-product-container"><div align="center" class="add-product-btn" id="addproduct-'+i+'">+ Aggiungi prodotto</div></div></div>');
sortable('.sortable-categorie');
});
Jquery can't listen to dynamically generated Elements directly, what you can do is you can provide parent element which is already there in DOM listen to them.
$("element which is already in DOM").on('click',"element to listen to", function() {
//Code here
});
$(".container-categorie").on('click',".categoria", function() {
//Code here
});
or you can directly listen to the body instead, but it is not preferable.
For Ref : https://api.jquery.com/on/#on-events-selector-data-handler
Try this
$(document).on('click',".your_class_name", function() {
//to delegate the click I applied this event to "add product" button's container
});
JQuery has no virtual DOM like Angular or React. That means JQ can't "see" the dynamically generated element. What you can do is using a onclick="functionYouWantToTrigger(someParameters)" directly in the HTML tag.

How do get my add to cart buttons to only use the value from that individual item?

I'm building a seed e-commerce site for my farmer friend to help build my portfolio and save hime some $$. I'm a beginner so it's been quite the learning experience.
Right now I'm having trouble with the number input fields that are used to an item's quantity before adding to the cart. I'm using the "id" tag, which I know is wrong, but I can't figure out what to use so that the value for one item doesn't affect the value of another item.
So my questions:
What do I use in my html to uniquely identify the value for each item/product?
How do I tweak my javascript to distinguish between each item's unique quantity?
Updated HTMl
<div class="container">
<div class="row">
<div class="col-sm-4">
<div class="panel panel-success">
<div class="panel-heading"><a href="Varieties
Grains/amaranth_hopireddye.html">Hopi Red Dye</a></div>
<div class="panel-body"><a href="Varieties
Grains/amaranth_hopireddye.html"><img
src="Images/amaranth_hopireddye.jpg" class="img-responsive"
style="width:100%" alt="Image"></a></div>
<div class="panel-footer">500 seeds per packet<br>$4.00 per
Packet</div>
<div class="panel-footer"><div align="center"><input type="number"
id="orderQty001" value="1" style="width: 50px; margin-right: 10px;"><a
href="#" class="productItem btn btn-primary center-block" data-
name="Hopi Red Dye " data-s="500 seeds" data-price="400" data-
id="001">Add to Cart</a></div></div>
</div>
</div>
<div class="col-sm-4">
<div class="panel panel-success">
<div class="panel-heading"><a href="Varieties
Grains/amaranth_dedosdedios.html">Dedos de Dios</a></div>
<div class="panel-body"><a href="Varieties
Grains/amaranth_dedosdedios.html"><img
src="Images/amaranth_dedosdedios.jpg" class="img-responsive"
style="width:100%" alt="Image"></a></div>
<div class="panel-footer">500 seeds per packet<br>$4.00 per
Packet</div>
<div class="panel-footer"><div align="center"><input type="number"
id="orderQty002" value="1" style="width: 50px; margin-right: 10px;"><a
href="#" class="productItem btn btn-primary center-block" data-
name="Dedos de Dios " data-s="500 seeds" data-price="400" data-
id="002">Add to Cart</a></div>
</div>
</div>
</div>
Updated Javascript:
var shopcart = [];
$(document).ready(function () {
outputCart();
$(".productItem").click(function (e) {
e.preventDefault();
var iteminfo = $(this.dataset)[0];
var inputId = "orderQty" + this.attr('data-id');
iteminfo.qty = document.getElementById(inputId).value;
var itemincart = false;
$.each(shopcart, function (index, value) {
//console.log(index + ' ' + value.id);
if (value.id == iteminfo.id) {
value.qty = parseInt(value.qty) + parseInt(iteminfo.qty);
itemincart = true;
}
})
if (!itemincart) {
shopcart.push(iteminfo);
}
sessionStorage["sca"] = JSON.stringify(shopcart);
outputCart();
})
I've also tried to assign a class and unique id to each element, but then I can't figure out how to get the unique user input in my javascript.
Make the ids unique.
One way to do this is to append the data-ids to each input id. For example id="orderQty001". Then in the JavaScript you can find the corresponding input based on the clicked element's data-id:
var inputId = "orderQty" + this.attr('data-id'); // 'this' is the clicked <a> element
iteminfo.qty = document.getElementById(inputId).value;
And the rest of the JavaScript could stay the same I think.
Edit (1/31): Since there are still problems I started a jsFiddle to run the code. Firstly, I found that this in the click handler is not a jQuery object, but a DOM element. As such, attr is not a function, and instead we must use getAttribute as follows:
var inputId = "orderQty" + this.getAttribute('data-id');
Next, I noticed a bug where the qty of the cart item was not getting set correctly. I found that the problem code was iteminfo.qty = document.getElementById(inputId).value;. This statement is a problem because it is manipulating the DOM earlier than we'd like. That is, it is setting the qty on the element immediately, instead of after we calculate the new qty. So instead we should declare a temporary variable to hold the input's value:
var qtyToAdd = document.getElementById(inputId).value;
Additionally, we must now set the iteminfo.qty before we add it to the cart for the first time:
if (!itemincart) {
iteminfo.qty = parseInt(qtyToAdd);
shopcart.push(iteminfo);
}
Here is the fiddle with these changes in place: https://jsfiddle.net/7vwyh03h/. The HTML was unchanged aside from formatting.
Edit (2/5): I've integrated my changes into your fiddle. All my previous updates edits are included. Updated fiddle:
https://jsfiddle.net/aougb72r/. When you click 'Add to Cart' the cart gets updated as you can see in the console and by checking the cart.
I changed one more thing, which was making iteminfo a clone of the dataset with:
var iteminfo = Object.assign({}, $(this.dataset)[0]);
This will make sure we don't edit the DOM accidentally when we really only want to manipulate the shopping cart in that function.
Check it out and see if you're still seeing any problems.

Why isn't jQuery append method working when passing parent class to add a child input?

I want to append a duplicate of an input box in a parent box. Here is my HTML structure:
<div class="reading-group input-group">
<input type="text" placeholder="Enter Reading link" id="link">
</div>
+ Add another link
And here is my jQuery code:
function addPlaceholder(parentClass){
var placeHolder = $(parentClass).children().eq(0);
$(parentClass).append(placeHolder);
console.log(placeHolder);
}
$('.add-reading-btn').click(function(){
addPlaceholder('.reading-group');
});
Here is the jsfiddle link: https://jsfiddle.net/abhishekraj007/kexe6gxn/
What am I doing wrong?
Your code is taking the existing <input> element and moving it from the <div> and back into the <div>, so it looks like nothing is happening. If you .clone() the element and then .append() it, a new element will be added.
Here is a working example:
function addPlaceholder(parentClass) {
var placeHolder = $(parentClass).children().eq(0).clone();
$(parentClass).append(placeHolder);
console.log(placeHolder);
}
$('.add-reading-btn').click(function() {
addPlaceholder('.reading-group');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="reading-group input-group">
<input type="text" placeholder="Enter Reading link" id="link">
</div>
+ Add another link
If you want to add focus to your <input> element on load, you can do so by adding this line to the bottom of your code:
$('#link').focus();
If you want to add focus to the new element on creation, as well as give it an empty value rather than copying the prior element's value, add this line to the end of your addPlaceholder() function:
$(placeHolder).val("").focus();
you can just add the .clone() method of jquery to create a clone of the textbox like below . You were only referring to the same element not the cloned html before.
$(document).ready(function(){
function addPlaceholder(parentClass){
var placeHolder = $(parentClass).children().eq(0).clone();
$(parentClass).append(placeHolder);
//console.log(placeHolder);
}
$('.add-reading-btn').click(function(){
addPlaceholder('.reading-group');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="reading-group input-group">
<input type="text" placeholder="Enter Reading link" id="link">
</div>
+ Add another link
Here is a working fiddle
https://jsfiddle.net/kexe6gxn/2/

Jquery dynamic creating HTML divs on click

I’m looking for some direction for my problem.
I’ve HTML divs and I want to replicate it when user clicks on span with id plus-1.
This is my html
<div id = “tab”>
<div class="row">
<div>
<select id="ProjectsFolder0FolderId" name="data[ProjectsFolder][0][folder_id]">
<option value="1">Project Presentation</option>
<option selected="selected" value="4">Project Root</option>
</select>
</div>
<div>
<div>
<input type="text" required="required" id="ProjectsFolder0Linux" value="xyz" name="data[ProjectsFolder][0][linux]">
</div>
</div>
<div id="plus-1" >
<span>
Click here
</span>
</div>
</div>
</div>
Jquery
$(document).on('click', '#plus-1' , function() {
var html = "<div class=\"row\" >"
???
+ "</div>";
$('#tab').append(html);
});
It is appending above html defined in jquery , but I don’t know how to append entire HTML efficiently as required above on each click.
Demo FIDDLE
Jquery
$(document).on('click', '#plus-1' , function() {
var html = $(this).parent().clone();
html.find('#plus-1').attr('id','plus-'+($('#tab').find('.row').length+1));
$('#tab').append(html);
});
Made a jsfiddle for you - http://jsfiddle.net/23GCn/. You also have an error in your html, you need to use correct parenthesis on <div id="tab">
jQuery(function($){
var count = 1;
$(document).on("click", "[id^='plus']", function(){
newBlock = $(this).parents(".row").clone();
count += 1;
// change id of Plus button
newBlock.find("[id^='plus']").attr("id", "plus-"+count);
// Change id and name of select box
newBlock.find("select")
.attr("id", "ProjectsFolder"+count+"FolderId")
.attr("name", "data[ProjectsFolder]["+count+"][folder_id]");
// Same for input
newBlock.find("input[type='text']")
.attr("id", "ProjectsFolder"+count+"Linux")
.attr("name", "data[ProjectsFolder]["+count+"][linux]");
// append new element to your tab
$("#tab").append(newBlock);
});
});
Note that [id^='plus'] type selectors are very inefficient, means, slow. Consider using classes instead of ids, this way you avoid all of the code required to change ids, since you can't have elements with same id on your page obviously.

jQuery cannot recognize appended cloned elements using jQuery.appendTo()

I want to make a list of group inputs allow user to dynamically let user add/remove group row:
<div id="div-form-denominations" class="form-denominations">
<div id="row-0" class="form-denomination">
<div class="form-field">
<div class="form-field">
<div class="form-field">
<input id="_denominations[0].id.reference" class="removableHiddenOrder" type="hidden" name="denominations[0].id.reference" value="87-070329-034COP-4444">
<input id="_denominations[0].denomination" class="removableHiddenDenom" type="hidden" name="denominations[0].denomination" value="10000">
<a id="deleteBtn-[0]" class="action-link delete-denomination" href="#">
<div class="spacer"></div>
</div>
<div id="row-1" class="form-denomination">
<div class="form-field">
<div class="form-field">
<div class="form-field">
<input id="_denominations[1].id.reference" class="removableHiddenOrder" type="hidden" name="denominations[1].id.reference" value="87-070329-034COP-4444">
<input id="_denominations[1].denomination" class="removableHiddenDenom" type="hidden" name="denominations[1].denomination" value="">
<a id="deleteBtn-[1]" class="action-link delete-denomination" href="#">
<div class="spacer"></div>
</div>
<div id="row-2" class="form-denomination">
<div class="form-field">
<div class="form-field">
<div class="form-field">
<input id="_denominations[2].id.reference" class="removableHiddenOrder" type="hidden" name="denominations[2].id.reference" value="">
<input id="_denominations[2].denomination" class="removableHiddenDenom" type="hidden" name="denominations[2].denomination" value="">
<a id="deleteBtn-[2]" class="action-link delete-denomination" href="#">
<div class="spacer"></div>
</div>
<div id="row-3" class="form-denomination">
.......
</div>
So each row include a group of form-field which include an input or select component(not show in above code) and some hidden fields and a delete link to remove current row from view.
Also I create a link to dynamic add a new row into the section
var rowTemplate = null;
j(document).ready(function() {
// Save the row template
rowTemplate = j('.form-denomination:first-child').clone();
j("#add_link").click(function() {
add_denomination();
});
});
and here is the content of add_denomination function that clone the first row and replace any cloned id with new index, and append the cloned row after last row of the list.
function add_denomination() {
var index = j('.form-denomination').length;
// set the new row id
var newRowId = 'row-' + index;
var newRow = rowTemplate.clone().attr('id', newRowId);
// Replace the id/name attribute of each input control
newRow.find('div, input, select, a').each(function() {
replaceAttribute(j(this), 'id', index);
replaceAttribute(j(this), 'name', index);
j(this).val('');
});
// add new element to the DOM
newRow.appendTo('.form-denominations');
alert("new list size = " + j(".delete-denomination").length);
console.log("DONE!");
}
each time click on the add-link the pop up alert show the new list size (j(".delete-denomination").length increment by 1), which in my understanding, new row appended successfully.
The problem is the following method
// delete denomination row
j('.delete-denomination').click(function () {
j(this).parent().remove();
}
ONLY WORKS FOR THE NON-CLONED ROW !!! Using firebug I can clearly see the appended row is successfully appended with same structure and same element as original rows but only difference is the id.
However, each time when I click on deleteBtn-[i], in which i is the cloned/appended row's index, the code even not going into the j('.delete-denomination').click() function, which in my understanding, Dom or jquery didn't recognize the new rows hence the failure of identifying the link by jQuery. It's kind of contradictory to the previous alert message that telling the size of list has grown.
But when I click on deleteBtn-[i] where i is the non-cloned row, everything works fine...
So the question is: how to append/add new doms and make them identified by jQuery or Dom? What is wrong in above processing? Is there any way to refresh the list so that Dom/jQuery understand the appended rows from all perspective?
jQuery 1.7+
j(".form-denomination").on("click", ".delete-denomination", function(){
j(this).parent().remove();
});
jQuery 1.3+
j(".delete-denomination").live("click", function(){
j(this).parent().remove();
});
jQuery 1.4.3+
j(".form-denomination").delegate(".delete-denomination", "click", function(){
j(this).parent().remove();
});
The problem is a matter of order and when expressions are evaluated. When you call jQuery with a selector, the selector is evaluated at that time to select the matching elements which exist at that time. The click handler is then registered to only those elements. Elements which are created later are, naturally, not affected.
One solution, demonstrated in another example, uses jQuery's "live events" to apply the selector at the time each event is fired to determine what elements, if any, it would match. There is a performance implication to this approach.
Another solution is to register the desired event handler on the newly created elements when you create them.
Add 'true' to the clone method in order to copy the data as well as the events attached to the original element.
rowTemplate = j('.form-denomination:first-child').clone(true);
This is disabled by default. Here is the clone documentation:
https://api.jquery.com/clone/
P.s. You don't need the click function within the document.ready and it won't bind until after the click.

Categories

Resources