How to display multi dimensional array into the multiple dropdown menu? - angular5

I am working in multiple dropdown menu. I have created an array from php and it looks like this:
https://api.myjson.com/bins/1emzic
Now from this json I want to display 4 dropdown menu.
In the first drop down I need to display
"FS A", "FS MT" and "FS OTHER"
Based on the first selection I need to display its related data in second third and fourth and so on as I add in my data.
This is what I need to bind
<select [(ngModel)]="first" id="first">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of first_list" [value]="item.category">{{item.category}}</option>
</select>
<br>
<select [(ngModel)]="second" id="second">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of first_list" [value]="item.category">{{item.category}}</option>
</select>
<br>
<select [(ngModel)]="third" id="third">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of first_list" [value]="item.category">{{item.category}}</option>
</select>
<br>
<select [(ngModel)]="four" id="four">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of first_list" [value]="item.category">{{item.category}}</option>
</select>
Here is my json data
{"FS A":{"BKK":{"BKK PULL":{"BKK SR1":[]},"BKK PUSH":{"BKK BCDE1":[],"BKK BAKE SE1":[]}},"RSM2":{"CHIANGMAI":{"CMI WS SE1":[],"CMI WS SE2":[]},"NORTH":{"NO1 SE1":[],"NO2 SEPLUS1":[],"NO3 SE1":[]},"ASM HOTEL BKK":{"BKK HO 5STARS1":[],"BKK HO SR1":[],"BKK HO SR2":[],"BKK HO SR3":[]}}},"FS MT":{"FSR1":{"FSA1":{"FS MAKRO":[]}},"FSR2":{"FSA2":{"FS FOODLAND":[],"FS GAS STATION":[],"FS VILLA MARKET JP":[],"SIAM FOODSERVICE":[]}},"FS LOCAL EXP":{"FS LOCAL EXP BKK":{"FS LOCAL EXP BKK":[]},"FS LOCAL EXP CD":{"FS LOCAL EXP CD":[]},"FS LOCAL EXP MM":{"FS LOCAL EXP MM":[]}}},"FS OTHER":{"FS OTHER":{"FS OTHER":{"FS OTHER":[]}}}}
Can anybody help me in this?
Here I am working:
https://stackblitz.com/edit/angular-dsylxi

You need to define the dependency on each other and based on that you can fill the models and its options. I will go for generic solution which can be applied with one function and works for all the drop-downs.
This are the model variables you need
wholeList:any = [];
first:any = [];
second:any = [];
third:any = [];
four:any = [];
firstModel = ''
secondModel = ''
thirdModel = ''
fourModel = ''
Then first you fill the first dropdown
this.testService.get_data().subscribe(
res => {
this.wholeList = res;
this.first = Object.keys(this.wholeList).map(a=> a);
console.log("res", this.first);
},
err => {
console.log(err);
}
)
Then in the view you need to fire a dependency which should look like this, note that I am defining dependency ChangeDropdown(this.wholeList[firstModel],'second')"
<select [(ngModel)]="firstModel" id="first" (ngModelChange)="ChangeDropdown(this.wholeList[firstModel],'second')">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of first" [value]="item">{{item}}</option>
</select>
<br>
<select [(ngModel)]="secondModel" id="second" (ngModelChange)="ChangeDropdown(this.wholeList[firstModel][secondModel],'third')">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of second" [value]="item">{{item}}</option>
</select>
<br>
<select [(ngModel)]="thirdModel" id="third" (ngModelChange)="ChangeDropdown(this.wholeList[firstModel][secondModel][thirdModel],'four')">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of third" [value]="item">{{item}}</option>
</select>
<br>
<select [(ngModel)]="fourModel" id="four">
<option value="" disabled selected>select a category</option>
<option *ngFor="let item of four" [value]="item">{{item}}</option>
</select>
and finally one common function which will update the models
ChangeDropdown = (value,dropdownName) =>{
this[dropdownName] = Object.keys(value).map(a=>{
return a;
})
}
Demo

Related

Change link href depending on drop-down value

