i have a timestamp column in one of my sql server table for maintaining row versioning ,
but i dont know how to display its value on kendo grid ,
this is required because my entities wont updating records with null values in that column , by displaying timestamp value on grid , i will take it back when updating records .
this is my kendo grid schema
schema: {
errors: function(response) {
if (response.Voucher && response.Voucher !== "True") {
return response.Voucher;
}
return false;
},
data: "data",
total: "total",
model: {
id: "ID",
fields: {
ID: { editable: false, nullable: true },
FK_Category_ID: { defaultValue: -1, validation: { required: { message: "" } } },
CompanynameAr: { type: "string", validation: { required: { message: " " } } },
CompanynameEn: { type: "string" },
FK_Country_ID: { defaultValue: -1, validation: { required: { message: "" } } },
Address: { type: "string", validation: { required: { message: "" } } },
PoBox: { type: "string" },
Contractno: { type: "number", validation: { required: { message: "" },min:0 } },
Refrence: { type: "number",validation:{min:0}},
RemarksMarketing: { type: "string" },
Active: { type: "string" },
Latitude: { type: "string" },
Longitude: { type: "string" },
RowVersion: {
type: "date", parse: function (value) {
return new Date(value * 1000);
}
}
//Address
}
}
}
here RowVersion is my column that hold timestamp values , parse function is just hit and try for solving particular issue but wont sucessful . so help needed
At the server-side, when adding or updating a record, you should NOT include the timestamp (RowVersion) column in your query (even with a NULL value). SQL Server will automatically generate the value for the RowVersion column on each change to any record. So if you are using plain SQL, remove RowVersion from your SQL; Or if you use Entity Framework Code-First, you may use a [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute to inform Entity Framework that it should not update the related column.
Anyway, if you want to display the timestamp (rowversion) value to your user, it is an 8-byte auto-incrementing integer that is usually mapped to a byte[] type and you may use BitConverter.ToInt64() to convert it to a long and show it to the user. But you never need to receive it in your controller on add/update requests because you should not include it in your query.
As you could see on MSDN, an sql server Timestamp value is a .net byte array, so you can't convert it to a Date value.
You can simply make no convertion on the received value and just hide it.
Related
I am having trouble saving changes using to the server using Kendo UI Listview.
The DataSource is configured like this:
var listViewDataSource = new kendo.data.DataSource({
transport: {
read: {
url: MyServiceURL
},
update: function() {
console.log("test"); // I expected to enter this function
// when the user changes data on the
//client, never happens
}
},
schema: {
Id: "Id",
fields: {
DeptName: {
editable: false,
},
HourRate: {
type: "number",
editable: true
},
ShowOnSavings: {
type: "boolean",
editable: true
},
ShowOnTechnicalCosts: {
type: "boolean",
editable: true
},
ShowOnOtherCosts: {
type: "boolean",
editable: true
}
}
},
sync: function (e) {
console.log("item synched"); //This should be fired after the
// updated data is sent, never
//happens
}
The ListView is initialised like this:
kendo.bind($("#listview-container"), {
listViewDataSource: listViewDataSource,
onItemSaved: function (e) {
console.log("item saved"); // fired every time the user changes
//an item, as expected
}
})
The ListView properly loads the data. When the user edits an item the change is visible locally (after leaving edit mode) and the save event is fired, as expected.
However the changes are never synchronized with the server, my update method is never called and no network activity is never called.
The documentation on the ListView save method states the following:
Saves edited ListView item. Triggers save event. If save event is not prevented and validation succeeds will call DataSource sync method.
As I don't call preventDefaulton the save event I expect the data sourve to sync, however this does not happen. Calling dataSource.sync() manually does not help either.
I am puzzled why this does not work. Any tips appreciated.
I skipped one level of nesting in the model configuration, model was missing
schema: {
model: {
id: "Id",
fields: {
Id: {
type: "number",
editable: false
},
DeptName: {
type: "string",
editable: false
},
HourRate: {
type: "number",
editable: true
},
ShowOnSavings: {
type: "boolean",
editable: true
},
ShowOnTechnicalCosts: {
type: "boolean",
editable: true
},
ShowOnOtherCosts: {
type: "boolean",
editable: true
}
}
}
}
I have a Kendo UI TreeList where every row has a checkbox displayed. If the user clicks on the checkbox then a request goes to the server and save the data. Unfortunately, I did something wrong because:
the update method does not send data to the server
and the sync method is not called automatically
What I did wrong?
I think the problem around how I set up that which item has changed. As you can see I iterate over the dataset coming from dataSource.data() and the item.checked and item.dirty properties are updated. If I understand correctly the documentation then this changes should trigger the sync method. It does not trigger the sync method and this it the reason I call it in the method.
My other question is related to the data structure should be sent to the server. It is based on the schema, right? So, once I can achieve that the request sends an object to the server I should create a similar C# POCO as model and I can read the data in the webapi controller.
In the documentation there is a saveRow() method, but I cannot translate that code to angular. Can somebody help me in this case?
//this row is my problem
var treeList = $("#treeList").data("kendoTreeList");
var dataSource = new kendo.data.TreeListDataSource({
transport: {
read: {
url: configurationService.goNoGoWebApiRootUrl + 'AreaPathDependencies/Get/ChildrenMarked/' + selectedAreaPathIdFromModalService,
dataType: "json",
type: "get"
},
update:
{
url: configurationService.goNoGoWebApiRootUrl + 'AreaPathDependencies/Update/AreaPathDependencies',
dataType: "json",
type: "post"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
schema: {
model: {
id: "id",
parentId: "parentId",
fields: {
Id: { type: "number", editable: false, nullable: true },
ParentId: { type: "number", editable: false, nullable: true },
Name: { type: "string", editable: false, nullable: true },
Checked: { type: "boolean", editable: true, nullable: false }
}
}
}
});
vm.treeListOptions = {
dataSource: dataSource,
sortable: false,
editable: false,
columns: [
{
field: "checked",
title: "Selected",
template: checkBoxTemplate,
width: 32
},
{ field: "name", title: "Area Path", width: "200px", expandable: true },
{ field: "fullPath", title: "FullPath", width: "500px" },
],
save: onSave,
change: onChange,
sync: sync,
autoSync: true,
};
}
function checkboxOnclick(selectedId) {
console.log('checkboxOnclick', selectedId);
var data = vm.treeListOptions.dataSource.data();
for (var i = 0; i < data.length; i++) {
if (selectedId == data[i].id) {
data[i].set("checked", true);
//data[i].dirty = true;
}
}
vm.treeListOptions.dataSource.sync();
//console.log('flush', vm.treeListOptions.dataSource.data());
}
Well batch: true has to be set to get parameterMap working, because models parameters will be available only when the batch option is enabled. (parameterMap docs)
And to second question - I am not so sure but as noted in sync docs,
The sync method will request the remote service if:
the transport.create option is set and the data source contains new data items
the transport.destroy option is set and data items have been removed from the data source
the transport.update option is set and the data source contains updated data items
How I understand to that - to get sync method working you need to return updated records. Please check, if your server method for update/delete returns that.
I have a string that can look like this:
[
{
Id:{
editable:false,
nullable:true
}
},
{
Product:{
validation:{
required:true
}
}
},
{
Cost:{
type:"number",
validation:{
required:true
}
}
}
]
It can also look like this:
[
{
Id:{
editable:false,
nullable:true
}
},
{
Car:{
validation:{
required:true
}
}
},
{
Make:{
validation:{
required:true
}
}
}
]
The point is that the string will always have an Id field with some predictable values, but additional fields can be named anything.
I have some javascript which I need to look like this:
schema: {
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
Product: { validation: { required: true } },
Cost: { type: "number", validation: { required: true }}
}
}
}
... where the content of fields needs to correlate the string.
Currently I have an ajax call that get some other data my code needs and I would like to also give it the results I need for the fields. I would like to replace the json like so:
schema: {
model: {
id: "Id",
fields: ajaxResult.fields
}
}
}
The normal route is to create a class (or classes) to which I can deserialize the json string, but in this case the fields in the json string can be completely arbitrary. So I cannot create classes for this since I don't know what the properties will be called.
How can I deserialize this string so when I return it from my Action it will work as I describe?
Currently my controller action looks something like this:
public IActionResult GetJsonData(Guid id)
{
var model = new GridDataModel
{
schema = SchemaToJson(id),
//fields = FieldsToJson(id),
gridData = RowsToJson(id)
};
return Json(model);
}
In Visual Studio 2015, you can use the "paste special" function, Visual studio will generate all classes (including nested classes etc.) for you, no single line of your own coding is needed:
See animations below: (original GIF is from here.)
I am trying to figure out how to format individual values in a Kendo grid bound to a dynamic data source.
The challenge is that the columns are not fixed and the format is not even consistent throughout the column.
From what I can tell Kendo supports format strings at the column level using
columns:[{field:Name,format:{1:c}}]
However this solution is not suitable since it sets the format for the entire column.
I have also found a template based solution that lets you format your data manually using notation like this
columns:[{field:Name,template: "#= kendo.toString(kendo.parseDate(SomeDate, 'yyyy-MM-dd')}]
However, again this is too hard coded for me since it assumes a single type in the column.
I am looking for a way to specify in the data source itself what the type a value is. Is that possible?
Something like this
data = [{field:SomeField,Value:4,Format:{1:c}}]
It turns out you can solve this with a custom template. This will run formatting on every value.
for (var c = 0; c < grid.Cols.length; c++) {
grid.Cols[c].template = "#= FormatValue(" + grid.Cols[c].field + ")#";
}
function FormatValue(value) {
return kendo.toString(value, "c0")//currency formatting
}
If you are going to bind dynamic data source then there in no need to format value in column or feilds. It will automatic adjust with the data.
You should use this pattern
fields: {
EventID: { editable: true, nullable: false },
EventName: { validation: { required: true} },
UserID: { validation: { required: true} },
EventDate: { validation: { required: true} },
EventTimeFrom: { validation: { required: true} },
EventTimeTo: { validation: { required: true} }
}
columns: [
{ field: "EventID", title: "Event ID" },
{ field: "EventName", title: "Event Name" },
{ field: "UserID", title: "User ID" },
{ field: "EventDate", title: "Event Date" },
{ field: "EventTimeFrom", title: "Start Time" },
{ field: "EventTimeTo", title: "End Time" },
],
I am using this html code for Keno UI grid
function loadPhoneGrid(salesRepsId){
$("#phone-grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "operations/get_phones_sales_reps.php?salesRepsId="+salesRepsId,
type: "GET"
},
update: {
url: "operations/edit_phone_number.php?salesRepsId="+salesRepsId,
type: "POST"
},
destroy: {
url: "operations/delete_phone.php",
type: "POST"
},
create: {
url: "operations/add_phone.php?salesRepsId="+salesRepsId,
type: "POST",
},
},
schema: {
data:"data",
total: "data.length", //total amount of records
model: {
id: "PhoneId",
fields: {
PhoneType: { defaultValue: { PhoneTypeId: 1, PhoneTypeName: "Work"} },
PhoneNumber: { type: "string" },
IsMainPhone: {type: "boolean", editalbe:true},
}
}
},
pageSize: 5,
},
height: 250,
filterable: true,
sortable: true,
pageable: true,
reorderable: false,
groupable: false,
batch: true,
toolbar: ["create", "save", "cancel"],
editable: true,
columns: [
{
field:"PhoneType",
title:"Type",
editor: PhoneTypeDropDownEditor,
template: "#=PhoneType.PhoneTypeName#"
},
{
field: "PhoneNumber",
title:"Phone Number",
},
{
field: "IsMainPhone",
title:"Is Main",
width: 65,
template: function (e){
if(e.IsMainPhone== true){
return '<img align="center" src ="images/check-icon.png" />';
}else{
return '';
}
}
// hidden: true
},
{ command: "destroy", title: " ", width: 90 },
],
});
}
The code in the server side is (add_phone.php)
<?php
require_once("../lib/Phone.php");
$phone = array();
foreach($_POST as $name => $value){
$phone[$name] = $value;
}
Phone::AddPhoneNumber($_GET["salesRepsId"], $phone);
?>
For the first time, I added a new record. add_phone.php is calling once and everything is working fine. For the second time (with out refresh the page) when I try to add a new record, add_phone.php is called twice. One of them contains the first record which has been added to database before and the second is the new the data.
in the result I have 3 records ( 2 same data of first insert) and one new.
This an example to make it clear ( inspect the post request with firebug)
first click on save button (false, (111) 111-1111, 4,Fax) // after I enter this phone (111) 111-1111
second click on save button (false, (111) 111-1111, 4,Fax) in addition to (false, (222) 222-2222, 3,Work) // after I added this (222) 222-2222
Any help ??
May be your ajax request raise an error. You can see it by subscribing to the error event of your datasource.
In case of error, the data are not synchronized in your datasource. In your case, I think your dataitem stay in "dirty mode" so the datasource try to insert them for each synchronization...