web-dev-qa-db-fra.com

créer un identifiant unique avec javascript

J'ai un formulaire où un utilisateur peut ajouter plusieurs cases de sélection pour plusieurs villes. Le problème est que chaque boîte de sélection nouvellement générée doit avoir un identifiant unique. Cela peut-il être fait avec JavaScript?

UPDATE: voici la partie du formulaire de sélection des villes. Notez également que j'utilise des php pour renseigner les villes lorsqu'un état spécifique est sélectionné.

<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>

Voici le 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/>"
     );
});
42
JamesTBennett

ne pourriez-vous pas simplement garder un index en cours d'exécution?

var _selectIndex = 0;

...code...
var newSelectBox = document.createElement("select");
newSelectBox.setAttribute("id","select-"+_selectIndex++);

MODIFIER

Après mûre réflexion, vous préférerez peut-être utiliser des noms de style tableau pour vos sélections ...

par exemple.

<select name="city[]"><option ..../></select>
<select name="city[]"><option ..../></select>
<select name="city[]"><option ..../></select>

puis, côté serveur en php par exemple:

$cities = $_POST['city']; //array of option values from selects

EDIT 2 En réponse au commentaire de l'OP

La création dynamique d’options à l’aide de méthodes DOM peut être réalisée comme suit:

var newSelectBox = document.createElement("select");
newSelectBox.setAttribute("id","select-"+_selectIndex++);

var city = null,city_opt=null;
for (var i=0, len=cities.length; i< len; i++) {
    city = cities[i];
    var city_opt = document.createElement("option");
    city_opt.setAttribute("value",city);
    city_opt.appendChild(document.createTextNode(city));
    newSelectBox.appendChild(city_opt);
}
document.getElementById("example_element").appendChild(newSelectBox);

en supposant que le tableau cities existe déjà

Sinon, vous pouvez utiliser la méthode innerHTML .....

var newSelectBox = document.createElement("select");
newSelectBox.setAttribute("id","select-"+_selectIndex++);
document.getElementById("example_element").appendChild(newSelectBox);

var city = null,htmlStr="";
for (var i=0, len=cities.length; i< len; i++) {
    city = cities[i];
    htmlStr += "<option value='" + city + "'>" + city + "</option>";
}
newSelectBox.innerHTML = htmlStr;
20
Jonathan Fingland

une autre façon d'utiliser le minuteur de la milliseconde:

var uniq = 'id' + (new Date()).getTime();
36
Scott Evernden
var id = "id" + Math.random().toString(16).slice(2)
29
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);
}
19
Guy Thomas

Une fonction très courte vous donnera un identifiant unique:

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

alerte (uid ());

11
Junaid Atari

En réponse à @scott: Parfois, JS va très vite ... alors ...

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

mettez dans votre espace de noms une instance similaire à la suivante

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

Je travaille sur un problème similaire à celui du PO et j'ai constaté que des éléments des solutions de @Guy et de @Scott peuvent être combinés pour créer une solution plus solide, à la seule OMI. L'identifiant unique résultant comporte trois sections séparées par des traits de soulignement:

  1. Une lettre principale;
  2. Un horodatage affiché en base 36;
  3. Et une dernière section aléatoire.

Cette solution devrait très bien fonctionner, même pour les très grands ensembles:

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);
}
5
yodarunamok

Pour éviter de créer des compteurs et vous assurer que l'identifiant est unique, même s'il existe d'autres composants créant des éléments avec des identifiants sur la page, vous pouvez utiliser un nombre aléatoire et le corriger s'il ne vous convient pas (mais vous devez également définir immédiatement l'identifiant pour éviter les conflits):

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
2
YakovL

Vous pouvez générer un identifiant à l'aide d'une minuterie et éviter les doublons à l'aide de performance.now():

id = 'id' + performance.now()
dup = 'id' + performance.now()

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

Notez que l'API Temps de résolution élevé est disponible dans tous les navigateurs récents .

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

Cette fonction génère des identifiants uniques uniques triés par date générée .. .. Peut également être utilisé pour les identifiants des bases de données.

1
Matthias H.

Voici une fonction (fonction genID () ci-dessous) qui vérifie de manière récursive l'unicité du DOM en fonction de l'id que vous préférez.

Dans votre cas, vous pourriez l'utiliser comme tel 

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;
     }
 }
1
Bob Sheehan

Comme d'autres l'ont dit, vous pouvez utiliser un index en cours d'exécution ou, si vous n'aimez pas l'idée d'utiliser une variable, extrayez simplement l'identifiant de la dernière ville de la liste et ajoutez 1 à son identifiant.

1
qw3n

La combinaison aléatoire et date en ms devrait faire l'affaire avec pratiquement aucun changement de collision:

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

0
Bibou

Voici ma propre prise en main basée sur le xpath de l'élément créé:

/** 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();
}

D'abord, le xpath de l'élément est récupéré. 

Le hashcode du xpath est ensuite calculé. Nous avons donc un identifiant unique par xpath.

Le problème ici est que xpath n'est pas nécessairement unique si des éléments uniques sont générés à la volée. Ainsi, nous ajoutons l'horodatage à la fin.

Peut-être pourrions-nous aussi garantir des éléments plus uniques en ajoutant une dernière Math.Random ().

0
Laurent B

J'utilise une fonction comme celle-ci:

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

Dans le paramètre baseId, j'indique un préfixe pour que l'identifiant soit plus facile à identifier.

0
Ricardo Pereira

Vous pourriez tirer parti de closure.

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

Si vous voulez le joindre:

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

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

generator pourrait accepter un préfixe par défaut; generateId peut accepter un suffixe facultatif:

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

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

Cela est pratique si vous voulez que votre identifiant indique une séquence, très semblable à new Date().getTime(), mais plus facile à lire.

0
roland

Avertissement: Cette réponse peut ne pas être bonne pour l’intention générale de cette question, mais je la poste ici néanmoins, car elle résout une version partielle de ce problème.

Vous pouvez utiliser la variable uniqueId de lodash (documentation ici ). Ce n'est pas un bon générateur uniqueId pour, par exemple, des enregistrements de base de données ou des éléments qui conserveront une session dans un navigateur ou quelque chose comme ça. Mais la raison pour laquelle je suis venu ici pour chercher cela a été résolu en l'utilisant. Si vous avez besoin d'un identifiant unique pour quelque chose d'assez transitoire, cela suffira.

J'en avais besoin parce que je créais un composant réactif réutilisable comportant une étiquette et un contrôle de formulaire. L'étiquette doit avoir un attribut for="controlId", correspondant au id="controlId" que possède le contrôle de formulaire actuel (l'élément input ou select). Cet identifiant n'est pas nécessaire en dehors de ce contexte, mais je dois générer un identifiant pour les deux attributs à partager et m'assurer que cet identifiant est unique dans le contexte de la page en cours de rendu. Donc, la fonction de lodash a bien fonctionné. Juste au cas où est utile pour quelqu'un d'autre.

0
Ernesto

Le hasard est non unique. Les valeurs Times sont non unique. Les concepts sont assez différents et la différence monte en beauté lorsque votre application est mise à l’échelle et distribuée. Plusieurs des réponses ci-dessus sont potentiellement dangereuses.

Les UUID constituent une approche plus sûre de l'affiche: Créer GUID/UUID en JavaScript?

0
javajon