asp.net mvc - Kendo Grid multi column group based on object array -
i relatively new mvc
(and kendo
) have managed setup grid contains multi column headers using columns.group
functionality.
@(html.kendo().grid<result>() .name("mygrid") .columns(columns => { columns.bound(c => c.resultdatetime).title("date time"); foreach (lot lot in (lot[])viewbag.lots) { columns.group(group => group .title(lot.lotnumber) .columns(info => { info.bound(lot.result.count.tostring()); info.bound(lot.result.mean.tostring()); info.bound(lot.result.sd.tostring()); })); } columns.bound(c => c.standardcomment.description).title("comment"); columns.bound(c => c.reviewcomment.description).title("review comment"); columns.command(command => { command.destroy(); }); }) .editable(editable => editable .mode(grideditmode.inline) .displaydeleteconfirmation(true)) .pageable() .navigatable() .sortable() .groupable() .scrollable() .datasource(datasource => datasource .ajax() .batch(true) .pagesize(20) .serveroperation(false) .events(events => events.error("error_handler")) .read("resultsasync_read", "resultentry") .destroy("resultsasync_destroy", "resultentry") ) )
as can see trying build columns dynamically based on array has been setup , passed using viewbag
.
controller async function sets viewbag.lots
extracting array top level ienumerable<result>
object:
public async task<actionresult> resultsasync_read([datasourcerequest]datasourcerequest request) { ienumerable<result> controlsets = await _manager.readasync(test); viewbag.lots = controlsets.select(x => x.lotresults); return json(controlsets.todatasourceresult(request)); }
when run this, following error when trying access viewbag.lots
attribute in foreach
.
nullreferenceexception: object reference not set instance of object.
does know why getting error , if there more efficient way achieve goal?
edit: instead of using viewbag hold list of lot
objects, using hold maximum number of lots available in entire list<result>
s. have taken @ken2k's advice onboard , done within index()
function of controller:
public async task<iactionresult> index() { qctest test = new models.acusera.qctest(); test.testid = 3; ienumerable<result> controlsets = await _manager.readasync(test); viewbag.maxlots = controlsets.max(x => x.lotresults.count); return view("~/views/acusera/dataentry/resultentry.cshtml"); }
then loop on maximum number of lots available , create columns required:
.columns(columns => { columns.bound(c => c.resultdatetime).title("date time"); (int = 0; < viewbag.maxlots; ++i) { columns.group(group => group .title("test") .columns(info => { info.bound(x => x.lotresults[i].result.count); info.bound(x => x.lotresults[i].result.mean); info.bound(x => x.lotresults[i].result.sd); })); } columns.bound(c => c.standardcomment.description).title("comment"); columns.bound(c => c.reviewcomment.description).title("review comment"); columns.command(command => { command.destroy(); }); })
this results in grid displaying so:
so have managed create number of multi-header columns required display data. however, getting error:
uncaught typeerror: cannot read property 'result' of undefined
your resultsasync_read
method async method called kendo framework javascript ajax call, i.e. after page has been loaded , rendered.
this means when page rendered, viewbag.lots
null, throw exception.
what need initialize value when load page, not inside resultsasync_read
method. basically:
public async task<actionresult> index() { // gets values before rendering view ienumerable<result> controlsets = await _manager.readasync(test); // viewbag property available razor view viewbag.lots = controlsets.select(x => x.lotresults); // returns view display grid return this.view(); }
it's important remember how mvc stuff works. steps are:
- the server receives request on .../index route
- the server executes index() action
- as action returns this.view() (which equivalent this.view("index")), renders index.cshtml razor view (that means viewbag must not null here)
- if later ajax calls such
resultsasync_read
, changing viewbag won't have effect page rendered. thing modify page, return json, , change dom based on json result from inside ajax callback (i.e. using jquery/javascript).
Comments
Post a Comment