0

I try to have unique names to cloned checkboxes, and instead of getting, let's say:

 Origin_1, Origin_2, Origin_3, for cloned 1, 2, 3 of the same element,

I get:

Origin_1, Orignin_11, Origin_111

I understand the issue: the clone, uses the past clone as origin name. I do not know what should be the approach to go around. Either finding a way to use the very original name, or trim by one character the name of the previous clone and make sure the counter does not start at the begining again. Your hints will be appreciated.

Here is the javascript code:

$(window).load(function() { 
    var bindFunction = $('#quickmenuall input:checkbox').change(function(){ 
        var uniqueId = 1;
        var currentName = $(this).attr('name'); 
        newName = currentName + (uniqueId++);
        if($(this).is(':checked')){
            var clonedClient = $(this).parent().parent().parent().parent().parent().clone(true) 
            var ori = $(this).parent().parent().parent().parent().parent() 
            clonedClient.insertBefore(ori)
            $(this).attr('name', newName)
            var clonedClient = $(this);
            $(this).prop('checked', false)
        } else {
            var clonedClient = $(this);
            clonedClient.parent().parent().parent().parent().parent().remove() 
            checkbox.bind("change", bindFunction);
            bindFunction();
        }
    });
});

Here is a jsfiddle : http://jsfiddle.net/Sergelie/ULywc/

Sergelie
  • 363
  • 1
  • 14
  • 1
    `parent().parent().parent().parent().parent()` you are not doing this right – rafaelcastrocouto Mar 11 '14 at 00:29
  • Could you supply a fiddle please? just noticed, can you put ```var uniqueId = 1;``` outside ```change``` event so it wont get overwritten everytime? – Varinder Mar 11 '14 at 00:29
  • Avoid using chained ```parent()``` methods - try using ```closest()``` more info here: http://api.jquery.com/closest/ – Varinder Mar 11 '14 at 00:31
  • you could setup a template and create new items from it - See http://stackoverflow.com/questions/13487647/understanding-jquery-template – blurfus Mar 11 '14 at 00:32
  • @Varinder here is the jsfiddle (I got rid of several parent() : http://jsfiddle.net/Sergelie/ULywc/ – Sergelie Mar 11 '14 at 00:44

3 Answers3

0

currentName is a String and you are concatenating an Integer to it.

newName = "1"+1; // "11"
newName = 1+1; // 2

To solve your immediate issue, using regular expressions, match the digit/numeric part of the currentName and parse it into an integer before adding your uniqueId to it.

// Regex goes something like
// starts with a non-digit character 1 or more times 
// followed by and ending with zero or more digits
var nameParts = currentName.match(/^([^0-9]+)(\d*)$/);
newName = nameParts[1] + (parseInt(nameParts[2]||0) + uniqueId++);

FIDDLE Fork

UPDATE

Check out this FIDDLE

Read the comments below for explanation. You no longer need uniqueId I believe.

input[name^="F_1_"] gets all the clones (starts with F_1_) input[name="F_1"], gets the original

var currentName = $(this).attr('name'); 
// We are again matching the core part of the clone element to get the itemFamily
var nameParts = currentName.match(/^([^0-9]+(_[0-9]+))(_[0-9]+)?$/);
// Then we use the attribute starts with selector and attribute equals to selector
// to get the original and all clones of with the core itemFamily name part
// the length attribute will be your next number in the item family clone.
var itemFamilyCount = $('input[name^="'+nameParts[1]+'_"], input[name="'+nameParts[1]+'"]').length;
newName = nameParts[1] + '_' + itemFamilyCount;
cbayram
  • 2,259
  • 11
  • 9
  • Thanks @cbayram, we are getting there! Although, I did not mention (I did not realise, at that point it would become important) that my Names are created dynamically in this way : F_1, F_2, F_3, F_4 (could go to F_100dreds, so when cloning, if F_1 clone is named F_2, I have a problem with the real F_2. So, your solution would be perfect if the result would be added to the original name without trunkating anything. (I am not a programmer, but I can understand and adapt)! – Sergelie Mar 11 '14 at 02:20
  • Fiddle from yours adapted with real "Names" situation. – Sergelie Mar 11 '14 at 02:37
  • @user3371049, I think I get you. If I clone F_1 two times, can I have 2 F_12s or should it be F_12 and F_13? – cbayram Mar 11 '14 at 02:38
  • The best solution is to keep the integrality of the original name, as the basis of clones name and add an incremental number to it, for clone 2, 3, 4, etc. – Sergelie Mar 11 '14 at 02:45
  • @user3371049, but if there already is a F_11 (original), this would conflict if you create a clone of F_1 which would also be F_11. Is F_1_1, F_1_2, F_1_3, ... acceptable to resolve this conflict? – cbayram Mar 11 '14 at 02:46
  • damn! you are right! Let's do some thinking! @cbayram – Sergelie Mar 11 '14 at 02:50
  • I mean, starting all clone's "addition" name with _ should be the solution @cbayram – Sergelie Mar 11 '14 at 02:52
  • @user3371049, Let me know if the updated Fiddle/solution works for you and makes sense. – cbayram Mar 11 '14 at 03:06
  • you are great, thanks a lot! it is the perfect solution. Was incapable to solve it myself! Thank you. – Sergelie Mar 11 '14 at 03:18
0

Part of the problem is that your uniqueId is declared in scope of the change function, and so will always start with 1. Also, you are using the post-increment operator (uniqueId++) which changes 1 into 2 AFTER you assign it to newName. This is why you get "1", "11", "111", etc. Try moving uniqueId into window.load (for example).

Try this:

$(window).load(function() { 
        var uniqueId = 1;

    var bindFunction = $('#quickmenuall input:checkbox').change(function(){ 
        var currentName = $(this).attr('name'); 
        newName = currentName + (uniqueId++);
        if($(this).is(':checked')){
            var clonedClient = $(this).parent().parent().parent().parent().parent().clone(true) 
            var ori = $(this).parent().parent().parent().parent().parent() 
            clonedClient.insertBefore(ori)
            $(this).attr('name', newName)
            var clonedClient = $(this);
            $(this).prop('checked', false)
        } else {
            var clonedClient = $(this);
            clonedClient.parent().parent().parent().parent().parent().remove() 
            checkbox.bind("change", bindFunction);
            bindFunction();
        }
    });
});

and either combine this with the regular expression method also suggested, or simply save off a "prefix" ID for your checkboxes.

var prefix = 'checkbox_';
var uniqueId = 1;
var id1 = prefix + (uniqueId++).toString(); // checkbox_1
var id2 = prefix + (uniqueId++).toString(); // checkbox_2
var id3 = prefix + (uniqueId++).toString(); // checkbox_3
nothingisnecessary
  • 6,099
  • 36
  • 60
0

you will need to get the original name by using either regex or substring()

I have managed to make it work with substring, because i know that I am building my clones such as One_1 One_2 etc... However, it is better to do it with regex such as in the other answer from @cbayram. I will build a regex and update the fiddle when i have time.

var lastIndexOf_ = oldName.lastIndexOf('_');
// we build the clones with and underscore + number. get substring from the beginning of     the oldName until the "_"
if (lastIndexOf_ != -1)
    oldName = oldName.substring(0,lastIndexOf_);
// else just use the oldName
var newName = oldName + '_' + i++; // build new name and increment counter.

please check this jsfiddle http://jsfiddle.net/houssamk/Dzr58/39/

i also reworked and cleaned up how the event handler is bound. i use $.on() instead of bind(). $.on() is much better because it attaches the event handler dynamically when new clones are created.

hope it helps

houss
  • 670
  • 5
  • 9