Adding input rows using jQuery clone() - javascript

Background:
I've got a set of input elements form invoice item details. I want a user to be able to add rows of input fields for each additional item.
Input Markup
<div class="input-row">
<div class="form-group">
<label for="item_name">Item:</label>
<div>
<input type="text" name="item_name[]" placeholder="Name">
</div>
<div>
<input type="text" name="item_qty[]" placeholder="Quantity">
</div>
<div>
<input type="text" name="item_price[]" placeholder="Price">
</div>
<div>
<input type="text" name="item_total[]" placeholder="Total">
</div>
</div>
</div>
And a button to add an additional item
Button Markup
<div class="col-lg-2">
<a id="add-item" href="#">Add Item</a>
</div>
Button Javascript
$('#add-item').click(function(){
$('.input-row:first').clone().appendTo('.input-row:last');
})
Problem:
When I click the add button the first time, it works fine and adds a row of input fields after the first one, however if I click it again it adds 2 rows and then click it again it adds 4 rows. I realise this may be because the cloned .input-row div is being included in the clone, but I'm trying to only copy the first div element using the :first selector. Any ideas how to resolve this?
Question
How can I ensure only one div is appended to the markup.

The best solution I've seen so far is the following jQuery Library:
http://www.andresvidal.com/labs/relcopy.html

Solution
The jQuery appendTo method adds the element into the existing div, meaning when you clone it the second time the div contains two rows of input fields and then the third time will contain 4 rows of input fields.
To overcome this use the insertAfter() method
Button Javascript
$('#add-item').click(function(){
$('.input-row:first').clone().insertAfter('.input-row:last');
})

Related

jQuery - closest input to current input

I have two divs with same class names with one input inside each. First one has id, second - no, I need get closest input to my input with id. I can't set an id to second input, or change class names of divs.
HTML -
<div class="picker">
<input id="myInput"/>
</div>
<div class="picker">
<input/> <-- which I need to get ->
</div>
I have tried to use something like below, but, this operation returns me the first input.
$("#myInput").closest("input")
So you need to pick parent the "picker" and then you need to pick the next "picker" and then find the input.
const inp = $("#myInput").closest('.picker').next('.picker').find('input');
inp.val('found it');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="picker">
<input id="myInput" />
</div>
<div class="picker">
<input/>
<-- which I need to get ->
</div>

Get html elements (dynamically generated) with values using jQuery

Is it possible using jQuery to get whole div content(dynamically generated elements) with values? For example, child element may be a div, span, select, or input?
I am trying to save whole div content(generated on fly) with values as .html file. I tried with one div which has form and input elements.
HTML:
<div id="inputs">
<form class="mainForm">
<div style="height: 100%;" id="div1">
<label>Input1</label>
<input type="text" id="input1" name="input1"/>
</div>
</form>
</div>
<input id="addform" type="button" value="Click to add Input"/>
<input id="getform" type="button" value="Click to get html"/>
jQuery:
$(document).ready(function(){
$("input#addform").click(function(){
$("div#inputs").append($('form.mainForm').clone().html());
});
$("input#getform").click(function(){
alert($("div#inputs").clone().html());
});
});
FIDDLE:
http://jsfiddle.net/UhJfn/
How to get whole div#inputs content with values (entered by user) On click of Click to get html button?
Help would be appreciated.
P.S: Here I used only one input in form. But in my real case, we do have select, span, image, etc.
Try this,
You have to explicitly update the value attribute to achieve your need.
$(document).ready(function(){
$(document).on('keyup','input[type="text"]',function(){
$(this).attr('value',$(this).val());
});
$("input#addform").click(function(){
$("div#inputs").append($('form.mainForm').clone().html());
});
$("input#getform").click(function(){
alert($("div#inputs").clone().html());
});
});
DEMO

jQuery.val() doesn't work on an <input> tag

