[Coding] Best Practices for Integrating JavaScript with ASP.NET?

Posted by Khatharsis on November 3, 2013

After spending so much time with my HTML5/jQuery personal projects this year, it felt like I ran into a rather solid wall when I re-entered the working world. Building on my previous problem of going from an ASP.NET server control to a JavaScript function through a click event, I have a more general problem of how to use JS/jQuery properly with ASP.NET server controls.

My searches so far on “best practices” with JS and ASP.NET have turned up fruitless. The top results are often outdated, written back in 2008, and the most recent I was able to find being written in 2011. Often, they are articles on how jQuery works with very little reference on how to integrate it with ASP.NET server controls. StackOverflow results are often “one-way” about questions pertaining to how to reference an ASP.NET server control in JS.

I’m lucky in that I’m using Visual Studio 2010 and the ClientIDMode attribute is available. What’s been getting to me is I feel like I’m forced to put JS code on my ASP.NET pages instead of keeping it all external with a $(document).ready() (on the page) calling an init() function (defined externally).

My challenge this week was populating a GridView server control with some dummy data. As I don’t have access to any of the databases yet, I made a DataTable object and used that as the DataSource. The catch is each row on the GridView must include an edit link (an extra column) such that when a user clicks on it, a form above the table is pre-populated with the values from that row.

I came up with two solutions. The first relies completely on ASP.NET’s postback. The second is entirely JS/jQuery. Coding postback is messy. It’s not immediately clear that the form will be prepopulated with the postback values. In fact, my form gets prepopulated in the edit link click event handler (LinkButtonEdit_Click) because that method knows which row was selected. In a more traditional postback method (e.g., if (Page.IsPostBack){}), I’d have to hide the id of the row in a HiddenField, then requery the DataSource for that row id. I’m sure there’s probably a more elegant way of handling this, but it just doesn’t sit right with me. I shouldn’t have to send a request to the server just to fill out a form for the user with data that’s already available.

My second solution was a bit nicer, but I had to get a little creative. And stick JS code on my page. Which is okay since it’s page-specific code, but I’m afraid of having to break DRY principles later down the line, like if another page with a GridView needed an edit link with a form that gets pre-populated on click.

As I mentioned above, I made use of the ClientIDMode attribute and set it to static. Since the pages are small, this shouldn’t cause any problems for future developers who aren’t aware of the static IDs. My next challenge was, client-side, I couldn’t easily query the data from the DataSource like I could with ASP.NET. Here’s where the creative part came in.

I used the data- attributes of an <a> tag. I’m supporting as low as IE8, thankfully, but even then, jQuery works magic with data- attributes (you can do a search on this for more info on why it’ll work on IE6). I wouldn’t suggest going this route if the form has a lot of fields that need to be populated, but mine had only five, so I didn’t feel too guilty. My HTML code looked something like:

<a href="#" class="form-edit"
	data-id='1'
	data-date='11/01/2013'
	data-name='Talan DT' 
	data-color='blue'
	data-pet='Zhefir'
>
	edit
</a>

The ASP.NET code that produces this HTML code looked something like:

<a href="#" class="form-edit"
	data-id='<%# DataBinder.Eval(Container.DataItem, "id") %>'
	data-date='<%# DataBinder.Eval(Container.DataItem, "date") %>' 
	data-name='<%# DataBinder.Eval(Container.DataItem, "name") %>' 
	data-color='<%# DataBinder.Eval(Container.DataItem, "color") %>'
	data-pet='<%# DataBinder.Eval(Container.DataItem, "pet") %>'
>
	edit
</a>

Then, I bound a click event to my collection of edit links:

$('.form-edit').click(function (e) {
	var row = $(e.target);
	$('#form-date').val(row.data('date'));	// A text box
	$('#form-name option').each(function() {	// A dropdown list
		if ($(this).text() == row.data('name') {
			$(this).attr('selected', 'selected');
		}
	});
	$('#form-id').val(row.data["id"]);	// Another dropdown list
	// Additional form pre-population code
});


I included a few examples of how to pre-populate different form field types. The difference between the two dropdowns is one searches a dropdown by text and the other by value. Ideally, you’d want to have data with dropdown values rather than their text, but in case you’re are forced to do with text…

The tradeoff is the HTML code that is generated is more and JS code sits on the page. ASP.NET already generates a lot of extra HTML (like the ViewState hash) so this isn’t nearly as bad. I believe some other functionality, like validation controls (RequiredFieldValidator) can generate nicer code with an Unobtrusive switch. I didn’t read into it very heavily (yet), but my understanding is it also makes use of data- attributes. Unfortunately, I think it is only available in .NET 4.5 framework and I’m working with 4.0.

Despite my latest solution, I’m still at a impasse in regards to the “best practices” of JS with ASP.NET. Except for a few items (login credentials and database queries), I could largely code this project in HTML and JS. It’s half tempting to just set up a webservice that I hook into via AJAX, resulting in very little use of ASP.NET controls. Although, using the Master Page is helpful for design purposes. That would also mean I’d not be taking advantage of the ASP.NET platform, but really, unless I’m using MVC (which I may end up having to do), what other benefits am I getting out of it? Maybe that’s why there isn’t any good article on how to properly use JS with ASP.NET in a broad enough way to become a general practice.