1

I tried the following:

HTML:

<div contenteditable="true" id="editable"></div>

JS:

$('#editable').keyup(function() {
    addID();
});

function addID()
{
    $('#editable *').each(function() {

        var t = GenerateID();

        $(this).attr('id','id-' + t);

    });
}

function GenerateID() 
{
    var str = 'abcdefghijklmnopqrstuvwxyz0123456789';

    var alphabet = '', 
        genID = '';

    while(genID.length < 5)
    {
        alphabet = str.charAt(Math.floor(Math.random() * str.length)); 
        genID += alphabet;
    }

    return genID;
}

But on every keyup it keeps on changing the ID.

How can I just set the id once for all the elements while typing, and still keep it unique throughout the div ?

JSFiddle

Devang Mistry
  • 402
  • 2
  • 5
  • 21

3 Answers3

1

LAST UPDATE: Now I checked the code in your fiddle and I'm sure it works. The checking for uniqueness can probably be made into a function, but i'll leave that to you:

$('#editable').on( 'keyup', addID );


var count = 0;  // this will absolutely ensure that ID will be unique

function addID(){  

    var previousIDs = [];

    $('#editable *').each(function() {

        count++;
        var thisID = $(this).attr( 'id' );

        // let's check if we have duplicates:
        var index = 0, len = previousIDs.length, isDuplicate = false;

        for( index = 0; index < len; index++ ){
            if ( thisID === previousIDs[index] ) { 
                isDuplicate = true; 
                break;
            }
        }


        // now change the ID if needed:
        if (  isDuplicate    ||    ! thisID  ){

            var t = GenerateID();
            var newID = 'id-' + t + '-' + count;

            $(this).attr('id', newID);
            previousIDs.push( newID );

        }else{
            previousIDs.push( thisID );
        }

    });
}

Working Fiddle

Devang Mistry
  • 402
  • 2
  • 5
  • 21
Sorin C
  • 984
  • 10
  • 8
  • That is also repeating the id value! – Devang Mistry Aug 08 '15 at 17:20
  • So let me get this straight: you want to give a unique ID to all children of `#editable`, and you want to do this the first time a user hits a key. After that, stop changing the IDs. Is my understanding correct? – Sorin C Aug 08 '15 at 17:27
  • Stop changing IDs of the one's that have been set once. With what you suggested, it assigns the ID once only but then when you hit enter, the contenteditable div creates another `div` and assigns it the same value that the previous one was assigned. As the doc says, the value of an id should be unique throughout the document. – Devang Mistry Aug 08 '15 at 17:32
  • i don't see any code that creates a new div! Where is it? – Sorin C Aug 08 '15 at 17:41
  • check in the inspector of your browser! – Devang Mistry Aug 08 '15 at 17:42
  • 0ops! still doesn't work! I got this : `
    elem1
    elem2
    elem3

    `
    – Devang Mistry Aug 08 '15 at 18:27
  • Thanks! It works. I just have a doubt that as more the number of elements are added, the array will get bigger and so wouldn't it affect the performance ? – Devang Mistry Aug 09 '15 at 07:11
  • It most definetely will get slower as elements pile up. But you will have to test how many elements you can add before it gets slow. I suspect in a normal use case, you will have no problem with speed. However, if you want to be able to add a LOT of elements, then some optimizations can be made. Right now, the most significant optimization that I can think of is adjusting your selector `$('#editable *')`. You could gain a lot if you could be more specific. The array problem would be greatly reduced, or possibly even eliminated completely... – Sorin C Aug 09 '15 at 07:26
  • adjusting the selector means being more specific like `$('#editable div')` instead of selecting all the child elements like this `$('#editable * ')` ? – Devang Mistry Aug 09 '15 at 07:36
  • Exactly. Reduce to the minimum the number of selected elements. Select only those that absolutely need an ID. Going further with your example, I think that by selecting only the direct children `$('#editable > div')`, you will no longer need that array. – Sorin C Aug 09 '15 at 07:55
0

Try this:

$('#editable').keyup(addID);
function addID() {
    $('#editable *').each(function () {
        var t = GenerateID();
        var elem = $(this);
        var attr = elem.attr('id');
        if (!attr) {
            elem.attr('id', 'id-' + t);
        }
    });
}
/**
 * @return {string}
 */
function GenerateID() {
    var str = 'abcdefghijklmnopqrstuvwxyz0123456789';
    var alphabet = '',
            genID = '';
    while (genID.length < 5) {
        alphabet = str.charAt(Math.floor(Math.random() * str.length));
        genID += alphabet;
    }
    return genID;
}

Also consider that your random string generator may generate same string again.

Rayon
  • 36,219
  • 4
  • 49
  • 76
0

Replace your code with following :

$('#editable *').each(function() {

        if(!$(this).hasClass("idgenerated")){
            console.log( $(this).attr('id') );

            var t = GenerateID();

            $(this).attr('id','id-' + t);
            $(this).addClass("idgenerated");
            console.log($(this).prop("tagName") + ' = ' + t);
        }
});

Working fiddle

Bhavin Panchani
  • 1,332
  • 11
  • 17