Kendo UI Grid incell edit with client template - Razor view - kendo-ui

i am using kendo grid Q2 2014 and i want to use client template in cell edit mode. But it not work as i want . I need to click into that cell in order to get into edit mode.
Here is my grid .
#(Html.Kendo().Grid<AdminProject.Common.ViewModels.ProjectActivityViewModel>()
.Name("gridName")
.Columns(columns =>
{
columns.Bound(d => d.ResourceName);
columns.Bound(d => d.TotalHours).Title("Total Hours").Width(150).ClientFooterTemplate("Sum: #=sum#");
columns.Bound(d => d.TotalCost).Title("Total Cost").Format("{0:c0}").Width(150).ClientFooterTemplate("Sum: #= kendo.toString(sum, 'c0')#");
columns.Bound(d => d.Hours)
.ClientTemplate(Html.Kendo().TextBox().Name("NewHours").ToClientTemplate().ToHtmlString());
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.ToolBar(toolbar =>
{
toolbar.Save(); // The "save" command saves the changed data items
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5)
)
.Sortable()
.Events(e => e.Edit("onEdit"))
.AutoBind(true)
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(10)
.Aggregates(aggregates =>
{
aggregates.Add(p => p.TotalHours).Sum();
aggregates.Add(p => p.TotalCost).Sum();
})
.Events(events => { events.Error("error_handler").Sync("sync_handler"); })
.ServerOperation(true)
.Model(model =>
{
model.Id(product => product.ResourceId); // Specify the property which is the unique identifier of the model
model.Field(product => product.TotalHours).Editable(false);
model.Field(product => product.TotalCost).Editable(false);
model.Field(product => product.ResourceName).Editable(false);
})
.Read(read => read.Action(AdminProject.Common.Constants.ActionNames.GetDetail, AdminProject.Common.Constants.ControllerNames.Project).Data("additionalData"))
.Update(update => update.Action(AdminProject.Common.Constants.ActionNames.UpdateActivity, AdminProject.Common.Constants.ControllerNames.Project).Data("additionalData2"))
.Sort(sort => sort.Add(s => s.ResourceId).Ascending())
))
Sorry , i can not post the photo so i uploaded it into another host .
Before enter link description here
After enter link description here

have look on this http://jsfiddle.net/khNsE/70/ example.
This is kendo ui script you can use this instead of mvc wrapper.
var _roleDataSource = new kendo.data.DataSource({
data: [
{ id: 1, title: "Software Engineer" },
{ id: 2, title: "Quality Assurance Engineer" },
{ id: 3, title: "Team Lead" }
]
});
var _peopleDataSource = new kendo.data.DataSource({
data: [
{ id: 1, name: "John", roleId: 1, roleTitle: "Software Engineer" },
{ id: 2, name: "Dave", roleId: 2, roleTitle: "Quality Assurance Engineer" },
{ id: 3, name: "Aaron", roleId: 3, roleTitle: "Team Lead" }
]
});
var _grid = $("#grid").kendoGrid({
dataSource: _peopleDataSource,
columns: [
{
field: "name",
title: "Name"
},{
field: "roleTitle",
title: "Role",
editor: function(container, options) {
$("<input data-bind='value:roleTitle' />")
// .attr("id", "ddl_roleTitle")
.appendTo(container)
.kendoDropDownList({
dataSource: _roleDataSource,
dataTextField: "title",
dataValueField: "title",
template: "<span data-id='${data.id}'>${data.title}</span>",
select: function(e) {
var id = e.item.find("span").attr("data-id");
var person =_grid.dataItem($(e.sender.element).closest("tr"));
person.roleId = id;
setTimeout(function() {
$("#log")
.prepend($("<div/>")
.text(
JSON.stringify(_grid.dataSource.data().toJSON())
).append("<br/><br/>")
);
});
}
});
}
}
],
editable: true
}).data("kendoGrid");
Hope this helps
Regards
vinit

