2010-07-12 20 views
38

Tengo un formulario donde un usuario puede agregar múltiples cuadros de selección para varias ciudades. El problema es que cada cuadro de selección generado recientemente debe tener una identificación única. ¿Se puede hacer esto con JavaScript?crear identificación única con javascript

ACTUALIZACIÓN: esta es la parte del formulario para seleccionar ciudades. También tenga en cuenta que estoy usando algunos php para completar las ciudades cuando se selecciona un estado específico.

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

Aquí está el 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/>" 
    ); 
}); 
+0

¿Estás usando un framework/toolkit como Jquery o simplemente vanilla js? Además, ¿puedes publicar algo de tu código, al menos la salida html generada? – DeaconDesperado

+0

Puede ser mejor que use botones de opción para este tipo de comportamiento. De lo contrario, en Javascript puede encontrar un nombre como 'ciudades' y luego usar un iterador como 'var i = 0;' para cada cuadro de selección, haga .setAttribute ('id', 'cities' + i). getElementsByTagName ('?') ayudará aquí. Tendrá que proporcionar un poco de muestra HTML para que alguien realmente lo ayude. – Metalshark

+1

¿Está preguntando sobre la generación de un atributo de id único para cada nueva ? Puede, en javascript, mantener una referencia al nuevo elemento DOM específico, en lugar de solo su id. Por lo tanto, no tiene que generar una ID única, según lo que esté tratando de hacer. – pioto

Respuesta

20

se puede no sólo mantener un índice de ejecución?

var _selectIndex = 0; 

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

EDITAR

tras un nuevo estudio, en realidad se puede preferir utilizar los nombres de tipo matriz para sus selecciona ...

por ejemplo,

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

entonces, en el lado de servidor en php por ejemplo:

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

EDIT 2 En respuesta al comentario OP

la creación dinámica de opciones utilizando métodos DOM se puede hacer como sigue:

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

suponiendo que el cities gama ya existe

otra posibilidad es utilizar el método 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; 
+0

¿Cómo inserto la etiqueta en la selección con esto? – JamesTBennett

+0

Tenga en cuenta que el uso de un contador en ejecución puede provocar colisiones extremadamente probables * entre aciertos de página *. En otras palabras, si el contador comienza en 1 cada vez que se carga la página, es probable que colisione la próxima vez que edite/actualice el objeto. Es bueno tener esto en cuenta. –

34

otra forma que utilice el temporizador de milisegundo:

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

Puede tener el doble de la misma identificación ... ver mi código con Fix ... – molokoloco

+2

parecen no ser una buena idea '(+ new Date + + new Date)/2 === + new Date;' – fedeghe

+1

¿Qué sucede si el usuario crea la ID en un país diferente? \ –

1

Al igual que otros dijeron se puede utilizar una Ejecutando índice, o si no te gusta la idea de usar una variable, simplemente toma el ID de la última ciudad de la lista y agrega 1 a su ID.

9

En respuesta a @scott: En algún momento, JS va muy rápido ... así que ...

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

A menos que estés equivocado eso solo verificaría un duplicado una vez? –

+0

no está buscando un duplicado, ya que está incrementando el último valor numérico. –

+0

Por cierto, si configura su 'uniqueId' inicial de inmediato, no necesitará la condición. –

18
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); 
} 
+1

Es posible que desee explicar su respuesta para el beneficio de OP – Luca

+0

¿Cuál es la posibilidad de que usted genere la misma ID con este ejemplo? Parece posible, pero altamente improbable. – user699242

+1

teniendo en cuenta que el RNG en javascript es una mierda, es más probable de lo que piensas. – Nisk

10

función muy corto le dará la identificación única:

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

alerta (UID());

+0

fallará si por casualidad tiene un elemento con la siguiente identificación en línea que ya está en la página. – Michael

+0

Lo usé en muchos proyectos, ¡nunca he encontrado ningún problema! –

6

puesto en su espacio de nombres de una instancia similar a la siguiente

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

+1! myns.uid + 1 myns.uid * 1 funciona –

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

aunque remota la probabilidad de colisión no es nula – fedeghe

4

Estoy trabajando en un problema similar al OP, y se encontró que los elementos de las soluciones de @Guy y @Scott se puede combinar para crear una solución que sea más sólida. El ID único resultante aquí tiene tres secciones separadas por guiones bajos:

  1. Una letra inicial;
  2. Una marca de tiempo que se muestra en la base 36;
  3. Y una sección final, al azar.

Esta solución debe funcionar muy bien, incluso para conjuntos muy grandes:

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); 
} 
+0

bastante confiable –

+0

Gracias - así es como modifiqué mi uso. Reutilicé el código, reemplazando la línea de la letra con var IdStr = ''; Luego configuré el IdStrLen en 16 para darme una identificación ordenable (tiempo) como: ivm859mg_9dl74lu – MarkNHopgood

0

Aquí es mi propia toma en ello basa en el XPath del elemento creado:

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

En primer lugar el xpath del elemento es buscado.

El código hash de xpath se calcula. Por lo tanto, tenemos una identificación única por xpath.

El problema aquí es que xpath no es necesariamente único si se generan elementos únicos sobre la marcha. Por lo tanto, agregamos la marca de tiempo al final.

Tal vez también podamos garantizar elementos más únicos agregando un Math.Random final().

1

Aquí hay una función (función genID() a continuación) que revisa de manera recursiva el DOM para determinar la unicidad según el Id. De preferencia/ID que desee.

En el caso de que le puede utilizar como tal

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; 
    } 
} 
0

Usted podría tomar ventaja de closure.

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

Si quiere encerrarlo:

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

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

generator podría aceptar un prefijo predeterminado; generateId coud aceptar un sufijo opcional:

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

var generateId = generator('_'); 
generateId('_'); //_1_ 
generateId('@'); //[email protected] 

Esto es útil si desea que su ID para indicar una secuencia, muy parecido a new Date().getTime(), pero más fácil de leer.

2

Para evitar crear contadores y asegurarse de que el ID sea único incluso si hay otros componentes que crean elementos con identificadores en la página, puede usar un número aleatorio y corregirlo si no es lo suficientemente bueno (pero también hay que ajustar el ID de inmediato para evitar conflictos):

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 
0

podría generar una identificación usando un temporizador y evitar duplicados usando 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;}

Tenga en cuenta que el High resolution time API is available in all recent browsers.

0

Puedo utilizar una función como la siguiente:

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

En parámetro baseId I indican un prefijo para el ID de ser más fáciles de identificar los elementos.

0

Advertencia: Esta respuesta puede no ser buena para el propósito general de esta pregunta, pero la publico aquí sin embargo, porque resuelve una versión parcial de este problema.

Puede usar lodash's uniqueId (documentación here). Este no es un buen generador de Id único para registros de db, db, o cosas que persistirán en una sesión en un navegador o algo así. Pero el motivo por el que vine aquí en busca de esto se solucionó al usarlo. Si necesita una identificación única para algo transitorio, esto servirá.

Lo necesitaba porque estaba creando un componente de reacción reutilizable que tiene una etiqueta y un control de formulario. La etiqueta debe tener un atributo for="controlId", correspondiente al id="controlId" que tiene el control de formulario real (la entrada o elemento de selección). Esta identificación no es necesaria fuera de este contexto, pero necesito generar una identificación para compartir ambos atributos y asegurarme de que esta identificación sea única en el contexto de la página que se está procesando. Así que la función de Lodash funcionó bien. Por si acaso, es útil para otra persona.

Cuestiones relacionadas