Created
May 29, 2018 11:12
-
-
Save MatteoOreficeIT/0c5865848c24b8293c2d96d413dba4b6 to your computer and use it in GitHub Desktop.
Telerik Kendo grid checkbox mvvm binding to model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* La variabile $checkedField che vedi riferita arriva da una variabile lato server che contiene | |
* il nome della colonna da utilizzarsi per settare in automatico il campo del model sul checkbox click | |
* | |
* Puo anche valere null o false, in quel caso il valore Javascript deve corrispondere a null o false, per | |
* fare questo in php si usa il metodo json_encode | |
*/ | |
/** | |
* Determina quale e' la colonna tenuta in sync con la checkbox | |
* @type {string} | |
*/ | |
var // QUESTA ASSEGNAZIONE va convertita correttamente in .NET perche se checkedField == false|null | |
// dataBindCheckField deve essere == null o false | |
dataBindCheckField = '$checkedField' // oppure false/null | |
; | |
grid.one('dataBound', function __customEventAnd(e) { | |
var grid = e.sender, | |
CHECKBOXINPUT = 'td[data-role=rowselectcheckbox] input[data-role=checkbox]', | |
CLICK = 'click', | |
SELECTED = 'k-state-selected', | |
NS = '.hasrowselection', | |
// righe selezionate nello stato precedente | |
// contiene tutte le righe anche se e'presente | |
// la paginazione | |
selectedRows = {}, | |
multiple = $multiple; | |
/** | |
* Permette di salvare un elenco di model visualizzati durante la paginazione | |
* | |
* @param model | |
*/ | |
grid.setModelIdImpressions = function (model) { | |
this._bitiaModelIdImpressions = this._bitiaModelIdImpressions || {}; | |
this._bitiaModelIdImpressions[model[model.idField]] = true; | |
}; | |
/** | |
* Recupera le impressions dei model, in questo modo si puo sarepere | |
* quali model sono stati VISTI | |
* | |
* @returns {*|{}} | |
*/ | |
grid.getModelIdImpressions = function () { | |
return this._bitiaModelIdImpressions = this._bitiaModelIdImpressions || {}; | |
}; | |
if (dataBindCheckField) { | |
function setUserModelField(modelId, field, value) { | |
grid._bitiaModelsUserModifiedFields = grid._bitiaModelsUserModifiedFields || {}; | |
grid._bitiaModelsUserModifiedFields[modelId] = grid._bitiaModelsUserModifiedFields[modelId] || {}; | |
grid._bitiaModelsUserModifiedFields[modelId][field] = value; | |
} | |
// registra handler on click | |
grid.wrapper.on(CLICK + NS, 'tbody > tr ' + CHECKBOXINPUT, $.proxy(function (e) { | |
var that = this, | |
input = $(e.target); | |
row = input.closest('tr'), | |
uid = row.attr(kendo.attr('uid')), | |
checked = input.is(':checked'), | |
model = that.dataItem(row), | |
idField = model.idField, | |
idValue = model[idField] | |
; | |
if (!idField && console) { | |
throw new Error('Cannot save user selection, no model id has been assigned.'); | |
return false; | |
} | |
if (!idValue && console) { | |
throw new Error('Cannot save user selection, model id value is not valid.'); | |
return false; | |
} | |
if (!multiple) { | |
throw new Error('codice non testato ancora, testare e rimuovere questa eccezione'); | |
that._deselectCheckRows(that.select()); | |
} | |
// lancia evento, le righe selezionate si possono recuperare tramite selectedKeyNames() | |
that.trigger('selectrow', { | |
target: row[0], | |
checked: checked | |
}); | |
setUserModelField(idValue, dataBindCheckField, checked); | |
}, grid)); | |
} | |
}) | |
/** | |
* Questi eventi vengono agganciati solo se si vuole legate della checkbox al campo model in automatico | |
*/ | |
if(dataBindCheckField) { | |
grid.one('dataBound', function __closure(e) { | |
var grid = e.sender, | |
CHECKBOXINPUT = 'input[data-role=checkbox]', | |
CLICK = 'click', | |
NS = '.hasrowselection', | |
SELECTED = 'k-state-selected'; | |
if (!grid.getOptions().persistSelection) { | |
throw new Error('HasRowSelection need persistSelection must be set on current grid.'); | |
} | |
// Al click su checkAll tiene allineato il campo sui models | |
// sfrutta codice Telerik per intrappolare click su checkbox in header | |
// @see kendo.web.js:55049 (v2017.3.1026) | |
grid.wrapper.on(CLICK + NS, 'thead > tr ' + CHECKBOXINPUT, $.proxy(function (e) { | |
var that = this, | |
row = $(e.target).closest('tr'), | |
isChecking = $(e.target).is(':checked') | |
; | |
// controlla che il click sia sulla stessa grid | |
if (that !== kendo.widgetInstance(row.closest('.k-grid.k-widget'))) { | |
return; | |
} | |
// per ogni item sulla pagina caricata aggiorna il flag | |
$.each(that.dataSource.view(), function (i, dataItem) { | |
if (dataItem.get('$checkedField') != isChecking) { | |
// se usassimo set verrebbero scatenati N eventi change uno per ogni | |
// model, quindi e' preferibile fare aggiornare la grid solo alla fine | |
// di tutti i set | |
this._set('$checkedField', isChecking); | |
this.dirty = true; | |
this.dirtyFields['$checkedField'] = true; | |
} | |
}); | |
// aggiorna eventuali altri campi dipendenti | |
that.refresh(); | |
}, grid)); | |
}) | |
grid.bind('dataBound', function _mvvmRebind(e) { | |
var grid = e.sender, | |
count = 0, | |
SELECTED = 'k-state-selected', | |
CHECKBOXINPUT = 'input[data-role=checkbox]', | |
checked = []; | |
grid.items().each(function () { | |
var dataItem = e.sender.dataItem(this); | |
var checkbox = $(this).find('td[data-role=rowselectcheckbox] ' + CHECKBOXINPUT).attr('data-bind', 'checked: $checkedField'); | |
// fa il bind solo nella TD per evitare che altri campi vengano legati | |
kendo.bind(checkbox.closest('td'), dataItem); | |
// se campo sul model e' true aggiunge la classe selezionato | |
// poiche MVVM allinea input e non il TR padre | |
if (dataItem.get('$checkedField')) { | |
$(this).addClass(SELECTED); | |
count++; | |
// checked.push(this); | |
} | |
else { | |
$(this).removeClass(SELECTED); | |
} | |
// grid.select(checked); | |
// questo garantisce che se tutti sono selezionati verra marcato il checkAll | |
grid._persistSelectedRows(); | |
// salva le impressions dei modelli al fine di conoscere esattamente | |
// gli id dei modelli che sono stati caricati, utile per effettuare | |
// cancellazioni parziali | |
grid.setModelIdImpressions(dataItem); | |
}); | |
// ripristina la spunta checkAll poiche' se tutte sono selezionate | |
// il binding MVVM non simula un click utente. | |
grid.thead.add(grid.lockedHeader).find(CHECKBOXINPUT).prop('checked', count == grid.items().length); | |
}); | |
grid.bind('dataBound', function _restoreUserChoices(e) { | |
// evita un loop di dataBound dopo i set compiuti nel ciclo sottostante | |
if (_restoreUserChoices.refreshInProgress) { | |
_restoreUserChoices.refreshInProgress = false; | |
return; | |
} | |
// solo se arrivo da una pagina precedente | |
if (typeof (_restoreUserChoices.previousPage) != 'undefined' && | |
_restoreUserChoices.previousPage !== e.sender.dataSource.page()) { | |
var selectedKeys = e.sender._bitiaModelsUserModifiedFields, | |
checkedField = '$checkedField', | |
CHECKBOXINPUT = 'td[data-role=rowselectcheckbox] input[data-role=checkbox]', | |
SELECTED = 'k-state-selected'; | |
// per ogni model in pagina ripristino la colonna | |
$.each(e.sender.dataSource.view(), function (idx, item) { | |
if (item && selectedKeys && item.idField && item[item.idField] && | |
typeof (selectedKeys[item[item.idField]]) != 'undefined' && | |
typeof (selectedKeys[item[item.idField]][checkedField]) != 'undefined') { | |
var checked = selectedKeys && selectedKeys[item[item.idField]][checkedField] ? true : false; | |
// evita un databound per ogni set | |
if (item.get(checkedField) != checked) { | |
item._set(checkedField, checked); | |
item.dirty = true; | |
item.dirtyFields[checkedField] = true; | |
} | |
} | |
}); | |
_restoreUserChoices.refreshInProgress = true; | |
e.sender.refresh(); | |
} | |
_restoreUserChoices.previousPage = e.sender.dataSource.page(); | |
}); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment