VueJS Vuelidate and deep nested Array/objects - vuelidate

hope someone can help me I'm working on this since 2 days. I have the following Data in my component:
var types = [
{
**required**: true,
agreements: [
{ selected: true, desc: 'red' },
{ selected: false, desc: 'green'}
]
},
{
required: false,
agreements: [
{ selected: false, desc: 'red' },
{ selected: false, desc: 'green'}
]
},
];
I want to validate all the checkboxes (they have v-model on this selected attributes here!), to be checked, if the parent value required (see my data required!) is true. My Validations looks like this but I miss a last little bit of help to get this required value into my validator selected requiredIf function.
validations: {
types: {
$each: {
agreements: {
$each: {
selected: {
requiredIf: (value) => value === value.parent.required
}
}
}
}
}
}
Hope you understand me right. My Template looks like this:
<div class="mb-3" v-for="type in agreementTypes" :key="type.id">
<h3 class="text-primary">{{ type.displayName }}</h3>
<ul class="list-unstyled">
<li v-for="agreement in type.agreements" :key="agreement.id">
<p>{{ agreement.description }}</p>
<div class="mb-3 form-check form-switch">
<input
class="form-check-input"
type="checkbox"
role="switch"
:checked="agreement.active"
:id="agreement.id"
:required="agreement.required"
v-model="agreement.selected"
/>
<label class="form-check-label" for="agreements">{{ agreement.label }}<span v-if="agreement.required">**</span></label>
</div>
</li>
</ul>
</div>
Any Help will be apreshiated!
bye,
Marcel

Related

Refresh cdkDropListData after dialog closes and element is removed from array

I have the angular drag and drop list set up like this:
<div class="row col-12" *ngFor="let level of team_heirarchy; let i=index;">
<div class="col-3">
<p>{{level.name}}</p>
</div>
<div class="col-9">
<div cdkDropList id="{{level.key}}" [cdkDropListData]="level.value"
[cdkDropListConnectedTo]="heirarchy_levels" class="example-list" [cdkDropListDisabled]="level.disabled" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let item of level.value; let j=index;" cdkDrag>{{item}}
<button *ngIf="!level.disabled" mat-icon-button color="warn" (click)="deleteHeirarchyItem(i, j)"><mat-icon>cancel</mat-icon>
</button></div>
</div>
</div>
</div>
And the TS File:
team_heirarchy = [
{
"name": "Level 1(ROOT)",
"key": "level1",
"value": ["Administration"],
"disabled": true
},
{
"name": "Level 2",
"key": "level2",
"value": ["Lead HR", "Lead Manager"],
"disabled": false
}
]
deleteHeirarchyItem(i: number, j: number){
this.dialog.open(ConfirmDialogComponent, {
height: "auto",
width: "500px",
data:{
message: "Are you sure you want to delete this position.",
}
}).afterClosed().subscribe(result => {
if(result){
this.team_heirarchy[i].value.splice(j, 1)
}
})
}
The problem is, if I place this line
this.team_heirarchy[i].value.splice(j, 1)
outside the mat-dialog, the ui is updated instantly and the element is removed from the drop list.
But if I continue this way and wait till the user confirms and dialog closes with a positive result, the element is removed from the array but on the ui the element is still there until I try to drag an element.
Any help?

Use modal on a v-for element?

I am getting a GET request from my api to disply all users , and i want to modify maybe the name of the email of each users with a modal. The problem is , imagine i have 3 users displayed , 3 modals will be displayed even if i press on only one modal button.
How can i do to fix it ?
there is my code :
<template>
<div class="container">
<div>
<h1>
<b> Users </b>
<input
type="text"
v-model="search"
class="search"
placeholder="Search User"
/>
</h1>
</div>
<div class="overlay-container">
<form>
<div class="form-group">
<div
v-for="user in filterUser"
v-bind:key="user"
class="form-control"
>
<p>
<b>{{ user.fname }} </b> {{ user.lname }}
</p>
<b-button v-b-modal.modal-1>Modifiy</b-button>
<b-modal id="modal-1" title="User Modification">
<p class="my-4">Please edit informations</p>
</b-modal>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import axios from "axios";
import VueAxios from "vue-axios";
export default {
name: "users",
data() {
return {
search: "",
users: [],
};
},
computed: {
filterUser() {
return this.users.filter((user) => {
return user.fname.match(this.search);
});
},
},
created() {
axios
.get(`http://localhost:4000/api/users`)
.then((Response) => (this.users = Response.data.data));
},
};
</script>
I want to each users open his own modal, not all modals when i press only one modal button.
I hope its clear !
First, pull out the modal inside of v-for, then create a method to get your user index, and add it to the Modify button. this is how you can get the data a user without sending another HTTP Request. and then you can show this.user data in your modal as you want.
<div
v-for="(user, index) in filterUser"
v-bind:key="user"
class="form-control"
>
<p>
<b>{{ user.fname }} </b> {{ user.lname }}
</p>
<b-button
v-b-modal.modal-1
#click="getUserInfo(index)"
>
Modifiy
</b-button>
</div>
data() {
return {
search: "",
users: [],
user: {}
};
},
methods: {
getUserInfo(index) {
this.user = this.users[index]
}
}

