Hi everyone,
I’m using a search value converter to filter a list of elements, the value converter work perfectly.
Now, I want to return the result from the value converter to the view-model, so that when a user “toggles all” elements, only they elements which was returned to the view is toggled.
So my question is: “Is it possible to get the result of the value converter returned to the view-model and how?”.
Thanks in advance
1 Like
value converters are injectable just like all other stuff in aurelia.
so you can call “toView” in your VM, and store the result in a variable. and bind to that variable.
that way - you can access it later in your VM.
another option is to use the <let>
element in your view, to “store” the result of the value converter in a variable that can be acceseed later in the view or VM.
2 Likes
Thanks @avrahamcool , I actually tried this earlier but for some reason I had overlooked a property that the value converter needed to perform the search.
1 Like
manks
February 20, 2021, 4:51am
4
Can you update your question with code?
1 Like
@manks the feedback from @avrahamcool helped me realize that I had overlooked something in my code. So using the value converter worked as intended.
If you are asking me if I could share my solution with you then let me know.
1 Like
manks
February 24, 2021, 3:24pm
6
If you wouldn’t mind some example code. I’m sure it can benefit others as well. Thank you!
1 Like
bigopon
February 25, 2021, 12:54pm
7
Suppose we have
export class MyValueConverter {
compute(value) {
return 'Value is:' + value;
}
toView(value) {
return this.compute(value);
}
}
then we can inject the value converter as:
@inject(MyValueConverter)
export class MyElement {
constructor(myValueConverter) {
const value = myValueConverter.toView(someOtherValue);
}
}
2 Likes
This is how I have implemented it. I hope it helps you and many others, who might come by and see this post.
export class MyList {
private elements: MyElementDto[] = [];
private columnsToSearch: string[] = ['colName1', 'colName2', 'colName3', 'colName4', 'colName5'];
private selectedElements: MyElementDto[] = [];
private allSelected: boolean = false;
private searchTerm: string = "";
private viewContext: string;
private subscriptions: Subscription[];
constructor(private events: EventAggregator, private listService: ListService) {
this.viewContext = "someName";
}
async activate(params, routeConfig, navigationInstruction) {
const searchHandler = (data: any) => this.handleSearchEvent(data);
this.subscriptions = [
this.events.subscribe(this.viewContext + ":SearchTermChanged", searchHandler)
];
}
detached() {
this.subscriptions.forEach(subscription => (
subscription.dispose()
));
}
private handleSearchEvent(data) {
this.searchTerm = data;
}
async toggleAll() {
await this.listService.toggleAll(this.elements, this.searchTerm, this.columnsToSearch).then(result => {
this.selectedElements = result.selected;
this.allSelected = result.allSelected;
});
}
}
Service
import { SearchValueConverter } from 'resources/value-converters/search';
import { autoinject } from 'aurelia-framework';
@autoinject
export class MyService {
allSelected: boolean = false;
selectedElements: any[] = [];
constructor (private searchVC: SearchValueConverter) {}
public async toggleAll(list: any[], searchTerm: string = "", searchColumns: string[] = []): Promise<any> {
let listFilteredBySearch: any[] = [];
if (Boolean(searchTerm)) {
listFilteredBySearch = this.searchVC.toView(list, {
searchTerm: searchTerm,
columns: searchColumns
});
}
if (listFilteredBySearch.length > 0) {
if (listFilteredBySearch.every(x => x.selected)) {
return this.deselectAll(listFilteredBySearch);
}
if (listFilteredBySearch.every(x => !x.selected) || listFilteredBySearch.some(x => x.selected)) {
return this.selectAll(listFilteredBySearch, true);
}
}
if (list.every(x => x.selected)) {
return this.deselectAll(list);
}
if (list.every(x => !x.selected) || list.some(x => x.selected)) {
return this.selectAll(list);
}
}
private selectAll(list: any[], isListFiltered: boolean = false) {
list.forEach(x => {
x.selected = true;
});
this.selectedElements = Array.from(new Set(list));
this.allSelected = isListFiltered ? false : true;
return { selected: this.selectedElements, allSelected: this.allSelected };
}
private deselectAll(list: any[]) {
list.forEach(x => {
x.selected = false;
});
this.selectedElements = [];
this.allSelected = false;
return { selected: this.selectedElements, allSelected: this.allSelected };
}
}
Value Converter
export class SearchValueConverter {
toView(array, config) {
if (!Boolean(array) || config.searchTerm === "") return array;
return array.filter(obj =>
this.isFound(config, obj)
);
}
private isFound(config: any, obj: any): Boolean {
let found = false;
for (let index = 0; index < config.columns.length; index++) {
const x = this.resolve(config.columns[index], obj);
if (x === undefined) continue;
if (typeof(x) === 'string') {
found = x.toLowerCase().includes(config.searchTerm.toLowerCase());
}
if (found) break;
}
return found;
}
private resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
}
3 Likes