How to append value from more than 1 dropdowns into a single formcontrol in a reactive form? - angular8

I have a loop which contains dropdown in a form. I want the values entered in all the dropdowns to be appended in a single formcontrol in reactive form. But it is putting only last dropdown value .
How to achieve this?
<div class="row" *ngFor="let prod of products;" >
<div class="col-4 cols">
<div class="">{{prod.name}}</div>
</div>
<div class="col-3">
<div class="">
<ng-select class="required" [items]="prod.companies" bindLabel="name" placeholder="Select company" [searchable]="false" formControlName="companies">
<ng-option [value]=""></ng-option>
</ng-select>
</div>
</div>
</div>
This is a part of code inside tag. In this form, for multiple products from a list which will come from backend, a dropdown will be their containing companies with respect to product.The companies selected for multiple products should go into a single formcontrol . But only the value chosen last from any of the dropdown is getting assigned to the comapnies formcontrol instead of an array of companies selected from multiple products.
the form in component.ts is :
setform(): void {
this.form = this.fb.group({
id: [''],
name: [''],
companies: [null]
});
}

add [multiple]="true" in ng-select and get multiple select value.
For example see this link:- https://stackblitz.com/edit/ng-select

Related

Use unknown key in the v-model in vue js for loop

I have a dynamically made object of facets.
An example of the data could be:
facets: {
type: ['type1', 'type2', 'type3'],
color: ['color1', 'color2']
}
I also have an empty object for filters.
I then loop over the facets object and make checkbox groups for each facet. I want the v-model to be filters."name of the facet", so: filters.type and filters.color. I do not know the names forehand. I tried using the key in a loop but that does not work.
My loop looks like this:
<li v-for="(facet, facetKey, facetIndex) in facets" class="filter-item">
<strong>{{ facetKey }}</strong>
<div v-for="(value, valueIndex) in facet" class="form__fieldset" :key="valueIndex">
<div class="form__field-wrap">
<input type="checkbox" v-model="filters[facetKey]" :id="value.toLowerCase().trim()" :value="value">
<label :for="value.toLowerCase().trim()">{{ value }}</label>
</div>
</div>
</li>
If I hardcode v-model to filters.type, It works as intended. Has anyone achieved this type of dynamic v-models?
Populate filters with your facets properties
filters = ref({
...facets.value
})
Here is the playground link to a working example

Vue conditional list rendering

I am working on a Layered Navigation element where I have a v-for loop on filters in an array. Filters like color, size, gender etc...
Since the amount of options in some the filters can be quite overwhelming (color for example),I would like to add a button to show more options per filter.
I currently have the following function to show more options per filter
<div v-if="showMoreFilters === false">
<div
v-for="(attribute, index) in filter.attributes"
:key="attribute.index">
<div class="layered-navigation__item"
v-if="index < filter.facetsettings.nrofshownattributes"
>
<SfFilter
:label="attribute.title"
:count="attribute.nrofresults"
:selected="attribute.isselected"
#change="function(x)>
</SfFilter>
</div>
</div>
</div>
<div v-else>
<div
v-for="attribute in filter.attributes"
:key="attribute.index"
>
<div class="layered-navigation__item">
<SfFilter
:label="attribute.title"
:count="attribute.nrofresults"
:selected="attribute.isselected"
#change="function(x)">
</SfFilter>
</div>
</div>
</div>
</div>
<sfButton #click="showMoreFilters = !showMoreFilters">
Show more filters"
</sfButton>
The desired, initial, amount of filter-options per filter is given within each filter:
filter.facetsettings.nrofshownattributes
The problem, however, is that if I press the button (showMoreFilters), all filters show all of their options. Not just the array of option of the filter I clicked on. How could I resolve this?
The problem is that there are many filters but only one showMoreFilters flag. Consider adding a showMore property to every filter's facetsettings object...
<div v-if="!filter.facetsettings.showMore">
...
<sfButton #click="filter.facetsettings.showMore != filter.facetsettings.showMore">
Show more of just this filter"
</sfButton>

Input with datalist calling twice

