1

Need advice about form validation.

I have control structure like so:

<form name="myForm">
    <control-wrap>
        <label isRequired="myForm.field1">Some text here</label>
        <custom-control name="field1" 
                  ng-required="true"
                  ng-something-else="any"
                  ng-model="modelForm.field1"></custom-control>
        <info>Some data after control</info>
        <error-list field="myForm.field1"></error-list>
    </control-wrap>

    <control-wrap>
        <label isRequired="myForm.field2">Some text here</label>
        <custom-control name="field2" 
                  ng-required="true"
                  ng-something-else="any"
                  ng-model="modelForm.field2"></custom-control>
        <info>Some data after control</info>
        <error-list field="myForm.field2"></error-list>
    </control-wrap>

    <control-wrap>
        <label isRequired="myForm.field3">Some text here</label>
        <custom-control name="field3" 
                  ng-required="true"
                  ng-something-else="any"
                  ng-model="modelForm.field3"></custom-control>
        <info>Some data after control</info>
        <error-list field="myForm.field3"></error-list>
    </control-wrap>
</form>

And this is completely AWFUL, unDRY and I guess I'm doing something very wrong.

I want to stop using field names, but I don't know how to pass ngModel to the sibling the proper way (now I'm forced to pass ngModel via attributes to isRequired and error-list).

Best solution for me ofc is to require: '^ngModel' from isRequired and error-list.

Any advice will be very appreciated.

P.S. there is no way for me to store fields in json object, there is a lot of logic between fields and different tweaks on labels and hints.

2
  • Maybe you need smth like: invent one directive for all your controls, fiill the form by ng-repeat of that directive, than in its template perform all necessary logic with validation?! Commented Aug 4, 2016 at 15:33
  • P.S. in a question states, that I can't use ng-repeat. Unfortunately. Commented Aug 4, 2016 at 15:35

1 Answer 1

1

Well, I came to this solution: https://plnkr.co/edit/mPXpEaZs2uWZb3WRkmgp?p=preview

Maybe it's not the best solution, but I don't need names anymore.

The main idea is to set model reference to parent container and watch this reference from other children.

So in the end I have:

    <control-wrap>
        <label link-required>Field1 label:</label>
        <input link-to-wrap ng-model="mc.field1" 
            type="text" 
            ng-required="true" 
            ng-minlength="5" 
            ng-maxlength="10" />
        <errors-list></errors-list>
    </control-wrap>

UPDATE

Some more thoughts about storing validation rules with model:

https://plnkr.co/edit/6ZVv685oSRDt7ELBKb9z?p=preview

New directive my-rules and extended data in controller.js

Sign up to request clarification or add additional context in comments.

5 Comments

I like this; if you also want model validation, i.e. define the validation constraints in the code and not in the view - additionally being able to invoke validation programmatically, you may want to take a look at egkyron.
Thx @NikosParaskevopoulos , but my case just in anti-use cases. :) My forms is way too simple for a 3rd party library. In my example I just show a way to bind fields to validation errors spots. In real solution, I guess you should store some validation rules in JSON indeed, with related messages, maybe some i18n service.
Updated Plunker based on your comment :)
Looks it is well suited for the "simple forms" case! A comment by looking at the code: myRules could require the ngModel and add $validators for each case. This way your setup becomes more extensible - you can add new validators just by implementing the validation function, not a directive. Then again, this is minor for what you want (and you would have to re-implement Angular's standard validators).
I also suggest you accept your answer, this way people will know the status of this question in the future (and may be more helpful).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.