Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Naming conventions in MVC partial views to avoid ID collisions

Anyone coming from ASP.NET (pre-MVC) has become accustomed to being able to give their controls whatever IDs they want. You can create a field called Email in an .asmx file, a field called Email in your main page, a field called Email in your master page, place multiple instances of your .asmx file on the page and they'll all get their own unique IDs.

Now there are big problems with this that have all been discussed before. Often the solution suggested is to 'switch to MVC' where you can control your IDs. Fantastic!... except...

...the problem you end up with (after switching to MVC) if you're not careful is something like the following :

  • two forms on the page both containing an email field with Email as the ID.
  • the browser will render just fine (duplicate ids are not 'allowed by XHTML', but they're not rejected by the browser)
  • even the form submissions will work since the FORM will send its own corresponding content to the server action.

This you can get away with - if you're a really bad programmer that doesnt care about standards. However you will quickly start seeing some really wierd things if you begin to use jQuery or even just getElementById(..):

Let's say:

  • you have two user controls, one for 'Submit comments' and one for 'Join mailing list'. Each has an Email field inside. They each have id="Email"
  • you have javascript in the 'submit comments' control for validation :

    if ( $("#Email").val().indexOf("@") == -1 ) {
        // invalid email 
    }
    
  • Oops! The #Email selector will select the first instance of <input id="Email"> on the page. Therefore you may end up actually validating the FIRST Email field's value when submitting the SECOND form. But check the database - and you'll have the correct values. This can quickly drive your QA up the wall ;-)

I'm looking for any clever tricks anyone may have come up with. I found some interesting ideas in the question : ASP.NET MVC View User Control - how to set IDs but I didn't feel the answers went far enough or took advantage of some of the latest binding models.

Theres a few obvious things you could do such as always using unique IDS by prefixing every ID with a control prefix or something. This is starting quickly to look like ASP.NET 1.0 !

Another thing you COULD do is use a selector like $('#contatUsForm #Email') to get the Email ID. But only if you're fine with not having XHTML. I consider this solution to be very bad. In fact its so bad I havent even tested to see if jQuery even lets you run it!

One useful thing I came up with (with help from sunsean) is the following jQuery function - which I put on my master page and will certainly leave on until I deply.

// Warning Duplicate IDs - place on master page in $(function() { ... });
$('[id]').each(function(){
  var ids = $('[id='+this.id+']');
  if(ids.length>1 && ids[0]==this)
    alet('Multiple IDs #'+this.id);
});

This will help you quickly find which controls may exhibit this problem but leaves me still lookin for an elegant solution.

I'm especially interested in solutions that work in conjunction with model binding. As soon as I start adding in prefixes manually i'm going to start breaking model binding all over the place.

There has to be someone cleverer than me that's already thought through this...

like image 535
Simon_Weaver Avatar asked Feb 04 '09 04:02

Simon_Weaver


1 Answers

I think you're over-thinking it. The simple answer is, they're not the same, so don't give them the same ID. If they share similarities, that's what classes are for. If one input is for a newsletter sign up, call it NewsletterEmail. If another is for a user sign in form, call it UserEmail. Using more descriptive IDs is good HTML and not even remotely close to the mess Webforms creates.

like image 168
John Sheehan Avatar answered Sep 27 '22 17:09

John Sheehan