Bind a different copy of an array to vue select - vuejs2

I am trying to create some form for choosing a city and its dependent areas, the user can add multiple zones,
for each zone after the user has chosen the city they get a different list of areas depend on that city.
My problem here is that am passing the same area array for the select so every zone gets the array of the last selected city,
I want each zone to get its own copy of that array
Here's a snippet of my select for the city
<b-col v-for="(location, locationKey) in profile.location" :key="locationKey">
<main-select labelTitle='City' :name="`City ${locationKey + 1}`" placeholder="Choose"
:options="allCities" label="name" :reduce="data=> data.id"
#change="getAreasDependOnCity(location.city_id)" v-model="location.city_id">
</main-select>
Selecting a city changes the area list
getAreasDependOnCity (id) {
settingsService.getCityArea(id).then(res => {
this.allArea = res.data.data
})
}
Now for the area select I want it somehow to take unchanging copy of that array if they change the city for another zone
<main-select labelTitle='Area' :name="`Area ${locationKey + 1}`" placeholder="Choose"
:options="allArea" :multiple="true" label="name" :reduce="data=> data.id"
v-model="location.areas">
</main-select>
</b-col>
I tried to send a copy of allArea list
:options="[...allArea]"
but I guess it doesn't work like this
so any suggestions? can I do it with the same array or should I make completely different arrays for each zone?
Edit:
Expected output
[{ // zone 1
"city": "Cairo",
"areas": ["Nasr city", "Mohandseen"]
},
{ // zone 2
"city": "Giza",
"areas": ["6 October"]
}]

Related

How to use two arrays in Vuetifyes v-autocomplete

I have two arrays, one with 7 boolean values representing the weekdays, and the other with the weekdays names and the value of which day of the week it represents, kind of index of weekdays (0 beeing sunday, and 6 beeing saturday)
This sample is from the ts file belonging to the vue file where the autocomplete is.
export const scheduleDays: TextValueViewModel[] = [
{ Text: "Mon", Value: 1},
{ Text: "Tue", Value: 2 },
{ Text: "Wed", Value: 3 },
{ Text: "Thu", Value: 4 },
{ Text: "Fri", Value: 5 },
{ Text: "Sat", Value: 6 },
{ Text: "Sun", Value: 0 }
];
This is from a view model I have containing this array with booleans representing the weekdays.
public readonly SelectedDays: boolean[] = [false,false,false,false,false,false,false];
I then have a autocomplete where I want to save the clicked checkboxes and that would be saved into the boolean array
<v-autocomplete
v-model="editedReleaseSchedule.ScheduleInterval.SelectedDays"
:items="scheduleDays"
:item-text="item => `${item.Text}`"
:item-value="item => `${item.Value}`"
:label="'ADMINISTRATION_RELEASE_SCHEDULE_DETAILS_SCHEDULED_DAYS' | translate('Selected days')"
:disabled="formDisabled"
:rules="[rules.required]"
outlined
hide-details
multiple
dense
/>
How can I make the clicked value of the weekday array beeing saved into the boolean array in the right index spot? And at the same time I want the correct checkboxes be checked in the autocomplete field.
The implemented auto complete in the interface
Using Vue 2 at my workplace, so no solution for vue 3 would work out for me.
I've tried to google if I can get the index of the v-autocomplete row and use that in item-value like:
editedReleaseSchedule.ScheduleInterval.SelectedDays[index]
but that does not seem possible. I've also tried different ways of filtering before using v-autocomplete, but I still want the whole list, not only the clicked (marked) once.
Use an intermediate model for the selectedValues, watch it, and map the selected values ([1,2,3...,0]) into the real model.
data: () => ({
selectedValues: [],
// ...
<v-autocomplete
v-model="selectedValues"
<!-- etc -->
watch: {
selectedValues(newValues) {
const allFalse = [false,false,false,false,false,false,false];
this.editedReleaseSchedule.ScheduleInterval.SelectedDays = allFalse;
newValues.forEach(value => {
// presumes sunday is the last index, the others are offset by +1
let j = value === 0 ? 6 : value-1;
this.editedReleaseSchedule.ScheduleInterval.SelectedDays[j] = true;
})
},

Vue-Select reduce is not working - Showing ID instead of the label

I am using this vue select https://vue-select.org/guide/values.html#getting-and-setting for the dropdown countries. Here is the code:
<v-select
v-model="project_data.country"
:options="project_data.countries"
:reduce="country => country.value"
label="label"
:state="errors.length > 0 ? false : null"
/>
This project_data.country value is : 5
This project_data.countries value is array of object. Something like :
[
{ value : 1, label : Dhaka },
{ value : 2, label : India },
and so on ......
]
Now on my local, I can see the label on the dropdown BUT when I complied the code using :
npm run prod
and compressed the whole project and upload to live server then I can see the ID instead of the label. Something like this:
Does anyone know why? I am spending tooooo many hours to figure it out :( :( :(
My goal is to get the single ID value from the dropdown ( I can ) and save it to the database and then again show the label ( I can't ) based on the single ID value.
A common issue with that select and its in the Docs, its that you need to make sure that the value for v-model:
If options has by example only these 2:
[
{ value : 1, label : Dhaka },
{ value : 2, label : India }
]
and project_data.country is 3 the select will show the value 3 since the Vue Select searched for it and didnt find it.
So make sure in prod you have 5 in the list of countries.

Creating dropdown and populating unique value in Vue js

I am very new to Vue js. We are displaying a table on UI having 4 columns as
S.No | Column | Description | Type
We need to list all the unique value in Type in a drop-down (describing the datatype of a column), I am able to make Type as a drop-down however struggling to get the list of unique values in Type.
I am getting all data in an Array [sno:(..), column:(..), description:(..), type:(..)] and I am trying to get to type to put the value in one of the array and the taking unique value from that.
The code I tried first is
this.columnType = this.columnData.filter(data => {return data.type.toUpperCase()});
Also, I tried the following but it is just filtering on the specific datatype in this case "Timestamp"
this.columnType = this.columnData.filter(function(data) {
return data.type.toUpperCase() == "TIMESTAMP_NTZ"
});
Looking for some guidance to get this right.
Thanks in advance to all for helping
Use the following computed property to get the list of unique Type values:
computed:
{
onlyTypes()
{
// we want an Array with all the Type values
return this.tableDataRows.map(dataItem => dataItem.type);
},
uniqueTypes()
{
// we want only the unique Type values
return this.onlyTypes.filter((value, index, self) => self.indexOf(value) === index);
}
}

Aurelia repeat.for within repeat.for

I will try and keep this as simple as possible.
We have a list of stations, each station has the ability to have up to 4 channels set.
Each station you can change any of the 4 stations.
There is also a summary table below the form that shows what was chosen.
Any change made to the station level updates on the summary table below, but any update to the channel does not. I am wondering if this is something to do with the answer here https://stackoverflow.com/a/42629584/9431766
What I am confused about is if the station display updates, but the channels do not update.
Here is a simplified version of the code
constructor() {
this.stations = [
{
name: 'Station 1',
channels: [null, null, null, null]
},
{
name: 'Station 2',
channels: [null, null, null, null]
},
{
name: 'Station 3',
channels: [null, null, null, null]
}
];
this.channels = [
{ id: 1, name: 'Channel 1' },
{ id: 2, name: 'Channel 2' },
{ id: 3, name: 'Channel 3' },
{ id: 4, name: 'Channel 4' },
];
this.activeStation = {}
}
editStation(station) {
this.activeStation = station;
}
<div class="station">
<input value.bind="activeStation.name"/>
<div repeat.for="select of activeStation.channels">
<select value.bind="activeStation.channel[$index]">
<option model.bind="item" repeat.for="item of channels"></option>
</select>
</div>
</div>
<div class="summary">
<div repeat.form="station of stations">
<h3>${station.name}</h3>
<div repeat.for="channel of station.channels">
${channel ? channel.name : 'N/A'}
</div>
<div class="edit"><a click.delegate="editStation(station)">Edit</a></div>
</div>
</div>
If I reset the channels for each station after they have updated, only then does the summary update.
I do this by using map to re-map the stations, ie;
this.activeStation.channels = this.activeStation.channels.map(station);
I would prefer to not have to reset the channels after each update, this seems like a bit of overkill.
Nice question. The behavior you observed is because the repeat at the <div/> inside div.summary element couldn't see the changes to the array, since the mutation is done via index setter (caused by <select/> binding). So we have 2 choices:
Make the mutation to channels array of each station notify the array observer
Make the repeat aware of changes inside the array.
For (2), we can do it either in your way, or a value converter way to avoid modifying source array on edit. You can see an example here https://codesandbox.io/s/httpsstackoverflowcomquestions59571360aurelia-repeat-for-within-repeat-for-yuwwv
For (1), we need to resolve to manual change handling of the select, via change event
EDIT: in v2, we already fixed this issue so it will properly & naturally work without us having to add these work around.

How to restrict the search of a place by the code of the country using GeoSearchControl, vuejs?

Good morning, I am currently working with this bookstore
https://github.com/fega/vue2-leaflet-geosearch
I have applied the rules for the places finder in the following way:
geosearchOptions: {
provider: new OpenStreetMapProvider(),
searchLabel: '¿Que direccion buscas?',
showMarker: true,
showPopup: false,
maxMarkers: 1,
style: 'bar',
retainZoomLevel : true
}
But I want you to only show me the results of certain countries with your Country Code, since at the moment I am searching for all the places, for example:
I want to restrict only one country.
To restrict search by country for OpenStreetMapProvider specify countrycodes parameter.
Per documentation:
countrycodes=<countrycode>[,<countrycode>][,<countrycode>]...
Limit search results to a specific country (or a list of countries).
<countrycode> should be the ISO 3166-1alpha2 code, e.g. gb for the
United Kingdom, de for Germany, etc.
Example
geosearchOptions: {
provider: new OpenStreetMapProvider({
params: {
countrycodes: "gb"
}
})
}