diff --git a/demos/src/select/pages/page-one/page-one.html b/demos/src/select/pages/page-one/page-one.html
index e8eced2919..966b571e2f 100644
--- a/demos/src/select/pages/page-one/page-one.html
+++ b/demos/src/select/pages/page-one/page-one.html
@@ -20,6 +20,13 @@
+
+ Hair Color
+
+ {{o.text}}
+
+
+
Gaming
@@ -147,6 +154,13 @@
+
+ Skittles
+
+ {{o.text}}
+
+
+
Disabled
diff --git a/demos/src/select/pages/page-one/page-one.ts b/demos/src/select/pages/page-one/page-one.ts
index 48e9ca7950..e4bcaa81a2 100644
--- a/demos/src/select/pages/page-one/page-one.ts
+++ b/demos/src/select/pages/page-one/page-one.ts
@@ -10,6 +10,10 @@ export class PageOne {
petAlertOpts: any;
petData: any;
pets: Array;
+ hairColorData: any;
+ hairColor: any;
+ skittlesData: any;
+ skittles: Array;
notifications: string = 'mute_1';
rating: number = 2;
@@ -31,9 +35,37 @@ export class PageOne {
{ text: 'Honey Badger', value: 'honeybadger' },
];
+ this.hairColorData = [
+ { text: 'Brown', value: 'brown' },
+ { text: 'Blonde', value: 'blonde' },
+ { text: 'Black', value: 'black' },
+ { text: 'Red', value: 'red' }
+ ];
+
+ // Pre-selected object with different object reference
+ this.hairColor = { text: 'Brown', value: 'brown' };
+
+ this.skittlesData = [
+ { text: 'Red', value: 'red' },
+ { text: 'Orange', value: 'orange' },
+ { text: 'Yellow', value: 'yellow' },
+ { text: 'Green', value: 'green' },
+ { text: 'Purple', value: 'purple' }
+ ];
+
+ // Pre-selected object with different object reference
+ this.skittles = [
+ { text: 'Red', value: 'red' },
+ { text: 'Purple', value: 'purple' }
+ ];
+
this.pets = ['cat', 'dog'];
}
+ compareFn(option1: any, option2: any) {
+ return option1.value === option2.value;
+ }
+
monthChange(val: any) {
console.log('Month Change:', val);
}
diff --git a/src/components/select/select.ts b/src/components/select/select.ts
index 1c8f501462..28a94b32a3 100644
--- a/src/components/select/select.ts
+++ b/src/components/select/select.ts
@@ -123,6 +123,31 @@ import { SelectPopover, SelectPopoverOption } from './select-popover-component';
* };
* ```
*
+ * ### Object Value References
+ *
+ * When using objects for select values, it is possible for the identities of these objects to
+ * change if they are coming from a server or database, while the selected value's identity
+ * remains the same. For example, this can occur when an existing record with the desired object value
+ * is loaded into the select, but the newly retrieved select options now have different identities. This will
+ * result in the select appearing to have no value at all, even though the original selection in still intact.
+ *
+ * Using the `compareWith` `Input` is the solution to this problem
+ *
+ * ```html
+ *
+ * Employee
+ *
+ * {{employee.name}}
+ *
+ *
+ * ```
+ *
+ * ```ts
+ * compareFn(e1: Employee, e2: Employee): boolean {
+ * return e1 && e2 ? e1.id === e2.id : e1 === e2;
+ * }
+ * ```
+ *
* @demo /docs/demos/src/select/
*/
@Component({
@@ -153,6 +178,7 @@ export class Select extends BaseInput implements OnDestroy {
_overlay: ActionSheet | Alert | Popover;
_texts: string[] = [];
_text: string = '';
+ _compareWith: (o1: any, o2: any) => boolean = isCheckedProperty;
/**
* @input {string} The text to display on the cancel button. Default: `Cancel`.
@@ -187,6 +213,18 @@ export class Select extends BaseInput implements OnDestroy {
*/
@Input() selectedText: string = '';
+ /**
+ * @input {Function} The function that will be called to compare object values
+ */
+ @Input()
+ set compareWith(fn: (o1: any, o2: any) => boolean) {
+ if (typeof fn !== 'function') {
+ throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
+ }
+ this._compareWith = fn;
+ }
+
+
/**
* @output {any} Emitted when the selection was cancelled.
*/
@@ -448,7 +486,7 @@ export class Select extends BaseInput implements OnDestroy {
this._options.forEach(option => {
// check this option if the option's value is in the values array
option.selected = this.getValues().some(selectValue => {
- return isCheckedProperty(selectValue, option.value);
+ return this._compareWith(selectValue, option.value);
});
if (option.selected) {