You may force the last Cell into edit mode through
var grid = $('#gridName').data('kendoGrid');
grid.editCell(grid.tbody.find('tr:eq(0) td:last'));
please refer to this fiddle: http://jsfiddle.net/houssamk/7z0ubup7/1/
NOTE:
Please do not put this call inside the "edit" event handler because it will fire the edit event again. please see http://docs.telerik.com/kendo-ui/api/web/grid#methods-editCell

Related

Is it possible to iterate through a list of objects and do dynamic tests for each input?

I am currently learning cypress.io, and I have 7 checkboxes representing each day of the week Sun-Sat.
{days.map((day, idx) => (
<input
onChange={(e) => {
const { checked, value } = e.target;
setDays(
days => days.map(data => {
if (data.id === day.id) {
return {
...data,
id: value,
select: !data.select,
};
}
return data;
})
);
setDayId(prev => {
return checked
? [...prev, value] // add if checked
: prev.filter(val => val !== value) // remove if not checked
});
console.log("CHECKING CHECKED VALUE", e.target.checked);
// console.log("WHAT IS THE SET VALUE", values)
}}
key={idx}
name={day?.name}
type="checkbox"
value={day?.id}
checked={day.select}
id="habit-frequency"
/>
))}
And I am trying to avoid doing this 7 times, because I am sure that there is a much better way to do it
cy.get("#habit-frequency")
.should("have.attr", "name", "Sun")
.should("have.attr", "value", "1");
I though about doing this:
const DAYS = [
{ id: 1, name: "Sun", select: false },
{ id: 2, name: "Mon", select: false },
{ id: 3, name: "Tue", select: false },
{ id: 4, name: "Wed", select: false },
{ id: 5, name: "Thu", select: false },
{ id: 6, name: "Fri", select: false },
{ id: 7, name: "Sat", select: false },
];
DAYS.map(day => (
it(`Should have a checkbox for ${day.name}`, () => {
cy.get("#habit-frequency")
.should("have.attr", "name", day.name)
.should("have.attr", "value", day.id)
})
))
But it isn't really working. Any advise? Here is the full test I have written so far in case it helps
describe("Create Habit", () => {
beforeEach(() => {
cy.visit("/");
});
it("Should have a 'Habit' button which can be clicked to display a modal", () => {
cy.get("#modal-btn").should("contain", "Habit").click();
cy.get(".modal-title").should("contain", "Add Habit");
});
it("Should have a 'Add Habit' title, 2 inputs, one for name and one for description, a habit type option, a weekly frequency and an option to choose colors", () => {
cy.get("#modal-btn").click();
cy.get(".modal-title").should("contain", "Add Habit");
cy.get("#habit-name")
.should("have.attr", "placeholder", "Habit name");
cy.get("#habit-description")
.should("have.attr", "placeholder", "Habit description");
cy.get("#habit-todo")
.should("have.attr", "name", "To-Do")
.should("have.attr", "value", "1");
cy.get("#habit-nottodo")
.should("have.attr", "name", "Not-To-Do")
.should("have.attr", "value", "2");
DAYS.map(day => (
it(`Should have a checkbox for ${day.name}`, () => {
cy.get("#habit-frequency")
.should("have.attr", "name", day.name)
.should("have.attr", "value", day.id)
})
))
cy.get("#habit-frequency")
.should("have.attr", "name", "Sun")
.should("have.attr", "value", "1");
});
});
The problem you are having is because you are nesting it calls, Never nest them.
just use your code as is without the internal it call
it(`Should have a checkbox for ${day.name}`, () => { /// this should be removed
..
}/// this should be removed

Kendo chart change min and max date for CategoryAxis with script

I have a kendo chart that displays a weeks worth of data. Now I want to change the start and end dates when I change a date picker. But I can not figure out how to change the Category Axis start and end date
I have made a separate button to trigger the changing of the min and max value but it always show the initial input.
What I currently have
#(Html.Kendo().DatePicker().Name("startField")
.Events(e => e.Change("startChanged"))
.Value(DateTime.Now.Date.AddDays(-6))
)
<input id="btnRefresh" type="submit" value="#Html.Resource("Refresh")" class="btn btn-default" />
#(Html.Kendo().Chart<ECOnX.Web.Modules.Containers.Mvc.Models.Container
.ContainerDataChartViewModel>()
.Name("dataChart")
.Title(Html.Resource("Week"))
.ChartArea(chartArea => chartArea.Background("transparent"))
.DataSource(ds => ds.Read(read => read.Action("ChartContainerData_Read", "ContainerController").Data("containerReadData")))
.Series(series =>
{
series.Line(model => model.AccuPercentage, categoryExpression: model => model.RecievedAt).Name(Html.Resource("Battery")).Color("#f0ee20");
series.Line(model => model.PercentageFilled, categoryExpression: model => model.RecievedAt).Name(Html.Resource("Filling")).Color("#76c364");
})
.ValueAxis(axis => axis
.Numeric("percentage")
.Min(0)
.Max(100)
.Line(line => line.Visible(false))
)
.CategoryAxis(axiss =>
{ axiss.Date().BaseUnit(ChartAxisBaseUnit.Hours).BaseUnitStep(1).Min(DateTime.Now.Date.AddDays(-6)).Max(DateTime.Now.Date.AddDays(1).AddMilliseconds(-1))
.MajorGridLines(lines => lines.Visible(false)).Labels(labels => labels.Visible(false));
})
.CategoryAxis(axiss =>
{ axiss.Date().BaseUnit(ChartAxisBaseUnit.Days).BaseUnitStep(1).Min(DateTime.Now.Date.AddDays(-6)).Max(DateTime.Now.Date.AddDays(1).AddMilliseconds(-1))
.Labels(labels => labels.DateFormats(formats => formats.Days("D")));
})
.Tooltip(tooltip => tooltip.Visible(true).Shared(true))
)
And the scripts
$(document).ready(function () {
//change event
$("#btnRefresh").click(function () {
var grid = $("#dataChart").data("kendoChart");
var startPicker = $("#startField").data("kendoDatePicker");
grid.options.categoryAxis.min = startPicker.value();
var end = startPicker.value();
end.setDate(end.getDate() + 7);
grid.options.categoryAxis.max = end;
grid.refresh();
grid.dataSource.read();
});
});
function containerReadData() {
var startPicker = $("#startField").data("kendoDatePicker");
return {
containerId: $('#chartidfield').val(),
startDate: startPicker.value()
}
}
function startChanged() {
var grid = $("#dataChart").data("kendoChart");
grid.dataSource.read();
}
</script>
I have solved this by recreating the categoryaxis in the javescript
function SetCategoryRange()
{
var grid = $("#dataChart").data("kendoChart");
var startPicker = $("#startField").data("kendoDatePicker");
var end = new Date(startPicker.value().getTime());
end.setDate(end.getDate() + 7);
var start = kendo.toString(startPicker.value(), "yyyy/MM/dd HH:mm:ss");
var end = kendo.toString(end, "yyyy/MM/dd HH:mm:ss");
grid.setOptions({
categoryAxis: [{
labels: { visible: false },
majorGridLines: { visible: false },
type: "date",
baseUnit: "hours",
baseUnitStep: 1,
min: start,
max: end
},
{
labels: { dateFormats: { days: "D" } },
type: "date",
baseUnit: "days",
baseUnitStep: 1,
min: start,
max: end
}]
});
grid.refresh();
}

How can I restrict a number input between 1 to 12 in Kendo Grid Inline Editing

I have a kendo grid and one column should expect a number between 0 to 12. Everything else are working fine except HourTimeHours. I can't put min value smaller than 0 but i can put more than 12 for that. please help.
schema: {
model: {
id: "ID",
fields: {
ID: { editable: false },
TName: { editable: false },
HourTimeHours: { editable: true, type: "number", validation: { required: true, min: 0, max: 12 } },
Comment: { editable: true, nullable: true },
Reason: { editable: false, nullable: true },
ChargeRateText: { defaultValue: { CategoryID: "No Charge", CategoryName: "No Charge" } },
}
},
You will have to specify an editor for that field when creating your grid.
$("#grid").kendoGrid({
dataSource: dataSource,
columns: [
{ field: "HourTimeHours", title: "Hours", editor: hoursDropDownEditor }],
editable: true
});
And then if you want something like a kendo numeric text box, your function will look something like this:
function hoursDropDownEditor(container, options) {
$('<input/>')
.appendTo(container)
.kendoNumericTextBox({
min: 1,
max: 12,
step: 1
});
}
Update: You could also use a template, which makes it clear to the user that the field is editable.
http://jsfiddle.net/amomsen/vcpWD/1/
For Kendo UI MVC you can restrict length of Kendo Grid Inline Editing
$("body").delegate("#percentage", "keyup", function () {
$("#percentage").attr('maxlength', '5');
});
Where #percentage is id of cell to Edit
columns.Bound(p => p.percentage);
All grid:
#(Html.Kendo().Grid<Internal.Models.ExchangeRateData>()
.Name("ExchangeGrid")
.Columns(columns =>
{
columns.Bound(p => p.targetCurrency);
columns.Bound(p => p.percentage);
columns.Command(commands => { commands.Edit(); });
})
.Editable(edit =>
{
edit.Mode(GridEditMode.InLine);
})
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(item => item.targetCurrency);
})
.Events(events =>
{
events.Sync("onSync");
})
.Read(read => read.Action("ExchangeRate_Read", "ExchangeRatesFortius").Data("ReadRequestData"))
.Update(c => c.Action("Currencies_Update", "ExchangeRatesFortius"))
)
)
For kendo mvc, i was able to limit with a template as such:
columns.Bound(m => m.Inches)
.ClientTemplate("<input type=\"number\" value=#= Inches # min=\"0\" max=\"11\" step=\"1\" ></input>")
.Width(60);

Can you disable selection for specific cells or columns in KendoUI Grid?

The multi-select seems pretty good in KendoUI Grid, but it doesn't appear to support row headers or excluding ranges.
e.g. I want to not be able to select the highlighted cells shown below (e.g. I want to turn them into row headers):
Answer in JQuery/Javascript or server-side C# Razor syntax preferred.
Update based on answer below:
Based on lgorrious' suggestion below, I added this to the KendoGrid options:
dataBound: function() {
$('#grid tr td:first-child').addClass('k-group-cell');
},
which does the trick by fooling the grid into ignoring the first column (thinking it is a grouping level cell in a hierarchical grid).
I could not use the answer as-is as I am using a dataSource for the columns as they vary dynamically, but it lead me straight to a simple solution
This is a bit of a quirky work around, but I found this line in the grid's source code:
SELECTION_CELL_SELECTOR = "tbody>tr:not(.k-grouping-row):not(.k-detail-row):not(.k-group-footer) > td:not(.k-group-cell):not(.k-hierarchy-cell)"
td with class k-group-cell will not be selected.
With that, just add the attribute class = "k-group-cell" to the column that you don't want to be selected.
#(Html.Kendo().Grid<Employee>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.Department).HtmlAttributes(new { #class = "k-group-cell" }); //Add class to HtmlAttributes, on the column you don't want to be selected.
columns.Bound(p => p.EmployeeId);
columns.Bound(p => p.Name);
})
.Pageable()
.Sortable()
.Filterable()
.Selectable(x => x.Mode(GridSelectionMode.Multiple).Type(GridSelectionType.Cell))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Read(read => read.Action("GetEmployees", "Home"))
)
)
One more java script example:
<div id="grid" style="width: 400px;"></div>
<script type="text/javascript">
$(document).ready(function () {
var grid = $("#grid").kendoGrid({
columns: [
{
field: "Department",
title: "Department",
attributes: {
"class": "k-group-cell" //Same idea with the class attribute
}
}, {
field: "Name",
title: "Full Name"
}, {
field: "EmployeeId",
title: "Employee ID"
}
],
dataSource: {
data: [
{
EmployeeId: 0,
Name: "Joe Mintot",
Department: "Finance"
}, {
EmployeeId: 1,
Name: "Jane Smith",
Department: "IT"
}
],
schema: {
model: {
id: "EmployeeId",
fields: {
EmployeeId: { type: "number" },
Name: { type: "string" },
Department: { type: "string" }
}
}
},
pageSize: 10
},
selectable: "multiple cell",
scrollable: {
virtual: true
},
pageable: true
}).data("kendoGrid");
});
</script>

