Tuesday, September 3, 2013

Shredding your forms

Shredding your Forms

Using the <form> tag to wrap elements and then submit the data contained within worked in the 90’s. Hell it worked in the early 2000’s. But with the advent of AJAX techniques, the <form> element is now really more of a liability than a help. The problems are as follows:

1) Through some method, unbeknownst to me, when a <button type=”submit”> is clicked the <form> makes a post to the url found in one of it’s attributes. There is no hook into this process not before it goes out and not after it comes back.

2) Add to this that if you have something you need to submit outside of the <form>, you’re pretty much out of luck.

3) Thus you get what’s in your form and nothing else and you must redirect to a whole new page on return. No nice success or error message showing up smoothly, just a whole new page of HTML (which could include your messages of course).

4) This leads to the highly unappealing practice of packing hidden elements within the form, and/or - even worse - updating element names when you dynamically create a new element. Shudddr.

While there are work_arounds for these problems that allow you to use AJAX to catch a form submit, you can take it from me it can be a byzantine nightmare to try to customize.

So when you throw out your horrible <form> tags and start using AJAX to post and get data from the server, you will find that, while it did a rather crap job of it, the <form> tag did at least harvest your values from the elements contained. Without it, you must now query each element that contains data you want to post back. While this is exactly where you get the benefit, it is also a pain. Add to this the fact that, if you are using C# MVC, MVC expects that data to come back in a very precise and unintuitive manner, and you are now faced with a rather boring if not daunting task. In fact, it can be so daunting I may do a blog post explaining how to do it.

Luckily, the solution is not only beautiful it is wonderful and awesome, all wrapped into one. By employing a model binding framework like Knockout.js or one of it’s lesser cousins you can create two way binding between your DOM elements and a JSON object (heretofore referred to as the ViewModel). This means that when you change the value in, say, a text box, the corresponding property on the ViewModel changes as well, and vise versa. So now, when you want to submit your data via AJAX you don’t talk to the DOM at all. Insteadm, you just submit the ViewModel object. Again, the versa of this vise is that when you want to update the DOM you must merely speak, in it’s native tongue, to the ViewModel.

Creating this two-way binding, emancipates you to some degree from the business of mucking around in the DOM. I say to some degree because you most likely will still have to interact with the DOM to perform other actions: clicks, show/hide, fade out with pixels, etc. Still if you can find a way to abstract that noise, you could quite possibly, write tests for your javascript logic without the incredible hassle of spinning up a browser and mocking your HTML.

I have glossed over A LOT of the implementation details in favor of a much higher lever ( and much shorter post). I would be happy to write a post on the details should anyone ask.

In my next post I will discuss the strategy that I have found to be quite fruitful for employing two way binding without horribly polluting your HTML or creating a deep and vast plate of javascript spaghetti.

No comments: