volk
volk

Reputation: 1196

Creating an angular directive for changing placeholder text for a form

This isn't a direct coding question per se...more like what is the best practice or the smartest way to go about something like this.

I have a form with a button that should change placeholder text to the custom error if the input is invalid. So basically "on click" should the validity be checked.

Would I just surround the whole form in a directive and loop through each field when the button is clicked and check validity? My other solution included making a directive for each input and not include the button, but somehow interact with the form through the use of a parent scope when the button is clicked.

Upvotes: 0

Views: 715

Answers (1)

bhantol
bhantol

Reputation: 9616

The Angular form design i.e. the $validators, the $formatters and the $parsers are at the input directive level. The placeholder is an attribute at the input level. So at the lowest level the design intentions is to provide the error feedback as quickly as possible.

The timing of the display can always be controlled at higher level if the lower/granular level allows. in your case myform.$isvalid is an available property since ever form gets a formController. You can access it using a handle which comes from the name attribute on form.

In Angular vs. jQuery we deal with enhancing the html or html element at hand vs find other elements and enhancing them. Now which element is better suited for performing the functionality you describe ?

The individual input elements ate better equipped with most data i.e. the placeholders and the $validator[] array on the elements. You may perhaps alter the view/ colors here.

So my recommendation is do this at the input element. If are trying to please some boss/customer must have the old style error messages at the top you can still achieve this on form submit.

Problems associated with putting this logic on form elements:

You will end up doing DOM lookup. Your code will be more like jQuery as you will grab the placeholder attr value and stick it somewhere.

UPDATED as per the question in the comment.

If you are going to have such validation on submit consider this.

Where the 'Save/Submit' button fits into play?

Placement:

Inside the .

Save/Submit buttons's primary job is to save the entity/resource i.e. to send all that data to the resource end point. Typically the submit button has been inside the form. Just as the various form element's job is to take an input from the user the submit button is to take an input saying "I am done. Submit this form.". Also the browser and other engines must have finished constructing the form element to be able to submit so placing outside has slight risk or rather ideally you should not assume that all the elements in the hyper text document has actually finished constructing. However jQuery/Angular bootstraps on document.ready() so all raw elements are present. But the order in which directives are processed - the directive. Refer to the $compile, preLink and postLink cycles. (postLink will have access to all child elements).

Role/division of responsibility:

Form directive maintains field level errors in myForm.$error[]. The way this is organized is it looks like below when errors: $error.validationType = [control] where each control has $name which is the name attr on your . You see - the organization is perhaps not quite the way you want i.e. flat but you can use this to find which fields are invalid.

Also if you don;t mind the duplication but you could do something like below.

myForm.userName.$valid = {{myForm.userName.$valid}}
//downside is the form have to know all the children input names

Now you have some options as to how to communicate your placeholder to the parent

1) Let your directive at the input field level tell the form scope of the placeholder text by calling your parent scope function defined in your own controller at the form level. OR 2) You may enhance the angular model to add one more property on the control called $placeholder or $customError and set the value in your directive. Something like below:-

   var myform = elm.parent().controller('form');
   myform['yourInputName'].*$placeholder* = attr.$get('placeholder');

Upvotes: 1

Related Questions