Cloning div on click breaks when moving the button out of container? - javascript

I found this nifty js fiddle and it does nearly exactly what I need
However its cloning the parent of the button and id like to have the button separate from the actual div being cloned. (if you put the clone button back into the container with the remove button it works fine again)
In all I am trying to accomplish 3 things.
1. Have the button outside of the div that's being duplicated (1 button)
2. Limit the number of duplication's to a total of 6. (or any changeable variable)
3. Update the <h4> content and change the number 1 to the next number. ie: (1-6)
I'm not very JS savvy although I do dabble. If anyone has the time to help me figure out the above it would be beyond appreciated! Here's the JS FIDDLE I've been playing with.
Thanks!
var regex = /^(.+?)(\d+)$/i;
var cloneIndex = $(".clonedInput").length;
function clone(){
$(this).parents(".clonedInput").clone()
.appendTo("body")
.attr("id", "clonedInput" + cloneIndex)
.find("*")
.each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
}
})
.on('click', 'button.clone', clone)
.on('click', 'button.remove', remove);
cloneIndex++;
}
function remove(){
$(this).parents(".clonedInput").remove();
}
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);

I think the folowing is what you're trying to acheive, you have to add another variables cloned_nbr and clones_limit to control the cloned divs:
var cloneIndex = 1;
var clones_limit = 4;
var cloned_nbr = $(".clonedInput").length-1; //Exclude Default (first) div
function clone()
{
if(cloned_nbr<clones_limit)
{
cloneIndex++;
cloned_nbr++;
var new_clone = $(".clonedInput").first().clone();
new_clone.attr("id", "clonedInput" + cloneIndex);
new_clone.find(".label-nbr").text(cloneIndex);
new_clone.find(".category").attr("id","category"+cloneIndex);
new_clone.find(".remove").attr("id","remove"+cloneIndex);
new_clone.on('click', 'button.clone', clone);
new_clone.on('click', 'button.remove', remove);
$(".clone").before(new_clone);
}
}
function remove(){
if(cloneIndex>1){
$(this).parents(".clonedInput").remove();
cloned_nbr--;
}
}
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
body { padding: 10px;}
.clonedInput { padding: 10px; border-radius: 5px; background-color: #def; margin-bottom: 10px; }
.clonedInput div { margin: 5px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clonedInput1" class="clonedInput">
<div>
<label for="txtCategory" class="">Learning category <span class="label-nbr">1</span><span class="requiredField">*</span></label>
<select class="category" name="txtCategory[]" id="category1">
<option value="">Please select</option>
</select>
</div>
<div class="actions">
<button class="remove">Remove</button>
</div>
</div>
<button class="clone">Clone</button>

You can select the last occurence of .clonedInput and clone that, then insert it after the original element:
var regex = /^(.+?)(\d+)$/i;
function clone(){
var cloneIndex = $(".clonedInput").length + 1;
if (cloneIndex > 6) return;
$source = $(".clonedInput").last();
$source.clone()
.insertAfter($source)
.attr("id", "clonedInput" + cloneIndex)
.find("*")
.each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
}
})
.on('click', 'button.remove', remove)
.find('label').html('Learning category ' + cloneIndex + ' <span class="requiredField">*</span>');
}
function remove(){
$(this).parents(".clonedInput").remove();
}
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clonedInput1" class="clonedInput">
<div>
<label for="txtCategory" class="">Learning category 1 <span class="requiredField">*</span></label>
<select class="" name="txtCategory[]" id="category1">
<option value="">Please select</option>
</select>
</div>
<div class="actions">
<button class="remove">Remove</button>
</div>
</div>
<button class="clone">Clone</button>

I'd initialize plain block as template and use it as clone base.
HTML
<div class="box-wrap">
<button class="clone">Clone</button>
</div>
Full demo: http://jsfiddle.net/jeafgilbert/tfFLt/1898/

Related

JS- how to change option color base on if statment