How to print json array in angular

Here Stackblitz https://stackblitz.com/edit/angular-parse-object
Response format from REST API is
[{"id":123,"name":Test,"value":{"pass": true, "verified": true}}, {"id":435,"name":Test12,"value":{"pass": false, "verified": true}},]
<div *ngFor="let record of student.value">
<ul *ngFor="let key of objectKeys(record)">
<li>{{key}} :: {{record[key]}}</li>
</ul>
</div>
Getting error ** Cannot read property 'value' of undefined **
<div *ngFor="let rec of student">
<h2>{{rec.id}}</h2>
<div *ngFor="let result of rec.value">
<h4> {{value.pass}} </h4>
</div>
</div>
getting Error object of type 'string'. NgFor only supports binding to Iterables such as Arrays.
How to fix it?
I expect the output as
ID : 123 Name : Test Pass : true [yes] verified : true
I just write a basic ngFor code using your Student Array. Try this I hope it'll help you out. Thanks
HTML
<div class="studentList" *ngFor="let student of students">
<ul>
<li>ID : {{student.id}}</li>
<li>Name : {{student.name}}</li>
<li>Pass : {{student.value.pass}} [{{student.value.pass ? 'Yes' : 'No'}}]</li>
<li>Verified : {{student.value.verified}}</li>
</ul>
</div>
TS
students = [
{
"id":123,
"name":"Test",
"value":{"pass": true, "verified": true}
}, {
"id":435,
"name":"Test12",
"value":{"pass": false, "verified": true}
}
]
CSS
.studentList ul {
list-style: none;
margin: 0 0 10px;
padding: 0;
}
.studentList ul li {
display: inline-block;
margin-right: 10px;
}
You only need 1 ngFor, your value is not array.
<div *ngFor="let rec of student">
<h2>Id: {{rec.id}} Name: {{rec.name}} Pass: {{rec.value.pass}} Verified: {{rec.value.verified}}</h2>
</div>
Reference (you can format it)
https://stackblitz.com/edit/angular-iterator
Updated:
Change your map function with JSON.parse like this
this.student = ["{pass: true, verified: true}", "{pass: false, verified: true}"];
this.student = this.student.map(c=>JSON.parse(c.replace(/([a-zA-Z0-9-]+): ([a-zA-Z0-9-]+)/g, "\"$1\":\"$2\"")));
https://stackblitz.com/edit/angular-parse-object

Angular 6 :material checkbox checked all checkbox in loop

In loop
<li *ngFor="let item of verticalList;let i=index;">
<mat-checkbox [(ngModel)]="checked" name="i">Checked</mat-checkbox>
</li>
I want to give each checkbox a different checked value. How to do it?
I don't know what is verticalList type, but id you use a list of object you could do something like this:
verticalList = [
{
name: 'foo',
checked: false
},
{
name: 'foo1',
checked: false
},
{
name: 'foo2',
checked: false
}
]
<li *ngFor="let item of verticalList;let i=index;">
<mat-checkbox [(ngModel)]="item.checked" name="i">Checked {{ item.name }}</mat-checkbox>
</li>

AngularJS - Building a dynamic form based on a json

I am using the AngularDynamicform to generate a dynamic form in page and the fields are displaying fine in a horizontal manner. But I want to display the input fields with in different sections in the page.
In my page
<div class="box-content">
<h4 class="page-header">New Contact</h4>
<dynamic-table-form fields="fields" data="data" class="form-horizontal">
<input dynamic-field-type="string" ng-model="value" type="text" maxlength="{{config.maxLength}}" size="{{config.maxLength}}">
<input dynamic-field-type="date" ng-model="value" type="date">
<ul dynamic-field-type="array">
<li dynamic-field-child>
<ng-transclude></ng-transclude>
<button ng-click="removeChild(childKey)">Remove</button>
</li>
<button ng-click="addChild()">Add Another</button>
</ul>
<select dynamic-field-type="select" ng-model="value" ng-options="option.value as option.caption for option in config.options"></select>
<input dynamic-field-type="integer" ng-model="value" type="number" size="{{config.maxLength}}" maxlength="{{config.maxLength}}" min="{{config.minValue}}" max="{{config.maxValue}}">
<button ng-click="create()">Save</button>
</dynamic-table-form>
<button ng-click="create()">save</button>
And in my controller
$scope.fields = [
{
caption: 'Name',
model: 'name',
type: 'string',
maxLength: 25
},
{
caption: 'Date of Birth',
model: 'dateOfBirth',
type: 'date'
},
{
caption: 'Employee name',
model: 'employee.name',
type: 'string',
maxLength: 25
},
{
caption: 'Employee City',
model: 'employee.city',
type: 'string',
maxLength: 25
}
];
for example, I want to display the last two fields(Employee name & Employee City)in other section called Employee details. How can I do it?
Thanks in advance.