I wasn\'t sure if I could ask this kind of question, but after seeing this on Meta Stackoverflow, it looks like this kind of question is ok. Well, onto my question:
A fe
I like it a lot already, it keeps my html clean and the ability to build custom validators is great. One thing I added was a short hand for binding the validation and submit functions, and wrapped it up as a jQuery plugin:
if (jQuery) {
(function($)
{
$.regula = function(formId, callback)
{
regula.bind();
$("#" + formId).submit(function()
{
var validationResults = regula.validate();
if (validationResults.length > 0)
{
if (callback)
callback(validationResults);
return false;
}
return true;
});
};
})(jQuery);
}
Infact, I've just blogged about it to as I am that impressed with how clean and easy it is. I'm still going to spend time going through your source, to see how your accomplished it, but its a great start :)
In regards to integrating your framework, I work mostly with ASP.NET MVC, and it would be interesting to see how it translate server-side validation logic into client-side constraints. Something I might look over in the next month or so.
I'm doing completely different approach: With modern framework like React or Angular you have always state of form somewhere in javascript not in DOM input states (DOM is just view layer of data). And I think it should be like this because no matter what kind of fancy components you use to build you form there is always underneath object that holds all states. From this point to me natural approach is to just use raw JSR-303 (without annotations) to validate this object (because JSR-303 provides you such flexibility) and populate errors back to DOM. Let me show you an example:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import validator, {
Collection,
All,
Required,
Optional,
NotBlank,
Length,
Email
} from "@stopsopa/validator";
class App extends Component {
constructor(...args) {
super(...args);
this.state = {
data: {
name: "",
email: "",
comments: []
},
errors: {},
validate: false
};
}
onSubmit = async e => {
e.preventDefault();
const errors = await validator(
this.state.data,
new Collection({
name: new Required([new NotBlank(), new Length({ min: 3 })]),
email: new Required([new NotBlank(), new Email()]),
comments: new All([new NotBlank(), new Length({ min: 10 })])
})
);
this.setState({
errors: errors.getTree(),
validate: true
});
if (!errors.count()) {
console.log("send data to server", this.state.data);
}
};
onChange = (name, value) => {
console.log(name, value);
this.setState(state => ({
...state,
data: { ...state.data, ...{ [name]: value } }
}));
};
addComment = () =>
this.setState(state => {
const comments = state.data.comments;
comments.push("");
const newState = { ...state };
newState.data.comments = comments;
return newState;
});
deleteComment = i =>
this.setState(state => {
const newState = { ...state };
state.data.comments.splice(i, 1);
return newState;
});
editComment = (i, value) => {
this.setState(state => {
const newState = { ...state };
state.data.comments[i] = value;
return newState;
});
};
render() {
const s = this.state;
console.log("state", JSON.stringify(s, null, 4));
return (
<form onSubmit={this.onSubmit}>
<label>
name:
<input
value={s.data.name}
onChange={e => this.onChange("name", e.target.value)}
/>
</label>
{s.validate && s.errors.name && (
<div className="error">{s.errors.name}</div>
)}
<br />
<label>
email:
<input
value={s.data.email}
onChange={e => this.onChange("email", e.target.value)}
/>
</label>
{s.validate && s.errors.email && (
<div className="error">{s.errors.email}</div>
)}
<div>
comments:{" "}
<a onClick={this.addComment} href="javascript:void(0)">
add
</a>
{s.data.comments.map((m, i) => (
<div style={{ border: "1px solid red" }} key={i}>
<textarea
rows="2"
value={m}
onChange={e => this.editComment(i, e.target.value)}
/>
<a
onClick={() => this.deleteComment(i)}
href="javascript:void(0)"
>
delete
</a>
{s.validate && s.errors.comments && s.errors.comments[i] && (
<div className="error">{s.errors.comments[i]}</div>
)}
</div>
))}
</div>
<br />
<input type="submit" value="submit" />
</form>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
life example https://codesandbox.io/s/ymwky9603j