Dart PaperDropdownMenu getting selected item - dart

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
}

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.

how to use NgIF condition with formcontrol instead of ngModel

I want to compare my values using my formcontrol than using ngModel, when values is entered in my input box , I want to display my cancel image, so I given userTextValue as true inside subscribe, my query now is how to reset the value when cancel is clicked . I want the input box to be empty , now cancel button is hidden but still values available, I am using pipe to filter values.
<input matInput class="form-control input" placeholder="Enter name or Id" id="user"
[formControl]="userControl"[matAutocomplete]="auto>
<img src="assets/icons/cancel.svg" *ngIf="userTextvalue" class="cancel-icon"
aria-label="Clear" (click)="clearUserValues()">
ts:
constructor() {
this.userControl.valueChanges.subscribe((user) => {
this.filterResult = user;
this.userTextvalue = true;
});
}
clearUserValues() {
this.filterResult = "";
this.userTextvalue = false;
}
pipe.ts
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'filterUser'
})
export class FilterUserPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (searchText && searchText.length > 1) {
items = searchText ? this.filterUsers(items, searchText) : items.slice();
} else {
items = [];
}
return items;
}
filterUsers(items: any[], value: string): any[] {
const filterValue = value.toLowerCase();
return items.filter(item => item.name.toLowerCase().indexOf(filterValue) === 0);
}
}
First of All you have to get knowledge about what is difference between template driven and reactive form approach. When any change happens in formcontrol, it return new object of form (included its formcontrols) and that's what make it synchronous approach.
Let me wrap up this in short scenario.
When any change happens in formcontrol input or html tag
it could be tracked by subscribed it.
for example
// getting specific FormControl changed value.
// form: FormGroup
this.form.get('name of your formControl').subscribe(value => {// here (value) is changed value of that particular formControl. });
2nd Approach
For example you have formcontrol on any clickable input button or select input.
then you can emit an method on event click and on that method you can subscribe changed value and compare or save it to where you want.
sample code ::::
<mat-select formControlName="transferType">
<mat-option [value]="type" *ngFor="let type of transferTypes" (click)="onChanges()">{{type}}</mat-option>
</mat-select>
i am calling "onChanges()" method when i selects an option then i am subscribing this formControl and getting changed value and compare selected value by comparing operation.
same as you can get changed value and then set it to any boolean type variable then you can set any div with *ngIf="" statement in your html template/
if any confusion let me know.
Thanks..
angular7 #reactiveforms #formcontrol
As per your question i'm not completely sure why you want to use the filter since you have not shown the code. However, if you want to just reset your control, change this.filterResult = "" to this.userControl.setValue('') in clearUserValues() method.
Also, since you are subscribing to the valueChanges, it would be better if you do it in ngOnInit().
Check stackblitz here
Your TS code will be like this.
ngOnInit() {
this.onchanges();}
onchanges() {
this.form.get('userControl').valueChanges.subscribe( data => {
// here you can set your boolean value for condition to show cancel button
and push the value/or object which you take from input textbox in an your array for further comparison.
});}
clearUserValues() {
// here you will be set your boolean for hiding cancel button
and then you will be set empty state to your formControl input by doing like this.
this.form.get('userControl').patchValue(//here you will be pass empty string '' or what ever you want set it to.);}

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
});
}

Retrieving the selected item in a paper-element dropdown

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.

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