2010-04-24 26 views
47

¿Existe alguna solución al problema ilustrado en el siguiente código? Comience por abrir el código en un navegador para ir directo al grano y no tener que buscar todo ese código antes de saber lo que está buscando.¿Cómo puedo usar el atributo FOR de una etiqueta LABEL sin el atributo ID en la etiqueta INPUT

<html> 
<head> 
    <title>Input ID creates problems</title> 
    <style type="text/css"> 
    #prologue, #summary { margin: 5em; } 
    </style> 
</head> 
<body> 
    <h1>Input ID creates a bug</h1> 
    <p id="prologue"> 
    In this example, I make a list of checkboxes representing things which could appear in a book. If you want some in your book, you check them: 
    </p> 
    <form> 
    <ul> 
    <li> 
    <input type="checkbox" id="prologue" /> 
    <label for="prologue">prologue</label> 
    </li> 
    <li> 
    <input type="checkbox" id="chapter" /> 
    <label for="chapter">chapter</label> 
    </li> 
    <li> 
    <input type="checkbox" id="summary" /> 
    <label for="summary">summary</label> 
    </li> 
    <li> 
    <input type="checkbox" id="etc" /> 
    <label for="etc">etc</label> 
    <label> 
    </li> 
    </ul> 
    </form> 
    <p id="summary"> 
    For each checkbox, I want to assign an ID so that clicking a label checks the corresponding checkbox. The problems occur when other elements in the page already use those IDs. In this case, a CSS declaration was made to add margins to the two paragraphs which IDs are "prologue" and "summary", but because of the IDs given to the checkboxes, the checkboxes named "prologue" and "summary" are also affected by this declaration. The following links simply call a javascript function which writes out the element whose id is <a href="javascript:alert(document.getElementById('prologue'));">prologue</a> and <a href="javascript:alert(document.getElementById('summary'));">summary</a>, respectively. In the first case (prologue), the script writes out [object HTMLParagraphElement], because the first element found with id "prologue" is a paragraph. But in the second case (summary), the script writes out [object HTMLInputElement] because the first element found with id "summary" is an input. In the case of another script, the consequences of this mix up could have been much more dramatic. Now try clicking on the label prologue in the list above. It does not check the checkbox as clicking on any other label. This is because it finds the paragraph whose ID is also "prologue" and tries to check that instead. By the way, if there were another checkbox whose id was "prologue", then clicking on the label would check the one which appears first in the code. 
    </p> 
    <p> 
    An easy fix for this would be to chose other IDs for the checkboxes, but this doesn't apply if these IDs are given dynamically, by a php script for example. 
    Another easy fix for this would be to write labels like this: 
    <pre> 
    &lt;label&gt;&lt;input type="checkbox" /&gt;prologue&lt;/label&gt; 
    </pre> 
    and not need to give an ID to the checkboxes. But this only works if the label and checkbox are next to each other. 
    </p> 
    <p> 
    Well, that's the problem. I guess the ideal solution would be to link a label to a checkboxe using another mechanism (not using ID). I think the perfect way to do this would be to match a label to the input element whose NAME (not ID) is the same as the label's FOR attribute. What do you think? 
    </p> 
</body> 
</html> 
+1

Además de no tener una pregunta clara, este es un duplicado de http://stackoverflow.com/questions/8537621/possible-to-associate-label-with-checkbox-without-using-for-id. –

Respuesta

13

La mejor, en mi opinión, lo que puede hacer, es cambiar el nombre de todas las casillas de verificación, añadiendo un poco de prefijo a sus identificadores, por ejemplo input

<ul> 
    <li> 
    <input type="checkbox" id="input_prologue" /> 
    <label for="input_prologue">prologue</label> 
    </li> 
    <li> 
    <input type="checkbox" id="input_chapter" /> 
    <label for="input_chapter">chapter</label> 
    </li> 
    <li> 
    <input type="checkbox" id="input_summary" /> 
    <label for="input_summary">summary</label> 
    </li> 
    <li> 
    <input type="checkbox" id="input_etc" /> 
    <label for="input_etc">etc</label> 
    </li> 
    </ul> 

