[javascript] create unique id with javascript

I have a form where a user can add multiple select boxes for multiple cities. The problem is that each newly generated select box needs to have a unique id. Can this be done is JavaScript?

UPDATE: here is the part of the form for selecting cities. Also note that i'm using some php to fill in the cities when a specific state is selected.

<form id="form" name="form" method="post" action="citySelect.php">
<select id="state" name="state" onchange="getCity()">
    <option></option>
    <option value="1">cali</option>
    <option value="2">arizona</option>
    <option value="3">texas</option>
</select>
<select id="city" name="city" style="width:100px">

</select>

    <br/>
</form>

Here is the javascript:

$("#bt").click(function() {

$("#form").append(
       "<select id='state' name='state' onchange='getCity()'>
           <option></option>
           <option value='1'>cali</option>
           <option value='2'>arizona</option>
           <option value='3'>texas</option>
        </select>
        <select id='city' name='city' style='width:100px'></select><br/>"
     );
});

This question is related to javascript html select dynamic

The answer is


For generate unique id's:

const uid = () =>
  String(
    Date.now().toString(32) +
      Math.random().toString(32) +
      Math.random().toString(32)
  ).replace(/\./g, '')

For check that is works:

var size = 500000
var arr = new Array(size)
  .fill(0)
  .map(() => uid())

var b = new Set(arr)

console.log(
  size === b.size ? 'all ids are unique' : `not unique records ${size - b.size}`
)

No external libraries needed. Uniqueness proved.

You could do something like this.

_x000D_
_x000D_
// Function to generate unique id_x000D_
_x000D_
const uniqueId = (length=16) => {_x000D_
  return parseInt(Math.ceil(Math.random() * Date.now()).toPrecision(length).toString().replace(".", ""))_x000D_
}_x000D_
_x000D_
// ----------------------------_x000D_
_x000D_
document.querySelector("#butt01").onclick = () => {_x000D_
  document.querySelector("#span01").innerHTML = uniqueId()_x000D_
}_x000D_
_x000D_
ids = []_x000D_
count = 0_x000D_
document.querySelector("#butt02").onclick = () => {_x000D_
  for (let i = 0; i< 1000; i++){_x000D_
    ids.push(uniqueId())_x000D_
  }_x000D_
  for (el of ids){_x000D_
    for (ell of ids){_x000D_
      if(el == ell && ids.indexOf(el) != ids.indexOf(ell)){_x000D_
        count += 1_x000D_
      }_x000D_
    }_x000D_
  }_x000D_
  document.querySelector("#span02").innerHTML = `Found ${count} duplicated random values.`_x000D_
}
_x000D_
<button id="butt01">Generate</button>_x000D_
<br>_x000D_
<span id="span01"></span>_x000D_
<br>_x000D_
<hr>_x000D_
<br>_x000D_
<button id="butt02">Check collision potentiality in 1000 cases</button>_x000D_
<br>_x000D_
<span id="span02"></span>
_x000D_
_x000D_
_x000D_

Multiply time in milliseconds since epoch with a random value to fixed size.

Run this to see possible collisions.

You would see there are no collisions whether it is 1000, 10000 or 1000000000.

It would have a very small chance if two users generate ids at the same time and gets the rame random number.

To increase the uniqueness you could multiply date more Math.random()s.


Here's my own take at it based on the xpath of the element created :

/** Returns the XPATH of an element **/
var getPathTo = function(element) {
  if (element===document.body)
      return element.tagName;

  var ix= 0;
  var siblings= element.parentNode.childNodes;
  for (var i= 0; i<siblings.length; i++) {
      var sibling= siblings[i];
      if (sibling===element)
          // stripped xpath (parent xpath + tagname + index)
          return getPathTo(element.parentNode)+ element.tagName + ix+1;
      if (sibling.nodeType===1 && sibling.tagName===element.tagName)
          ix++;
   }
}

/** hashcode function (credit http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery **/
var hashCode = function(str) {
  var hash = 0, i, chr, len;
  if (str.length === 0) return hash;
  for (i = 0, len = str.length; i < len; i++) {
    chr   = str.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
 }
return hash;
};

/** Genaretes according to xpath + timestamp **/
var generateUID = function(ele)
{
  return hashCode(getPathTo(ele)) + new Date().getTime();
}

First the xpath of the element is fetched.

The hashcode of the xpath is then computed. We therefore have a unique id per xpath.

The problem here is that xpath are not necesseraly unique if unique elements are generated on the fly. Thus we add the timestamp at the end.

Maybe we could also garantee more unique elements by adding a final Math.Random().


