0

I was looking for form validation in CanJS and came to know about can.Map.Validate plugin http://canjs.com/docs/can.Map.validations.prototype.errors.html

In the below example taken from the documentation itself, we need to give the properties of the object like 'dueDate' before the creating of the object itself

Task = can.Map.extend({
  init : function(){
    this.validatePresenceOf("dueDate")
  }
},{});
var task = new Task(),
    errors = task.errors()

Now my requirement is I want to build a Map which checks whether my field attribute is empty and returns me a suitable error. But the problem is, there are multiple forms on my page and formObject gets generated dynamically. Now in the above scenario before the creation of object itself, you need to allot the property in init method on which validation needs to be performed. It is not good for my requirement as the object is getting build and properties are unknown before the creation of the object. I searched over the web a lot but unable to crack it.

Providing the code for better understanding EJS File: login.ejs

<form id="registrationForm" name="registrationForm" method="POST">

     <input type="text" name="userName" placeholder="UserName" class="inputFieldStyle"></input>
     <input type="password" name="password" placeholder="Password" class="inputFieldStyle"></input>
     <input type="password" name="confirmPassword" placeholder="Confirm Password" class="inputFieldStyle"></input>
     <input type="email" name="email" placeholder="Email" class="inputFieldStyle"></input>
     <input type="button" name="registrationSubmit" value="Register" class="registrationLoginButton"></input>
     <input type="hidden" name="formType" value="registration"></input>
</form>

    <form id="loginForm" name="loginForm" method="POST">
        <input type="userName" name="userName" placeholder="UserName or Email" class="inputFieldStyle"></input>
        <input type="password" name="password" placeholder="Password" class="inputFieldStyle"></input>
         <input type="button" name="loginSubmit" value="Login" class="registrationLoginButton"></input>
          <input type="hidden" name="formType" value="login"></input>
    </form> 

Controller:

var LoginController=can.Control({
    defaults: {view:'login.ejs'}
},
{
    init:function(element,options)
    {
        var fragment=can.view(this.options.view);
        this.element.html(fragment)
    },
    'input[name="registrationSubmit"],input[name="loginSubmit"] click':function(el,ev)
    {
        ev.preventDefault();
        var formDOMObject=el.parent('form');
        var formValueObject=can.deparam(formDOMObject.serialize());
               /*Need to validate formValueObject. Problem is either formDOMObject can be resgitrationForm or LoginForm. Now both have different properties, So i cannot provide predefined properties in init method */
    }
});

Is there any way of validating the dynamic object properties using ca.Map.Validate plugin? How can I access the instance object passed inside the init method?

Thanks in advance :)

4

2 回答 2

2

您需要为状态和胡子助手制作 ,can.map (或计算)以反映 dom 中的状态为此我使用来自 sebastion proto http://sporto.github.io/blog/2014/03/的方法04/form-validations-with-canjs/

这是jsfiddle

   can.fixture({
    "GET contacts":function(){
        return [{'fname':'Cherif','lname':'BOUCHELAGHEM'}]
    }
})

can.Model.extend('Contact',{
    init:function(){
          this.validatePresenceOf(['fname','lname']);
    },
    findAll: 'GET contacts'
},{});

can.Control.extend('ContactForm',{
    init:function(el,options){
        this.contact=new Contact();
        this.errors=new can.Map({});
        this.element.html(can.view('validation',contact:this.contact,                                              errors:this.errors}));
    },

    'form submit': function () {
        var errors = this.contact.errors();
        this.errors.attr(errors, true);  
        return false;
    }
});
Mustache.registerHelper('showErrors', function (errors, prop) {
  var attr = errors.attr(prop);
  if (attr) {
    return prop + ' ' + attr[0];
  } else {
    return '';  
  }
});
new ContactForm('#val');
于 2014-03-30T21:47:27.900 回答
2

似乎您想要的是使用从现有对象构建的验证来制作临时的一次性类,然后可以观察到错误。

这是一个示例,显示验证是可观察的,并且随着源 can.Map 动态变化

can.Map("DynamicFormValidator", {
    newInstance : function(data) {
        var cls = this.extend();
        can.each(data.serialize(), function(val, key) {
            cls.validatePresenceOf(key);
        });
        //cls.prototypes.data = data;
        return can.Map.newInstance.call(cls, data);
    }
}, {
    init : function(data) {
        var that = this;
        this.attr("data", data);
        this.bind("change", function(ev, attr, how, newVal) {
            if(attr.indexOf('data.') === 0) {
                that.attr(attr.substr(5), newVal);
            }
        })
    }
    , computed_errors : can.compute(function() { return this.errors(); })
});

在http://jsfiddle.net/air_hadoken/8rK2n/2/上查看它的实际 应用

于 2014-04-01T18:56:14.553 回答