this is template of my component sortable-table-checkbox.hbs
<table class="table table-checkbox" data-page-length="{{dataPageLength}}">
<thead>
<tr>
<th> </th>
{{#each-in columns as |prop value| }}
<th
class="{{if (or (eq (get sortingStatus prop) '')
(eq (get sortingStatus prop) 'asc')
(eq (get sortingStatus prop) 'desc')) 'sorting'}} w25p {{get sortingStatus prop}}"
{{action 'toggleSorting' prop}}>
{{#if value.title}}
{{value.title}}
{{else}}
{{value}}
{{/if}}
</th>
{{/each-in}}
</tr>
</thead>
<tbody>
{{#each data as |item|}}
<tr>
<td>
<div class="">
{{input
type='checkbox'
checked=item.checked
change=(action 'chooseItem' item)}}
</div>
</td>
{{#each-in columns as |prop value| }}
<td>
{{#collection- value=(get item prop) field=value.field as |col|}}
{{#number-format isNumber=(eq value.type 'number') value=col as |val|}}
{{#if value.linkable}}
{{#link-to value.linkable.route (get item value.linkable.paramField)}}
{{value.prefix}}
{{val}}
{{/link-to}}
{{else}}
{{value.prefix}}
{{val}}
{{/if}}
{{/number-format}}
{{/collection-}}
</td>
{{/each-in}}
</tr>
{{/each}}
</tbody>
</table>
<p>Your Selected Items:</p>
<ul>
{{#each selectedItems as |item|}}
<li>{{item.title}}</li>
{{else}}
<em>No items selected</em>
{{/each}}
</ul>
{{checked}}
{{yield}}
this is my component sortable-table-checkbox.js
import Ember from 'ember';
/**
* Table component
*
* Allows to render dynamic tables with sorting where items are displayed as
* checkboxes
*
* Header titles of table should passed as ``columns`` arg to the component.
*
* columns: {
* title: {
* title: 'Game Title',
* sorting: 'title',
* linkable: {
* route: 'home.cabinet.developer.games.game',
* paramField: 'game_uid',
* },
* },
* genres: {
* title: 'Genre',
* },
* amount: {
* title: 'Ad Revenue Earned',
* prefix: '$',
* type: 'number',
* sorting: 'amount'
* },
* platforms_data: {
* title: 'Platform',
* collection: true,
* field: 'title',
* },
* ages_data: {
* title: 'Ages',
* collection: true,
* field: 'value',
* },
* },
*
* Example of using of this component
*
* {{sortable-table data=model.games.results columns=columns sorting=sorting}}
*
* @class SortingTableComponent
* @module components/sortable-table
* @extends Ember.Component
* @public
*/
export default Ember.Component.extend({
/**
* Sorting status
*
* @property sortingStatus
* @type {Object}
* @default null
* @public
*/
sortingStatus: null,
/**
* Avoid sharing state between components
*
* @method init
* @return {undefined}
* @public
*/
init() {
this._super(...arguments);
this.set('sortingStatus', {});
this.selectedItems = [];
this.checked=false;
},
/**
* Fill ``sortingStatus`` object with reset statuses
*
* @method willInsertElement
* @return {undefined}
* @public
*/
willInsertElement() {
const columns = this.get('columns');
for (const element in columns) {
if (columns[element].sorting) {
this.set(`sortingStatus.${element}`, '');
}
}
},
actions: {
/**
* Toggle sorting
*
* @method toggleSorting
* @param prop {String} name of property
* @return {boolean} false if this property doesn't exist in ``sorting`` object
* @public
*/
toggleSorting(prop) {
// If ``prop`` property doesn't exist in ``sorting`` object, return false
if (!(prop in this.get('sortingStatus'))) {
return false;
}
// Reset another properties sorting state
for (const element in this.get('sortingStatus')) {
if (element !== prop) {
this.set(`sortingStatus.${element}`, '');
}
}
// Set asc if starting state, desc if asc and starting state if desc
if (this.get(`sortingStatus.${prop}`) === '') {
this.set(`sortingStatus.${prop}`, 'asc');
} else if (this.get(`sortingStatus.${prop}`) === 'asc') {
this.set(`sortingStatus.${prop}`, 'desc');
} else {
this.set(`sortingStatus.${prop}`, '');
}
// Sending action
this.sendAction('action', this.get(`columns.${prop}.sorting`), this.get(`sortingStatus.${prop}`));
return true;
},
chooseItem(item, e) {
const added = e.target.checked;
this.set('checked', added);
if (added) {
item.checked=true;
this.get('selectedItems').pushObject(item);
}
else {
this.get('selectedItems').removeObject(item);
}
},
},
});
So when I navigate through pages app does API call querying next 5 items to be displayed, when I come back to page #1 I have no item.checked status - as an item is a new object that came from API call, therefore it doesn't have .checked property that I set inside chooseItem action.
Maybe there is a dynamic way to check if checked property of checkbox can be set?
These changes are not saved because you don't save the model with proper checked field on backend. I suggest two ways of dynamically calculating the checked state of checkbox:
{{input type='checkbox' checked=(array-contains selectedItems item.id property='id') change=(action 'chooseItem' item)}}
table-row
and move there everything you have in <tr></tr>
in sortable-table-checkbox.hbs. The component will have item
and selectedItems
as parameters. Then you can use Ember computed properties://table-row.js // ... isChecked: Ember.computed('item.id', 'selectedItems.length', function() { const itemId = this.get('item.id'); const selectedItems = this.get('selectedItems'); return selectedItems.some(el => el.get('id') === itemId); }) // ...
//table-row.hbs {{input type='checkbox' checked=isChecked change=(action 'chooseItem' item)}}