Why does the KendoUI Grid not rollback a delete when the options.error function is called?

I have put a fiddle here that demonstrates the issue.
http://jsfiddle.net/codeowl/fmzay/1/
Just delete a record, and it should rollback the delete as I am calling options.error from inside the destroy function.
Why is it that the grid doesn't roll back?
Regards,
Scott
Markup:
<div id="KendoGrid"></div>
JS:
var _data = [
{ Users_ID: 1, Users_FullName: 'Bob Smith', Users_Role: 'Administrator' },
{ Users_ID: 2, Users_FullName: 'Barry Baker', Users_Role: 'Viewer' },
{ Users_ID: 3, Users_FullName: 'Bill Cow', Users_Role: 'Editor' },
{ Users_ID: 4, Users_FullName: 'Boris Brick', Users_Role: 'Administrator' }
],
_dataSource = new kendo.data.DataSource({
data: _data,
destroy: function (options) {
options.error(new Error('Error Deleting User'));
}
});
$('#KendoGrid').kendoGrid({
dataSource: _dataSource,
columns: [
{ field: "Users_FullName", title: "Full Name" },
{ field: "Users_Role", title: "Role", width: "130px" },
{ command: ["edit", "destroy"], title: " ", width: "180px" }
],
toolbar: ['create'],
editable: 'popup'
});
Signaling the error is not enough. Lets say that having an error on removing a record is not enough since KendoUI doesn't know if the record has actually been removed in the server and the reply is the one producing the error. So KendoUI approach is a conservative approach: You have to decide what to do and explicitly say it:
So what you should do is add an error hander function that invokes a cancelChanges in the grid.
The code would be:
_dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
options.success(_data);
console.log('Read Event Has Been Raised');
},
destroy: function (options) {
options.error(new Error('Error Deleting User'));
console.log('Destroy Event Has Been Raised');
}
},
schema: {
model: {
id: "Users_ID",
fields: {
Users_ID: { editable: false, nullable: true },
Users_FullName: { type: "string", validation: { required: true } },
Users_Role: { type: "string", validation: { required: true } }
}
}
},
error: function(a) {
$('#KendoGrid').data("kendoGrid").cancelChanges();
}
});
And the updated JSFiddle in here: http://jsfiddle.net/OnaBai/fmzay/3
The ASP.NET-MVC equivalent solution to the OnaBai answer would be:
<script type="text/javascript">
function cancelChanges(e) {
e.sender.cancelChanges();
}
</script>
#Html.Kendo().Grid<MyClass>()
.DataSource(dataSource =>
dataSource
.Ajax()
.Read(read => read.Action("Read", "MyController"))
.Destroy(destroy => destroy.Action("Destroy", "MyController"))
.Events(evt => evt.Error("cancelChanges"))
)
[...]
Please be aware that the cancelChanges event will be called upon an error on every CRUD request.

Resources