0

I am using Alloy UI and YUI3 and have a form which, depending on the the users option choice from a select dropdown, fires an ajax call to the server. The server returns new validation rules which I send to the AUI-Form-Validation module. The rules are changing fine but the form is outputting duplicate rules. That is, not replacing the form validation instance but appending to the old one so I have duplicate error field strings in the broswer. I think I need to destroy all instances but the latest but cannot seem to achieve this. How can I destroy/renew the old form validation so I only ever have the latest displayed in the DOM?

Here is my code (I am using on.failure as am testing locally):

<!DOCTYPE html>
<html>
<head>
    <title>Form Validation</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="http://cdn.alloyui.com/2.5.0/aui-css/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>

    <div class="container-fluid">
        <div class="row-fluid">
            <div class="span12">

                <form id="myForm">

                    <select id="card-type" name="card-type" class="select_card_type">
                        <option value="7" selected="selected" label="Seven"></option>
                        <option value="2" label="Two"></option>
                        <option value="5" label="Five"></option>
                    </select>

                    <div class="control-group card_number">
                        <label class="control-label" for="cardNumber">Card number</label>
                        <div class="controls">
                            <input name="cardNumber" id="cardNumber" type="text" />
                        </div>
                    </div>

                    <div class="control-group csc">
                        <label class="control-label" for="picture">Card security code</label>
                        <div class="controls">
                            <input name="csc" id="csc" type="text">
                        </div>
                    </div>

                    <input class="btn btn-info" type="submit" value="Submit">

                </form>
            </div><!--/span-->
        </div><!--/row-->

        <hr>

        <footer>
            <p>&copy; Company 2013</p>
        </footer>

    </div><!--/.fluid-container-->

    <script src="http://cdn.alloyui.com/2.5.0/aui/aui-min.js"></script>
    <script>
        YUI().use('node', 'node-base', 'event', 'transition', 'aui-io-request', 'json-parse', 'aui-form-validator', function(Y) {

            var rules;
            function Validator(rules) {
                this.rules = rules;
                this.fieldStrings = {
                    cardNumber: {
                        required: 'Type your card number in this field.'
                    },
                    csc: {
                        required: 'Please provide your csc.'
                    }
                };

                this.val = new Y.FormValidator(
                    {
                        boundingBox: '#myForm',
                        fieldStrings: this.fieldStrings,
                        validateOnInput: true,
                        rules: this.rules
                    }
                );
            }
            Y.one('.select_card_type').on('change', function(e) {

                var len = Y.one('#card-type option:checked').get('value');

                Y.io.request('<%= selectProductTypeResource.toString() %>', {
                    method: 'post',
                    on: {
                        failure: function() {
                            rules = {
                                cardNumber: {
                                    required: true,
                                    digits: true,
                                    minLength: len,
                                    maxLength: len
                                },
                                csc: {
                                    required: true,
                                    digits: true,
                                    minLength: len,
                                    maxLength: len
                                }
                            };
                            if (typeof (validator) === 'object') {
                                validator.val.destroy(true); // not working
                            }
                            validator = new Validator(rules);
                        }
                    }
                });
            });
        });</script>
</body>
</html>
Karma Kaos
  • 69
  • 13

2 Answers2

0

You aren't appending rules, you are binding multiple validators. Even if you were able to clear out the rules, the old validator would still be bound and validating against no rules.

To keep from having to "destroy" it, you could create the validator once and then modify the rules accordingly.

AlloyUI uses get/set methods to modify properties.

  • To modify the rules, call the getter - var rules = validator.get('rules') - and then modify.
  • To set new rules, call setter: validator.set('rules', {cardNumber: {required: true}})

I have setup an example fiddle to demonstrate. If you click Create New Validator and Submit you will see the same behavior you have described.


The aui-form-validator source on github.

Origineil
  • 3,108
  • 2
  • 12
  • 17
  • Thanks for the reply origineil, I've tried what you mention and got it working. I used the setAttrs to reset the new rules and all is now working as expected. Many thanks. Here is my full working code: – Karma Kaos Jun 09 '14 at 08:15
0

Thanks for the reply origineil, I've implemented what you mention and got it working. I used the setAttrs to reset the new rules and all is now working as expected. Here is my full working code:

YUI().use('node', 'node-base', 'event', 'transition', 'aui-io-request', 'json-parse', 'aui-form-validator', function(Y) {

  var validator = new Y.FormValidator(
   {
     boundingBox: '#myForm',
     validateOnInput: true
   });

  Y.one('.select_card_type').on('change', function(e) {
    var len = Y.one('#card-type option:checked').get('value');
    validator.resetAllFields();

    Y.io.request('<%= selectProductTypeResource.toString() %>', {
                    method: 'post',
                    on: {
                        failure: function() {
                            var rules = {
                                cardNumber: {
                                    required: true,
                                    digits: true,
                                    minLength: len,
                                    maxLength: len
                                },
                                csc: {
                                    required: true,
                                    digits: true,
                                    minLength: len,
                                    maxLength: len
                                }
                            };
                            validator.setAttrs({rules: rules});
                        }
                    }
    });
  });
});
Origineil
  • 3,108
  • 2
  • 12
  • 17
Karma Kaos
  • 69
  • 13