I have a button witha a href link:
My button
Then I have 3 drop-down (select) inputs, lets call them A, B & C
Depending on what the users choose, I want the link to be changed as this
My button
All three drop-downs will be Required
Find the following snippet useful. Handle the default values for the query params.
<select id="a" onchange="changeUrl()">
<option value="a1">a1</option>
<option value="a2">a2</option>
</select>
<select id="b" onchange="changeUrl()">
<option value="b1">b1</option>
<option value="b2">b2</option>
</select>
<select id="c" onchange="changeUrl()">
<option value="c1">c1</option>
<option value="c2">c2</option>
</select>
<a id="test" href="mysite.com">My button</a>
<script>
function changeUrl(){
let url="mysite.com?a=";
let a= document.getElementById('a').value;
url+=a+"&b=";
let b=document.getElementById('b').value;
url+=b+"&c=";
let c=document.getElementById('c').value;
url+=c;
document.getElementById('test').href=url;
}
</script>
</body>

How can I get optgroup label when select an option in vuejs?

I want to get country group name when select option. I've countries with several group like
<template>
<select id="countries" v-model="country" #change="getCountryGroup($event)">
<optgroup label="Asia">
<option value="AF">Afghanistan</option>
<option value="AM">Armenia</option>
<option value="AZ">Azerbaijan</option>
...
<option value="BD">Bangaldesh</option>
...
</optgroup>
<optgroup label="Australia / Oceania">
<option value="AS">American Samoa</option>
<option value="AU">Australia</option>
<option value="CK">Cook Islands</option>
</optgroup>
<optgroup label="Africa">
<option value="DZ">Algeria</option>
<option value="AM">Angola</option>
<option value="AZ">Azerbaijan</option>
</optgroup>
<optgroup label="South America">
<option value="AR">Argentina</option>
<option value="BO">Bolivia</option>
<option value="BR">Brazil</option>
</optgroup>
<optgroup label="North America">
<option value="US">United States</option>
<option value="UM">United States Minor Outlying Islands</option>
<option value="CA">Canada</option>
</optgroup>
<optgroup label="Europe">
<option value="UK">United Kingdom</option>
<option value="AL">Albania</option>
<option value="AD">Andorra</option>
</optgroup>
</select>
</template>
Suppose when I select Bangladesh then I want to get optgroup name Asia. Here is my vueJs method
getCountryGroup: function(event){
console.log( event.target.getAttribute('label') );
}
Here are two steps
Get the selected index
Find the selected option
Select the parent element (optgroup) for the selected option
Finally, get the label (Country group)
getCountryGroup: function(event){
// 1. Get the selected index
const index = event.target.selectedIndex;
// 2. Find the selected option
const option = event.target.options[index];
// 3. Select the parent element (optgroup) for the selected option
const optgroup = option.parentElement;
// 4. Finally, get the label (Country group)
const countryGroup = optgroup.getAttribute('label');
console.log(countryGroup);
}
Here is the demo https://codepen.io/maab16/pen/KKKpJba

v-model and selected is not working at the same time... --vue.js

UPDATED
select input's selected option is not working if I use v-model on select.
<p class="topics">fruits</p>
<select class="select" v-model="selectFruit">
<option selected value="">--all--</option>
<option :key="index" :value="item" v-for="(item,index) in fruitList">{{item}}</option>
</select>
if I don't use v-model, then selected is working. But I need that v-model bind for filter my array. But it looks like I can't use v-model and selected at the same time.
Use selected attribute
https://www.w3schools.com/tags/att_option_selected.asp
<select class="select" v-model="searchCity">
<option value="" selected>--全部--</option>
<option :value="item" v-for="item in uniqueCity">{{item}}</option>
</select>
Adding a bonus to the above answer, if you want to have a default placeholder but not a valid value (Like "Select country here") you can do it like this:
<select>
<option value="" selected disabled hidden>Select country here</option>
<option value="1">Bulgaria</option>
<option value="2">Serbia</option>
<option value="3">Cyprus</option>
</select>

Angular 5 dropdown setting default value

I am trying to preselect (set as default) value from Angular 5 drop down.
There are three values and I am trying to set the second one with this code but it doesn't work. I can't make any changes in the component, only in the template.
<select [(ngModel)]="declaration.media" name="media" (change)="onChangeMedia()" class="form-control form-control-sm" required>
<option *ngFor="let media of mediaArray" value="{{media.value}}" selected = "{{media.value == '02'}}">{{media.text}}</option>
</select>
UPDATE: if I remove [(ngModel)] then it works, but no two way binding.
<select>
<option value="" selected disabled hidden>Choose here</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>
</select>

