4
<!-- Some place on the webpage -->
  <input type="text" id="firstName">

<!-- Some other place on the same webpage, or maybe content ajaxed in later -->
  <input type="text" id="firstName">

Let's say I have a server-side script that generates an HTML page with some input fields each with its own ID. One server-side class may be responsible for adding input fields to one part of the webpage while another class handles another part of the webpage. Or you might have different programmers working on different parts of the page. I want to avoid collision with the HTML input field IDs. An example of this could be a parent form that has a jQuery dialog popup with input field IDs the same as the parent. Currently, I am prefixing the IDs with the name of the server-side class that generates them (and an underscore to make it clear which part is the prefix). To get a fully unique ID this way, I might have to start including the full namespace of the server-side class, and this might make my IDs very long.

Is there a better approach than prefixing the inputs or what is the best practice for this? I normally use camelCase for all my variables, with only this exception. Is this a good exception for breaking that rule?

What are most of you doing? Are you altering the way you select these input fields instead of by ID? Wrapping the input fields in form tags or div tags and adding functionality to the server-side to create these? (I'd like to have the freedom of not restricting what I wrap these inputs in to select them. My server-side code should just generate client-side code that grabs the values only knowing those inputs are going onto the page, and not knowing about any other tags on the page. Much easier to manage.) Are you adding css classes to each group of fields?

prograhammer
  • 17,458
  • 12
  • 81
  • 108
  • I guess you could use classes to add at least some of the functionality you described – user2521439 Jan 06 '14 at 20:14
  • 1
    you could store the namespace in a different attribute (`data-namespace="ns"` or something) and just use classes. That way jQuery can use the namespace in addition to the classname if you need the unique one. – Zach Lysobey Jan 06 '14 at 20:18
  • Honestly though, if you're even running into this problem, it sort of makes me think that maybe your app architecture is a little whacky to begin with? To me it seems bad to have the client and server so tightly coupled. But I'm no expert on this sorta thing. – Zach Lysobey Jan 06 '14 at 20:20
  • @ZachL What if you don't want to type the input field tag each time or write retrieval code each and every time for the fields you are populating server side? Why not have some sort of "View Composer" or server-side HTML/jquery wrapper/helper generate the retrieval code based on the data coming from your database/etc? – prograhammer Jan 06 '14 at 20:29
  • Personally, I prefer to generate my HTML client side and just send data down from the server..., but I'm not sure I understand what you mean. – Zach Lysobey Jan 06 '14 at 20:32
  • Using PHP, is this something you would have in your HTML "view" file: ``? Instead I prefer something like `=$firstName;?>` and that includes the full HTML input tag and data. – prograhammer Jan 06 '14 at 20:38
  • And `=$jsHelpCode;?>` at the top of the file, instead of writing the selection and retrieval code over and over for every page, having to alter it based on what the names of my fields are and what type they are (certain non-standard inputs require special techniques) and so on. – prograhammer Jan 06 '14 at 20:41
  • Of course I do manually put jquery and HTML on pages, but mostly stuff that is more unique to what is needed for that page. If something like adding input and retrieving it is done on almost every page, it's better to take care of that globally I think. Kind of like the server-side handling the header HTML that is inserted (unless you are using a template engine with some sort of `include` at the top, but then I'm part of the "PHP is the template engine" camp) – prograhammer Jan 06 '14 at 20:47

4 Answers4

2

This answer is a little more directed towards users coming in from search engines. In my opinion, if you are using the id attribute in a dynamically generated form, they should probably be some kind of generated id/hash, unless it truly is a unique field. That aside, this is probably the best way to namespace HTML forms, especially when it is subject to collision:

<input name="pet_store[name]" value="" />

<input name="dogs[0][name]" value="" />
<input name="dogs[1][name]" value="" />
<input name="dogs[2][name]" value="" />

<input name="cats[0][name]" value="" />
<input name="cats[1][name]" value="" />
<input name="cats[2][name]" value="" />

