Why is my grid calling "CreateFooBar" for every row of data when delete and update are submitted? It's probably something stupid but I can't see it.
@(Html.Kendo()
.Grid<FooBarViewModel>()
.Name("FooBarGrid")
.Sortable()
.Scrollable()
.Filterable()
.Resizable(g => g.Columns(true))
.Columns(columns =>
{
columns.Command(command =>
{
command.Edit();
command.Destroy();
}).Width(150);
columns.Bound(g => g.Id).Hidden();
columns.Bound(g => g.Name).Title("Name").Width(200);
columns.Bound(g => g.FooBarNumber).Title("FooBar<br />Number").Width(200);
columns.Bound(g => g.CreatedBy).Width(100).Title("Created By");
columns.Bound(g => g.CreatedDate).Width(100).Title("Created Dt");
columns.Bound(g => g.ModifiedBy).Title("Modified By").Width(100);
columns.Bound(g => g.ModifiedDate).Width(100).Title("Modified Dt");
})
.DataSource(dataSource => dataSource.Ajax()
.Model(model =>
{
model.Id(m => m.Id);
model.Field(p => p.CreatedBy).Editable(false);
model.Field(p => p.CreatedDate).Editable(false);
model.Field(p => p.ModifiedDate).Editable(false);
model.Field(p => p.ModifiedBy).Editable(false);
})
.Batch(false)
.PageSize(25)
.ServerOperation(false)
.Read(read => read.Action("GetFooBars", "FooBar"))
.Create(update => update.Action("CreateFooBar", "FooBar"))
.Update(update => update.Action("UpdateFooBar", "FooBar"))
.Destroy(update => update.Action("DeleteFooBar", "FooBar"))
.Events(ev => ev.RequestEnd("onSave"))
.Events(events => { events.Error("onError"); })
)
.ClientDetailTemplateId("collectionTemplate")
.Events(ev => ev.Edit("onEdit"))
.ToolBar(toolbar =>
{
toolbar.Create().Text("Add FooBar");
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable(pager => pager
.Input(true)
.Numeric(true)
.Info(true)
.PreviousNext(true)
.Refresh(true)
.PageSizes(new int[5] { 25, 50, 100, 200, 500 })
)
.ColumnMenu()
)
I'm having an issue with Kendo Grid in Angular where the custom drop down I've implemented will not open when tab navigating to that column. The built in text and number editor fields are editable on tab navigation but my custom drop down will not expand. I have to click on it to get the drop down effect.
My goal here is to allow the user to log an an entire row of data without having to take their hands off the keyboard.
My column is defined like so:
gridColumns.push({ field: currentField.FieldName.replace(/ /g, "_"), title: currentField.FieldName, editor: $scope.dropDownAttEditor, template: function (dataItem) { return $scope.dropDownTemplate(dataItem, currentField.FieldName); }});
My gridOptions are defined as follows:
$scope.gridOptions = { dataSource: new kendo.data.DataSource({ transport: { read: { url: appconfig.basePath + '/api/DrillHoleManager/DrillHoleInterval', type: 'POST', contentType: 'application/json' }, update: { url: appconfig.basePath + '/api/DrillHoleManager/DrillHoleIntervalUpdate', type: 'POST', contentType: 'application/json' }, parameterMap: function (data, operation) { if (operation === "read") { data.DrillHoleId = $scope.entity.Id; data.DrillHoleIntervalTypeId = $stateParams.ddhinttypeid; // convert the parameters to a json object return kendo.stringify(data); } if (operation === 'update') { // build DrillHoleIntervalDto object with all ATT/CMT values to send back to server var drillHoleInterval = { Id: data.Id, Name: data.Name, From: data.From, To: data.To }; drillHoleInterval.Attributes = []; drillHoleInterval.Comments = []; var attributeFields = $.grep($scope.currentFields, function (e) { return e.DrillHoleTabFieldType == DrillHoleTabFieldTypeEnum.IntervalAttribute }); $.each(attributeFields, function (idx, attributeField) { drillHoleInterval.Attributes.push({ Id: attributeField.AttributeDto.Id, LookupId: data[attributeField.FieldName.replace(/ /g, "_")] }); }); var commentFields = $.grep($scope.currentFields, function (e) { return e.DrillHoleTabFieldType == DrillHoleTabFieldTypeEnum.IntervalComment }); $.each(commentFields, function (idx, commentField) { drillHoleInterval.Comments.push({ Id: commentField.CommentDto.Id, Value: ((data[commentField.FieldName.replace(/ /g, "_")] != "") ? data[commentField.FieldName.replace(/ /g, "_")] : null) }); }); return kendo.stringify(drillHoleInterval); } // ALWAYS return options return options; } }, schema: { model: { id : "Id" }}, serverPaging: false, serverSorting: false, serverFiltering: false //,autoSync: true }), columns: gridColumns, dataBound: onDataBound, autoBind: false, navigatable: true, scrollable: false, editable: true, selectable: true, edit: function (e) { var grid = $("#ddhintgrid").data("kendoGrid"); //grid.clearSelection(); grid.select().removeClass('k-state-selected'); // select the row currently being edited $('[data-uid=' + e.model.uid + ']').addClass('k-state-selected'); e.container[0].focus(); } };
$("#ddhintgrid").keydown(function (e) { if (e.key == "Tab") { var grid = $("#ddhintgrid").data("kendoGrid"); var data = grid.dataSource.data(); var selectedItem = grid.dataItem(grid.select()); var selectedIndex = null if (selectedItem != null) { selectedIndex = grid.select()[0].sectionRowIndex; if (selectedIndex == data.length - 1) { // if the bottom record is selected // We need to manually add a new record here so that the new row will automatically gain focus. // Using $scope.addRecord() here will add the new row but cause the grid to lose focus. var newRecord = { From: grid.dataSource.data()[selectedIndex].To }; var currentCmtFields = $.grep($scope.currentFields, function (e) { return e.DrillHoleTabFieldType == DrillHoleTabFieldTypeEnum.IntervalComment; }); $.each(currentCmtFields, function (idx, currentCmtField) { newRecord[currentCmtField.FieldName.replace(/ /g, "_")] = null; }); grid.dataSource.insert(data.length, newRecord); // edit the new row grid.editRow($("#ddhintgrid tr:eq(" + (data.length) + ")")); } } } });Here is my template for the drop down column:
$scope.dropDownTemplate = function (dataItem, fieldName) { var currentLookups = $.grep($scope.currentFields, function (e) { return e.FieldName == fieldName; })[0].AttributeDto.Lookups; var selectedLookup = $.grep(currentLookups, function (e) { return e.Id == dataItem[fieldName.replace(/ /g, "_")]; })[0]; // With the custom dropdown editor when going from null to a value the entire lookup object (id, name) is placed in the // dataItem[field_name] instead of just the id. We need to replace this object with just the id value and return the name of // the lookup to the template. if (typeof selectedLookup == 'undefined' && dataItem[fieldName.replace(/ /g, "_")] != null) { selectedLookup = angular.copy(dataItem[fieldName.replace(/ /g, "_")]); dataItem[fieldName.replace(/ /g, "_")] = selectedLookup.Id; } if (selectedLookup != null && selectedLookup != '') { return selectedLookup.Name; } else { return ''; }};And finally here is the custom editor for the drop down column:
$scope.dropDownAttEditor = function (container, options) { var editor = $('<input k-data-text-field="\'Name\'" k-data-value-field="\'Id\'" k-data-source="ddlDataSource" data-bind="value:' + options.field + '"/>') .appendTo(container).kendoDropDownList({ dataSource: $.grep($scope.currentFields, function (e) { return e.FieldName == options.field.replace(/_/g, ' '); })[0].AttributeDto.Lookups, dataTextField: "Name", dataValueField: "Id" });};I know this is a lot to take in but if you have any questions just let me know.
My ultimate goal is that I want the user to be able to navigate the grid using the 'Tab' key and edit every field without having to use the mouse.
Hey there, I have a panel bar that can have multiple items. I use the select method to do a bunch of code work. I know want to implement an unsaved changes warning on the page so I need to implement a way to stop the panelbar from expanding or collapsing.
I know I can do it from the expand and collapse events - I have tested this and it works great (e.preventDefault()). However since I have all of my coding within the select event and I have other actions that sometimes expand and collapse the panels dynamically I would like the ability to stop the panelbar from expanding and collapsing from the select event. Is that possible? I do see that the select event fires first.
Thanks,
Coty
I'm trying to do a multi checkbox filter in my grid, but something is going wrong and i don't know what, here is my grid configuration.
PS: in $scope.data i have all the data i need
function createGrid() { jQuery("#grid").kendoGrid({ columns: [ { field: "id", title: "ID", menu: false, filterable: { dataSource: $scope.data } }, { field: "invoiceCode", title: "CÓDIGO", width: '180px', filterable: { dataSource: $scope.data } }, { field: "operationCode", title: "COD OPERAÇÃO", width: '200px', filterable: { dataSource: $scope.data } }, { title: 'Tipo', field: "tipoContrato", filterable: { multi: true, dataSource: $scope.data }, width: '120px' }, { field: "contraparteName", title: "NOME EMPRESA", width: '150px', filterable: { dataSource: $scope.data } }, { field: "contraparteCode", title: "RAZÃO SOCIAL", width: '8%', filterable: { dataSource: $scope.data } }, { field: "contraparteCnpj", title: "CNPJ", width: '190px', filterable: { dataSource: $scope.data } }, { field: "nomeContrato", title: "NOME CONTRATO", width: '250px', filterable: { dataSource: $scope.data } }, { field: "energiaRef", title: "QTD. ENERGIA", width: "150px", filterable: { dataSource: $scope.data } }, { field: "preco", title: "PREÇO ENERGIA", width: "150px", filterable: { dataSource: $scope.data } }, { field: "custoEnergia", title: "TOTAL", width: "150px", filterable: { dataSource: $scope.data } }, { field: "statusEnergia", title: "STATUS QTD.", width: "190px", filterable: { dataSource: $scope.data } }, { field: "statusPreco", title: "STATUS PREÇO", width: "190px", filterable: { dataSource: $scope.data } }, { field: "statusGeral", title: "STATUS GERAL", width: "190px", filterable: { dataSource: $scope.data } }, { field: "ciclo", title: "DATA BASE", width: "190px", type: "date", format: "{0:dd/MM/yyyy}", filterable: { dataSource: $scope.data } }, { field: "vencimento", title: "DATA VENCIMENTO", width: "190px", type: "date", format: "{0:dd/MM/yyyy}", filterable: { dataSource: $scope.data } }, { field: "percent", title: "PROCENTAGEM", width: "190px", filterable: { dataSource: $scope.data } }, { field: "statusPagamento", title: "PAGA", width: "190px", filterable: { dataSource: $scope.data } }, { field: "created", title: "CADASTRO", width: "190px", type: "date", format: "{0:dd/MM/yyyy}", filterable: { dataSource: $scope.data } } ], dataSource: { transport: { read: function(options){ var today = new Date(); var mm = today.getMonth()+1; var yy = today.getFullYear(); var date = yy + '-' + mm; var query = { "Options": { "order": [ {"field": "supplyDate"}, {"field": "dInvoiceGroupId"}, {"field": "baseDate"} ], "limit": 20, "page": 1 }, "Criteria": {"baseDate": date} }; query.Options.page = options.data.page; query.Options.limit = options.data.pageSize; if(typeof options.data.sort !== "undefined" && options.data.sort !== null) { for(var i = 0; i< options.data.sort.length; i++) { if(options.data.sort[i].field == "parentName"){ options.data.sort[i].field = "Parent.name" } if(options.data.sort[i].dir === "desc") { query.Options.order = [{ "direction": "descending", "field": options.data.sort[i].field }]; }else { query.Options.order = [{ "direction": "ascending", "field": options.data.sort[i].field }]; } } } var criteria = $scope.buildCriteria(options.data.filter); if(typeof criteria != 'undefined'){ query.Criteria = criteria; } Api.get("Invoices", query, 'gridList').then(function (data) { options.success(data); }, function () { PopupManager.notice(headerPopupManager, bodyPopupManager); }); } }, schema: { data: function(response){ return response.Data; }, model: { fields: { code: {type: "string"}, operationCode: {type: "string"}, invoiceType: {type: "string"}, companyName: {type: "string"}, razaoSocial: {type: "string"}, companyCnpj: {type: "string"}, operationName: {type: "string"}, energiaRef: { type: "number" }, preco: { type: "number" }, custoEnergia: { type: "number" }, qttStatus: {type: "string"}, priceStatus: {type: "string"}, generalStatus: {type: "string"}, ciclo: {type: "date"}, vencimento: {type: "string"}, percent: {type: "string"}, statusPagamento: {type: "string"}, created: {type: "date"} } }, total: function(response) { if(typeof response.MetaData.PaginationInfo != 'undefined'){ return response.MetaData.PaginationInfo.total; } return 0; } }, serverPaging: true, serverFiltering: true, serverSorting: true }, editable: true, reorderable: true, resizable: true, sortable: true, selectable: "multiple", columnMenu: true, filterable: true, pageable: { pageSize: 20, refresh: true, pageSizes: true, buttonCount: 5 } }); }I'm using TypeScript and the this object inside the upload event is the instance of the kendoupload, not the angular controller.
To get at a value on the controller, I'm currently using this.$angular_scope.vm.datavariable but is this the best way to access controller variables within the upload event?
Hi all,
These is an error when I'm trying to Ioad my Kendo Grid, with dynamic data, so i'm doing something very wrong!? - i'm getting a invalid "template Error" (I'm not using templates as i see it?)
Error: Invalid template:'
<tr data-uid="#=data.uid#" role='row'>
<td role='gridcell'>#:data.Code==null?'':data.Code#</td>
<td role='gridcell'>#:data.Name==null?'':data.Name#</td>
<td role='gridcell'>#:data.319==null?'':data.319#</td>
<td role='gridcell'>#:data.383==null?'':data.383#</td>
<td role='gridcell'>#:data.394==null?'':data.394#</td>
<td role='gridcell'>#:data.396==null?'':data.396#</td>
<td role='gridcell'>#:data.398==null?'':data.398#</td>
<td role='gridcell'>#:data.466==null?'':data.466#</td>
<td role='gridcell'>#:data.147==null?'':data.147#</td>
<td role='gridcell'>#:data.149==null?'':data.149#</td>
<td role='gridcell'>#:data.150==null?'':data.150#</td>
<td role='gridcell'>#:data.148==null?'':data.148#</td>
<td role='gridcell'>#:data.143==null?'':data.143#</td>
<td role='gridcell'>#:data.421==null?'':data.421#</td>
</tr>
' Generated code:'var o,e=kendo.htmlEncode;with(data){o='
<tr data-uid="'+(data.uid)+'" role=\'row\'>
<td role=\'gridcell\'>'+e(data.Code==null?'':data.Code)+'</td>
<td role=\'gridcell\'>'+e(data.Name==null?'':data.Name)+'</td>
<td role=\'gridcell\'>'+e(data.319==null?'':data.319)+'</td>
<td role=\'gridcell\'>'+e(data.383==null?'':data.383)+'</td>
<td role=\'gridcell\'>'+e(data.394==null?'':data.394)+'</td>
<td role=\'gridcell\'>'+e(data.396==null?'':data.396)+'</td>
<td role=\'gridcell\'>'+e(data.398==null?'':data.398)+'</td>
<td role=\'gridcell\'>'+e(data.466==null?'':data.466)+'</td>
<td role=\'gridcell\'>'+e(data.147==null?'':data.147)+'</td>
<td role=\'gridcell\'>'+e(data.149==null?'':data.149)+'</td>
<td role=\'gridcell\'>'+e(data.150==null?'':data.150)+'</td>
<td role=\'gridcell\'>'+e(data.148==null?'':data.148)+'</td>
<td role=\'gridcell\'>'+e(data.143==null?'':data.143)+'</td>
<td role=\'gridcell\'>'+e(data.421==null?'':data.421)+'</td>
</tr>
';}return o;'
I have tryed to simplify my grid, but still same error.., -The key elements of the code looks like this:
in script;
kendo.destroy($('#objects_search_grid'));
$('#objects_search_grid').kendoGrid({
dataSource: new kendo.data.DataSource(gridListJson),
groupable: true,
columnMenu: true,
filterable: true,
columns: col,
});
var gridListJson = JSON.stringify(objlist);
gridListJson =
[{"143":"test 23","147":"I60","148":"A1","149":"","150":"s2","319":"","383":"","394":"","396":"","398":"","421":"","466":"","Code":"TEST","Name":"TEST"},{"143":"","147":"","148":"","149":"","150":"","319":"","383":"","394":"","396":"","398":"10.000","421":"","466":"","Code":"TEST","Name":"TEST"},{"143":"","147":"","148":"","149":"","150":"","319":"","383":"","394":"CCS Del af produkt","396":"2","398":"","421":"Projectspine.com her finder du også et link bips.dk","466":"Primære bygningsdele","Code":"TEST","Name":"TEST"}]
This is how I make my Columns(col) dynamic -> I use id as 'field' and name as 'title' -> The grid shows the column titles correct before failure. So the grid only shows the titles after loading the page.
// First 2 columns are hardcoded - then rest is looped into column objects
var col = [{ field: "Code", title: "Code", hidden: false }, { field: "Name", title: "Name", hidden: false }];
for (var i = 0; i < data.propertyItems.length; i++) {
var coldata = {};
coldata["field"] = data.propertyItems[i].Key;
coldata["title"] = data.propNames[data.propertyItems[i].Key].trim();
coldata["hidden"] = false;
col.push(coldata);
}
Any help is appreciated thanks.
Cheers
/Martin
Hi,
Attached is a file called Unresponsive grid, which shows the result of the code below. As you can see, the text in the Fp column is too long for that column and runs off the screen. Is there a way to make the grid more responsive, for example, locking the first column so that a horizontal scroll bar appears to scroll across the subsequent columns like in the file, responsive grid.
<div class="row " style="max-width: 98%">
<div class="columns">
<div class="full-width">
@(Html.Kendo().Grid<EPP.AdminPortal.ViewModels.Test>()
.Name("grid")
.HtmlAttributes(new { style = "table-layout: fixed, height: 550px;" })
.Columns(columns =>
{
columns.Bound(c => c.Id).Width(1000);
columns.Bound(c => c.Name).Width(2000);
columns.Bound(c => c.Email).Width(5000);
columns.Bound(c => c.Ap).Width(5000);
columns.Bound(c => c.Bp).Width(5000);
columns.Bound(c => c.Cp).Width(5000);
columns.Bound(c => c.Dp).Width(5000);
columns.Bound(c => c.Ep).Width(5000);
columns.Bound(c => c.Fp).Width(200);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("T_Read", "Test"))
)
//.Groupable()
.Sortable()
)
</div>
</div>
</div>