diff --git a/README.md b/README.md index cb8b819..2cbc515 100644 --- a/README.md +++ b/README.md @@ -68,18 +68,20 @@ Add the component in your vue view. List of available props to use in component: -Prop | Data Type | Default | Description --------------- | ---------- | -------- | ----------- -`action` | String | | Action URL where to send form data. -`method` | String | POST | Request method (i.e. GET or POST). -`headers` | Object | | Request headers ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). -`timeout` | Number | | Request headers ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). -`credentials` | Boolean | | Flag that indicates if request has credentials ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). -`emulate-http` | Boolean | | Flag that indicates if request should emulate HTTP ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). -`emulate-json` | Boolean | | Flag that indicates if request should emulate JSON ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). -`errors` | Object | Object | List of default validation rules error messages. -`id` | String | | Form given ID. -`key` | String | | Form given loop key (i.e. in case of being used inside a v-for). +Prop | Data Type | Default | Description +--------------- | ---------- | -------- | ----------- +`action` | String | | Action URL where to send form data. +`method` | String | POST | Request method (i.e. GET or POST). +`headers` | Object | | Request headers ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). +`timeout` | Number | | Request headers ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). +`credentials` | Boolean | | Flag that indicates if request has credentials ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). +`emulate-http` | Boolean | | Flag that indicates if request should emulate HTTP ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). +`emulate-json` | Boolean | | Flag that indicates if request should emulate JSON ([reference](https://github.com/vuejs/vue-resource/blob/master/docs/http.md#options)). +`errors` | Object | Object | List of default validation rules error messages. +`id` | String | | Form given ID. +`key` | String | | Form given loop key (i.e. in case of being used inside a v-for). +`response-json` | Boolean | false | Forces response to be returned and parsed as JSON. +`response-blob` | Boolean | false | Forces response to be returned as Blob. ### Request diff --git a/dist/vue.form.js b/dist/vue.form.js index e6f0a72..bc778fc 100644 --- a/dist/vue.form.js +++ b/dist/vue.form.js @@ -6,7 +6,7 @@ * @author Alejandro Mostajo * @copyright 10Quality * @license MIT - * @version 1.0.8 + * @version 1.0.9 */ Vue.component('vform', Vue.extend({ props: @@ -127,6 +127,26 @@ Vue.component('vform', Vue.extend({ type: [String, Number], default: undefined, }, + /** + * Flag that indicates if response needs to be converted to json. + * @since 1.0.9 + * @var bool + */ + responseJson: + { + type: [String, Boolean], + default: false, + }, + /** + * Flag that indicates if response needs to be converted to json. + * @since 1.0.9 + * @var bool + */ + responseBlob: + { + type: [String, Boolean], + default: false, + }, }, data: function() { return { @@ -203,12 +223,21 @@ Vue.component('vform', Vue.extend({ * @since 1.0.1 Added event dispatch. * @since 1.0.3 Added event broadcast. * @since 1.0.4 Response errors triggers invalid event. + * @since 1.0.9 Forces response conversion to jsob or blob. * * @param object response Response */ onSubmit: function(response) { - this.$set('response', response.data); + this.$set( + 'response', + this.responseJson + ? response.json() + : (this.responseBlob + ? response.blob() + : response.data + ) + ); this.$dispatch('vform_success'); this.$broadcast('vform_success'); if (this.response.errors !== undefined && Object.keys(this.response.errors).length > 0) { diff --git a/dist/vue.form.min.js b/dist/vue.form.min.js index 3e8438f..f06a577 100644 --- a/dist/vue.form.min.js +++ b/dist/vue.form.min.js @@ -1 +1 @@ -"use strict";Vue.component("vform",Vue.extend({props:{action:{type:String,"default":""},method:{type:String,"default":"POST"},headers:{type:Object,"default":function(){}},timeout:{type:[String,Number],"default":void 0},credentials:{type:[String,Boolean],"default":void 0},emulateHttp:{type:[String,Boolean],"default":void 0},emulateJson:{type:[String,Boolean],"default":void 0},errors:{type:Object,"default":function(){return{required:"Required field.",number:"Value must be numeric.",email:"Email value is invalid.",min:"Value must have at least %1% character(s).",min_number:"Value must be at least %1%.",max:"Value must have no more than %1% character(s).",max_number:"Value must be no more than %1%.",between:"Value must have between %1% to %2% characters.",between_number:"Value must be between %1% to %2%.",equals:"Value must be equal to %1%.",required_if:"Required field.",url:"Url value is invalid."}}},id:{type:[String,Number],"default":void 0},key:{type:[String,Number],"default":void 0}},data:function(){return{request:{},isLoading:!1,response:{}}},computed:{hasMessage:function(){return void 0!=this.response.message},hasError:function(){return void 0!=this.response.error&&this.response.error}},methods:{submit:function(){var a=!0;this.$set("response",{});for(var b in this.$children)"function"==typeof this.$children[b].validate&&(a=this.$children[b].validate()&&a);a?(this.$set("isLoading",!0),this.$http(this.getOptions()).then(this.onSubmit,this.onError)):(this.$dispatch("vform_invalid",this.response.errors),this.$broadcast("vform_invalid",this.response.errors))},onSubmit:function(a){return this.$set("response",a.data),this.$dispatch("vform_success"),this.$broadcast("vform_success"),void 0!==this.response.errors&&Object.keys(this.response.errors).length>0&&(this.$dispatch("vform_invalid",this.response.errors),this.$broadcast("vform_invalid",this.response.errors)),void 0!==a.data.redirect?window.location=a.data.redirect:void this.onComplete()},onComplete:function(){this.$set("isLoading",!1),this.$dispatch("vform_complete"),this.$broadcast("vform_complete")},onError:function(a){console.log(a),this.$dispatch("vform_error",a),this.$broadcast("vform_error",a),this.onComplete()},getOptions:function(){var a={url:this.action,method:this.method};switch(void 0!==this.headers&&(a.headers=this.headers),void 0!==this.timeout&&(a.timeout=this.timeout),void 0!==this.credentials&&(a.credentials="boolean"==typeof this.credentials?this.credentials:"true"===this.credentials),void 0!==this.emulateHttp&&(a.emulateHTTP="boolean"==typeof this.emulateHttp?this.emulateHttp:"true"===this.emulateHttp),void 0!==this.emulateJson&&(a.emulateJSON="boolean"==typeof this.emulateJson?this.emulateJson:"true"===this.emulateJson),this.method){case"post":case"POST":case"put":case"PUT":case"patch":case"PATCH":a.body=this.request;break;default:a.params=this.request}return a}},components:{"input-handler":Vue.extend({template:'
  • {{error}}
',props:{listen:{type:String,"default":""},"class":{type:String,"default":""},classError:{type:String,"default":void 0},response:{type:[Object,Array],"default":function(){return{}}},validations:{type:String,"default":""}},computed:{inputErrors:function(){var a=[];return void 0!==this.response.errors&&void 0!==this.response.errors[this.listen]&&(a=this.response.errors[this.listen]),a},hasErrors:function(){return this.inputErrors.length>0},errorCss:function(){var a={};return void 0!==this.classError&&(a[this.classError]=this.hasErrors),a}},methods:{validate:function(){var a=!0,b=this.validations.split("|");for(var c in b){var d=b[c].split(":");switch(d[0]){case"required":void 0!==this.$parent.request[this.listen]&&0!==this.$parent.request[this.listen].length||(this.addError(d),a=!1);break;case"number":void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&isNaN(this.$parent.request[this.listen])&&(this.addError(d),a=!1);break;case"min":if(d.length<2)throw"Minimum value is not defined in validation rules";void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&this.$parent.request[this.listen].length0&&this.$parent.request[this.listen].length>parseInt(d[1])&&(this.addError(d),a=!1);break;case"max_number":if(d.length<2)throw"Minimum value is not defined in validation rules";void 0!==this.$parent.request[this.listen]&&parseInt(this.$parent.request[this.listen])>parseInt(d[1])&&(this.addError(d),a=!1);break;case"between":if(d.length<3)throw"One or all between values are not defined in validation rules";void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&(this.$parent.request[this.listen].lengthparseInt(d[2]))&&(this.addError(d),a=!1);break;case"between_number":if(d.length<3)throw"One or all between values are not defined in validation rules";void 0!==this.$parent.request[this.listen]&&(parseInt(this.$parent.request[this.listen])parseInt(d[2]))&&(this.addError(d),a=!1);break;case"email":var e=/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&!e.test(this.$parent.request[this.listen])&&(this.addError(d),a=!1);break;case"equals":if(d.length<2)throw"Comparison field is not defined in validation rules";void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen]!==this.$parent.request[d[1]]&&(this.addError(d),a=!1);break;case"required_if":if(d.length<2)throw"Comparison field is not defined in validation rules";void 0!==this.$parent.request[d[1]]&&this.$parent.request[d[1]].length>0&&(void 0===this.$parent.request[this.listen]||0===this.$parent.request[this.listen].length)&&(this.addError(d),a=!1);break;case"url":var e=/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/;void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&!e.test(this.$parent.request[this.listen])&&(this.addError(d),a=!1)}}return a},addError:function(a){void 0===this.$parent.response&&this.$parent.$set("response",{}),void 0===this.$parent.response.errors&&this.$parent.$set("response.errors",{}),void 0===this.$parent.response.errors[this.listen]&&this.$parent.$set("response.errors."+this.listen,[]);var b=this.$parent.errors[a[0]];a.length>1&&(b=b.replace(/\%1\%/,a[1])),a.length>2&&(b=b.replace(/\%2\%/,a[2])),this.$parent.response.errors[this.listen].push(b)}}}),results:Vue.extend({props:{model:{type:[Array,Object,String],"default":function(){return[]}},request:{type:Object,"default":function(){return{}}},fetchOnready:{type:[String,Boolean],"default":!1},clearOnFetch:{type:[String,Boolean],"default":!0}},data:function(){return{buffer:[]}},computed:{records:function(){if(!this.$parent.hasMessage&&Array.isArray(this.model))if(this.clearOnFetch)this.$set("buffer",this.model);else for(var a in this.model)void 0!==this.model[a]&&null!==this.model[a]&&this.buffer.push(this.model[a]);return this.buffer},hasRecords:function(){return this.records.length>0}},ready:function(){this.fetchOnready&&this.$parent.submit()}})}})); \ No newline at end of file +"use strict";Vue.component("vform",Vue.extend({props:{action:{type:String,"default":""},method:{type:String,"default":"POST"},headers:{type:Object,"default":function(){}},timeout:{type:[String,Number],"default":void 0},credentials:{type:[String,Boolean],"default":void 0},emulateHttp:{type:[String,Boolean],"default":void 0},emulateJson:{type:[String,Boolean],"default":void 0},errors:{type:Object,"default":function(){return{required:"Required field.",number:"Value must be numeric.",email:"Email value is invalid.",min:"Value must have at least %1% character(s).",min_number:"Value must be at least %1%.",max:"Value must have no more than %1% character(s).",max_number:"Value must be no more than %1%.",between:"Value must have between %1% to %2% characters.",between_number:"Value must be between %1% to %2%.",equals:"Value must be equal to %1%.",required_if:"Required field.",url:"Url value is invalid."}}},id:{type:[String,Number],"default":void 0},key:{type:[String,Number],"default":void 0},responseJson:{type:[String,Boolean],"default":!1},responseBlob:{type:[String,Boolean],"default":!1}},data:function(){return{request:{},isLoading:!1,response:{}}},computed:{hasMessage:function(){return void 0!=this.response.message},hasError:function(){return void 0!=this.response.error&&this.response.error}},methods:{submit:function(){var a=!0;this.$set("response",{});for(var b in this.$children)"function"==typeof this.$children[b].validate&&(a=this.$children[b].validate()&&a);a?(this.$set("isLoading",!0),this.$http(this.getOptions()).then(this.onSubmit,this.onError)):(this.$dispatch("vform_invalid",this.response.errors),this.$broadcast("vform_invalid",this.response.errors))},onSubmit:function(a){return this.$set("response",this.responseJson?a.json():this.responseBlob?a.blob():a.data),this.$dispatch("vform_success"),this.$broadcast("vform_success"),void 0!==this.response.errors&&Object.keys(this.response.errors).length>0&&(this.$dispatch("vform_invalid",this.response.errors),this.$broadcast("vform_invalid",this.response.errors)),void 0!==a.data.redirect?window.location=a.data.redirect:void this.onComplete()},onComplete:function(){this.$set("isLoading",!1),this.$dispatch("vform_complete"),this.$broadcast("vform_complete")},onError:function(a){console.log(a),this.$dispatch("vform_error",a),this.$broadcast("vform_error",a),this.onComplete()},getOptions:function(){var a={url:this.action,method:this.method};switch(void 0!==this.headers&&(a.headers=this.headers),void 0!==this.timeout&&(a.timeout=this.timeout),void 0!==this.credentials&&(a.credentials="boolean"==typeof this.credentials?this.credentials:"true"===this.credentials),void 0!==this.emulateHttp&&(a.emulateHTTP="boolean"==typeof this.emulateHttp?this.emulateHttp:"true"===this.emulateHttp),void 0!==this.emulateJson&&(a.emulateJSON="boolean"==typeof this.emulateJson?this.emulateJson:"true"===this.emulateJson),this.method){case"post":case"POST":case"put":case"PUT":case"patch":case"PATCH":a.body=this.request;break;default:a.params=this.request}return a}},components:{"input-handler":Vue.extend({template:'
  • {{error}}
',props:{listen:{type:String,"default":""},"class":{type:String,"default":""},classError:{type:String,"default":void 0},response:{type:[Object,Array],"default":function(){return{}}},validations:{type:String,"default":""}},computed:{inputErrors:function(){var a=[];return void 0!==this.response.errors&&void 0!==this.response.errors[this.listen]&&(a=this.response.errors[this.listen]),a},hasErrors:function(){return this.inputErrors.length>0},errorCss:function(){var a={};return void 0!==this.classError&&(a[this.classError]=this.hasErrors),a}},methods:{validate:function(){var a=!0,b=this.validations.split("|");for(var c in b){var d=b[c].split(":");switch(d[0]){case"required":void 0!==this.$parent.request[this.listen]&&0!==this.$parent.request[this.listen].length||(this.addError(d),a=!1);break;case"number":void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&isNaN(this.$parent.request[this.listen])&&(this.addError(d),a=!1);break;case"min":if(d.length<2)throw"Minimum value is not defined in validation rules";void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&this.$parent.request[this.listen].length0&&this.$parent.request[this.listen].length>parseInt(d[1])&&(this.addError(d),a=!1);break;case"max_number":if(d.length<2)throw"Minimum value is not defined in validation rules";void 0!==this.$parent.request[this.listen]&&parseInt(this.$parent.request[this.listen])>parseInt(d[1])&&(this.addError(d),a=!1);break;case"between":if(d.length<3)throw"One or all between values are not defined in validation rules";void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&(this.$parent.request[this.listen].lengthparseInt(d[2]))&&(this.addError(d),a=!1);break;case"between_number":if(d.length<3)throw"One or all between values are not defined in validation rules";void 0!==this.$parent.request[this.listen]&&(parseInt(this.$parent.request[this.listen])parseInt(d[2]))&&(this.addError(d),a=!1);break;case"email":var e=/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&!e.test(this.$parent.request[this.listen])&&(this.addError(d),a=!1);break;case"equals":if(d.length<2)throw"Comparison field is not defined in validation rules";void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen]!==this.$parent.request[d[1]]&&(this.addError(d),a=!1);break;case"required_if":if(d.length<2)throw"Comparison field is not defined in validation rules";void 0!==this.$parent.request[d[1]]&&this.$parent.request[d[1]].length>0&&(void 0===this.$parent.request[this.listen]||0===this.$parent.request[this.listen].length)&&(this.addError(d),a=!1);break;case"url":var e=/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/;void 0!==this.$parent.request[this.listen]&&this.$parent.request[this.listen].length>0&&!e.test(this.$parent.request[this.listen])&&(this.addError(d),a=!1)}}return a},addError:function(a){void 0===this.$parent.response&&this.$parent.$set("response",{}),void 0===this.$parent.response.errors&&this.$parent.$set("response.errors",{}),void 0===this.$parent.response.errors[this.listen]&&this.$parent.$set("response.errors."+this.listen,[]);var b=this.$parent.errors[a[0]];a.length>1&&(b=b.replace(/\%1\%/,a[1])),a.length>2&&(b=b.replace(/\%2\%/,a[2])),this.$parent.response.errors[this.listen].push(b)}}}),results:Vue.extend({props:{model:{type:[Array,Object,String],"default":function(){return[]}},request:{type:Object,"default":function(){return{}}},fetchOnready:{type:[String,Boolean],"default":!1},clearOnFetch:{type:[String,Boolean],"default":!0}},data:function(){return{buffer:[]}},computed:{records:function(){if(!this.$parent.hasMessage&&Array.isArray(this.model))if(this.clearOnFetch)this.$set("buffer",this.model);else for(var a in this.model)void 0!==this.model[a]&&null!==this.model[a]&&this.buffer.push(this.model[a]);return this.buffer},hasRecords:function(){return this.records.length>0}},ready:function(){this.fetchOnready&&this.$parent.submit()}})}})); \ No newline at end of file diff --git a/package.json b/package.json index 09c854b..38e9028 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-form", - "version": "1.0.8", + "version": "1.0.9", "description": "Form component for Vue JS.", "main": "dist/vue.social-share.js", "repository": { diff --git a/src/vue.form.js b/src/vue.form.js index e6f0a72..bc778fc 100644 --- a/src/vue.form.js +++ b/src/vue.form.js @@ -6,7 +6,7 @@ * @author Alejandro Mostajo * @copyright 10Quality * @license MIT - * @version 1.0.8 + * @version 1.0.9 */ Vue.component('vform', Vue.extend({ props: @@ -127,6 +127,26 @@ Vue.component('vform', Vue.extend({ type: [String, Number], default: undefined, }, + /** + * Flag that indicates if response needs to be converted to json. + * @since 1.0.9 + * @var bool + */ + responseJson: + { + type: [String, Boolean], + default: false, + }, + /** + * Flag that indicates if response needs to be converted to json. + * @since 1.0.9 + * @var bool + */ + responseBlob: + { + type: [String, Boolean], + default: false, + }, }, data: function() { return { @@ -203,12 +223,21 @@ Vue.component('vform', Vue.extend({ * @since 1.0.1 Added event dispatch. * @since 1.0.3 Added event broadcast. * @since 1.0.4 Response errors triggers invalid event. + * @since 1.0.9 Forces response conversion to jsob or blob. * * @param object response Response */ onSubmit: function(response) { - this.$set('response', response.data); + this.$set( + 'response', + this.responseJson + ? response.json() + : (this.responseBlob + ? response.blob() + : response.data + ) + ); this.$dispatch('vform_success'); this.$broadcast('vform_success'); if (this.response.errors !== undefined && Object.keys(this.response.errors).length > 0) { diff --git a/tests/test1.html b/tests/test1.html index a93a038..4e9812d 100644 --- a/tests/test1.html +++ b/tests/test1.html @@ -6,6 +6,7 @@ action="https://restcountries.eu/rest/v1/alpha" method="GET" v-ref:form + :response-json="true" >

Country search sample

Provided by: http://restcountries.eu/