You could take advantage of closure.

var i = 0;
function generateId() {
    return i++;
}

If you want to enclose it:

function generator() {
  var i = 0;
  return function() {
    return i++;
  };
}

var generateId = generator();
generateId(); //1
generateId(); //2

generator could accept a default prefix; generateId coud accept an optional suffix:

function generator(prefix) {
  var i = 0;
  return function(suffix) {
    return prefix + (i++) + (suffix || '');
  };
}

var generateId = generator('_');
generateId('_'); //_1_
generateId('@'); //_2@

This comes in handy if you want your id to indicate a sequence, very much like new Date().getTime(), but easier to read.


Like others said you can use a running index, or if you don't like the idea of using a variable just pull the id of the last city in the list and add 1 to its id.


function uniqueid(){
    // always start with a letter (for DOM friendlyness)
    var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
    do {                
        // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
        var ascicode=Math.floor((Math.random()*42)+48);
        if (ascicode<58 || ascicode>64){
            // exclude all chars between : (58) and @ (64)
            idstr+=String.fromCharCode(ascicode);    
        }                
    } while (idstr.length<32);

    return (idstr);
}

You could generate an ID using a timer and avoiding duplicates using performance.now():

_x000D_
_x000D_
id = 'id' + performance.now()_x000D_
dup = 'id' + performance.now()_x000D_
_x000D_
console.log(id)_x000D_
console.log(id.replace('.','')) // sexy id_x000D_
console.log(id === dup) // false!
_x000D_
.as-console-wrapper{border-top: none !important;overflow-y: auto !important;top: 0;}
_x000D_
_x000D_
_x000D_

Note that the High resolution time API is available in all recent browsers.


To avoid creating any counters and be sure that the id is unique even if there are some other components that create elements with ids on the page, you can use a random number and than correct it if it's not good enough (but you also have to set the id immediately to avoid conflicts):

var id = "item"+(new Date()).getMilliseconds()+Math.floor(Math.random()*1000);
 // or use any random number generator
 // whatever prefix can be used instead of "item"
while(document.getElementById(id))
    id += 1;
//# set id right here so that no element can get that id between the check and setting it

Here is a function (function genID() below) that recursively checks the DOM for uniqueness based on whatever id prefex/ID you want.

In your case you'd might use it as such

var seedNum = 1;
newSelectBox.setAttribute("id",genID('state-',seedNum));

function genID(myKey, seedNum){
     var key = myKey + seedNum;
     if (document.getElementById(key) != null){
         return genID(myKey, ++seedNum);
     }
     else{
         return key;
     }
 }

var id = "id" + Math.random().toString(16).slice(2)

function generateId() {
       
return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
       
    
}

console.log(generateId())

There are two packages available for this.

  • For short unique id generation nanoid link
import { nanoid } from 'nanoid'
const id = nanoid()    // "Uakgb_J5m9g-0JDMbcJqLJ"
const id = nanoid(10)  // "jcNqc0UAWK"
  • For universally unique id generation uuid link
import { v4 as uuidv4 } from 'uuid';
const id= uuidv4();    // quite big id

I use a function like the following:

function (baseId) {
  return baseId + '-' + Math.random().toString(16).slice(2);
}

In parameter baseId I indicate a prefix for the id to be easier to identify the elements.


put in your namespace an instance similar to the following one

var myns = {/*.....*/};
myns.uid = new function () {
    var u = 0;
    this.toString = function () {
        return 'myID_' + u++;
    };
};
console.dir([myns.uid, myns.uid, myns.uid]);

Random is not unique. Times values are not unique. The concepts are quite different and the difference rears its ugly head when your application scales and is distributed. Many of the answers above are potentially dangerous.

A safer approach to the poster's question is UUIDs: Create GUID / UUID in JavaScript?


I'm working on a similar problem to the OP, and found that elements of the solutions from @Guy and @Scott can be combined to create a solution that's more solid IMO. The resulting unique id here has three sections separated by underscores:

  1. A leading letter;
  2. A timestamp displayed in base 36;
  3. And a final, random section.

This solution should work really well, even for very large sets:

