{"action":"created","issue":{"url":"https://api.github.com/repos/vuejs/vue-validator/issues/41","labels_url":"https://api.github.com/repos/vuejs/vue-validator/issues/41/labels{/name}","comments_url":"https://api.github.com/repos/vuejs/vue-validator/issues/41/comments","events_url":"https://api.github.com/repos/vuejs/vue-validator/issues/41/events","html_url":"https://github.com/vuejs/vue-validator/issues/41","id":97639918,"number":41,"title":"2.0 plan","user":{"login":"kazupon","id":72989,"avatar_url":"https://avatars.githubusercontent.com/u/72989?v=3","gravatar_id":"","url":"https://api.github.com/users/kazupon","html_url":"https://github.com/kazupon","followers_url":"https://api.github.com/users/kazupon/followers","following_url":"https://api.github.com/users/kazupon/following{/other_user}","gists_url":"https://api.github.com/users/kazupon/gists{/gist_id}","starred_url":"https://api.github.com/users/kazupon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kazupon/subscriptions","organizations_url":"https://api.github.com/users/kazupon/orgs","repos_url":"https://api.github.com/users/kazupon/repos","events_url":"https://api.github.com/users/kazupon/events{/privacy}","received_events_url":"https://api.github.com/users/kazupon/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/vuejs/vue-validator/labels/feedback%20welcome","name":"feedback welcome","color":"009800"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":19,"created_at":"2015-07-28T07:57:46Z","updated_at":"2015-10-06T09:02:32Z","closed_at":null,"body":"Hi everyone !!\r\n\r\nI'm planning for the v2.0 release.\r\nI will start development on `dev/latest` branch at an early date.\r\n\r\nI have been publish the v1.0 release, fixed some bugs and adopted some user feedbacks.\r\n\r\nI think that want to adopt the user coming feedback to v1.0 implementation, but v1.0 implementation is bad design.\r\nEven if i adopting the user coming feedback, the bug occur easily.\r\n\r\nFor these reasons, I have decided to implement the v2.0 with full-scratch.\r\n\r\nI did rework the specification once again.\r\nThe following specifications (sorry my poor english):\r\n\r\n\r\n## spec\r\n\r\n- custom element (e.g. `<v-validator></v-validator>`)\r\n    - custom element enable validation result scope that did **inherit** from user data scope. vue-validator do not operate user data via validation result scope\r\n    - `id` attribute: keep the validation result data in custom element (e.g. vm.$validators.validator1)\r\n    - `name` attribute: change the validator result scope namespace (e.g. default: `validity`)\r\n    - available multiple validator (e.g. vm.$validators.validator1, vm.$validators.validator2, ...)\r\n- set custom directive (`v-validate`) to target element\r\n    - specify **field name**: keep the validation result\r\n    - validation result format: object property base structure (e.g. `validity.field.constraint`)\r\n    - accessable validation result with property keypath base (e.g. `validity.username.xxx`)\r\n- support for each field, the following validation property\r\n    - `valid` (e.g. `validity.field.valid`)\r\n    - `invalid` (reverse of `valid`, e.g. `validity.field.invalid`)\r\n    - `modified` (from **initial** field value, e.g. `validity.field.modified`)\r\n    - `dirty` (angluar-like, attached even **once**, e.g. `validity.field.dirty`)\r\n    - `pristine` (angluar-like, **not** attached even once, e.g. `validity.field.pristine`)\r\n- support the following top level property that keep the validation result of all fields\r\n    - `valid` (when **all** property is valid, return `true`)\r\n    - `invalid` (if exist even **one** invalid property, return `true`)\r\n    - `modified` (if exist even **one** modified property, return `true`)\r\n    - `dirty` (if exist even **one** dirty property, return `true`)\r\n    - `pristine` (if exist even **one** pristine property, return `true`)\r\n- build-in validators\r\n    - required\r\n    - pattern\r\n    - min\r\n    - max\r\n    - minLength\r\n    - maxLength\r\n- improve delay validator initialization feature\r\n    - custom element base (not for each custom directive)\r\n- validator use HTML5 Form attributes base. (e.g. `min`, `max` ...)\r\n    - support custom validator: use attribute (e.g. `myValidator1` -> `<input type=\"text\" my-validator1=\"foo\">`)\r\n    - support reactivity & function or inline expression like `v-on`: `{{ mustache }}` expressions (e.g. `<input type=\"text\" min=\"{{constraints.min}}\">`)\r\n    - support async validator\r\n- validator assets feature\r\n    - aseets management: like vue.js\r\n    - register/retrieve custom validator or build-in validtors\r\n\r\n## sample code\r\n\r\n```html\r\n<div id=\"app\">\r\n    <h1>user registration</h1>\r\n    <v-validator id=\"validator1\">\r\n        <form>\r\n            username:<input type=\"text\" required maxLength=\"16\" pattern=\"/[a-zA-Z0-9_-]/\" exist v-validate=\"username\"><br>\r\n            age:<input type=\"number\" required min=\"{{constraints.age.min}}\" max=\"{{constraintAgeMax}}\" v-validate=\"age\"><br>\r\n            email:<input type=\"email\" required email v-validate=\"email\"><br>\r\n            password:<input type=\"password\" required minLength=\"8\" v-validate=\"password\"><br>\r\n            site:<input type=\"number\" url v-validate=\"site\"><br>\r\n            <button type=\"submit\" value=\"join\" v-class=\"disabled: invalid\"><br>\r\n            <div>\r\n                <span v-if=\"validity.username.required\">required username.</span>\r\n                <span v-if=\"validity.username.maxLength\">too long username.</span>\r\n                <span v-if=\"validity.username.pattern\">invalid username format.</span>\r\n                <span v-if=\"validity.username.exsit\">already exist username.</span>\r\n                <span v-if=\"validity.age.required\">required age.</span>\r\n                <span v-if=\"validity.age.min\">too small age.</span>\r\n                <span v-if=\"validity.age.max\">too big age.</span>\r\n                <span v-if=\"validity.email.required\">required email.</span>\r\n                <span v-if=\"validity.email.email\">invalid email format.</span>\r\n                <span v-if=\"validity.password.required\">required password.</span>\r\n                <span v-if=\"validity.password.minLength\">too short password.</span>\r\n                <span v-if=\"validity.site.url\">invalid site url format.</span>\r\n            </div>\r\n        </form>\r\n    <v-validator>\r\n</div>\r\n```\r\n\r\n```javascript\r\nvar Vue = require('vue')\r\nvar VueValidator = require('vue-validator')\r\n\r\n//\r\n// register custom validators with validator assets\r\n//\r\n\r\n// url validator, sync validation\r\nVueValidator.asset('url', function (val) {\r\n    return /^(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-\\/]))?$/.test(val)\r\n})\r\n\r\n// exist validator, async validaiton\r\nVuevalidator.asset('exist', function (val) {\r\n    return function (resolve, reject) {\r\n        // server-side validation with ajax (e.g. using `fetch` case)\r\n        fetch('/validators/exist', {\r\n            method: 'post',\r\n            headers: {\r\n                'content-type': 'application/json',\r\n                'x-token': 'xxxxxxxx'\r\n            },\r\n            body: JSON.stringify({ username: val })\r\n        }).then(function (res) {\r\n            if (res.status === 200) {\r\n                resolve(true)\r\n            } else if (res.status === 400) {\r\n                resolve(false)\r\n            }\r\n        }).catch(function (err) {\r\n            // something todo ...\r\n            reject(new Error('exist validator fail'))\r\n        })\r\n    }\r\n})\r\n\r\n// email validator, async validation\r\nVueValidator.asset('email', function (val) {\r\n    return function (resolve, reject) {\r\n        // something todo ...\r\n    }\r\n})\r\n\r\n// install vue-validator\r\nVue.use(VueValidator)\r\n\r\n// create Vue instance\r\nnew Vue({\r\n    data: {\r\n        constraints: {\r\n            age: {\r\n                min: 18,\r\n            }\r\n        },\r\n        name: '',\r\n        age: 18,\r\n        email: '',\r\n        password: ''\r\n    },\r\n    computed: {\r\n        constraintAgeMax: function () {\r\n            return this.constraints.age.min * 5\r\n        }\r\n    }\r\n}).$mount('#app')\r\n```\r\n\r\n\r\n**NOTE:**\r\nThis is just a tentative specification."},"comment":{"url":"https://api.github.com/repos/vuejs/vue-validator/issues/comments/145791420","html_url":"https://github.com/vuejs/vue-validator/issues/41#issuecomment-145791420","issue_url":"https://api.github.com/repos/vuejs/vue-validator/issues/41","id":145791420,"user":{"login":"aristidesfl","id":208149,"avatar_url":"https://avatars.githubusercontent.com/u/208149?v=3","gravatar_id":"","url":"https://api.github.com/users/aristidesfl","html_url":"https://github.com/aristidesfl","followers_url":"https://api.github.com/users/aristidesfl/followers","following_url":"https://api.github.com/users/aristidesfl/following{/other_user}","gists_url":"https://api.github.com/users/aristidesfl/gists{/gist_id}","starred_url":"https://api.github.com/users/aristidesfl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aristidesfl/subscriptions","organizations_url":"https://api.github.com/users/aristidesfl/orgs","repos_url":"https://api.github.com/users/aristidesfl/repos","events_url":"https://api.github.com/users/aristidesfl/events{/privacy}","received_events_url":"https://api.github.com/users/aristidesfl/received_events","type":"User","site_admin":false},"created_at":"2015-10-06T09:02:31Z","updated_at":"2015-10-06T09:02:31Z","body":"@trippo80 That is the point, we want to disable the lazy directive after the first blur, so that the validation is on keystroke after the first blur."}}