De esta manera no tendrá ningún conflicto con otros identificadores en una página, y al hacer clic en la etiqueta se activará la casilla de verificación sin ninguna función especial de JavaScript.

2

En pocas palabras, un ID se supone sólo para ser utilizado una vez en una página, por lo que no que no habría diseñar una solución para múltiples identificaciones en una sola página que no se supone que exista.

Para responder el resto de la pregunta: no, el atributo ID es lo único que verá el atributo 'for' de una etiqueta. Siempre puede usar un evento JavaScript onclick para buscar la entrada por nombre y cambiarla, aunque eso parece demasiado complicado cuando solo puede solucionar su problema de ID, lo que tendría mucho más sentido.

+0

+1 por golpear dos problemas de un tiro. Algunos FYI sin sentido: el atributo for es del tipo de datos IDREF, que se ve a valor de tipo ID, que debe ser exclusivo. Estos son tipos de datos heredados disponibles para XML Schema, así que supongo que eso significa que son tipos de datos residentes de SGML. –

+9

El problema se produce cuando los identificadores para las entradas se crean dinámicamente. No puedo saber qué serán cuando elija los ID para los otros elementos en la página, por lo que no puedo asegurarme de que no tengan duplicados. Y como dices, la solución javascript es demasiado complicada (y algunas personas no tienen javascript). – Shawn

+0

Genera GUID para los ID. – Triynko

6

EDIT: En retrospectiva, mi solución está lejos de ser ideal. Le recomiendo que en vez aprovechar "etiqueta de asociación implícita" como se muestra en esta respuesta: stackoverflow.com/a/8537641/884734

Mi propuesta, a menos que ideales solución es a continuación:

Este problema se puede solucionar fácilmente con un poco de javascript. Acaba de lanzar el siguiente código en uno de los archivos de su página js para dar <label> etiquetas el siguiente comportamiento:

Cuando se hace clic en una etiqueta:

Si hay un elemento de la página con una id coincide con el atributo de la etiqueta for , vuelva a la funcionalidad predeterminada y enfoque esa entrada.

Si se encuentra ninguna coincidencia usando id, busque un hermano de la label con un juego classfor atributo de la label 's, y enfocarla.

Esto significa que usted puede poner sus formularios de la siguiente manera:

<form> 
    <label for="login-validation-form-email">Email Address:</label> 
    <input type="text" class="login-validation-form-email" /> 
</form> 

Por desgracia, el código real:

$(function(){ 
    $('body').on('click', 'label', function(e){ 
     var labelFor = $(this).attr('for'); 
     if(!document.getElementById(labelFor)){ 
      e.preventDefault(); e.stopPropagation(); 
      var input = $(this).siblings('.'+labelFor); 
      if(input) 
       input[0].focus(); 
     } 
    }) 
}); 

Nota: Esto puede causar problemas al validar su sitio contra la especificación del W3C , ya que se supone que el atributo <label>for siempre tiene un elemento correspondiente en la página con un ID coincidente.

Espero que esto ayude!

+0

Gracias a quien bajó la votación. En retrospectiva, mi solución está lejos de ser ideal. Le recomiendo que aproveche la "asociación implícita de etiquetas" como se muestra en esta respuesta: http://stackoverflow.com/a/8537641/884734 – Eric

100

que ha sido resuelta aquí: https://stackoverflow.com/a/8537641 acaba de hacerlo de esta manera

<label><input type="checkbox">Some text</label> 
+8

Esto solo funciona si la etiqueta y la casilla de verificación están una al lado de la otra. – Shawn

+7

@Shawn Cuál es el caso para la publicación original. –

+0

Lo único que recomendaría es poner el texto antes de la etiqueta de entrada. De lo contrario, perfecto! – Stan

0

solución fácil Tal vez sencilla sería utilizar uniqueid() php o función alternativa de otro lenguaje de programación.

Cuestiones relacionadas