I'm new to Vue and am trying to build a form with a datalists. The code I've written seems to work fine but I'm not sure why the dropdown list will appear twice. Once when nothing is typed into the input where it will show all the options available, and the second time when an option is chosen and the dropdown will show only the options that match the one typed. Is there a way to get rid of the second dropdown, where it will only show the dropdown once?
Template
<input list=list1 v-model="test">
<datalist id=list1>
<option v-for "item in items" :value="item" :key="item"></option>
</datalist>
Script
export defaults{
data(){
items: [1,2,3,4,5],
test: ''
}
}
Try using {{ item }} instead of binding :value to show and populate the value.
<div>
<input type="text" list="list1" v-model="test" #change="onChange()" />
<datalist id="list1">
<!-- use normal {{ item }} here without binding value-->
<option v-for="item in items" :key="item">{{ item }}</option>
</datalist>
</div>

Vue v-model not reactive with BS4 radio button group

I'm hoping I'm just missing something simple because I've been looking at this for too long, but I'm stumped.
I have a form with inputs bound to vuejs. I have a group of 2 radio buttons for selecting the "gender", and the binding is working perfectly. If I click on either of the radio buttons, I can see the data change in the vue component inspector.
But I'm trying to change the radio buttons to a Bootstrap 4 button group, and can't seem to get the v-model binding to work. No matter what I try, the gender_id in my vue data is not getting updated when I click either of the buttons in the button group.
The form input values are being fed in through vue component properties, but for simplicity, my data for the radio buttons/button group would look like this:
export default {
data() {
return {
genders: {
1: "Men's",
2: "Women's"
},
gender_id: {
type: Number,
default: null
}
}
}
}
Here is the code I have for the radio button version (which is working properly):
<div class="form-group">
<label>Gender:</label>
<div>
<div class="form-check form-check-inline" v-for="(gender, key) in genders" :key="key">
<input type="radio"
class="form-check-input"
name="gender_id"
:id="'gender_' + key"
:value="key"
v-model.number="gender_id">
<label class="form-check-label" :for="'gender_' + key">
{{ gender }}
</label>
</div>
</div>
</div>
Here is the button group version that is not properly binding to the gender_id data in vue.
<div class="form-group">
<label>Gender:</label>
<div>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-outline-secondary" v-for="(gender, key) in genders" :key="key">
<input type="radio"
class="btn-group-toggle"
name="gender_id"
:id="'gender_' + key"
:value="key"
autocomplete="off"
v-model.number="gender_id">
{{ gender }}
</label>
</div>
</div>
</div>
I've been using the following Boostrap 4 documentation to try to get this working.
https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons
In the documentation for button groups they don't even include the value property of the radio inputs, whereas they do include it in the documentation for form radio buttons.
https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios
Is this for simplicity or do button groups of radio buttons not even return the value of the checked button?
I see other threads stating that buttons groups are not meant to function as radio buttons, but if that's true for BS4, then why would Bootstrap have button groups with radio buttons as they do in their documentation referenced above? If you can't retrieve the checked state, then why not just use a <button> instead of <label><input type=radio></label>?
Any ideas as to what I'm doing wrong and/or not understanding correctly?
Thanks so much!
Thanks so much to #ebbishop for his helpful insights.
The issue was related to vue and bootstrap both trying to apply javascript to the buttons in the button group.
To get around this issue, it was as simple as removing data-toggle="buttons" from the button group. By removing the data-toggle attribute, the bootstrap js is not applied and vue can manage the button group.
Nothing is actually wrong your use of v-model here.
However: you must add the class "active" to the <label> that wraps each radio-button <input>.
See this fiddle for a working example.
Is that what you're after?

How to make event only true for one element in Vue?

I have vue event attached to elements that are looped.
I'm having challenge trying display CRUD action on an item, instead, all the looped items display their individual CRUD
How can I make it unique to an element? any vue event modifier for this?
Below is my code
<i class="material-icons">list</i>
<div v-if="showButtons">
<ul>
<li>Edit</li>
<li>Delete</li>
<li>Stop</li>
</ul>
</div>
The showIcons method below
showIcons: function () {
this.showButtons = true
}
since you are binding showButtons property to all your looped items, when you mouse over an item theshowButtonsis toggled true and all the items bound to showButtons are displayed.
So you need to use a unique identifier to decide whether the buttons for an item should be displayed or not.
You might be looping using v-for so you can make use of index.
template
<div v-for="(item , index)">
<i class="material-icons">list</i>
<div v-if="currentlyShowing === index">
<ul>
<li>Edit</li>
<li>Delete</li>
<li>Stop</li>
</ul>
</div>
</div>
script
data(){
return{
currentlyShowing: null
}
},
methods:{
showIcons: function (index) {
this.showButtons = true
this.currentlyShowing = index;
}
}