Retrieving the selected item in a paper-element dropdown - dart

I have the following code following the examples at https://github.com/dart-lang/polymer-core-and-paper-examples/blob/master/web/paper_dropdown.html and https://github.com/dart-lang/polymer-core-and-paper-examples/blob/master/web/paper_dropdown.dart
EDITED
.html
<paper-dropdown-menu
label='Click to select..'
on-core-select='{{onCoreSelectCountryHandler}}'>
<paper-dropdown class='dropdown'>
<core-menu id='country' class='menu'>
<template repeat='{{country in countries}}'>
<paper-item>{{country.name}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
.dart
final List<Country> countries = [
const Country('Afghanistan', 'AF'),
const Country('Åland Islands', 'AX')];
class Country {
final String name;
final String code;
const Country(this.name, this.code);
}
void onCoreSelectCountryHandler(dom.CustomEvent e, var detail) {
var detail = new JsObject.fromBrowserObject(e)['detail'];
if (detail['isSelected']) {
// DOES NOT WORK - HOW DO I GET THE SELECTION ATTEMPTED BELOW
// The detail should be related to the Country class but
// I can't seem to relate it so I could get the selection.
var kuntry = (detail['item'] as PaperItem).text;
}
How do I retrieve the selected element in the dropdown (that displays normally) using dart code?

update
I think this is the easiest way
void onCoreSelectCountryHandler(dom.CustomEvent e, var detail) {
print(countries[$['country'].selected].name);
// or if you really need to access the `<paper-item>` element
print(detail['item'].text);
}
old
There is no selected in paper-dropdown. Wrap a core-menu within the paper-dropdown which provides selected.
see
- https://www.polymer-project.org/0.5/docs/elements/core-menu.html and the example at https://www.polymer-project.org/0.5/docs/elements/paper-dropdown-menu.html

Simple make the country list observable
final List<Country> cuntries = toObservable[
const Country('Afghanistan', 'AF'),
const Country('Åland Islands', 'AX')}]
The selection is retrieved.
My oversight.

Related

Why won't my <mat-select> have the specified value selected when loaded?

I've created a form to edit data in a table. Several fields of the form are drop down lists (mat-select) that are populated from other tables in a database. I'm populating the drop downs (mat-select) successfully, but I'm struggling to set the selected value to match the data from the row that the user is intending to edit.
I actually have one dialog working, but for some reason a more complex dialog (with 3 drop downs) is not working. I was originally only setting the ngModel, but I've added in the [comparewith] in hopes of resolving the problem or learning more. My compare method always receives a null value for the second parameter.
certificationEdit.dialog.html:
<div class="form">
<mat-form-field>
<mat-label>Connector - {{m_connectorid}}</mat-label>
<mat-select [(ngModel)]="m_connectorid" [value]="m_connectorid" [compareWith]="compareConnector" required>
<mat-option *ngFor="let item of connectorList" [value]="item.id"> {{item.connector}} ({{item.id}}) </mat-option>
</mat-select>
</mat-form-field>
</div>
certificationEdit.dialog.component.ts:
export class CertificationEditDialogComponent {
connectorList = [];
m_connectorid: string;
ngOnInit() {
this.databaseService.loadConnectorList().subscribe(response => {
this.connectorList = response as any[];
});
}
compareConnector(obj1: string, obj2: string) {
return obj1 === obj2;
}
constructor(
public dialogRef: MatDialogRef<CertificationEditDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: CERTIFICATION,
public databaseService: DatabaseService
) {
this.m_connectorid = this.data.connectorid;
}
The code opening the edit dialog:
public CertificationStartEdit(
i: number,
id: string,
releaseid: string,
productid: string,
connectorid: string,
certtype: string,
driverversion: string,
certdate: string,
changeneeded: string,
comments: string
) {
//this.release = release;
this.index = i;
const dialogRef = this.dialog.open(CertificationEditDialogComponent, {
data: {
id: id,
releaseid: releaseid,
productid: productid,
connectorid: connectorid,
certtype: certtype,
driverversion: driverversion,
certdate: certdate,
changeneeded: changeneeded,
comments: comments
}
});
The label shows m_connectorid has the value I expect, and the drop down list shows the id used for the value has the value I expect. None the less, the value I expect to be selected is not being selected.
You shouldn't bind to both ngModel and value - use one only, in your case ngModel because you are using template forms (if using reactive forms use formControl or formControlName instead).
Because of ngModel/forms, using MatSelect.value to determine what is selected might not work. I'm not sure if that's a bug or if it just isn't designed to work that way. Instead you should use MatSelect.selected.value (single selection) or just the bound variable m_connectorid or MatSelect.ngControl.value.

Aurelia + Select2 custom element not propagating selected changed

I have created a custom element in Aurelia.
import {bindable, inject, customElement, bindingMode} from 'aurelia-framework';
import 'select2';
import * as $ from 'jquery';
import {BindingSignaler} from "aurelia-templating-resources";
#customElement('select2')
#inject(Element, BindingSignaler)
export class Select2CustomMultiselect {
#bindable name = null; // name/id of custom select
#bindable selected = null; // default selected values
#bindable ({defaultBindingMode: bindingMode.oneWay, attribute:"options"}) source:Array<{id:number, name:any}>= []; // array of options with id/name properties
#bindable placeholder = "";
#bindable allow_clear = true;
private $select2: $;
constructor(private element, private signaler:BindingSignaler) {
}
attached() {
let $select = $(this.element).find('select');
this.$select2 = $select.select2({theme: 'bootstrap', placeholder: this.placeholder});
// on any change, propagate it to underlying select to trigger two-way bind
this.$select2.on('change', (event) => {
if (event.originalEvent) { return; }
const select2Value = this.$select2.val();
if(select2Value == this.selected) { return; }
// dispatch to raw select within the custom element
var notice = new Event('change', {bubbles: true});
event.target.dispatchEvent(notice);
});
this.$select2.val(this.selected);//.trigger('change');
}
selectedChanged(newValue,oldValue){
console.log(newValue);
}
detached() {
$(this.element).find('select').select2('destroy');
}
}
And it's template:
<template>
<select value.two-way="selected" name.one-way="name" id.one-way="name" class="form-control" data-allow-clear.one-way="allow_clear" size="1">
<option></option>
<option repeat.for="src of source" model.bind="src.id">${src.name & t}</option>
</select>
</template>
I use the control like this:
<select2 name="payingBy" selected.two-way="model.countryId & validate" options.bind="countries" placeholder="${'Select' & t}" allow_clear="true"></select2>
And model is:
countries:Array<{id:number, name:string}> = [{id:1, name:"USA"}, {id:2, name:Canada'}];
model.countryId: number;
Now, everything works fine if I change the select and on initial binding.
But if i change the model.countryId from ie. 1 to 2, the change is not reflected in the select control, the control still displays "USA" as like 1 is selected.
Because 'selected' property is bind two-way I would expect it to update the select when it change. But it does not. Why?
What Am I doing wrong?
Please help
Ok, I implemented it like in this post:Custom Select2 Aurelia component
And it works perfectly.
That is because you are using the data version which expects an object, but you have set your select to work with the id value only. So you should use the val to pass the id.
selectedChanged(newValue, oldValue) {
console.log(newValue);
if (this.select2) {
this.select2.select2({
val: newValue, // << changed this from data: newValue
theme: 'bootstrap',
placeholder: this.placeholder
});
}

Dart PaperDropdownMenu getting selected item

I'm kind of struggling getting the selected item id or even the text displayed in a dropdown menu list. Here's my code:
HTML:
<paper-dropdown-menu label="Currency" on-core-select="{{selectCurrency}}">
<paper-dropdown class="dropdown" halign='right'>
<core-menu class="menu" selected="{{selectedCurrency}}">
<template repeat="{{c in currencies}}">
<paper-item>{{c}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
Dart:
void selectCurrency(CustomEvent e, var detail, PaperDropdownMenu m) {
var id = m.getAttribute("selected");
//id = mCurrencyDropdown.selected;
JsObject detail = new JsObject.fromBrowserObject(e)['detail'];
if(detail['isSelected']) {
PaperItem selected = detail['item'] as PaperItem;
print( 'source | $selected' );
}
print(detail);
}
I can see several properties from which I might get the information I want but I can't access them as the don't seem to be public:
https://drive.google.com/file/d/0B9-4jVIpB0XuTXJ5eVBMZllyanM/view
Any idea? Thank you!
Thanks to Günter I have found the answer:
I have an observable like this:
#observable int selectedCurrency = 20;
Apparently you can simply add a method to your class matching the members name like this and it's called each time the observable is changed:
selectedCurrencyChanged(var oldValue, var newValue) {
print(newValue);
}
Official Documentation
Where is the field selectedCurrency you have bound to ?
I guess you can drop the on-core-select event handler entirely and instead add a method
selectedCurrencyChanged(newValue) {
// event handler code here
}

How do I turn these results into a list for use w/ Polymer's repeat attribute?

In the following code f.onChildAdded is an Instance of '_BroadcastStream<Event>':
f.onChildAdded.forEach((e) {
print(e.snapshot.val());
//TODO: Turn this somehow into a list
});
The print outputs each item fine, and now I'd like to turn it into a list that's friendly with Polymer's repeat="{{item in items }}" magic.
How do I turn it into a list? List myList = new List(); and myList.add(e.snapshot.val()); isn't helping me there.
How do I pass that from my main() in my index.dart to my-element.dart?
FWIW, here's my project: https://github.com/DaveNotik/dartstack. Any other guidance as I get a handle on this would be great!
At first you should ensure that your main look like shown here
how to implement a main function in polymer apps
in your main:
List myList = new List();
f.onChildAdded.forEach((e) {
myList.add(e.snapshot.val());
});
(querySelector('your-element') as YourElement).myList = myList;
or when you don't want to create a new list each time:
The list field in you custom element should look like
#observable List myList = toObservable([]);
in your main:
List myList = (querySelector('your-element') as YourElement).myList;
f.onChildAdded.forEach((e) {
myList.add(e.snapshot.val());
});

Prevent selection of a particular item in spark list

I have a Spark List which has a custom itemRenderer for rendering each item in the List.
I wish to prevent an item in that list from being selected (based on some custom logic) by the user.
What is the best way I can achieve this?
Here's how my List is defined:
<s:List id="myList" itemRenderer="com.sample.MyItemRenderer" />
and of course, I have a item renderer defined as the class com.sample.MyItemRenderer.
The selection of items is handled by the list alone as far as I know, so I would say that you can manage it from there. I would have a field on the Objects that are in the list called "selectable" or something like that and when the list item is changing check to see if the new item is actually selectable and if it isn't then you can either have it clear the selection or reset to the previous selection. You can accomplish that by reacting to the "changing" event on the list component and calling "preventDefault" on the IndexChangeEvent as follows:
protected function myList_changingHandler(event:IndexChangeEvent):void {
var newItem:MyObject = myList.dataProvider.getItemAt(event.newIndex) as MyObject;
if(!newItem.selectable) {
event.preventDefault();
}
}
// Jumping ahead ...
<s:List id="myList" changing="myList_changingHandler(event)" // ... continue implementation
The relevant part of the MyObject class is as follows:
public class MyObject {
private var _selectable:Boolean;
public function MyObject(){
}
public function set selectable(value:Boolean):void {
_selectable = value;
}
public function get selectable():Boolean {
return _selectable;
}
}

Resources