Unable to select a dropdown by value, visible text or index using selenium select command

I am unable to select an option dynamically using select commands by value, visible text or index, the workaround was i can use actions to click select and select a particular option or sending keys ArrowDown which is not a best way to implement because i want to use the same select function globally to automate UI all over the website like a keyword function.
sample script below:
WebElement selectElement = driver.findElement(By.xpath(.//*[#id='XYZPopUpForm:j_idt90:country_label']));
Actions selectItem = new Actions(driver);
selectItem.moveToElement(selectElement).click().perform();
selectItem.sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).perform();
selectItem.sendKeys(Keys.ENTER).perform();
HTML Code :
<tr>
<td>
<label for="XYZPopUpForm:j_idt90:country">Country</label>
</td>
<td>
<div id="XYZPopUpForm:j_idt90:country" class="ui-selectonemenu ui-widget ui-state-default ui-corner-all">
<div class="ui-helper-hidden-accessible">
<div class="ui-helper-hidden-accessible">
<select id="XYZPopUpForm:j_idt90:country_input" tabindex="-1" name="XYZPopUpForm:j_idt90:country_input">
<option selected="selected" disabled="disabled">--select--</option>
<option value="AF">Afghanistan</option>
<option value="AX">Åland Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
<option value="AO">Angola</option>
<option value="AI">Anguilla</option>
<option value="AQ">Antarctica</option>
<option value="AG">Antigua and Barbuda</option>
<option value="AR">Argentina</option>
<option value="AM">Armenia</option>
<option value="AW">Aruba</option>
<option value="AU">Australia</option>
<option value="AT">Austria</option>
<option value="AZ">Azerbaijan</option>
<option value="BS">Bahamas</option>
<option value="BH">Bahrain</option>
<option value="BD">Bangladesh</option>
<option value="BB">Barbados</option>
<option value="BY">Belarus</option>
<option value="BE">Belgium</option>
<option value="BZ">Belize</option>
<option value="BJ">Benin</option>
<option value="BM">Bermuda</option>
<option value="BT">Bhutan</option>
<option value="BO">Bolivia, Plurinational State of</option>
<option value="BQ">Bonaire, Sint Eustatius and Saba</option>
<option value="BA">Bosnia and Herzegovina</option>
<option value="BW">Botswana</option>
<option value="BV">Bouvet Island</option>
<option value="BR">Brazil</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="BN">Brunei Darussalam</option>
<option value="BG">Bulgaria</option>
<option value="BF">Burkina Faso</option>
<option value="BI">Burundi</option>
<option value="KH">Cambodia</option>
<option value="CM">Cameroon</option>
<option value="CA">Canada</option>
<option value="CV">Cape Verde</option>
</select>
</div>
Updated Script:
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement selectElement = driver.findElement(By.id("XYZPopUpForm:j_idt90:country_input"));
((JavascriptExecutor)driver).executeScript("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text == arguments[1]){ select.options[i].selected = true; } } ", selectElement, "Afghanistan");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("XYZPopUpForm:j_idt90:country_input")));
Screenshot of HTML to be more clear :
Seems you are finding incorrect element By.xpath your drop-down id looks like XYZPopUpForm:j_idt90:country_input but you are finding id XYZPopUpForm:j_idt90:country_label in By.xpath, May be that is the problem. Try using Select with correct drop-down id as below :-
WebElement selectElement = driver.findElement(By.id("XYZPopUpForm:j_idt90:country_input"));
//Now use select
Select select = new Select(selectElement);
select.selectByVisibleText("Afghanistan");
or
sel.selectByIndex(1);
or
sel.selectByValue("AF");
Edited :- If above does not work due to visibility of element you should try using JavascriptExecutor as below :-
WebElement selectElement = driver.findElement(By.id("XYZPopUpForm:j_idt90:country_input"));
((JavascriptExecutor)driver).executeScript("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text == arguments[1]){ select.options[i].selected = true; } }", selectElement, "Afghanistan");
Hope it works...:)