How to add Validation to multiple Email address to one recipient field comma separated - Angular 5 - angular5

I have an issue in validating multiple comma separated email address to one recipient field. I have no issue in validating one email. Any pointers are much appreciated. My code is below thanks.
html
<form ng-submit="onSend()" [formGroup]="sendEmailForm">
<div class="email-field">
<mat-form-field>
<input matInput #emailTo placeholder="to#company.ca, to#company.ca..." formControlName="toAddress">
</mat-form-field>
</form>
Typescript
ngOnInit() {
this.sendEmailForm = this.fb.group({
toAddress: new FormControl('', [Validators.email, Validators.required])
});
}
Will I have to write any custom validator?

You could create custom validator which calls Validators.email for each email in input value - stackblitz
commaSepEmail = (control: AbstractControl): { [key: string]: any } | null => {
const emails = control.value.split(',').map(e=>e.trim());
const forbidden = emails.some(email => Validators.email(new FormControl(email)));
return forbidden ? { 'toAddress': { value: control.value } } : null;
};
and use it like
this.sendEmailForm = this.fb.group({
'toAddress': ['', [Validators.required, this.commaSepEmail]]
});

Related

Can't return empty value to input box on vue

I want made a validation for input to be number only, whenever someone input a string, the input box will be cleared.
First, I made a method function on $event like this (ps. I use props)
<BaseInput
:value="nama"
#update="nama = ruled($event)"
label="Nama"
type="type"
/>
and this is the method, I use RegExp to check if the $event value is number. When it's false then I return $event value to empty string.
ruled(event) {
console.log(event)
var intRegex = new RegExp(/[0-9]/);
var data = intRegex.test(event)
if(!data) {
alert("Value Must Number")
event = ""
console.log('masuk if' + data)
}
return event
}
but it didn't clear the input box, anyone know why it happened ?
As Creative Learner said, I must clearing input box in child component only, so I did this on my component child
<template>
<input
:value="value"
:placeholder="label"
#input="$emit('update', ruled($event))"
/>
</template>
And this is the methods:
methods: {
ruled(event) {
//console.log(event)
var val = event.target.value
if(event.target.type == "number"){
var intRegex = new RegExp(/[0-9]/);
var intdata = intRegex.test(val)
if(intdata == false) {
error = "Value must contain number"
//alert("Value must contain number")
return event.target.value = ""
}
}
return val
}
}
great thanks to Creative Learner who made me understand
Suggestions :
Instead of #update you have to use #keypress or #change.
You can use v-model for two-way data binding.
Working Demo :
new Vue({
el: '#app',
data: {
nama: ''
},
methods: {
ruled(event) {
var intRegex = new RegExp(/^\d+$/);
var data = intRegex.test(this.nama);
if (!data) {
alert("Value must contain number");
this.nama = "";
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input
v-model="nama"
#change="ruled($event)"
label="Nama"
type="text"
/>
</div>

Unable to put value using :value wiht v-model together in VueJS 2

In a page i am fetcing data from API and showing the data in the text field. After that user can change the data and submit the form. I am uanble to show data using :value in the inout field. Its showing conflicts with v-model on the same element because the latter already expands to a value binding internally
I tried to mount the data after it loads. But it is still not showing.
<input v-model="password" :value="credentials.password">
created() {
let txid = this.$route.params.id
this.$axios.get(this.$axios.defaults.baseURL+'/v1/purno/internal/users/'+ txid, {
}).then((response) => {
if (response.data.status == 'error') {
toast.$toast.error('Something Went Wrong at!', {
// override the global option
position: 'top'
})
} else if (response.data.status == 'success') {
if(response.data.data.found ==true) {
this.credentials = response.data.data;
})
}
}
})
});
},
data(){
return {
credentials:[],
password:null
}
},
mounted(){
this.password = this.credentials.password
}
How can i solve this problem? Thanks in advance
Please complete it within the request callback
this.credentials = response.data.data;
this.password = this.credentials.password;
like this in the then callback fn. Try it!
conflicts with v-model on the same element because the latter already expands to a value binding internally error message tells it all
v-model="password" is same as :value="password" #input="password = $event.target.value" (for text and textarea - see here)
So using it together with another :value makes no sense...

vue axios post how to submit formdata array?

I need to submit an ARRAY data because the backend can only recognize such data
Expected effect:
&row[weigh]=0
&row[status]=normal
code:
row:{
weigh: 0,
status: 'normal'
}
actual effect:
row:{
weigh: 0,
status: 'normal'
}
When I submit the data, the console displays JSON instead of Array, but the backend cannot get it
What I need is to be consistent with the results from the form submission below
<form method="POST" >
<input name="row[a]" type="text" value="">
<input name="row[b]" type="text" value="">
public register(rowObject: RowObject): AxiosPromise<any> {
return axios.post('http://localhost/api/register', rowObject);
}
This way you can pass the data in Post method.
rowObject = {
weigh: 0,
status: 'normal'
}
Try this code.
let row = {
weigh: 0,
status: 'normal'
};
let finalArr = [];
Object.keys(row).forEach((key) => {
finalArr.push(`row[${key}]=` + row[key]);
});
console.log(finalArr.join('&'));
// outputs: row[weigh]=0&row[status]=normal
Your code also should pass an array just like this.
data = [
{weigh: 0},
{status: 'normal'}
]
then when you send it to server for example using axios, your code should look like this
axios.post('/api endpoint', {row:data})
.then(response => {
// response here
});
ok
const formData = new FormData()
Object.keys(this.form).forEach(e => {
formData.append(`row[${e}]`, this.form[e])
})

Vue2 populate inputs in edit view

I´m trying to create a simple CRUD in vue2 and works perfectly, but when i enter in edit view i need to fill form inputs based on Firebase data.
View
<v-text-field prepend-icon="person" v-model="user" name="user" label="User" type="text" required></v-text-field>
<v-text-field prepend-icon="mail" v-model="email" name="email" label="Email" type="email"></v-text-field>
JS
export default {
data: function () {
return {
user: '',
email: '',
drawer: null
}
var edit = ref.child(this.$route.params.id)
edit.on('value', function (snapshot) {
this.user = snapshot.val().name
this.email = snapshot.val().email
})
snapshot.val().name
Return name properly but when i try to assign this value to this.user does not work. Console does not return any error.
¿Anybody has a idea whats is the correct way?
export default {
data: function () {
return {
user: '',
email: '',
drawer: null
}
var edit = ref.child(this.$route.params.id)
var self = this;
edit.on('value', function (snapshot) {
self.user = snapshot.val().name
self.email = snapshot.val().email
})
It might be a scope issue. Try the code above to maintain the scope let’s see if that helps.
var edit = ref.child(this.$route.params.id)
edit.on('value', snapshot => this.user = snapshot.val().name)
edit.on('value', snapshot => this.email = snapshot.val().email)
This works, but exist a form to 'code' better?

How to separate in vue.js entered value and displayed value in input[type=text]?

Example:
<span class='prefix'>+{{ prefix }}</span>
<input type='tel' v-model='phone'>
What should be displayed
When phone === '790012345678', it is actually
prefix = '7'
phone = '90012345678'
And displayed accordingly
<span class='prefix'>+7</span>
<input type='tel' value='90012345678'>
When user removes value from input, prefix is removed too.
Problem (jsfiddle http://jsfiddle.net/4qqza69k/48/)
I use watcher for `phone`.
When user changes something inside `input` watcher must update value for `phone`, but this way it is triggered again and it receives updated (incorrect) value.
Scenarios:
Phone equals 7-100-200-30-40
prefix = +7, phone = 1002003040
Phone equals 7
prefix = +7, phone = ''
Phone equals 7123
prefix = +7, phone = 123
Phone is empty
prefix = '', phone = ''
Problem: how to exclude prefix from input without triggering updates?
I think you need to rewrite v-model into more explicit v-on + v-bind pair and listen to input for a phone number, while calculating prefix and the rest part separately:
new Vue({
el: '#app',
data: {
prefix: '',
phone: '', // full phone number
},
methods: {
handleInput: function(e) {
if (e.target.value === '') this.prefix = '';
if (this.prefix !== '') {
this.phone = this.prefix + e.target.value;
} else {
const v = e.target.value;
this.phone = v;
this.prefix = v.slice(0,1);
}
}
},
computed: {
withoutPrefix: function() {
return (this.prefix !== '') ? this.phone.slice(1) : ''
}
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<span class='prefix'>+{{ prefix }}</span>
<input type='tel' #input="handleInput" :value="withoutPrefix">
<p>Phone: {{ phone }}</p>
</div>
It does not exactly work cause I'm being a bit confused by your example, but I think one way is to use computed getter/setter instead.
data() {
return {
hiddenInputValue: ''
}
},
computed: {
inputValue: {
get() {
return this.hiddenInputValue;
},
set(val) {
// do something with the input value...
this.hiddenInputValue = // assign a modified version of the input value...
}
}
}
You should be able to do something with that, but check my comment. It's probably a better solution.