javascript - Aurelia ValueConverter fromView confusion with multi-select -


i'm trying use , understand aurelia valueconverter in context of multi-select form. thought straight forward, has turned out challenge me.

i have form create new deal has multiple categories assigned via multi-select input field. i've bound output form new_deal.categorizations (in database deals have categories through categorizations).

right on create, through 'brute force' method, i'm converting each category id {category_id: id} object before posting api.

example logging post output:

  create(){       var categorizations = this.new_deal.categorizations;       this.new_deal.categorizations = categorizations.map(function (e) {           return {category_id: e}       });       logger.debug ('post: ', json.stringify(this.new_deal));   } 

example output:

post:  {"name":"new deal","categorizations":[{"category_id":"1"},{"category_id":"2"}]} 

but think better accomplished through valueconverter.

plunker here full code it's basically:

app.js:

export class app {   constructor(){     this.categories = [{id: 1, name: 'test1'}, {id: 2, name: 'test2'}];     this.new_deal = {         name:       'new deal',         categorizations: null,     };   }    create(){       var categorizations = this.new_deal.categorizations;       this.new_deal.categorizations = categorizations.map(function (e) {return {category_id: e}});       logger.debug ('post: ', json.stringify(this.new_deal));   }    create2(){       logger.debug ('post: ', json.stringify(this.new_deal));   }  }  export class categorytoidvalueconverter {     fromview(id) {         return id ? id: null;     } } 

and app.html:

<template>   <h1>testing valueconverter</h1>    <h3 >new brute force deal</h3>      <form role="form">        <label>name</label>           <input type="text" placeholder="ex. buy 1 1 free" value.bind="new_deal.name">        <label>categories</label>           <select value.bind="new_deal.categorizations" multiple size="2">               <option repeat.for="category of categories" value.bind="category.id">${category.name}</option>           </select>        </form>        <button type="submit" click.delegate="create()">save</button>    <h3>new valueconverter deal</h3>     <form role="form">       <label>name</label>           <input type="text" placeholder="ex. buy 1 1 free" value.bind="new_deal.name">       <label>categories</label>           <select class="form-control" value.bind="new_deal.categorizations | categorytoid" multiple size="2">             <option repeat.for="category of categories" value.bind="category.id">${category.name}</option>           </select>     </form>     <button class="btn btn-success" type="submit" click.delegate="create2()">save</button> </template> 

with output of

post:  {"name":"new deal","categorizations":["1","2"]} 

in fromview in app.js, think change:

return id ? id: null; 

to return object instead of individual value:

return id ? {category_id: id} : null 

but results in error:

uncaught error: null or array instances can bound multi-select. 

upon further inspection, looks id coming fromview array...

so modified fromview this:

    fromview(id) {         if(id){           var categorizations = [];           id.foreach(function(cat_id){             categorizations.push({category_id: cat_id})           });           logger.debug(categorizations);           logger.debug(object.prototype.tostring.call(categorizations));           return categorizations;         } else { return null; }     } } 

trying expect array, , build array of categorization objects return, can see in this plunker, loses select click (though debug logs show objects being created).

you have array of category objects, each having name (string) , id (number). these used populate select element allows multiple selection:

export class app {   categories = [     { id: 1, name: 'test1'},     { id: 2, name: 'test2'}   ]; } 
<select multiple size="2">   <option repeat.for="category of categories">${category.name}</option> </select> 

the deal object comprised of name (string) , categorizations. categorization objects this: { category_id: 1 }

export class app {   categories = [     { id: 1, name: 'test1'},     { id: 2, name: 'test2'}];    deal = {     name: 'new deal',     categorizations: [],   } } 

we want bind select element's value deal object's categorizations array of objects. means each of select element's options need have object "value". htmloptionelement's value attribute accepts strings. assign coerced string. can store categorization object in special model attribute can handle type. more info on can found in aurelia docs.

<select multiple size="2">   <option repeat.for="category of categories" model.bind="{ category_id: category.id }">${category.name}</option> </select> 

finally need bind select element's value deal object's categorizations:

<select value.bind="deal.categorizations" multiple size="2">   <option repeat.for="category of categories" model.bind="{ category_id: category.id }">${category.name}</option> </select> 

all together, view , view-model this:

export class app {   categories = [     { id: 1, name: 'test1'},     { id: 2, name: 'test2'}];    deal = {     name: 'new deal',     categorizations: [],   }    createdeal() {     alert(json.stringify(this.deal, null, 2));   } } 
<template>   <form submit.delegate="createdeal()">     <label>name</label>     <input type="text" placeholder="ex. buy 1 1 free" value.bind="deal.name">      <label>categories</label>     <select value.bind="deal.categorizations" multiple size="2">       <option repeat.for="category of categories" model.bind="{ category_id: category.id }">${category.name}</option>     </select>      <button type="submit">save</button>   </form> </template> 

here's working plunker: http://plnkr.co/edit/ko3ifbostdthrhua0qhy?p=preview


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -