Nested Angular Material Menu - json

I am new to angular and I'm creating a dynamic/nested menu based from my data below. I include the codes that I started with. Any help is appreciated.
Below is my json data:
dataList = [
{List: 'List 1', Client: 'Client A', Program: 'Client A Program 1'},
{List: 'List 2', Client: 'Client A', Program: 'Client A Program 1'},
{List: 'List 3', Client: 'Client A', Program: 'Client A Program 2'},
{List: 'List 4', Client: 'Client A', Program: 'Client A Program 2'},
{List: 'List 5', Client: 'Client B', Program: 'Client B Program 1'},
{List: 'List 6', Client: 'Client B', Program: 'Client B Program 1'},
];
Here's what I've started so far:
<ng-container *ngFor="let item of dataList>
<div class="clientList">
<button mat-menu-item [routerLink]="['/home']" color="primary" (click)="menuClick()"><i class="fa object_group"
aria-hidden="true"></i> {{item.Client}}</button>
</div>
</ng-container>
I would like to have an angular material menu that looks like this:
https://imgur.com/a/WGpYRlK

Related

I have created a dropdown in Angular where there are values from 1 to 20 in it. If I select number <10 , it will show a msg and if >10 then diff. msg

html: -
<div class="form-group">
<label for="experience" class="form-label">I am experience</label>
<select class="custom-select" formControlName="experience" name="experience" onchange="change(this);">
<option *ngFor="let experience of experiences">{{experience}}</option>
</select>
</div>
ts:-
experiencesLessThanTenYears = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
experiencesMoreThanTenYears = ['10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20'];
experiences = [ ...this.experiencesLessThanTenYears, ...this.experiencesMoreThanTenYears];
ngOnInit(): void {
this.registrationForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(3)]],
lastName: ['', [Validators.required, Validators.minLength(3)]],
startDate: [ '',[Validators.required]],
endDate: ['',[Validators.required]],
experience: ['',[Validators.required,]],
})
I want to show message on selecting values less than 10 and greater than 10 on my view. Please help me on how to do that.
I tried using the change event of my html select but it was not working. I was hoping to make a custom validator but I don't know was just an idea. Please someone help me out
{{+registrationForm.get('experience').value>10?
'You have a great experience':
'You have a poor experience'}}.
But this makes that if you don't selected anything show that you have a poor experience.
We can use a ng-container *ngIf in the way
<ng-container *ngIf="registrationForm.get('experience').value">
{{+registrationForm.get('experience').value>10?
'You have a great experience':
'You have a poor experience'}}.
</ng-container>
Well, as we use a *ngIf, we can create a temporaly variable
<ng-container *ngIf="registrationForm.get('experience').value as experience">
{{+experience>10?
'You have a great experience':
'You have a poor experience'}}.
</ng-container>
The another way is use a ternary operator inside a ternary operator. Really is an ugly (but equal effective solution)
{{registrationForm.get('experience').value?
+registrationForm.get('experience').value>10?
'You have a great experience':
'You have a poor experience':
''}}

Angular - Display different dropdown values based on condition

