I have a form that is using markup from Bootstrap, like the following:
<form class="form-horizontal"> <fieldset> <legend>Legend text</legend> <div class="control-group"> <label class="control-label" for="nameInput">Name</label> <div class="controls"> <input type="text" class="input-xlarge" id="nameInput"> <p class="help-block">Supporting help text</p> </div> </div> </fieldset> </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>
generates:
<div class="control-group"> <label class="control-label" for="nameInput">Name</label> <div class="controls"> <input type="text" class="input-xlarge" id="nameInput"> </div> </div>
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.
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?
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.
Components are directives with templates. The only difference between Components and the other two types of directives is the Template. Attribute and Structural Directives don't have Templates.
Custom directives are used in AngularJS to extend the functionality of HTML. Custom directives are defined using "directive" function. A custom directive simply replaces the element for which it is activated.
Angular creates the directive class and specifies the CSS selector, appUnless , that identifies the directive in a template. Import Input , TemplateRef , and ViewContainerRef . Inject TemplateRef and ViewContainerRef in the directive constructor as private variables.
angular.module('formComponents', []) .directive('formInput', function() { return { restrict: 'E', compile: function(element, attrs) { var type = attrs.type || 'text'; var required = attrs.hasOwnProperty('required') ? "required='required'" : ""; var htmlText = '<div class="control-group">' + '<label class="control-label" for="' + attrs.formId + '">' + attrs.label + '</label>' + '<div class="controls">' + '<input type="' + type + '" class="input-xlarge" id="' + attrs.formId + '" name="' + attrs.formId + '" ' + required + '>' + '</div>' + '</div>'; element.replaceWith(htmlText); } }; })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With