I'm trying to change the option color base on an if statment. This is my form:
function myFunction() {
var lia = document.createElement("h5");
var lib = document.createElement("p");
var item = document.getElementById('task').value;
var pro = document.getElementById('priority').value;
var item_list = document.createTextNode(item);
var item_pro = document.createTextNode(pro);
lia.appendChild(item_list);
lib.appendChild(item_pro);
document.getElementById("result").appendChild(lia);
document.getElementById("priorit").appendChild(lib);
if (pro == 'Urgent') {
$("p").css('color', 'red');
}
if (pro == 'Critical') {
$("p").css('color', 'orange');
}
if (pro == 'Normal') {
$("p").css('color', 'green');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="task" type="text" />
<select id="priority">
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="Normal">Normal</option>
</select>
<button onclick="myFunction()">Add</button>
<h3>List Result</h3>
<table>
<th id="result"></th>
<th id="priorit"></th>
<table>
This if statement its what i want to do. but for now, any time im adding to the list another item with other option, all the colors are change to the last one.
you can see my problem here:
https://jsbin.com/selenifepa/edit?html,js,output
what should i do?
Use the :last-child css selector.
See this code
function myFunction() {
var lia = document.createElement("h5");
var lib = document.createElement("p");
var item = document.getElementById('task').value;
var pro = document.getElementById('priority').value;
var item_list = document.createTextNode(item);
var item_pro = document.createTextNode(pro);
lia.appendChild(item_list);
lib.appendChild(item_pro);
document.getElementById("result").appendChild(lia);
document.getElementById("priorit").appendChild(lib);
if(pro=='Urgent'){
$("p:last-child").css('color','red');
}
if(pro=='Critical'){
$("p:last-child").css('color','orange');
}
if(pro=='Normal'){
$("p:last-child").css('color','green');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="task" type="text"/>
<select id="priority">
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="Normal">Normal</option>
</select>
<button onclick="myFunction()">Add</button>
<h3>List Result</h3>
<table>
<th id="result"></th>
<th id="priorit"></th>
<table>
Instead of selecting all paragraph elements, you can select added element like this:
if(pro=='Urgent'){
$(lib).css('color','red');
}
if(pro=='Critical'){
$(lib).css('color','orange');
}
if(pro=='Normal'){
$(lib).css('color','green');
}
Replace your if with this one and this is it...
The issue is because the $('p') selector matches all existing p elements in the DOM, not just the one you added. You can fix that by using $(lib) to affect only the newly added p tag.
$(lib).css('color', 'green');
However, I would also suggest you look in to using unobtrusive event handlers as on* event attributes are considered outdated. As you're already using jQuery, here's how to do that:
$('#add').click(function(e) {
e.preventDefault();
var pro = $('#priority').val();
var $lia = $("<h5 />").text($('#task').val()).appendTo('#result');
var $lib = $("<p />").text(pro).appendTo('#priorit');
if (pro == 'Urgent') {
$lib.css('color', 'red');
}
if (pro == 'Critical') {
$lib.css('color', 'orange');
}
if (pro == 'Normal') {
$lib.css('color', 'green');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="task" type="text" />
<select id="priority">
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="Normal">Normal</option>
</select>
<button id="add">Add</button>
<h3>List Result</h3>
<table>
<th id="result"></th>
<th id="priorit"></th>
<table>
The reason is that you are selecting all the p tags with $('p'). Also, you have mixed jQuery with vanilla JS. I'll assume you want to use jQuery to simplify your code. Here it goes.
function add() {
// select the elements and assign to a var, that way we don't have to be selecting the elements over and over, which is 'slow' (research "Why traversing the DOM is slow")
var results = $('#results'),
task = $('#task'),
priority = $('#priority'),
// create the new div element with it's content
newResult = $('<div>'+task.val()+' '+priority.val()+'</div>');
// Decide what color to apply
if(priority.val() == 'Urgent'){
newResult.css('color','red');
}
if(priority.val() == 'Critical'){
newResult.css('color','orange');
}
if(priority.val() == 'Normal'){
newResult.css('color','green');
}
// append the new div to the list of results
results.append(newResult);
// clear the input and focus the cursor for the next value to be added
task.val('').focus();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="task" type="text"/>
<select id="priority">
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="Normal">Normal</option>
</select>
<button onclick="add()">Add</button>
<h3>List Result</h3>
<div id="results"></div>
Here This should do the trick
function myFunction() {
var lia = document.createElement("h5");
var lib = document.createElement("p");
var item = document.getElementById('task').value;
var pro = document.getElementById('priority').value;
var item_list = document.createTextNode(item);
var item_pro = document.createTextNode(pro);
lia.appendChild(item_list);
lib.appendChild(item_pro);
if(pro=='Urgent'){
lia.style.color='red';
lib.style.color='red';
}else{
lia.style.color='orange';
lib.style.color='orange';
}
document.getElementById("result").appendChild(lia);
document.getElementById("priorit").appendChild(lib);
document.getElementById('task').value = '';
}
The only issue was that you're selectin all the p elements by $("p"). You need to just select the currently added element i.e. lib. But lib is a javascript variable, so wrap it in jQuery to convert it into a jQuery object and then apply jQuery css.
e.g. $(lib).css('color', 'red');
function myFunction() {
var lia = document.createElement("h5");
var lib = document.createElement("p");
var item = document.getElementById('task').value;
var pro = document.getElementById('priority').value;
var item_list = document.createTextNode(item);
var item_pro = document.createTextNode(pro);
lia.appendChild(item_list);
lib.appendChild(item_pro);
document.getElementById("result").appendChild(lia);
document.getElementById("priorit").appendChild(lib);
if (pro == 'Urgent') {
$(lib).css('color', 'red');
}
if (pro == 'Critical') {
$(lib).css('color', 'orange');
}
if (pro == 'Normal') {
$(lib).css('color', 'green');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="task" type="text" />
<select id="priority">
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="Normal">Normal</option>
</select>
<button onclick="myFunction()">Add</button>
<h3>List Result</h3>
<table>
<th id="result"></th>
<th id="priorit"></th>
<table>

JavaScript match selected text with div id

I am trying to show and hide certain div based on selected text in drop down list. The option in drop-down list is generated by getting id from certain class name. I thought of using looping of an array in javascript but am unsure how to do so. Sorry that i may sound unclear of what i wanted to do as i am lost and unsure how to do them.
My Codes:
JavaScript:
var elements = document.body.getElementsByClassName("headline-bar");
window.onload = function() {
var year = document.getElementById("year");
for (i=0;i<elements.length;i++)
{
var Entry = document.createElement("option");
Entry.text = elements[i].textContent;
year.add(Entry ,null);
}
}
Html:
<form>
<select id="year">
<option>All</option>
</select>
<input type="submit" value="Submit">
</form>
<form action="#" id="release_year" method="post" >
<div class="release_holder" id="2015" style="margin-bottom: 20px">
<div class="headline-bar">2015</div>
<div class="content">hello there</div>
</div>
<div class="release_holder" id="2014" style="margin-bottom: 20px">
<div class="headline-bar">2014</div>
<div class="content">hello there</div>
</div>
</form>
JavaScript Loop array that i thought of using:
var selectedText = yearSelect.options[yearSelect.selectedIndex].text;
var classList = document.getElementByClassName('press_release_holder').id.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
if (classList[i] === 'selectedText') {
//do something
}
}
Easier solution would to use querySelectorAll considering the condition of All option.
Use change listener for select-input.
var elements = document.body.getElementsByClassName("headline-bar");
var year = document.getElementById("year");
for (i = 0; i < elements.length; i++) {
var Entry = document.createElement("option");
Entry.text = elements[i].textContent;
year.add(Entry, null);
}
function showHide(elem) {
var val = elem.value;
if (val == 'All') {
[].forEach.call(document.querySelectorAll('.release_holder'), function(el) {
el.style.display = 'block';
});
} else {
[].forEach.call(document.querySelectorAll('.release_holder'), function(el) {
el.style.display = 'none';
});
document.querySelector('[id="' + val + '"]').style.display = '';
}
}
<form>
<select id="year" onchange='showHide(this)'>
<option>All</option>
</select>
<input type="submit" value="Submit">
</form>
<form action="#" id="release_year" method="post">
<div class="release_holder" id="2015" style="margin-bottom: 20px">
<div class="headline-bar">2015</div>
<div class="content">hello there</div>
</div>
<div class="release_holder" id="2014" style="margin-bottom: 20px">
<div class="headline-bar">2014</div>
<div class="content">hello there</div>
</div>
</form>
Fiddle Demo
You can use the onchange event in your drop down to fire your code:
<select onchange="myFunction()">
http://www.w3schools.com/jsref/event_onchange.asp
Then once myFunction() is fired, you get the selected text and set the CSS manually, as with this answer:
https://stackoverflow.com/a/21070237/5882767
use this on change function
<select onchange="myChangeFunction()">
function myChangeFunction(){
if( $('#year').val() == 'yourSelectedOption'){
$('.className').hide(); // use javascript function for hide show of element
}
}
Do the values of the dropdown list correspond to the year? i.e. the id of the div tag you want to hide.
If so, you can try the following:
var optionList = document.getElementById("year");
var selectedText = optionList.options[optionList .selectedIndex].value;
//hide the div with the id = selectedText
document.getElementById(selectedText).style.display = 'none';

Jquery: How to reorder DIVs after removing a single Div?

I am working on an application in which contains a few DIVs having IDs like a1,a2,a3 etc.
There is option of navigation DIVs by hitting next and previous button which brings one Div on screen at a time. strong text There are two more actions: Add and Remove. Add adds a Div with ID greated than last ID, for instance if last DIV id was a3 then Add brings a4.
The real issue is removing current DIV. If the user is on Div a2 and hits Remove option then it deletes the current Div by using .remove() method of jQuery
Now navigation breaks because it is sequential. It tries to find Div a2 but does not find. What I think that Ids of all remaining DIVs should be renamed. Since there is no a2 so a3 should become a2 and so on. How can I do that? Code doing different tasks is given below:
function removeQuestion()
{
$("#_a"+answerIndex).remove();
if(answerIndex > 1)
{
if ($("#_a"+(++answerIndex)).length > 0)
{
$("#_a"+answerIndex).appendTo("#answerPanel");
}
else if($("#_a"+(--answerIndex)).length)
{
$("#_a"+answerIndex).appendTo("#answerPanel");
}
totalOptions--;
}
}
function addQuestion()
{
var newId = 0;
totalOptions++;
var d = 1;
newId = totalOptions;
var _elemnew = '_a'+newId;
$("#_a"+d).clone().attr('id', '_a'+(newId) ).appendTo("#answers_cache");
var h = '<input onclick="openNote()" id="_note'+newId+'" type="button" value=" xx" />';
$("#"+_elemnew+" .explain").html(h)
$("#"+_elemnew+" ._baab").attr("id","_baab"+newId);
$("#"+_elemnew+" ._fx").attr("id","_fasal"+newId);
$("#"+_elemnew+" .topic_x").attr("id","_t"+newId);
$("#"+_elemnew+" .topic_x").attr("name","_t"+newId);
$("#"+_elemnew+" .answerbox").attr("id","_ans"+newId);
$("#"+_elemnew+" .block").attr("onclick","openFullScreen('_ans"+newId+"')");
$('.tree').click( function()
{
toggleTree();
}
);
$('.popclose').click( function()
{
unloadPopupBox();
}
);
}
function next()
{
console.log("Next ->");
if(answerIndex < totalOptions)
{
answerIndex++;
console.log(answerIndex);
setInitialAnswerPanel();
}
}
function previous()
{
console.log("Next <-");
if(answerIndex > 1)
{
answerIndex--;
console.log(answerIndex);
setInitialAnswerPanel();
}
}
Html of Composite DIV is given below:
<div class="answers" id="_a1" index="1">
<input placeholder="dd" id="_t1" type="text" name="_t1" class="urduinput topic_masla" value="" />
<img class="tree" onclick="" src="tree.png" border="0" />
<label class="redlabel">
xx :
</label>
<label id="_baab1" class="baabfasal _baab">
</label>
<label class="redlabel">
xx :
</label>
<label id="_fasal1" class="baabfasal _fasal">
</label>
<a title=" ddd" class="block" href="#" onclick="openFullScreen('_ans1')">
<img src="fullscreen.png" border="0" />
</a>
<textarea id="_ans1" class="answerbox" cols="40" rows="15"></textarea>
<span class="explain">
<input onclick="openNote()" id="_note1" type="button" value=" xx" />
</span>
<span style="float:left;padding-top:5%">
plus | <a onclick="removeQuestion()" href="#">minus</a>
</span>
</div>
Why don't you keep currently opened page instead of the index and search for previous and next pages using prev() and next() jQuery tree traversal methods?
Select all div elements containing questions, preferable with a css class selector, use the each method, and assign new ids to them:
$('.questionDiv').each(function(index) { $(this).attr('id', 'a' + (index + 1)); })
That should be enough.
var originalSet = $('.answers');
var container = originalSet.up() ;
var byId = function(a, b){
return $(a).attr('id') > $(b).attr('id') ? 1 : -1;
}
originalSet
.order(byId)
.each(function rearrangeIds(position){
$(this).attr({
'index': poition,
'id': '_a'+position
});
}).appendTo(container)

jquery clone form fields and increment id

I have a block of form elements which I would like to clone and increment their ID's using jQuery clone method. I have tried a number of examples but a lot of them only clone a single field.
My block is structured as such:
<div id="clonedInput1" class="clonedInput">
<div>
<div>
<label for="txtCategory" class="">Learning category <span class="requiredField">*</span></label>
<select class="" name="txtCategory[]" id="category1">
<option value="">Please select</option>
</select>
</div>
<div>
<label for="txtSubCategory" class="">Sub-category <span class="requiredField">*</span></label>
<select class="" name="txtSubCategory[]" id="subcategory1">
<option value="">Please select category</option>
</select>
</div>
<div>
<label for="txtSubSubCategory">Sub-sub-category <span class="requiredField">*</span></label>
<select name="txtSubSubCategory[]" id="subsubcategory1">
<option value="">Please select sub-category</option>
</select>
</div>
</div>
Obviously elements are lined up a lot better but you get the idea.
I would like to keep the id structure i.e. category1, subcategory1 etc as I use these to dynamically display select options based on the parent selection so if its possible to have each cloned block like category1/category2/category3 etc that would be great.
HTML
<div id="clonedInput1" class="clonedInput">
<div>
<label for="txtCategory" class="">Learning category <span class="requiredField">*</span></label>
<select class="" name="txtCategory[]" id="category1">
<option value="">Please select</option>
</select>
</div>
<div>
<label for="txtSubCategory" class="">Sub-category <span class="requiredField">*</span></label>
<select class="" name="txtSubCategory[]" id="subcategory1">
<option value="">Please select category</option>
</select>
</div>
<div>
<label for="txtSubSubCategory">Sub-sub-category <span class="requiredField">*</span></label>
<select name="txtSubSubCategory[]" id="subsubcategory1">
<option value="">Please select sub-category</option>
</select>
</div>
<div class="actions">
<button class="clone">Clone</button>
<button class="remove">Remove</button>
</div>
</div>
JavaScript - Jquery v1.7 and earlier
var regex = /^(.+?)(\d+)$/i;
var cloneIndex = $(".clonedInput").length;
$("button.clone").live("click", function(){
$(this).parents(".clonedInput").clone()
.appendTo("body")
.attr("id", "clonedInput" + cloneIndex)
.find("*").each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
}
});
cloneIndex++;
});
There is only one silly part :) .attr("id", "clonedInput" + $(".clonedInput").length) but it works ;)
JAvascript - JQuery recent (supporting .on())
var regex = /^(.+?)(\d+)$/i;
var cloneIndex = $(".clonedInput").length;
function clone(){
$(this).parents(".clonedInput").clone()
.appendTo("body")
.attr("id", "clonedInput" + cloneIndex)
.find("*")
.each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
}
})
.on('click', 'button.clone', clone)
.on('click', 'button.remove', remove);
cloneIndex++;
}
function remove(){
$(this).parents(".clonedInput").remove();
}
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
working example here
Another option would be to use a recursive function:
// Accepts an element and a function
function childRecursive(element, func){
// Applies that function to the given element.
func(element);
var children = element.children();
if (children.length > 0) {
children.each(function (){
// Applies that function to all children recursively
childRecursive($(this), func);
});
}
}
Then you can make a function or three for setting the attributes and values of your yet-to-be-cloned form fields:
// Expects format to be xxx-#[-xxxx] (e.g. item-1 or item-1-name)
function getNewAttr(str, newNum){
// Split on -
var arr = str.split('-');
// Change the 1 to wherever the incremented value is in your id
arr[1] = newNum;
// Smash it back together and return
return arr.join('-');
}
// Written with Twitter Bootstrap form field structure in mind
// Checks for id, name, and for attributes.
function setCloneAttr(element, value){
// Check to see if the element has an id attribute
if (element.attr('id') !== undefined){
// If so, increment it
element.attr('id', getNewAttr(element.attr('id'),value));
} else { /*If for some reason you want to handle an else, here you go*/ }
// Do the same with name...
if(element.attr('name') !== undefined){
element.attr('name', getNewAttr(element.attr('name'),value));
} else {}
// And don't forget to show some love to your labels.
if (element.attr('for') !== undefined){
element.attr('for', getNewAttr(element.attr('for'),value));
} else {}
}
// Sets an element's value to ''
function clearCloneValues(element){
if (element.attr('value') !== undefined){
element.val('');
}
}
Then add some markup:
<div id="items">
<input type="hidden" id="itemCounter" name="itemCounter" value="0">
<div class="item">
<div class="control-group">
<label class="control-label" for="item-0-name">Item Name</label>
<div class="controls">
<input type="text" name="item-0-name" id="item-0-name" class="input-large">
</div>
</div><!-- .control-group-->
<div class="control-group">
<label for="item-0-description" class="control-label">Item Description</label>
<div class="controls">
<input type="text" name="item-0-description" id="item-0-description" class="input-large">
</div>
</div><!-- .control-group-->
</div><!-- .item -->
</div><!-- #items -->
<input type="button" value="Add Item" id="addItem">
And then all you need is some jQuery goodness to pull it all together:
$(document).ready(function(){
$('#addItem').click(function(){
//increment the value of our counter
$('#itemCounter').val(Number($('#allergyCounter').val()) + 1);
//clone the first .item element
var newItem = $('div.item').first().clone();
//recursively set our id, name, and for attributes properly
childRecursive(newItem,
// Remember, the recursive function expects to be able to pass in
// one parameter, the element.
function(e){
setCloneAttr(e, $('#itemCounter').val());
});
// Clear the values recursively
childRecursive(newItem,
function(e){
clearCloneValues(e);
}
);
// Finally, add the new div.item to the end
newItem.appendTo($('#items'));
});
});
Obviously, you don't necessarily need to use recursion to get everything if you know going in exactly what things you need to clone and change. However, these functions allow you to reuse them for any size of nested structure with as many fields as you want so long as they're all named with the right pattern.
There's a working jsFiddle here.
Clone the main element, strip the id number from it.
In the new element replace every instance of that id number in every element id you want incremented with the new id number.
Ok, here's a quicky code here.
Basically, this part is the most important:
(parseInt(/test(\d+)/.exec($(this).attr('id'))[1], 10)+1
It parses the current id (using RegEx to strip the number from the string) and increases it by 1. In your case instead of 'test', you should put 'clonedInput' and also not only increase the value of the main element id, but the three from the inside as well (category, subcategory and subsubcategory). This should be easy once you have the new id.
Hope this helps. :)
Add data attribute to the input to get the field name, increment the value with variable.
html :
<td>
<input type="text" data-origin="field" name="field" id="field" required="" >
<div role="button" onclick='InsertFormRow($(this).closest("tr"),"tableID","formID");' id="addrow"> + </div>
</td>
and put this javascript function
var rowNum = 1;
var InsertFormRow = function(row, ptable, form)
{
nextrow = $(row).clone(true).insertAfter(row).prev('#' + ptable + ' tbody>tr:last');
nextrow.attr("id", rowNum);
nextrow.find("input").each(function() {
this.name = $(this).data("origin") + "_" + rowNum;
this.id = $(this).data("origin") + "_" + rowNum;
});
rowNum++;
}

jQuery Append UL with LI from DropDownList and Vice Versa

I have a dropdownlist with values. On a click of a button a unordered list gets appended with an <li> with details from the selected item in the dropdown list.
The <li> has an <a> tag in it which will remove the <li> from the <ul>.
I need to repopulate the dropdown list with the item removed from the <ul> when the <li> is removed.
Any ideas?
UPDATE:
Thanks for all your help. Here is my whole implementation:
<script type="text/javascript">
$(function() {
$("#sortable").sortable({
placeholder: 'ui-state-highlight'
});
$("#sortable").disableSelection();
$('#btnAdd').click(function() {
if (validate()) {
//Remove no data <li> tag if it exists!
$("#nodata").remove();
$("#sortable").append("<li class='ui-state-default' id='" + $("#ContentList option:selected").val() + "-" + $("#Title").val() + "'>" + $("#ContentList option:selected").text() + "<a href='#' title='Delete' class='itemDelete'>x</a></li>");
$("#ContentList option:selected").hide();
$('#ContentList').attr('selectedIndex', 0);
$("#Title").val("");
}
});
$('#btnSave').click(function() {
$('#dataarray').val($('#sortable').sortable('toArray'));
});
$('.itemDelete').live("click", function() {
var id = $(this).parent().get(0).id;
$(this).parent().remove();
var value = id.toString().substring(0, id.toString().indexOf('-', 0));
if ($("option[value='" + value + "']").length > 0) {
$("option[value='" + value + "']").show();
}
else {
var lowered = value.toString().toLowerCase().replace("_", " ");
lowered = ToTitleCase(lowered);
$("#ContentList").append("<option value='" + value + "'>" + lowered + "</option>");
}
});
});
function validate() {
...
}
function ToTitleCase(input)
{
var A = input.split(' '), B = [];
for (var i = 0; A[i] !== undefined; i++) {
B[B.length] = A[i].substr(0, 1).toUpperCase() + A[i].substr(1);
}
return B.join(' ');
}
</script>
<form ...>
<div class="divContent">
<div class="required">
<label for="ContentList">Available Sections:</label>
<select id="ContentList" name="ContentList">
<option value="">Please Select</option>
<option value="CHAN TEST">Chan Test</option>
<option value="TEST_TOP">Test Top</option>
</select>
<span id="val_ContentList" style="display: none;">*</span>
</div>
<div class="required">
<label for="ID">Title:</label>
<input class="inputText" id="Title" maxlength="100" name="Title" value="" type="text">
<span id="val_Title" style="display: none;">*</span>
</div>
<input value="Add Section" id="btnAdd" class="button" type="button">
</div>
<ul id="sortable">
<li class="ui-state-default" id="nodata">No WebPage Contents Currently Saved!</li>
</ul>
<div>
<input type="submit" value="Save" id="btnSave" class="button"/>
</div>
<input type="hidden" id="dataarray" name="dArray" />
</form>
You've acknowledged that you know very little about jQuery, so let's look at some of this piece by piece. This snippets will give you the information you need to construct your solution.
Adding click-events is relatively easy:
$("#myButton").click(function(){
/* code here */
});
Removing elements is also pretty simple:
$("#badThing").remove();
The thing about .remove() though is that you can add it elsewhere after removing it:
$("#badThing").remove().appendTo("#someBox");
That moves #badThing from wherever it was, to the inside of #someBox.
You can add new list items with the append method:
$("#myList").append("<li>My New Item</li>");
You can get the selected item of a drop-down like this:
var item = $("#myDropDown option:selected");

Categories