How to bind the formControlName to static radio-button value - angular-reactive-forms

I am new to the reactive forms, here I am trying to bind the form control name to the static radio button, but radio button depends on the loop where it keeps repeating based on the number of loops.
When I bind the radio button to the form control name then this is the issue I am facing
If i try to select the one value "good" then all button are selected with value "good"
Here is the code for the above issue:-
import {
Component
} from '#angular/core';
import {
FormBuilder,
FormGroup,
Validators
} from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [FormBuilder]
})
export class AppComponent {
name = 'Angular';
ipdForm: FormGroup;
IpdData = [];
response = {
"data": [{
"id": 19,
"question" : "question 1",
"options": "radio"
},
{
"id": 20,
"question" : "question 2",
"options": "radio"
},
{
"id": 33,
"question" : "question 3",
"options": "text"
},
{
"id": 34,
"question" : "question 4",
"options": "text"
},
]
}
constructor(
private fb: FormBuilder,
) {}
ngOnInit() {
this.getIpdFormData();
this.filterDefaultValues();
}
getIpdFormData() {
this.IpdData = this.response.data;
}
filterDefaultValues() {
this.ipdForm = this.fb.group({
ratingForm: [''],
question: [],
});
}
ipdFeedback() {
}
html
<form class="custom-form" [formGroup]="ipdForm" (submit)="ipdFeedback();">
<div class="form-group" *ngFor="let d of IpdData;let i = index">
<label for="dob" class="control-label">
{{d.question }}
<sup class="custom-required">*</sup>
</label>
<label class="radio-inline custom-radio">
<div *ngIf="d.options == 'radio'">
<div >
<label class="radio-inline custom-radio">
<input class="radio-text" formControlName="ratingForm" type="radio" value="Poor" />
<span class="radio-text">Poor</span>
</label>
<label class="radio-inline custom-radio">
<input class="radio-text" formControlName="ratingForm" type="radio" value="Fair" />
<span class="radio-text">Fair</span>
</label>
<label class="radio-inline custom-radio">
<input class="radio-text" formControlName="ratingForm" type="radio" value="Good" />
<span class="radio-text">Good </span>
</label>
</div>
</div>
<div *ngIf="d.options == 'text'">
<textarea placeholder="Comments" formControlName="ratingForm" type="text" class="form-control" tabindex="14"></textarea>
</div>
</label>
</div>
<button type="submit"></button>
</form>
here when I bind the value to form control name then all radio button is selected for that particular value
How to send the value of radio button and also id of that question to the ipdFeedback function.
This is required array
array [{
value : "good"
questionId : 20
}]

Your formControlName is inside a ngfor. It is same name for every index.That is why the value changed in every Index.You need to create FormArray.
ngOnInit() {
this.ipdForm = this.fb.group({
IpdData: this.fb.array([])
})
}
get ipdFormArray() {
return this.ipdForm.get('IpdData') as FormArray;
}
filterDefaultValues() {
for (let i = 0; i < this.IpdData.length; i++) {
const datas = this.fb.group({
ratingForm: [''],
question: [IpdData[i].question],
});
this.ipdFormArray.push(datas);
}
}
change your html like below; ngfor for reacctive form array and add formarray name
<form class="custom-form" [formGroup]="ipdForm"
(submit)="ipdFeedback();">
<div formArrayName="IpdData">
<div class="form-group" *ngFor="let d of ipdFormArray.controls;let i = index" [formGroupName]="i">
<label for="dob" class="control-label">
{{d.question }}
<sup class="custom-required">*</sup>
</label>
<label class="radio-inline custom-radio">
<div *ngIf="IpdData[i].options == 'radio'">
<div >
<label class="radio-inline custom-radio">
<input class="radio-text" formControlName="ratingForm" type="radio" value="Poor" />
<span class="radio-text">Poor</span>
</label>
<label class="radio-inline custom-radio">
<input class="radio-text" formControlName="ratingForm" type="radio" value="Fair" />
<span class="radio-text">Fair</span>
</label>
<label class="radio-inline custom-radio">
<input class="radio-text" formControlName="ratingForm" type="radio" value="Good" />
<span class="radio-text">Good </span>
</label>
</div>
</div>
<div *ngIf="IpdData[i].options == 'text'">
<textarea placeholder="Comments" formControlName="ratingForm" type="text" class="form-control" tabindex="14"></textarea>
</div>
</label>
</div>
<button type="submit"></button>
You will get the values in this.ipdFormArray.value

Related

Laravel inertia multi-part form data

I want to create a membership form with picture upload and other input data required. I have a form with input file and input text which to be considered as multi-part data. I am using the Laravel 8 and Inertia.js.
Here is what I've tried:
In my Form, I have like this:
<form action="/member" method="POST" #submit.prevent="createMember">
<div class="card-body">
<div class="form-group">
<label for="exampleInputFile">Picture</label>
<div class="input-group">
<div class="custom-file">
<input type="file" class="custom-file-input" id="exampleInputFile" #input="form.picture">
<label class="custom-file-label" for="exampleInputFile">Choose image</label>
</div>
<div class="input-group-append">
<span class="input-group-text">Upload</span>
</div>
</div>
</div>
<div class="form-group">
<label for="exampleInputEmail1">First name</label>
<input type="text" class="form-control" id="fname" placeholder="First name" v-model="form.firstname">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Middle name</label>
<input type="text" class="form-control" id="mname" placeholder="Middle name" v-model="form.middlename">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Last name</label>
<input type="text" class="form-control" id="lname" placeholder="Last name" v-model="form.lastname">
</div>
<div class="col-md-12">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Name ext</label>
<input type="text" class="form-control" id="next" placeholder="Name extension" v-model="form.name_ext">
</div>
<div class="form-group">
<label>Membership Date:</label>
<div class="input-group date" id="reservationdate" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" id="mem_date" data-target="#reservationdate" v-model="form.membership_date"/>
<div class="input-group-append" data-target="#reservationdate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
<div class="form-group">
<label>Date of Birth:</label>
<div class="input-group date" id="reservationdate" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" id="date_of_birth" data-target="#reservationdate" v-model="form.date_of_birth"/>
<div class="input-group-append" data-target="#reservationdate" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
<div class="form-group">
<label>Sex:</label>
<div class="radio-inline">
<label class="radio radio-solid">
<input type="radio" name="travel_radio" class="details-input" value="Male" v-model="form.sex"/> Male
<span></span>
</label>
<label class="radio radio-solid">
<input type="radio" name="travel_radio" class="details-input" value="Female" v-model="form.sex"/> Female
<span></span>
</label>
</div>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
then I have tried vue and inertia implementation like this:
export default {
props: [],
components: {
AppLayout,
},
data() {
return {
form: {
picture: '',
firstname: '',
middlename: '',
lastname: '',
name_ext: '',
date_of_birth: '',
sex: '',
membership_date: '',
}
}
},
methods: {
createMember() {
this.$inertia.post('/member', this.form, {
_method: 'put',
picture: this.form.picture,
onSuccess: () => {
console.log('success');
// $('.toastrDefaultSuccess').click(function() {
// toastr.success('Successfully Added');
// });
},
onError: (errors) => {
console.log(errors);
},
})
}
}
}
then from my backend, I tried to dd the request and got null from picture:
public function store(MemberPost $request) {
dd($request);
}
Assuming you are using inertia 0.8.0 or above, you can use the inertia form helper. This will automatically transform the data to a FormData object if necessary.
Change your data method to:
data() {
return {
form: this.$inertia.form({
picture: '',
firstname: '',
middlename: '',
lastname: '',
name_ext: '',
date_of_birth: '',
sex: '',
membership_date: '',
})
}
}
and the createMember function to:
createMember() {
// abbreviated for clarity
this.form.post('/member')
}
More info: docs. If you need to migrate FormData from inertia < 0.8.0 to a current version, see this page.
if you using multi-upload remove array from files
before: <input type="file" #input="form.image = $event.target.files[0]" multiple/>
after: <input type="file" #input="form.image = $event.target.files" multiple/>
add enctype="multipart/form-data" to form tag
and you need move the picture to directory. example
$name = $file->getClientOriginalName();
$file->move('uploads/posts/',$name);
sorry, i dont know how to implement this code to inertia.
This way works for me
this.$inertia.post('/member', this.form)

Unable to bind the Radio button and checkbox data on button click in react hooks

I am having a form, When I submit the data it is going to server and I displayed the data in a table..
In the Table I am having edit button, When clicked on Edit button, the data should bind to the Form.
Here I am unable to bind the Inputs fields, but not the Radio and Checkboxes...
const Form = () => {
const [data, setdata] = useState({
"UserName" : "",
"dropDown" :"",
"gender" : "",
"checking" :""
})
const [update, setUpdate] = useState([])
const handleChange =(e)=>{
if(e.target.name !=="gender" && e.target.name !=="checking"){
setdata({...data,[e.target.name]:e.target.value});
}else if(e.target.name ==="gender"){
let allgenders = document.getElementsByName("gender");
allgenders.forEach((allradio)=>{
if(allradio.checked){
setdata({...data,[e.target.name]:e.target.value});
}
})
}else if(e.target.name ==="checking"){
let getallCheckboxes =[];
let allCheckboxes =document.getElementsByName("checking");
allCheckboxes.forEach((allchecks)=>{
if(allchecks.checked){
getallCheckboxes.push(allchecks.value)
}
});
setdata({...data,[e.target.name]:getallCheckboxes});
}
}
useEffect(() => {
getAllData();
}, [])
const handleSubmit=(e)=>{
e.preventDefault();
// setUpdate({...data,update});
// console.log(data);
axios.post('http://localhost:3000/users',data).then((res)=>{
// console.log("user added successfully");
getAllData();
handleClear();
})
}
const getAllData=()=>{
axios.get('http://localhost:3000/users').then((res)=>{
setUpdate(res.data);
})
}
const deleteUser=(dating)=>{
console.log(dating);
axios.delete('http://localhost:3000/users/'+dating.id).then(res=>{
getAllData();
})
}
This is the Funtions for Edit and update,Here I am able to bind the Inputs fields, but not the Radio and Checkboxes...
const editUser=(userData)=>{
setdata(userData)
}
const handleEdit=()=>{
console.log(data);
axios.put('http://localhost:3000/users/'+data.id,data).then(res=>{
getAllData();
})
}
return (
<React.Fragment>
<h1>LordShiva</h1>
<div className="container mt-3">
<div className="row">
<div className="col-md-6">
<div className="card">
<div className="card-header bg-success text-white">
<h4>Form</h4>
<form>
<div className="form-group">
<input type="text" className="form-control" placeholder='UserName' name="UserName" value={data.UserName} onChange={handleChange} />
</div>
<div className="form-group">
<input name="phone" className="form-control" placeholder='PhoneNumber' name="PhoneNumber" value={data.PhoneNumber} onChange={handleChange} />
</div>
<div className="form-group">
<input name="email" className="form-control" placeholder='Email' value={data.email} onChange={handleChange} />
</div>
<div className="form-group">
<select name="dropDown" value={data.dropDown} onChange={handleChange} className="form-control" >
<option value=""></option>
<option value="Reactjs">ReactJS</option>
<option value="JS">JavaScript</option>
<option value="csCSSs">CSS</option>
<option value="HTML">HTML</option>
</select>
</div>
<div class="form-row">
<div className="form-group col-md-6">
<label className="font-weight-bold">Gender : </label>
<span className="font-weight-bold" > Male <input type="radio" name="gender" value={data.gender} onChange={handleChange}/></span>
<span className="font-weight-bold" > Female <input type="radio" name="gender" value={data.gender} onChange={handleChange} /></span>
</div>
<div class="form-check col-md-6">
<label class="form-check-label" for="gridCheck">Course</label><br />
<input type="checkbox" value="HTML" name="checking" value={data.checking} onChange={handleChange} /> HTML <br />
<input type="checkbox" value="JavaScript" name="checking" value={data.checking} onChange={handleChange} /> JavaScript <br />
<input type="checkbox" value="ReactJS" name="checking" value={data.checking} onChange={handleChange} /> ReactJS <br />
<input type="checkbox" value="CSS" name="checking" value={data.checking} onChange={handleChange} /> CSS <br />
</div>
<div className="form-row">
<button className="btn btn-cyan" type="button" onClick={handleSubmit}>Submit</button>
<button className="btn btn-cyan" type="button" onClick={handleEdit}>UpdateData</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div className="col-md-12">
<div className="card mt-5">
<div className="card-header blue-gradient text-white">
<h4>FormDetails</h4>
<div>
<div className="row mt-3">
<div className="col">
<div className="table table-hover table-striped text-center table-primary">
<thead className="bg-dark text-white font-weight-bold">
<tr>
<th>UserName</th>
<th>DropDownValue</th>
<th>Gender</th>
<th>CheckboxValue</th>
<th>EDIT</th>
<th>DELETE</th>
</tr>
</thead>
<tbody>
{
update.map(emp => {
return(
<tr>
<td>{emp.UserName} </td>
<td>{emp.gender}</td>
<td>{emp.checking}</td>
<td><button className="btn btn-cyan font-weight-bold" onClick={()=>{editUser(emp)}}>Edit</button></td>
<td><button className="btn btn-green font-weight-bold" onClick={()=>{deleteUser(emp)}}>Delete</button></td>
</tr>
)
})
}
</tbody>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</React.Fragment >
)
}
Change state to
const [data, setdata] = useState({
UserName: "",
dropDown: "",
gender: null,
checking: []
});
Update the handler to access the radio and checkbox id attributes
const handleChange = (e) => {
if (e.target.name !== "gender" && e.target.name !== "checking") {
setdata({ ...data, [e.target.name]: e.target.value });
} else if (e.target.name === "gender") {
let allgenders = document.getElementsByName("gender");
allgenders.forEach((allradio) => {
if (allradio.checked) {
setdata({ ...data, [e.target.name]: e.target.id }); // <-- grab input id
}
});
} else if (e.target.name === "checking") {
let getallCheckboxes = [];
let allCheckboxes = document.getElementsByName("checking");
allCheckboxes.forEach((allchecks) => {
if (allchecks.checked) {
getallCheckboxes.push(allchecks.id); // <-- grab checkbox id
}
});
setdata({ ...data, [e.target.name]: getallCheckboxes });
}
};
Update/add handleClear to reset the state
handleClear = () => {
setdata({
UserName: "",
dropDown: "",
gender: null,
checking: []
});
};
Add id properties and change the value prop to checked and pass a boolean value
<label className="font-weight-bold">Gender : </label>
<span className="font-weight-bold">
<label>
Male
<input
id="male"
type="radio"
name="gender"
checked={data.gender === "male"}
onChange={handleChange}
/>
</label>
</span>
<span className="font-weight-bold">
<label>
Female
<input
id="female"
type="radio"
name="gender"
checked={data.gender === "female"}
onChange={handleChange}
/>
</label>
</span>
...
<label class="form-check-label" for="gridCheck">
Course
</label>
<br />
<label>
<input
id="HTML"
type="checkbox"
name="checking"
checked={data.checking.includes("HTML")}
onChange={handleChange}
/>
HTML
</label>
<br />
<label>
<input
id="JavaScript"
type="checkbox"
name="checking"
checked={data.checking.includes("JavaScript")}
onChange={handleChange}
/>
JavaScript
</label>
<br />
<label>
<input
id="ReactJS"
type="checkbox"
name="checking"
checked={data.checking.includes("ReactJS")}
onChange={handleChange}
/>
ReactJS
</label>
<br />
<label>
<input
id="CSS"
type="checkbox"
name="checking"
checked={data.checking.includes("CSS")}
onChange={handleChange}
/>
CSS
</label>

VueJs: How to create a select where options come from a query to other model

I'm new on VueJs and I don't know why I have the following problem:
I'm creating a view called Owners.vue where I show pub owners. In UpdateProfile.vue I show the owner data and here is where I have my problem: I'd like to build a select where the options are the possible pubs stored in my table "pubs":
My vue component is as follows:
UpdateProfile.vue
<template>
<confirm title="Edit User" ok="Save user" :show="show"
v-on:save="save"
v-on:close="close">
<div class="field">
<label class="label">Name</label>
<div class="control">
<input class="input" type="text" placeholder="User name" v-model="data.name">
</div>
</div>
<div class="field">
<label class="label">Lastname</label>
<div class="control">
<input class="input" type="text" placeholder="last name" v-model="data.lastname">
</div>
</div>
<div class="field">
<label class="label">Email</label>
<div class="control">
<input class="input" type="email" placeholder="email" v-model="data.email">
</div>
</div>
<!--Owner Pubs-->
<div class="field">
<label class="label">Pubs</label>
<div v-for="pub in data.userPubsOwned" class="control">
<input class="input" type="text" placeholder="Pub tapps" v-model="pub.name">
<div class="button is-danger" #click="deletePubFromOwner(pub.id)">
<span class="icon"><i class="far fa-trash-alt"></i></span>
<span>Delete</span>
</div>
</div>
<br>
</div>
<!--Owner Pubs-->
<!--Add Pubs to Owner-->
<div class="field">
<label class="label">Add new Pub</label>
<div class="select">
<select v-model="pubs">
<option v-for = "pub in pubs" :value="pub.id" >{{pub.name}}</option>
</select>
</div>
<br>
<br>
<div class="button is-info" #click="addPubToOwner()">
<span class="icon"><i class="fas fa-save fa-lg"></i></span>
<span>Add Tapp</span>
</div>
</div>
<!--Add Pubs to Owner-->
</confirm>
import User from "../../models/user";
export default {
props: {
show: Boolean,
data: Object,
},
data() {
return {
selected: null,
data: new User(),
pubs: [],
pub: new Pub(),
}
},
computed: {
},
methods: {
save() {
this.$emit('save', this.data);
},
close() {
this.$emit('close');
},
hasRootPermissionsAndIsNotRoot() {
return this.CONSTANTS.hasRootPermissions() && this.data.permissions !== this.CONSTANTS.ROOT_USER.permissions;
},
addPubToOwner(){
this.api.post('/owners/' + this.data.id + '/' + this.selected).then(response => {
this.data = response.data;
});
},
deletePubFromOwner(ownerpub) {
this.api.delete('/owners/' + this.data.id + '/' + ownerpub).then(response => {
this.data = response.data;
});
},
}
}
I just need to show all the pubs stored in my table pub...do I have to create a function? And how it would be?
Thanks a lot for your help!!
Yes, create a method in the mounted() section. I use a similar process to show all of the flavors/prices of a product in a shopping cart. Here is my code that you can use and hopefully extrapolate your answer from:
Mounted function to load upon vue mount
mounted: function() {
this.getPrice();
},
getPrice() function:
getPrice: function(){
axios.post('/getproductinfo', this.$data.model)
.then((response) => {
console.log(response);
this.display_name = response.data.display_name;
this.price = '$' + response.data.price;
})
.catch(error => {
this.errors.record(error.response.data.errors);
});
},
And finally the code in your view blade file
<select class="centerSelect" v-show="!loading && ordering" ref="quantitySelect" v-model="model.id" name="code_id" #change="getPrice">
#foreach ($code as $item)
<option value="{{$item->id}}">{{$item->display_name}}</option>
#endforeach
</select>

vee-validate: Required only if a condition is met

I'm using Vuejs2 and vee-validate for form validation. It's a great package, however I'm struggling to implement a conditional required field.
When a particular radio option is selected, I want two select fields to be required. And when that radio is not selected, I want the two select fields to be optional.
I've tried using the attach and detach methods. I can successfully detach the validation. And I can see when I attach a field it appears in the fields object. But it's not picked up by the validator.
Here is my code:
<template>
<form class="ui form" role="form" method="POST" action="/activate" v-on:submit.prevent="onSubmit" :class="{ 'error': errors.any() }">
<div class="ui segment">
<h4 class="ui header">Basic Company Information</h4>
<div class="ui message">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="field" :class="{ 'error': errors.has('name') }">
<div class="ui labeled input">
<label class="ui label" for="name">
Company
</label>
<input id="name" type="text" name="name" v-validate="'required'" v-model="name">
</div>
</div>
<div class="ui error message" v-show="errors.has('name')">
<p>{{ errors.first('name') }}</p>
</div>
<div class="grouped fields" :class="{ 'error': errors.has('organisation_type_id') }">
<label for="organisation_type_id">Organisation type</label>
<div class="field">
<div class="ui radio checkbox">
<input class="hidden" type="radio" name="organisation_type_id" value="1" data-vv-as="organisation type" v-validate="'required'" v-model="organisation_type">
<label>Buyer</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input class="hidden" type="radio" name="organisation_type_id" value="2" checked>
<label>Seller</label>
</div>
</div>
</div>
<div class="ui error message" v-show="errors.has('organisation_type_id')">
<p>{{ errors.first('organisation_type_id') }}</p>
</div>
<div v-show="organisation_type == '2'">
<div class="field" :class="{ 'error': errors.has('countries[]') }">
<label for="countries">Countries</label>
<select class="ui fluid search dropdown" id="countries" name="countries[]" multiple data-vv-as="countries" v-validate="'required'">
<option v-for="country in countries" :value="country.value">{{ country.text }}</option>
</select>
</div>
<div class="ui error message" v-show="errors.has('countries[]')">
<p>{{ errors.first('countries[]') }}</p>
</div>
<div class="ui message field-description">
<p>Select all the countries you export to.</p>
</div>
<div class="field" :class="{ 'error': errors.has('ciphers[]') }">
<label for="ciphers">Ciphers</label>
<select class="ui fluid search dropdown" id="ciphers" name="ciphers[]" multiple data-vv-as="ciphers" v-validate="'required'">
<option v-for="cipher in ciphers" :value="cipher.value">{{ cipher.text }}</option>
</select>
</div>
<div class="ui error message" v-show="errors.has('ciphers[]')">
<p>{{ errors.first('ciphers[]') }}</p>
</div>
<div class="ui message field-description">
<p>Select all the ciphers you support.</p>
</div>
</div> <!-- End organisation_type_id -->
<button class="ui fluid green button" type="submit">Continue</button>
</div> <!-- .ui.segment -->
</form>
</template>
<script>
export default {
props: ['countriesJson', 'ciphersJson'],
data() {
return {
name: null,
organisation_type: '2',
countries: [],
ciphers: [],
}
},
watch: {
organisation_type: function(value) {
var vm = this
if (value == '2') {
vm.$validator.attach('countries[]', 'required');
const select = document.getElementById('countries');
select.addEventListener('change', function() {
vm.$validator.validate('required', this.value);
});
vm.$validator.attach('ciphers[]', 'required');
const select = document.getElementById('ciphers');
select.addEventListener('change', function() {
vm.$validator.validate('required', this.value);
});
} else {
vm.$validator.detach('countries[]')
vm.$validator.detach('ciphers[]')
}
},
},
mounted() {
this.countries = JSON.parse(this.countriesJson)
this.ciphers = JSON.parse(this.ciphersJson)
},
methods: {
onSubmit: function(e) {
this.$validator.validateAll().then(success => {
e.target.submit()
}).catch(() => {
return
})
}
}
}
</script>
May be you mean something like this?
<input id="name"
type="text"
name="name"
v-validate="{ required: this.isRequired }"
v-model="name">
Where "isRequired" is computed field, which depend from condition
<input id="name"
type="text"
name="name"
v-validate=" isRequired ? 'required' : '' "
v-model="name">
In my case it worked by giving above condition.. Also it is helpful in case of multiple validation rules... e.g. 'required|integer|between:18,99'..
Adding {} will break the expression
you can simply use
v-validate="`required_if:${condition}`"

apply validation on ko.computed using knockout.js

i just created a scenario , the thing i wanted, can you check out this fiddle jsfiddle.net/5PRMe/393. i want to validate this, some piece of code i used here, but comment it.kindly check this.
Bascially i am follow this link https://github.com/knockout/knockout/wiki/View-Add-Edit-Delete-Design-Pattern (full code of this link is at the bottom of the page), to create my code, but i want knockout validation, with proper messages, but i did't understand how to do validation if we have with binding with computedObservable, can anyone help me to sort out the problem?
var baseModel = function () {
this.id = ko.observable(0);
this.name = ko.observable("").extend({ required: true });
this.title = ko.observable(undefined).extend({
required: { message: "You must select title" },
});
this.email = ko.observable("").extend({ required: true });
this.phone = ko.observable("").extend({ required: true });
this.mobile = ko.observable('');
this.streetAddress = ko.observable('');
this.city = ko.observable('');
this.state = ko.observable('');
this.zipCode = ko.observable('');
this.fax = ko.observable('');
this.description = ko.observable('');
this.editSelectedItemErrors = ko.validation.group([this.name,this.accountId,this.title,this.gender,this.email,this.phone,this.country]);
}
var viewModel = function () {
var self = this;
self.editSelectedItem = ko.observableArray('');
var mappedItems = ko.mapping.fromJS(new baseModel());
self.editSelectedItem(mappedItems);
self.saveContact = function (form) {
if (baseModel.editSelectedItemErrors().length === 0) {
// save data
}
else{
baseModel.editSelectedItemErrors.showAllMessages();
}
}
self.SelectedRecord = ko.computed(function () {
var selected = self.editSelectedItem();
selected.selectedOption;
//selected.selectLanguage;
selected.streetAddress;
var result = (selected);
console.log(result.length);
if (result != null) {
result = ko.toJS(result);
var observable = ko.mapping.toJS(result);
//console.log(observable);
return observable;
} else {
return new baseModel();
};
}, self);
}
var contactModel = new viewModel();
$(function () {
ko.validation.init({
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true,
messageTemplate: null,
decorateElement: true,
grouping: { deep: true, observable: true, live: true }
}, true);
ko.applyBindings(contactModel);
});
<div id="divContact" class="flt w100 space form" data-bind="with : SelectedRecord()">#*<!-- ko with : SelectedRecord -->*#
<div class="row">
<label>
First Name</label>
<span>
<input id="Name" name="Name" type="text" data-bind="value : name,uniqueName: true" class="field required" placeholder="Name" />
</span>
</div>
<div class="row">
Email</label>
<span>
<input id="Email" type="text" data-bind="value : email,uniqueName: true" class="required field" placeholder="Email" /></span>
</div>
<div class="row">
<label>
Phone</label>
<span>
<input id="Phone" type="text" data-bind="value : phone,uniqueName: true" class="field" placeholder="Phone" /></span>
<label>
Mobile</label>
<span>
<input id="Mobile" type="text" data-bind="value : mobile,uniqueName: true" class="field" placeholder="Mobile" /></span>
</div>
<div class="row">
<label>
Street Adress</label>
<span>
<input id="Street" type="text" data-bind="value : streetAddress,uniqueName: true" class="field" placeholder="Street" /></span>
<label>
City</label>
<span>
<input id="City" type="text" data-bind="value : city,uniqueName: true" class="field" placeholder="City" /></span>
</div>
<div class="row">
<label>
State</label>
<span>
<input id="State" type="text" data-bind="value : state,uniqueName: true" class="field" placeholder="State" /></span>
<label>
Zip Code</label>
<span>
<input id="Zip" type="text" data-bind="value : zipCode,uniqueName: true" class="field" placeholder="Zip Code" /></span>
</div>
<div class="row">
Fax</label>
<span>
<input id="Fax" type="text" data-bind="value : fax,uniqueName: true" class="field" placeholder="Fax" /></span>
</div>
<div class="row">
<label>
Description</label>
<span>
<textarea class="input-field " data-bind="value: description,uniqueName: true"></textarea></span>
</div>
<div class="row">
<input data-bind="click: function() { contactModel.saveContact($data,0);}" type="submit" value="Save" class="btn"/>
<input type="button" class="btn" value="Cancel" data-bind="click: function() { contactModel.cancelCreate($data,0);}">
</div>

Resources