If submitted all at once, the inputs will automatically be organized into arrays (at least in PHP).

In jQuery, you can select all dog name fields like this:

$('input[name$="[name]"][name^=dogs]')
  • Hmmm...+1 for this interesting approach! I ended determining that the best solution was to just have my server-side input generation class add a prefix whenever I wanted one. – prograhammer Feb 23 '15 at 16:07
  • So "first_name" would become "users_first_name" or "employees_first_name", etc. The server-side class would also add HTML classes to each input, these classes would be named the same as the prefix (`.users` or `.employees`). Then I had a jQuery class that I would attach to all the inputs like `$(".users").myInputClass();` and I could call a method called `get()` on myInputClass like this: `var data = $(".users").data("myInputClass").get()"` and get all the inputs with the prefix stripped off. For example, `alert(data.first_name);` – prograhammer Feb 23 '15 at 16:08
1

I would use classes in this case. If you can't control what the uniqueness of ID's then they become pretty meaningless.

Instead of generating a super-long class name from the code that generates the html, you could add many shorter css classes to inputs that need them. It's not unusual to have lots of different classes in your document and they can all be used together with jQuery selectors. Also remember that if your inputs are in different forms then the form id (or class) could also be considered to work a bit like a 'namespace' too.

For reference, point 7.5.2 of the W3C Global Structure of an HTML document states that the id must be unique.

charliefortune
  • 2,450
  • 2
  • 20
  • 41
  • Yeah I'm thinking this might be the way to go. Don't mess with ID (leave it named what it is) but add a class to represent the "namespace" the field is in. This would break up ID holding both namespace+name. However the namespace can still be very long for the css class, if I'm using a truly unique one based on my server-side classes. – prograhammer Jan 06 '14 at 20:19
  • 1
    "Don't mess with ID (leave it named what it is)" – Zach Lysobey Jan 06 '14 at 20:21
  • Ok, ID must be unique. So now I start using classes as if they were ID's, then use another class for the "namespace" part? – prograhammer Jan 06 '14 at 20:32
  • 1
    @DavidGraham You could do as you _can_ add multiple classes to an element, just seperate them with a space, eg: `class="nmspc input header"` – user2521439 Jan 06 '14 at 20:40
  • @charliefortune Can you update your answer to more specifically state if you would just give the css class a name based on the full namespace of the server-side class + fieldname? Or would you do 2 css class names on the same input field, separating namespace from fieldname? (and does this feel right to create a css class for every fieldname just because W3C says ID must be unique?) – prograhammer Jan 06 '14 at 20:52
0

Use data-xxx attributes if you must, but I can't really think of a practical case of independent server-side scripts generating hundreds of DOM elements with unique IDs up to the point where name collision would become an issue.

kuroi neko
  • 7,721
  • 1
  • 16
  • 38
  • You have a form that asks "What's your name and who is in your group?" You input your name, then you click a button to bring up an AJAXed form that asks for the names of people in your group. Now you have `id="firstName` collisions. This obviously is a simple example. – prograhammer Jan 06 '14 at 20:31
  • I see, but if someone is designing such a page, he will probably have to cope more globally with the potential problems caused by juggling with multiple personal data. – kuroi neko Jan 07 '14 at 00:54
0

The idea of ids is that they are a unique reference to an element and as such it is not legal (valid HTML) to have multiple elements referring to the same id. If you want to avoid collisions and still identify the element you could use a combination of classes.

For example if you have 2 forms asking for a name (as in your previous comment) you could use:

<input type="text" class="ajax firstName" /> 

For the form generated by ajax, and

<input type="text" class="initial-form firstName" /> 

For the initial form on the webpage.

Equally you could use the data- attribute to hold a namespace. E.g:

<input type="text" data-namespace="ajax" class="firstName" />

(This can be accessed through Javascript with element.dataset["namespace"])

user2521439
  • 1,275
  • 1
  • 12
  • 18