5

How to set default selected values in multiselect. I get current_options and all_options from database and I want to update current_options and send new values do database again.

Updating database works but when I refresh page none of options are selected.

current_options = [{id:1, name:'name1'}];                    #from database
all_options = [{id:1, name:'name1'},{id:2, name:'name2'}];   #from database

My template:

<select multiple name="type" [(ngModel)]="current_options">
    <option  *ngFor="let option of all_options" [ngValue] = "option">
        {{option.name}}
    </option>
</select>`
pelcomppl
  • 575
  • 2
  • 6
  • 16

4 Answers4

6

You should be using an array of selected items

<select [(ngModel)]="selectedElement" multiple>
     <option *ngFor="let type of types" [ngValue]="type"> {{type.Name}}</option>
</select>

My selected item will be as below

selectedElement:any= [
                {id:1,Name:'abc'},
                {id:2,Name:'abdfsdgsc'}];

LIVE DEMO

Aravind
  • 40,391
  • 16
  • 91
  • 110
5

If you will pass the values as an id array to ngModel

let idArrary = ["1"];

<select multiple name="type" [(ngModel)]="idArrary">
    <option  *ngFor="let option of all_options" [ngValue] = "option">
        {{option.name}}
    </option>
</select>

`

Anshul
  • 375
  • 3
  • 14
2

current_options = [all_options[0]] To initialize the default value of your input.

Current_options need to be initialize with an array containing the same objects present in all_options.

I forked the Plunker from another answer to illustrate it.

Keep in mind that :

{id:1, name:'name1'} !== {id:1, name:'name1'}

Edit:

Assuming current_options is already containing some value you are receiving from your server:

current_options = current_options.map((current_option) => {
   return all_options.find((all_option) => current_option.id === all_option.id);
})

Or probably more performant:

for (let i in all_options) { 
   for (let j in current_options) { 
      if (all_options[i].id === current_options[j].id ) { 
         current_options[j] = all_options[i]; 
      } 
   } 
}

Edit: According to angular documentation you can use a compare with function to specify how to assume two objects are equal.

<select multiple [compareWith]="compareFn" ...>
</select>

compareFn(c1: Category, c2: Category): boolean {
  return c1 && c2 ? c1.id === c2.id : c1 === c2;
}
nubinub
  • 1,898
  • 2
  • 15
  • 23
  • What is `optionFromDatabase`? I can use only `current_options` and `all_options` – pelcomppl Dec 07 '17 at 10:15
  • You said your current_options was initialised by database. – nubinub Dec 07 '17 at 10:46
  • `current_options` is a part of bigger object I want to display `current_options` as selected items in select field, eventually change selected items and send object to database. – pelcomppl Dec 07 '17 at 11:06
  • I edited my answer, guess i forgot about the multiple part of the select. – nubinub Dec 07 '17 at 12:45
  • So, to initialize the default values (if current_options I get from database I should do this: `for (let i in all_options) { for (let j in current_options) { if (this.all_options[i].id === current_options[j].id ) { current_options.push(this.all_options[i]); } } }` ? – pelcomppl Dec 07 '17 at 14:12
  • `for (let i in all_options) { for (let j in current_options) { if (this.all_options[i].id === current_options[j].id ) { current_options[j] = this.all_options[i]; } } }` I'll put a smoother solution into my post. – nubinub Dec 07 '17 at 14:28
  • Nubinub, your solution works well, but I have to set current_options in every component. I'd like to subscribe current_options in model like that: `for (let cat of obj.cat) { this.category.push(new Category(at)); }` and use it: ` – pelcomppl Dec 12 '17 at 10:05
  • `cat !== new Category(cat)` – nubinub Dec 12 '17 at 10:21
  • @pelcomppl I edited my answer with a feture i just discovered in angular documentation. – nubinub Dec 12 '17 at 10:40
1

If you want create multiple select and option with ngModel and set default value and two way bind its working code

<div  *ngFor="let options of optionsArray; let in = index">
 <br>
 <select [(ngModel)]="res[in]" >
 <option  [ngValue]="option" *ngFor="let option of options.options; let i =index">


{{option}}
</option>
</select>
 {{res[in]}}
</div>
{{res}}

export class ExComponent implements OnInit {
public res=[];
 public optionsArray = [
   {id: 1, text: 'Sentence 1', options:['kapil','vinay']},
   {id: 2, text: 'Sentence 2', options:['mukesh','anil']},
   {id: 3, text: 'Sentence 3', options:['viky','kd']},
  {id: 4, text: 'Sentence 4', options:['alok','gorva']},
]
ngOnInit() 
{
this.optionsArray.forEach(data=>{
 this.res.push(data.options[0]);
})
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253