Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- [Chrome](https://pikax.me/vue-composable/composable/breakpoint/breakpointChrome) - reactive chrome breakpoints
- [TailwindCSS](https://pikax.me/vue-composable/composable/breakpoint/breakpointTailwindCSS) - reactive TailwindCSS breakpoints
- [format](https://pikax.me/vue-composable/composable/format/format) - Reactive string format
- [Validation](https://pikax.me/vue-composable/composable/validation/validation) - model based validation inspired by [vuelidate](https://vuelidate.js.org/)

## 1.0.0-dev.9

Expand Down
115 changes: 115 additions & 0 deletions docs/.vuepress/components/ValidationExample.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<template>
<div class="about">
<h1>Form validation</h1>
<form @submit="onSubmit">
<input v-model="form.firstName.$value" placeholder="firstName" />
<input v-model="form.lastName.$value" placeholder="lastName" />
<input v-model="form.password.$value" placeholder="password" />
<input v-model="form.samePassword.$value" placeholder="password2" />
<p v-if="form.samePassword.$dirty && form.samePassword.match.$invalid">
{{ form.samePassword.match.$message }}
</p>

<br />
<input
type="submit"
v-model="submitText"
:class="{
invalid: form.$anyDirty && form.$anyInvalid,
dirty: form.$anyDirty && !form.$anyInvalid,
error: form.$errors.length > 0
}"
/>
</form>
</div>
</template>

<script>
import { createComponent, ref, reactive, computed } from "@vue/composition-api";
import { useValidation } from "vue-composable";

const required = x => !!x;

export default createComponent({
setup() {
const name = ref("");
const surname = ref("");
const password = ref("");

const form = useValidation({
firstName: {
$value: name,
required
},
lastName: {
$value: surname,
required
},
password: {
$value: password,
required: {
$validator: required,
$message: ref("password is required")
}
},
samePassword: {
$value: ref(""),

match: {
$validator(x) {
return x === password.value;
},
$message: "Password don't match"
}
}
});

const submitText = computed(() => {
if (form.$anyDirty && form.$anyInvalid) {
return "Invalid form";
}
if (!form.$anyDirty) {
return "Please populate the form";
}
if (form.$errors.length > 0) {
console.log(form.$errors);
return "Error";
}

return "Submit";
});

const onSubmit = e => {
e.preventDefault();
if (form.$anyInvalid) {
alert("invalid form");
} else {
alert("submit form");
}
};

return {
onSubmit,
submitText,
form
};
}
});
</script>

<style scoped>
.invalid {
color: #aa2233;
background: grey;
}

.dirty {
color: yellow;
background: grey;
}

.error {
color: red;
background: grey;
}
</style>
6 changes: 6 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ module.exports = {
["composable/web/geolocation", "Geolocation API"]
]
},
{
title: "Validation",
sidebarDepth: 1,
collapsable: false,
children: [["composable/validation/validation", "Validation"]]
},
{
title: "External",
sidebarDepth: 1,
Expand Down
4 changes: 4 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ Check out the [examples folder](examples) or start hacking on [codesandbox](http
- [BroadcastChannel](composable/web/broadcastChannel) - reactive `BroadcastChannel API`
- [Geolocation](composable/web/geolocation) - reactive `Geolocation API`

### Validation

- [Validation](composable/validation/validation) - model based validation inspired by [vuelidate](https://vuelidate.js.org/)

### External

> New packages needed
Expand Down
Loading