Hi I'm creating an ingredients app that has a form that looks like:
http://jsfiddle.net/PZjfT/
As you can see, there is a span containing 2 textfields, and a select. You can delete any span by clicking on the X next to it.
My problem is that I'm using jQuery Clone, so if you delete all of the spans, then click "Add Ingredient", there is no divs to clone, so it doesn't add an ingredient.
How could I fix this? Thanks for any and all help!
Use .detach() instead of .clone() for your last div, so you don't lose it.
.detach() will let you remove your last div from the DOM and save it in a variable, so you can later insert it again or clone from it.
Easy fix, clone the element on document ready but don't put it into the page and use that to clone.
jsFiddle
(function ($) {
$(document).ready(function () {
var myClone = $('#ingredientsCOUNT > span:first').clone();
$('#btnAddIngredients').click(function () {
var num = $('#ingredientsCOUNT span').length;
var newNum = new Number(num + 1);
myClone
.clone()
.attr('name', 'ingredient' + newNum)
.appendTo('#ingredientsCOUNT')
.fadeIn();
});
$('.formelementcontainer').on('click', '.deleteThis', function () {
var span = $(this).closest('span');
console.log(span);
span.fadeOut('slow', function () {
span.remove();
});
});
});
})(jQuery);
My approach would be that you don't let the user delete the last div.
So you always start out with one ingredient div on the page. Let them add new ones by cloning.
When the user removes an ingredient, delete the div and check how many ingredients are left. If it is only one, remove or hide the delete button, so they can't delete the last ingredient.
Related
So I have a large button on the left and a form on the right. When you click the button it creates up to 5 additional forms. It also updates the id's and the flavor profile # text.
Its still a little buggy and was looking for some help sorting it out as im not the best with JS.
Problem 1: If you create the 5 additional clones and then delete them. When you create them again it labels them as #7 #8 #9 - Since only 6 forms are allowed. I need this number to only display 1-6 and not go above or below. I would like the same thing for the id's too.
Problem 2: Another issue I have is i would like to remove the "Remove button" from Flavor Profile #1 (The first form). Because if all the forms are deleted there is nothing left to clone.
Thanks for any help!
JS FIDDLE
var cloneIndex = 1;
var clones_limit = 5;
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.show(".remove").attr("id","remove"+cloneIndex);
new_clone.on('click', 'button.clone', clone);
new_clone.on('click', 'button.remove', remove);
$("#formy").append(new_clone);
}
}
function remove(){
if(cloneIndex>1){
$(this).parents(".clonedInput").remove();
cloned_nbr--;
}
}
$(".clone").on("click", clone);
$(".remove").on("click", remove);
I changed it up a bit. It should work with proper indexes and remove buttons!
function getFreeIds() {
var used = $('.clonedInput').find('.label-nbr').map(function(i, v) {
return parseInt(v.innerText)
}).get();
return allowed.filter(function (i) {return used.indexOf(i) === -1});
}
It does what you need.
http://jsfiddle.net/tfFLt/1921/
Add a function that checks the number of removable divs present. If its more than 1, display the remove button, else don't:
function handleRemoveButton(){
var numItems = $('.clonedInput').length;
if(numItems<=1){
$(".remove").hide();
}
else{
$(".remove").show();
}
}
And call it thrice : once on $(document).ready(); and once at the last of clone(){} and remove().
write a rearrange function to update the content and call it from when you are cloning an item or removing it
function rearrange(){
var count = 1;
var totalCount = $(".clonedInput").length;
$(".clonedInput").each(function(){
$(this).attr("id", "clonedInput"+count).find(".label-nbr").text(count).end().
find(".category").attr("id","category"+count).end().find(".remove").toggle(totalCount!=1).attr("id","remove"+count).on("click", remove);
count++;
});
}
Check the jsfiddle at : http://jsfiddle.net/tfFLt/1922/
I am trying to load DIV on button click inside another DIV and on another click it should create a new DIV inside the newly created DIV. Here is my fiddle:http://jsfiddle.net/LzCW5/4/ and my code:
HTML:
Generate
<div id='x0'>
0
</div>
JavaScript:
int level=1;
function nestDiv()
{
document.getElementById('x'+(level-1)).innerHTML="<div id='x"+level+"'>"+level+"</div>";
level++;
if(level==5)
//do somthing
}
I also want to perform some special operation when nesting level reaches 5. I am not so pro at JavaScript. So please tell me how can I achieve this?
In your code you only have to change int to var and call the function as a variable:
var level=1;
nestDiv = function()
{
document.getElementById('x'+(level-1)).innerHTML="<div id='x"+level+"'>"+level+"</div>";
level++;
}
You can see this working here
Here's how to append a div in jQuery:
var newDiv = $("<div id='x"+level+"'>"+level+"</div>");
$('#x'+(level-1)).append(newDiv);
This should replace your document.getElementById... line
My understanding as per your question:
When you click a button, add a div to another div.
Now when the user clicks another button, new div must be added in the previously created new div.
so let's break it down:
$("button").click(function() {
if($("#referenceDivId").children().length == 0) {
// if there are no children initially
$("#referenceDivId").append("<div>New div</div>");
} else if($("#referenceDivId").children().length == 5) {
// do your magic when children divs are 5
}
else {
// if it already had children
$("#referenceDivId").find("div:last").append("<div>New div</div>");
}
});
DEMO
I have a TableSorted table, and in each TD element are five SPAN elements. Four are always hidden, but upon clicking a div outside the table, certain spans are hidden dependent on which div is clicked.
I have the table sorting fine, but what I need is for the textExtraction to grab a different SPAN, depending on the value of the div which has been selected.
I've tried the following to no avail:
textExtraction:function(node){
var filter=$("div.career a.sel").text();
if(filter=="a"){var theindex=0;}
if(filter=="b"){var theindex=1;}
if(filter=="c"){var theindex=2;}
if(filter=="d"){var theindex=3;}
if(filter=="e"){var theindex=4;}
return $(node).find("span").eq(theindex).text();
}
What is the best way to achieve this?
The textExtraction function is only called when tablesorter is initialized or updated. Try triggering an update after the selection has changed.
var indexes = 'abcde'.split(''),
// Is this a select box?
$sel = $("div.career a.sel").on('change', function(){
$('table').trigger('update');
});
$('table').tablesorter({
textExtraction: function(node){
// if this is a select, get val(), not text()
var filter = $sel.val(),
theindex = $.inArray( filter, indexes );
return $(node).find("span").eq(theindex).text();
}
});
Update: for a link, try this:
var indexes = 'abcde'.split(''),
$careers = $("div.career a").on('click',function(){
var searcher = $(this).attr("rel");
$("div.career a").removeClass("sel");
$(this).addClass("sel");
$("td.stat span").hide();
$("td.stat span.career_" + searcher).show();
});
$('table').tablesorter({
textExtraction: function(node){
// find selected
var filter = $careers.filter('.sel').text(),
theindex = $.inArray( filter, indexes );
return $(node).find("span").eq(theindex).text();
}
});
Note: Don't use live() in jQuery version 1.9+, it was removed.
I am trying to implement a function which will change the elements order in a table. The logic is very easy: Each TR (except the first and the last ones) has a button_up and a button_down. When the user clicks one of those buttons, the element will change his place with the one above or below.
To do this, I am using jQuery and each TR has a unique Id and the buttons have a common class.
When a button with the specific class is clicked, I am executing this JavaScript code:
$('.upArrow').click( function(something)
{
var id = $(this).attr("id");
var n=id.split("_");
var new_id = '#row_'+n[1];
var parent =$(new_id);
var prev = $(new_id).prev();
swap(prev, parent);
init_authors_list_ordering();
});
$('.downArrow').live('click', function()
{
var id = $(this).attr("id");
var n=id.split("_");
var new_id = '#row_'+n[1];
var parent =$(new_id);
var next = $(new_id).next();
swap(next, parent);
init_authors_list_ordering();
});
}
function swap(a, b, direction)
{
var html = a.wrapInner('<tr></tr>').html();
a.replaceWith(b.wrapInner('<tr></tr>').html());
b.replaceWith(html);
}
The problem is that: The first time, everything works fine (my funxtion is not finished, I have to set some other parameters on change but the logic is there). But then, The two elements who changed their place have lost the TR's id, so they can't be touched anymore.
I don't know why the id is lost. This is the replaceWith() method.
Any help is welcome. Thank you.
To swap the elements, simply do:
function swap(a, direction, b) {
a[direction](b);
}
and call like:
var firstElem = $('#divID'),
secondElem = $('#divID');
swap(firstElem, 'before', secondElem); // or after, whatever you need ?
FIDDLE
Your constant <tr></tr> has no id attribute, so it ends up with no id attribute.
EDIT:
Here is what I reference:
function swap(a, b, direction)
{
var html = a.wrapInner('<tr></tr>').html();
a.replaceWith(b.wrapInner('<tr></tr>').html());
b.replaceWith(html);
}
I'm trying to append a div to the bottom of a another div, by clicking a button in javascript, but once the height of the outer container is reached, it no longer scrolls the list to the bottom, after an insert.
Please see the fiddle here
If you click the red add button until you get to about 13 items in the list, it seems something goes wrong with the scrollTop function, and it it no longer functions correctly (hovers around the same spot in).
I'm pretty lost on this, and have tried a bunch of different combinations of css settings for both the container and side div. Please help me.
I've reformatted your code to be more jQuery-esque. The main change, however, was to change the list.scrollTop() function so that it just scrolls to the bottom of list:
$(document).ready(function() {
var list = $("#q-d-list");
$(document).on('click', '#add', function() {
$('.active', list).removeClass("active");
var count = list.children().length + 1;
var active = $('<div />', {
'data-qid': count,
'class': 'mli active'
}).text('q' + count).appendTo(list);
list.scrollTop(list[0].scrollHeight);
});
});
Demo: http://jsfiddle.net/MrvcB/19/
Use
list.scrollTop(list.get(0).scrollHeight);
rather than
list.scrollTop($(".active").offset().top);
Try:
$(document).ready(function () {
var count = 2;
$("#add").live("click", function () {
var list= $("#q-d-list");
// remove the active class from the old item
var $clone = $(list.find("div:last-child").removeClass("active").clone());
count+=1;
var str_count = "q"+count.toString();
$clone.addClass("active").attr("data-qid",str_count).text(str_count);
list.append($clone);
list.scrollTop(list.get(0).scrollHeight);
});
});
http://jsfiddle.net/H4Kb3/