Friday, August 9, 2013

AngularJS Missing Directives: Native Form Resets

If you haven't played around with AngularJS yet, I highly advise you give it a try. There are plenty of introductory articles and videos out there that will whet your appetite and get you up and running (here, here and here to name a few). Go ahead, go play. This post will still be here later when you need it. And you will need it.

Okay, for everyone else, after the excitement and wonderment of two-way binding begins to wane you will start to notice some of the peculiarities about AngularJS. And then after that you will start to wonder why it doesn't do some of the things you would expect to it to do (the simple answer is generally the great dev team working on AngularJS hasn't gotten around to it yet). I refer to these missing functionalities as missing directives. Which means we can write our own directives to add any desired functionality!

Lets jump in and take a look at form resets. If you have been developing for the web for any period of time you know that there is a native INPUT element type that will reset all form input elements (including selects, textareas, etc.) to their original values. The following fiddle has a simple form that includes a native reset button and an Angular controller to initialize the model ("myModel").

Try editing the fields and hitting reset.



Wait. What happened? The expected behavior is for the form to reset the values of the input fields ('foo' and 'bar') to their original values ('Boop' and 'Beep' respectively). But as you can see this does not happen. What gives?

First, two underlying points:

  1. Since AngularJS forms do not use the value attribute to specify original values for forms, the native form elements therefore have no initial values outside of the AngularJS world.
  2. AngularJS forms do not understand which model is being used to manage the two-way binding for the input fields (this example uses 'myModel').

Second, you might be wondering why this is how AngularJS behaves. I did and so at a recent AngularJS meetup I asked Igor Minar, a core Google Angular developer, why it hadn't been implemented and he responded that the team just hadn't done it yet.

So, that leads to the question of what would be needed to make it work. Interestingly enough it's not a difficult thing to do once you have a firm understanding of AngularJS and its concept of directives. If you don't know what a directive is, this should be a good example.

Based on the points mentioned above, the directive would need to be:
  • aware of which model is represented by the form
  • what the original input element values are (the original state of the model)
  • capturing the native form reset event and preventing it from reseting the inputs to no values
  • restoring the original values to the form input elements from the model on the form reset event

Since directives can be attributes of an element, the directive can be an attribute of the form element itself similar to the ngSubmit directive. We then can use the attribute value to pass in the model for the form. This placement will also allow the capture of the native form reset event.

Lets preview with the finished directive before we dissect it. Once again, edit the form and hit the reset button.



Whew! It works.

If you notice on the HTML tab, the directive is invoked by applying an attribute to the form element with the value set to the model. The directive is then called and executes the returned function.



From the JavaScript tab we can see how the directive accomplishes our goals.



But first, some background on some of the key pieces used in the directive:

  • $parse - since you can't pass the model object itself through the attribute (at least without creating an isolated scope), you can use this handy dandy service to get the model object from the attribute value string
  • angular.copy - creates a deep copy of an object or an array
  • scope.$apply - executes the model assignment in an AngularJS context
  • $setPristine - used for setting the form to a 'pristine' state indication

We can see the first thing the directive linking function does is to create a getter/setter for the passed model and then it creates a deep copy of this model. This deep copy will be the value that the model is reset to on any form reset events. Since $parse will only return an object with method assign if it is a model, we can use that to error check the input from the attribute.

The next step binds the custom reset handler to the native form reset event. When the native form reset event is fired, the custom reset handler prevents the default action (resetting the input elements to their non-existent value attributes), sets the model to the original copied state and finally updates the form state to indicate it is pristine.

That's it. That's all it takes. Nothing more. If you haven't realized it yet, while two-way binding is magical, directives are the building blocks of AngularJS.

50 comments:

  1. This is such a good post. One of the best posts that I\'ve read in my whole life. I am so happy that you chose this day to give me this. Please, continue to give me such valuable posts. Cheers!

    ReactJS Online Training

    ReplyDelete
  2. Because nowadays every business needs a huge support of Digital Marketing. Many people are searching a best products in internet, so to show our product as best in particular industry we need Digital Marketing.
    ExcelR Digital Marketing Courses In Bangalore

    ReplyDelete
  3. You should take part in a contest for one of the greatest websites on the web. I'm going to highly recommend this blog!
    Techno

    ReplyDelete


  4. This post is really nice and informative. The explanation given is really comprehensive and informative. I also want to say about the digital marketing online training

    ReplyDelete

  5. Thanks for your extraordinary blog. Your idea for this was so brilliant. This would provide people with an excellent tally resource from someone who has experienced such issues. You would be coming at the subject from a different angle and people would appreciate your honesty and frankness. Good luck for your next blog!
    Tally ERP 9 Training
    tally classes
    Tally Training institute in Chennai
    Tally course in Chennai
    seo training classes
    seo training course
    seo training institute in chennai
    seo training institutes
    seo courses in chennai
    seo institutes in chennai
    seo classes in chennai
    seo training center in chennai

    ReplyDelete
  6. I really appreciate your method to explaining, I hope to see more posts from your blog. thank you!
    Digital Marketing Course In Kolkata
    Web Design Course In Kolkata
    SEO Course In Kolkata

    ReplyDelete
  7. Excellent Blog! I would like to thank for the efforts you have made in writing this ExcelR Digital Marketing Course Pune post. I am hoping the same best work from you in the future as well. I wanted to thank you for this websites! Thanks for sharing. Great websites!

    ReplyDelete
  8. Way cool! Some very valid points! I appreciate you writing this write-up plus the rest of the site develop is also very good.

    ReplyDelete
  9. Hi there! I just want to give you a big thumbs up for your great info you have got here on this post. I am returning to your press web site for more soon.

    ReplyDelete
  10. Welcome to the party of my life here you will learn everything about me.
    Digital Marketing Course Pune

    ReplyDelete

  11. You have clarified the idea truly well. Was searching for this data from some time and fortunately I discovered your post. Searching forward for a greater amount of such useful updates from you
    Data Science Training In Hyderabad
    Data Science Course In Hyderabad

    ReplyDelete
  12. This is an awesome motivating article. I am practically satisfied with your great work. You put truly extremely supportive data. Keep it up. Continue blogging. Hoping to be perusing your next post
    Courses in Digital Marketing in Pune

    ReplyDelete
  13. It's very nice to find out other writers share like minds on some content. This is the case with your article. I really enjoyed this.
    Best Data Science training in Mumbai

    Data Science training in Mumbai

    ReplyDelete
  14. Very interesting article with great useful information. Java training in chennai I am also sharing this article with my friends you have written excellent content. Thanks for sharing this kind of informative blog about Java.
    Java training in chennai | Java training in annanagar | Java training in omr | Java training in porur | Java training in tambaram | Java training in velachery

    ReplyDelete
  15. Great Content, For training in Angularjs do visit GoLogica
    AngularJS Trainings

    ReplyDelete
  16. I wondered upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and I hope you post again soon



    Dot Net Training in Chennai | Dot Net Training in anna nagar | Dot Net Training in omr | Dot Net Training in porur | Dot Net Training in tambaram | Dot Net Training in velachery





    ReplyDelete
  17. Nice blog Post ! This post contains very informative and knowledgeable. Thanks for sharing the most valuable information.
    Data Science Training in Hyderabad

    ReplyDelete