<div id=
"evaluationlists"
data-role=
"grid"
date-scrollable=
"true"
data-editable=
"false"
data-columns="[
{field:
'DisplayId'
, title:
'Id'
},
{field:
'Name'
, title:
'Name'
},
{field:
'Evaluatee'
, title:
'Evaluating'
},
{field:
'ParentName'
, title:
'Curricular Entity'
},
{field:
'DateRange'
, title:
'Open'
},
{command:{ text:
'Open Action'
, click: openAction, name:
'openAction'
} }
]"
data-bind=
"source: evaluations, visible:isVisible"
>
</div>
var
vm = kendo.observable({
isVisible:
true
,
openAction:
function
(e) {
window.console && console.log(e);
},
evaluations:
new
kendo.data.DataSource({
schema: {
data:
"Data"
,
model: {
id:
"Id"
}
},
transport: {
read: {
url:
"@Url.Action(Model.ActionMethod, "
Home
")"
,
type:
"get"
,
contentType:
"application/json"
}
}
})
});
kendo.bind($(
'#evaluationlists'
), vm);
I am using in-cell editing in the Kendo grid. I need to call the service layer for each record to determine whether it is editable. Therefore when the change event is received, I call the service layer for the selected records(). When the service layer result arrives, if it indicates not editable then I use grid.closeCell to prevent editing. When the edit event is received, I check if the previously received result indicates not editable, and if so then I use grid.closeCell to close the cell. (I am saving the service layer result by record ID so that I only need to call the service the first time a row is clicked.)
However I have a synchronization problem. The first time a row is clicked, the cell opens for editing, because the service layer result has not been received yet. If the row is not editable, then the cell closes when the service result is received. This is not good, as the user might think the cell is editable and start to edit the cell before it closes.
I would like to prevent the cell from opening in edit mode when it is clicked the first time, but I'm not sure how to do this. I tried modifying the change event actions by calling grid.closeCell before making the service layer call, but I'm not sure how to open the cell back up when I get back a result indicating that the row is editable. I thought I could use editCell, but that requires the jQuery of the cell. Since I get the result back under the change event, how do I know at that point which cell was clicked?
An existing MSSQL Stored Procedure that updates records in the current application I'm building a new version of returns a totally different set of fields which then try to populate the grid the Datasource is bound to.
My current solution is to call this.read() on the Datasource sync event which usually handles it well enough but there are instances where is a hiccup in the process (e.g., network or page rendering) results in the grid showing various mismatched column values, if only briefly.
One possibility I thought of was to use schema.parse and if it sees one of the fields only returned by the UPDATE call then null the whole response, hopefully preventing the grid from trying to populate with the mismatched data.
Any other ideas? Am I overlooking a simple & elegant solution?
Hello!
I've just update dialog module to fix dialogservice issues, but now modals are not centered.
How can I fix?
Thank's!!
Hello. I'm using Kendo UI ASP.NET. I have a grid with 2 dropdowns. The first dropdown is not virtualized, the second one is (and also cascades off the first dropdown). All of this works.
I need to be able to quickly tab through all columns and rows in the grid using only the keyboard. If the 2nd dropdown gets focus and the current value isn't yet loaded in the virtualized dropdown, I get stopped with a client-side "This value is required" error message. I would like to know what the best strategy is to force the 2nd dropdown to navigate to the dropdown entry (in psuedocode, .select() to the virtualized, non-loaded entry) associated with its current value even when that entry is not yet loaded because of virtualization when that 2nd dropdown receives focus.
Thanks,
Richard
Hi,
Instead of having an edit button for each individual button, I want to have 1 Edit button at the bottom of the grid that will fire only after changes have been made to all editable columns. Is there a way to do this in Angular 2? I don't want the user to have to click Edit for each row, make changes and then move to the next row, click edit and make changes again. This is what my app.component.ts file looks like
import { Observable } from 'rxjs/Rx';
import { Component, OnInit, Inject } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { GridDataResult } from '@progress/kendo-angular-grid';
import { State, process } from '@progress/kendo-data-query';
import { Product } from './model';
import { EditService } from './edit.service';
@Component({
selector: 'my-app',
template: `
<kendo-grid
[data]="view | async"
[height]="533"
[pageSize]="gridState.take" [skip]="gridState.skip" [sort]="gridState.sort"
[pageable]="true" [sortable]="true"
[selectable]="true"
(dataStateChange)="onStateChange($event)"
(edit)="editHandler($event)" (cancel)="cancelHandler($event)"
(save)="saveHandler($event)" (remove)="removeHandler($event)"
(add)="addHandler($event)"
>
<!--<ng-template kendoGridToolbarTemplate>
<button kendoGridAddCommand>Add new</button>
</ng-template> -->
<kendo-grid-column field="ProductName" title="Product Name" [editable]="false"></kendo-grid-column>
<kendo-grid-column field="UnitPrice" editor="numeric" title="Price"></kendo-grid-column>
<kendo-grid-column field="Discontinued" editor="boolean" title="Discontinued"></kendo-grid-column>
<kendo-grid-column field="UnitsInStock" editor="numeric" title="Units In Stock" [editable]="false"></kendo-grid-column>
<kendo-grid-command-column title="command" width="220">
<ng-template kendoGridCellTemplate let-isNew="isNew">
<button kendoGridEditCommand class="k-primary">Edit</button>
<button kendoGridRemoveCommand>Remove</button>
<button kendoGridSaveCommand [disabled]="formGroup?.invalid">{{ isNew ? 'Add' : 'Update' }}</button>
<button kendoGridCancelCommand>{{ isNew ? 'Discard changes' : 'Cancel' }}</button>
</ng-template>
</kendo-grid-command-column>
</kendo-grid>
`
})
export class AppComponent implements OnInit {
public view: Observable<GridDataResult>;
public gridState: State = {
sort: [],
skip: 0,
take: 10
};
public formGroup: FormGroup;
private editService: EditService;
private editedRowIndex: number;
constructor( @Inject(EditService) editServiceFactory: any) {
this.editService = editServiceFactory();
}
public ngOnInit(): void {
this.view = this.editService.map(data => process(data, this.gridState));
this.editService.read();
}
public onStateChange(state: State) {
this.gridState = state;
this.editService.read();
}
protected addHandler({ sender }: any) {
this.closeEditor(sender);
this.formGroup = new FormGroup({
'ProductID': new FormControl(),
'ProductName': new FormControl("", Validators.required),
'UnitPrice': new FormControl(0),
'UnitsInStock': new FormControl("", Validators.compose([Validators.required, Validators.pattern('^[0-9]{1,2}')])),
'Discontinued': new FormControl(false)
});
sender.addRow(this.formGroup);
}
protected editHandler({ sender, rowIndex, dataItem }: any) {
//protected editHandler({ sender, rowIndex, dataItem }){
this.closeEditor(sender);
this.formGroup = new FormGroup({
'ProductID': new FormControl(dataItem.ProductID),
'ProductName': new FormControl(dataItem.ProductName, Validators.required),
'UnitPrice': new FormControl(dataItem.UnitPrice),
'UnitsInStock': new FormControl(dataItem.UnitsInStock, Validators.compose([Validators.required, Validators.pattern('^[0-9]{1,2}')])),
'Discontinued': new FormControl(dataItem.Discontinued)
});
this.editedRowIndex = rowIndex;
sender.editRow(rowIndex, this.formGroup);
}
protected cancelHandler({ sender, rowIndex }: any) {
this.closeEditor(sender, rowIndex);
}
private closeEditor(grid: any, rowIndex = this.editedRowIndex) {
grid.closeRow(rowIndex);
this.editedRowIndex = undefined;
this.formGroup = undefined;
}
protected saveHandler({ sender, rowIndex, formGroup, isNew }: any) {
const product: Product = formGroup.value;
this.editService.save(product, isNew);
sender.closeRow(rowIndex);
}
protected removeHandler({ dataItem }: any) {
this.editService.remove(dataItem);
}
}
Hello,
Using the Kendo Menu demo (copied into this dojo: http://dojo.telerik.com/@richm/UgAPe), I observed the following using the latest version of NVDA:
1. In Chrome, navigating to a submenu doesn't announce the submenu item, but 'list' instead. E.g. in the dojo example, use the keyboard to navigate to Furniture, then right arrow. NVDA announces, "list", though the visual focus is on the first sub-menu element ("Tables and Chairs"). Pressing down arrow properly announces the second item, "Sofas".
The user will not know the first item in the list unless the navigate away and back to it. It is also a bit confusing that they are now on a submenu.
2. Same scenario, but in Firefox. Navigate to Furniture and select right-arrow. The sub-menu opens, but NVDA's focus remains on "Furniture", and NVDA again announces the furniture item. Pressing right arrow again closes the entire menu. If instead down-arrow is pressed, suddenly Sofa is selected.
Please advise if I should open bugs, and if any workarounds are available.
Thank you!
Rich
I am getting below error, I am not sure why this happening. Please help
java.lang.NoSuchMethodError: com.kendoui.taglib.GridTag.setExcel(Lcom/kendoui/taglib/grid/ExcelTag;)V
namespace TelerikMvcDropdownMunicipality.Controllers
{
using System.Linq;
using System.Web.Mvc;
using TelerikMvcDropdownMunicipality.Models;
using System.Data;
using System.Data.Entity;
public partial class MunicipalController : Controller
{
public ActionResult Index()
{
return View();
}
public JsonResult GetCascadeDistricts()
{
var municipality = new MunicipalityEntities();
return Json(municipality.Districts.Select(d => new { DistrictId = d.DistrictId, DistrictName = d.DistrictName }), JsonRequestBehavior.AllowGet);
}
public JsonResult GetCascadeLocals(int? districts)
{
var municipality = new MunicipalityEntities();
var locals = municipality.Locals.AsQueryable();
if (districts != null)
{
locals = locals.Where(l => l.DistrictId == districts);
}
return Json(locals.Select(l => new { LocalId = l.LocalId, LocalMunName = l.LocalName }), JsonRequestBehavior.AllowGet);
}
public JsonResult GetCascadeTowns(int? locals)
{
var municipality = new MunicipalityEntities();
var towns = municipality.Towns.AsQueryable();
if (locals != null)
{
towns = towns.Where(t => t.LocalId == locals);
}
return Json(towns.Select(t => new { TownId = t.TownId, TownName = t.TownName }), JsonRequestBehavior.AllowGet);
}
}
}
and my view is:
@{
ViewBag.Title = "Index";
}
<
div
class
=
"demo-section"
style
=
"width: 250px;"
>
<
h2
>Municipalities</
h2
>
<
p
>
<
label
for
=
"districts"
> Districts</
label
>
@(Html.Kendo().DropDownList()
.Name("districts")
.HtmlAttributes(new { style = "width:200px" })
.OptionLabel("Select district...")
.DataTextField("DistrictName")
.DataValueField("DistrictId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeDistricts", "ComboBox");
});
})
)
</
p
>
<
p
>
<
label
for
=
"locals"
>Locals</
label
>
@(Html.Kendo().DropDownList()
.Name("locals")
.HtmlAttributes(new { style = "width:200px" })
.OptionLabel("Select local...")
.DataTextField("LocalName")
.DataValueField("LocalId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeLocals", "ComboBox")
.Data("filterLocals");
})
.ServerFiltering(true);
})
.Enable(false)
.AutoBind(false)
.CascadeFrom("districts")
)
<
script
>
function filterLocals() {
return {
districts: $("#districts").val()
};
}
</
script
>
</
p
>
<
p
>
<
label
for
=
"towns"
>Towns</
label
>
@(Html.Kendo().DropDownList()
.Name("towns")
.HtmlAttributes(new { style = "width:200px" })
.OptionLabel("Select towns")
.DataTextField("TownName")
.DataValueField("TownId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeTowns", "ComboBox")
.Data("filterTowns");
})
.ServerFiltering(true);
})
.Enable(false)
.AutoBind(false)
.CascadeFrom("towns")
)
<
script
>
function filterTowns() {
return {
towns: $("#filterTowns").val()
};
}
</
script
>
</
p
>
</
div
>
<
script
>
$(document).ready(function () {
var districts = $("#districts").data("kendoDropDownList"),
locals = $("#localMun").data("kendoDownList"),
towns = $("#towns").data("kendoDropDownList");
$("#get").click(function () {
var districtInfo = "\nDistricts: { id: " + districts.value() + ", name: " + districts.text() + " }",
localInfo = "\nLocal: { id: " + locals.value() + ", name: " + locals.text() + " }",
townInfo = "\nTown: { id: " + towns.value() + ", name: " + towns.text() + " }";
alert("Town details:\n" + districtInfo + localInfo + townInfo);
});
});
</
script
>
Currently I'm using Kendo UI 2015 Q1 SP1 in my project. The cascading function is working fine.
When I update with the latest version it is not working as expected. The 2nd dropdown is rendering only, the user select the first drop down.
Note: I'll be having sorting operation in the controller, So I've to bind as "k-options".
Can you assist to fix this bug.