I am displaying data value as dropdown if below condition in html is met.
I would like to add another condition where on change of another dropdown which contains companies name I show data1value. For example if 1st dropdown (companies name) is changed toAmazonthen I only displaydata1` as its value
<dd>
<mat-select *ngIf="editMode"; else showData" [disabled]="!editMode"
[(ngModel)]="term.data" (ngModelChange)="recordModified.emit()">
<mat-option *ngFor="let tag of data" [value]="tag.value">{{tag.text}}</mat-option>
</mat-select>
<ng-template #showData>{{term.data}}</ng-template>
</dd>
data = [
{value: '1', text: 'Amazon'},
{value: '2', text: 'Google'},
{value: '3', text: 'Apple'},
data1 = [
{value: '1', text: 'Amazon'},
From what I can gather you want to access the data that has been selected by the dropdown, correct? You're close... check out this demo for a working version https://stackblitz.com/edit/angular-ivy-xmxqpg?file=src%2Fapp%2Fapp.component.ts

Dash Plotly hotkeys

I have a DASH app with a number of checkboxes. I wish to setup a hotkey that would make a keyboard shortcut to check some boxes if the user hits a keyboard "command D" for example. I searched everywhere I could, and the only reference I found was to use an "accessKey" (recommended by the Dash creator chriddyp). I haven't found any documentation or examples of how to utilize this. Could anyone give me some pointers?
dcc.Checklist(
options=[
{'label': 'Asleep', 'value': 'sleep'},
{'label': 'Direct Vision', 'value': 'direct'},
{'label': 'Blind', 'value': 'blind'},
{'label': 'Video Laryngoscope', 'value': 'video'},
{'label': 'Flex FiberOptic', 'value': 'fiber'},
{'label': 'Laryngoscope', 'value': 'Laryngo'},
{'label': 'ET tube', 'value': 'ET'},
{'label': 'Oral', 'value': 'Oral'},
{'label': 'Nasal', 'value': 'nasal'},
{'label': 'cuffed', 'value': 'cuffed'},
{'label': 'RAE', 'value': 'rae'},
{'label': 'LMA', 'value': 'lma'},
],
value=['sleep', 'direct', 'ET', 'nasal', 'cuffed', 'rae', 'Laryngo'],
inputStyle={'margin-right':'20px','margin-left':'10px'},
Currently, I have set defaults to the checklist, but ideally I would like to have everything unchecked on loading and connected with hotkeys. Thanks

How can I get display varying number of data elements of a specific attribute in Vue js?

I have a product listing which I am looping on using v-for. These products have headlines and top features. A headline-top feature can look something like this on my webpage:
PRODUCT 1
**First headline**
This is the description of the feature of product 1 under the first headline
**Second headline**
This is the description of the feature of product 1 under the second headline
**Third headline**
This is the description of the feature of product 1 under the third headline
PRODUCT 2
**First headline**
This is the description of the feature of the product 2 under the first headline.
**Second headline**
This is the description of the feature of the product 2 under the second headline.
THE PROBLEM: The number of headline-top feature for each product could vary, like PRODUCT 1 has 3 headline-top feature and PRODUCT 2 has 2 headline-top feature. I am not quite sure how I could specify these varying number of headline-top feature in my Vue app. I have something like this:
Product_listing.vue
<template>
<div class="content">
<div class="nested" v-for="product in products">
<div class="one">{{product.Name}}</div>
<div class="two"> {{product.headline}}</div> ---->
<div class="three"> {{product.top_feature}}</div> ----> I think I need a loop here? Not sure how?
</div>
</div>
</template>
<script>
export default {
data () {
return {
products:[
{id: 1, Name: 'Product 1',
Headline_1:'Headline 1', top_feature_1: 'This is the description of the feature of product 1 under the first headline',
Headline_2:'Headline 2', top_feature_2: 'This is the description of the feature of product 1 under the second headline',
Headline_3:'Headline 3', top_feature_3: 'This is the description of the feature of product 1 under the third headline'
},
{id: 2, Name: 'Product 2',
Headline_1:'Headline 1', top_feature_1: 'This is the description of the feature of product 2 under the first headline',
Headline_2:'Headline 2', top_feature_2: 'This is the description of the feature of product 2 under the second headline',
}
and so on...
]
}
},
created: function() {
axios.get('ajaxfile.php')
.then(function (response) {
app.products = response.data;
})
.catch(function (error) {
console.log(error);
});
}
}
})
</script>
I would really appreciate some help here. Thanks!
The solution above via reshaping data can solve this problem,and i have easier way to solve it,getting a total keys prior then loop the total keys in the template,and display the fields which have varying number by dynamic.
new Vue({
el: "#app",
data: {
products: [
{
id: 1,
Name: 'Product 1',
Headline_1: 'Headline 1',
top_feature_1:
'This is the description of the feature of product 1 under the first headline',
Headline_2: 'Headline 2',
top_feature_2:
'This is the description of the feature of product 1 under the second headline',
Headline_3: 'Headline 3',
top_feature_3:
'This is the description of the feature of product 1 under the third headline',
},
{
id: 2,
Name: 'Product 2',
Headline_1: 'Headline 1',
top_feature_1:
'This is the description of the feature of product 2 under the first headline',
Headline_2: 'Headline 2',
top_feature_2:
'This is the description of the feature of product 2 under the second headline',
},
],
},
computed: {
},
created(){
this.products.map(product => {
const totalKeys = Object.keys(product).length;
product.totalKeys = totalKeys
});
console.log('this.products', this.products)
},
methods: {
}
})
<div id="app">
<div class="content">
<div class="nested" v-for="product in products">
<div class="one">{{product.Name}}</div>
<div class="two" v-for="num in product.totalKeys">
<p v-if="product['Headline_'+num]">{{product['Headline_'+num]}}</p>
<div class="three"> {{product['top_feature_'+num]}}</div>
</div>
</div>
</div>
</div>
<b>https://jsfiddle.net/happy9527/a0rjgp6y/</b>
Assuming the data returned from your axios call has the same shape as the products example, the easiest solution is to reshape the data prior to using it in the template. You can do this using a computed property. Here's a complete working example:
<template>
<div class="content">
<div v-for="product in productsWithHeadlines" :key="product.id">
<div>{{ product.name }}</div>
<ul>
<li v-for="(headline, index) in product.headlines" :key="index">
<div>{{ headline.text }}</div>
<div>{{ headline.feature }}</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
products: [
{
id: 1,
Name: 'Product 1',
Headline_1: 'Headline 1',
top_feature_1:
'This is the description of the feature of product 1 under the first headline',
Headline_2: 'Headline 2',
top_feature_2:
'This is the description of the feature of product 1 under the second headline',
Headline_3: 'Headline 3',
top_feature_3:
'This is the description of the feature of product 1 under the third headline',
},
{
id: 2,
Name: 'Product 2',
Headline_1: 'Headline 1',
top_feature_1:
'This is the description of the feature of product 2 under the first headline',
Headline_2: 'Headline 2',
top_feature_2:
'This is the description of the feature of product 2 under the second headline',
},
],
};
},
computed: {
// Returns `products` with the following structure:
// {
// id: Number,
// name: String,
// headlines: [
// text: String,
// feature: String,
// ],
// }
productsWithHeadlines() {
return this.products.map(product => {
const totalKeys = Object.keys(product).length;
const headlines = [];
for (let index = 1; index < totalKeys; index += 1) {
const text = product[`Headline_${index}`];
const feature = product[`top_feature_${index}`];
if (text && feature) headlines.push({ text, feature });
}
return {
id: product.id,
name: product.Name,
headlines,
};
});
},
},
};
</script>

How to create component dynamically from a json in Vuejs2

I'm trying to populate a table dynamically with cells component.
input structure looks like:
tableData: {
headers: ['1', '3', '2', '4'],
rows: [
[{h: '1', t: 'Sample', v: {name: 'logan'}},
{h: '2', t: 'Sample', v: {name: 'dgd'}},
{h: '3', t: 'Sample', v: {name: 'logasdn'}},
{h: '4', t: 'Sample', v: {name: 'loezgan'}}]
],
showHeaders: ['1', '2', '3']
}
the html sections looks like that:
<!--table data-->
<tr v-for='(row,rowIndex) in tableData.rows'>
<td><input type='checkbox'></td>
<td v-for="(element,colIndex) in row">
<component is='Sample' v-bind='element.v' ></component>
</td >
</tr>
When I pass 'Sample' (the component name) as parameter it works, but its not when I replace 'Sample' by 'element.t' or {{element.t}} which I don't understand.
Does anyone knows why its not working and how to do that?
You need to bind to is via v-bind:is or the shorthand :is:
<component :is='element.t' v-bind='element.v'></component>