Directive help: Customizing template based on attributes [Newbie]

524 views
Skip to first unread message

Marty Pitt

unread,
May 16, 2012, 10:46:21 PM5/16/12
to ang...@googlegroups.com
Hi

I'm new to AngularJS, and having a crack at cleaning up some forms with some custom components.

I have a form that is using markup from Bootstrap, like the following:

  1. <form class="form-horizontal">
  2. <fieldset>
  3. <legend>Legend text</legend>
  4. <div class="control-group">
  5. <label class="control-label" for="nameInput">Name</label>
  6. <div class="controls">
  7. <input type="text" class="input-xlarge" id="nameInput">
  8. <p class="help-block">Supporting help text</p>
  9. </div>
  10. </div>
  11. </fieldset>
  12. </form>

There's a lot of boilerplate code in there, that I'd like to reduce to a new directive - form-input, like follows:

<form-input label="Name" form-id="nameInput"></form-input>

I have this much working via a simple template.

angular.module('formComponents', []) .directive('formInput', function() { return { restrict: 'E', scope: { label: 'bind', formId: 'bind' }, template: '<div class="control-group">' + '<label class="control-label" for="{{formId}}">{{label}}</label>' + '<div class="controls">' + '<input type="text" class="input-xlarge" id="{{formId}}" name="{{formId}}">' + '</div>' + '</div>' } })

However it's when I come to add in more advanced functionality that I'm getting stuck.

How can I support default values in the template?

I'd like to expose the "type" parameter as an optional attribute on my directive, eg:

<form-input label="Password" form-id="password" type="password"/></form-input> <form-input label="Email address" form-id="emailAddress" type="email" /></form-input>

However, if nothing is specified, I'd like to default to "text". How can I support this?

How can I customize the template based on the presence / absence of attributes?

I'd also like to be able to support the "required" attribute, if it's present. Eg:

<form-input label="Email address" form-id="emailAddress" type="email" required/></form-input>

If "required" is present in the directive, I'd like to add it to the generated <input /> in the output, and ignore it otherwise. I'm not sure how to achieve this.

I suspect these requirements may have moved beyond a simple template, and have to start using the pre-compile phases, but I'm at a loss where to start.


Thanks for your help,


Marty

Marty Pitt

unread,
May 17, 2012, 1:24:50 AM5/17/12
to ang...@googlegroups.com
Here's what I've ended up using.  I'm still hours old at AngularJS, so if there's a better way, or any feedback at all about this approach, I'd love to hear it:


Regards,

Marty

Pawel Kozlowski

unread,
May 17, 2012, 4:51:59 PM5/17/12
to ang...@googlegroups.com
Hi Marty!

On Thu, May 17, 2012 at 7:24 AM, Marty Pitt <mart...@mango-factory.com> wrote:
> Here's what I've ended up using.  I'm still hours old at AngularJS, so if
> there's a better way, or any feedback at all about this approach, I'd love
> to hear it:
>
> https://gist.github.com/2716646

It is great that you've discovered angular.js and diving into
directives: you will soon discover the incedible power of this
framework :-)

Angular.js is truly powerful and one of its main advantages is 2-way
data binding so it is a pity that your gist is not taking advantage of
data binding. What I mean is that your directive will produce _markup_
for a label, input etc. but the input won't be able to dispaly model
values (nor update them).

I've prepared another jsFiddle where you can see 2-way data binding in
action: http://jsfiddle.net/pkozlowski_opensource/na9CR/11/

It is just a skeleton to build upon (in reality you will need to copy
more attributes and prepare markup for validation errors) but I hope
it will get you started. Funnny thing is that John Lindquist published
recently 2 excelent tutorials on directives:
http://blog.angularjs.org/, they are of tremendous help.

BTW: would love to hear any comments on my jsFiddle. In particular I
didn't know how 'switch-off' attributes coping from the 'form-input'
element to the 1st div element.

Hope this helps,
Pawel

Marty Pitt

unread,
May 17, 2012, 9:13:01 PM5/17/12
to ang...@googlegroups.com
That's awesome.

Thanks for the feedback.  I much prefer your approach of templating and updating the template, than what I had of simply stitching a string together.

Any you're right - not taking advantage of the data binding is just nuts.

Thanks again


Marty

On Friday, May 18, 2012 6:51:59 AM UTC+10, Pawel Kozlowski wrote:
Hi Marty!
Reply all
Reply to author
Forward
0 new messages