function uniqueId () {
    // desired length of Id
    var idStrLen = 32;
    // always start with a letter -- base 36 makes for a nice shortcut
    var idStr = (Math.floor((Math.random() * 25)) + 10).toString(36) + "_";
    // add a timestamp in milliseconds (base 36 again) as the base
    idStr += (new Date()).getTime().toString(36) + "_";
    // similar to above, complete the Id using random, alphanumeric characters
    do {
        idStr += (Math.floor((Math.random() * 35))).toString(36);
    } while (idStr.length < idStrLen);

    return (idStr);
}

    const generateUniqueId = () => 'id_' + Date.now() + String(Math.random()).substr(2);

    // if u want to check for collision
    const arr = [];
    const checkForCollision = () => {
      for (let i = 0; i < 10000; i++) {
        const el = generateUniqueId();
        if (arr.indexOf(el) > -1) {
          alert('COLLISION FOUND');
        }
        arr.push(el);
      }
    };

Look at this tiny beauty, this will get ur job done.

function (length) {
    var id = '';
    do { id += Math.random().toString(36).substr(2); } while (id.length < length);
    return id.substr(0, length);
}

Simple Solution :)

const ID = (_length=13) => {
  // Math.random to base 36 (numbers, letters),
  // grab the first 9 characters
  // after the decimal.
  return '_' + Math.random().toString(36).substr(2, _length); // max _length should be less then 13
};
console.log("Example ID()::", ID())

const uid = function(){
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
}

This Function generates very unique IDs that are sorted by its generated Date. Also useable for IDs in Databases.


Warning: This answer may not be good for the general intent of this question, but I post it here nevertheless, because it solves a partial version of this issue.

You can use lodash's uniqueId (documentation here). This is not a good uniqueId generator for say, db records, or things that will persist a session in a browser or something like that. But the reason I came here looking for this was solved by using it. If you need a unique id for something transient enough, this will do.

I needed it because I was creating a reusable react component that features a label and a form control. The label needs to have a for="controlId" attribute, corresponding to the id="controlId" that the actual form control has (the input or select element). This id is not necessary out of this context, but I need to generate one id for both attributes to share, and make sure this id is unique in the context of the page being rendered. So lodash's function worked just fine. Just in case is useful for someone else.


Very short function will give you unique ID:

var uid = (function(){var id=0;return function(){if(arguments[0]===0)id=0;return id++;}})();

alert ( uid() );


Combining random & date in ms should do the trick with almost no change of collision :

_x000D_
_x000D_
function uniqid(){_x000D_
  return Math.random().toString(16).slice(2)+(new Date()).getTime()+Math.random().toString(16).slice(2);_x000D_
}_x000D_
alert(uniqid()+"\r"+uniqid());
_x000D_
_x000D_
_x000D_


In reply to @scott : Sometime JS go very fast... so...

var uniqueId = null,
    getUniqueName = function(prefix) {
        if (!uniqueId) uniqueId = (new Date()).getTime();
        return (prefix || 'id') + (uniqueId++);
    };

another way it to use the millisecond timer:

var uniq = 'id' + (new Date()).getTime();

I think if you really want to have a unique ID then the best approach is to use a library like:
uuid or uniqueid

Note: Unique ID is not the same as Random ID

To use only date time milliseconds approach is wrong.
Nowadays computers are fast enough and able to run more than one iteration of a loop in a single millisecond.

npm install uuid

Importing the library:

If you are using ES modules

import { v4 as uuidv4 } from 'uuid';

And for CommonJS:

const { v4: uuidv4 } = require('uuid');

Usage:

uuidv4();

// This will output something like: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d

let transactionId =${new Date().getDate()}${new Date().getHours()}${new Date().getSeconds()}${new Date().getMilliseconds()}

_x000D_
_x000D_
let transactionId =`${new Date().getDate()}${new Date().getHours()}${new Date().getSeconds()}${new Date().getMilliseconds()}` 

console.log(transactionId)
_x000D_
_x000D_
_x000D_


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to select

Warning: Use the 'defaultValue' or 'value' props on <select> instead of setting 'selected' on <option> SQL query to check if a name begins and ends with a vowel Angular2 *ngFor in select list, set active based on string from object SQL: Two select statements in one query How to get selected value of a dropdown menu in ReactJS DATEDIFF function in Oracle How to filter an array of objects based on values in an inner array with jq? Select unique values with 'select' function in 'dplyr' library how to set select element as readonly ('disabled' doesnt pass select value on server) Trying to use INNER JOIN and GROUP BY SQL with SUM Function, Not Working

Examples related to dynamic

Please help me convert this script to a simple image slider Declare an empty two-dimensional array in Javascript? Compiling dynamic HTML strings from database Changing datagridview cell color dynamically What is the difference between dynamic programming and greedy approach? Dynamic variable names in Bash Dynamically Add C# Properties at Runtime How to generate a HTML page dynamically using PHP? Change UITableView height dynamically How to create own dynamic type or dynamic object in C#?