After typing something in an input, and clicking on the button, ".val()" return an empty value, any idea why?
HTML CODE:
<div class="mainClass">
<div class="class1" >
<div class="class2">
<h3>Settings 1</h3>
<label>
<span>Text 1:</span>
<input type="text" name="text">
</label>
<label>
<span>Text 2:</span>
<input type="text" name="text2">
</label>
</div>
</div>
<div class="class3" >
<div class="class4">
<h3>Settings 2</h3>
<label>
<span>Text 1:</span>
<input type="text" name="text">
</label>
<label>
<span>Text 2:</span>
<input type="text" name="text2">
</label>
</div>
</div>
</div>
<button id="Go" class="go" >GO </button>
JAVASCRIPT CODE:
$('#Go').on('click', function() {
alert($('.class1 input').val()); //return an empty value
$('.class1 input').val("test");
alert($('.class1 input').val()); //return test
});
EDIT:
Even this doesnt work, and here i have only one input so I can't type in the wrong one:
<div class="mainClass">
<div class="class1" >
<div class="class2">
<h3>Settings 1</h3>
<label>
<span>Text 1:</span>
<input type="text" name="text">
</label>
</div>
</div>
</div>
<button id="Go" class="go" >GO </button>
EDIT 2: I found a beginning of the problem...
When I am doing that:
$('.class1 input').each(function () {
alert($(this).attr('name') + " value:" +$(this).val() );
});
I get two "alert" like this:
text value:
text value:myinputText
So two created for one in my HTML, the first one is empty and the second one work well!
Looking closely to my page, i found that all element are duplicated( <select,field, input...)
Any idea how is that possible? Am i calling two time my html file?
And all my code is in a popup( I don't know if it can help)
(I am new in Javascript and jQuery)
Thanks
There's more than one element matching '.class1 input'. You probably didn't fill the first one of the set.
From the documentation :
Get the current value of the first element in the set of matched
elements.
While val('text') fills all matching elements :
Set the value of each element in the set of matched elements
Which is why you see something in your second alert.
You'd better use a more selective selector. Usually we use an id, or a name if a form is used to send the values to a server.
$('.class1 input').val()
refers to two elements
<input type="text" name="text">
and
<input type="text" name="text2">
You have more than one element that matches.
From the jQuery docs
.val()
Get the current value of the first element in the set of
matched elements or set the value of every matched element.
You are only getting the first element of the matched set as the docs state. If you want all the values, you need to loop over the set.
Wrap your Jquery code around a Document-ready block:
$('document').ready(function(){});
like so:
$('document').ready(function(){
$('#Go').on('click', function() {
alert($('.class1 input').val()); //return an empty value
$('.class1 input').val("test");
alert($('.class1 input').val()); //return test
});
});
Even with so much help from google search and Stackoverflow, it took us 1 hour to identify this issue.
I had a similar problem Chrome repeatedly told me .val() is not a function, instead of using .val() I had to use .value That got the job done for me hope it works for you.

Accordion + Appended Content Jquery

So I have an accordion menu that I created with Jquery:
<script>
$(document).ready(function() {
/*Accordian Script for the Request New Appraisal Panel*/
$('.accordian_item').hide();
$('.accordian_item').first().slideDown();
$('.accordian_trigger').click(function(event) {
event.preventDefault();
$(this).parent().find('.accordian_item').slideToggle();
});
});
</script>
Now, I want to be able to dynamically append extra accordion items to the accordion box, which I have done like this:
<script>
$('#add_contact_btn').click(function(event) {
event.preventDefault();
var large = '<div class="accordian_container"><h4>Co-Borrower Information</h4><hr/><div class="accordian_item"><label> First Name</label><br/><input type="text"/><br/><label>Middle Name</label><br/><input type="text"/><br/><label>Last Name</label><br/><input type="text" /><br/><label>Home Number</label><br/><input type="text"/><br><label>Work Number</label><br/><input type="text"/><br><label>Cell Number</label><br/><input type="text"/><br></div></div>';
$('#accordion_container_box').append(large);
});
</script>
This works perfect, except the dynamically generated items don't collaps when you click on the collapse button. The existing accordion items still work. For some reason it seems like Jquery wont trigger for dynamically created links. Any ideas how I can correct this?
BTW, here is the basic HTML structure:
<div id="accordion_container_box">
<div class="accordian_container">
<h4>Borrower's Information</h4>
<hr/>
<div class="accordian_item">
<label> First Name</label><br/>
<input type="text"/><br/>
<label>Middle Name</label><br/>
<input type="text"/><br/>
<label>Last Name</label><br/>
<input type="text" /><br/>
<label>Home Number</label><br/>
<input type="text"/><br>
<label>Work Number</label><br/>
<input type="text"/><br>
<label>Cell Number</label><br/>
<input type="text"/><br>
</div>
</div>
<div class="accordian_container">
<h4>Co-Borrower's Information</h4>
<hr/>
<div class="accordian_item">
<label> First Name</label><br/>
<input type="text"/><br/>
<label>Middle Name</label><br/>
<input type="text"/><br/>
<label>Last Name</label><br/>
<input type="text" /><br/>
<label>Home Number</label><br/>
<input type="text"/><br>
<label>Work Number</label><br/>
<input type="text"/><br>
<label>Cell Number</label><br/>
<input type="text"/><br>
</div>
</div>
</div>
+ Additional Contact
You have to use .live('click'... on dynamically created content.
By default binding events to elements will only affect nodes that exist at the time that the bind runs. By using event delegation you can make use of the built in way that events bubble. jQuery < 1.7 did this with the delegate and live methods, jQuery 1.7 added the on method to consolidate all the event handlers in a single API.
For example you could use the following to handle all clicks on nodes with a class of accordian_trigger regardless of when they were created.
​$(document).on('click', '.accordian_trigger', function() {
//whatever you need to do
});​​​​​​​​​​​
What this will do is attach an onclick event handler to the document itself. When any click occurs in the DOM it will bubble up from the node that the event occurred on to its parent and its parent until it reaches the document. jQuery will then check whether the event occurred on a node that matches the selector passed in as the second parameter of on, in this case it will check whether the node has a class of accordian_trigger. If it does it will run the function passed in as the third parameter.
For efficiency's sake you'll likely want to replace document with a parent node that you know will contain all accordian_trigger nodes. Otherwise all clicks bubble all the way up to the document and check whether the node that was clicked on has the accordian_trigger class, which is potentially expensive, especially if you have a large DOM.

Is it possible to show a html element already on a page a second time without copying it?

I have a page with a hidden form containing several divs.
<form action="...">
<div>
<input id="menubar_open_article_bid" name="bid" onfocus="this.select();" onkeyup="do_v(); type="text">
<a href="#" onclick="return do_h();">
Beitrag öffnen </a>
</div>
<div>
<input id="menubar_open_article_cid" name="cid" onfocus="this.select();" onkeyup="do_a();" type="text">
<a href="#" onclick="return do_y();">
Container öffnen </a>
</div>
<div>
<input id="menubar_open_article_iid" name="iid" onfocus="this.select();" onkeyup="do_b();" type="text">
<a href="#" onclick="return do_x();">
Inhalt öffnen </a>
</div>
</form>
As a first try i copied one of the divs using jQuery to another form in order to show it there (visible).
That worked great, but now the html element id is there twice.
I do not want to change that id. So a solution where i could only reffer to the div with id "menubar_open_article_iid" to show the html-element would solve my problem. Is that possible? (though i never heard of something like this)
As far as I am aware, this is not possible.
I think the main problem here is that you want one input shown twice, but still being the same input. That is going to be problematic, and it is also bad interface design. The user is likely to be confused by having two separate but different inputs in a form.
I'd recommend you to not do this.
Maybe you can leverage this approach:
I'd use jQuery and jQuery metadata:
http://plugins.jquery.com/project/metadata
In your hidden form, don't specify any id's. Instead, specify what you want the ids to be via class metadata:
<form class="hide form-to-clone">
<div>
<input class="setId {id:'id1'}" />
</div>
<div>
<input class="setId {id:'id2'}" />
</div>
<div>
<input class="setId {id:'id3'}" />
</div>
</form>
In jQuery, clone the hidden form:
var clone = $('.form-to-clone').clone();
Then, loop through the elements in the clone and set the ids:
clone.find('.setId').each(function() {
var $this = $(this);
$this.attr('id', $this.metadata().id);
});
Then, append your cloned form to the page somewhere:
clone.show().appendTo('body');

Categories