I'm trying to format my DateTime object in my Kendo ListView Template but the suggested kendo.toString method doesn't seem to work for me.
I've cut out a lot of code that doesn't relate to my problem to make it a little more simple to understand.
I have a Kendo DataSource that looks like the following:
contactDataSource: new kendo.data.DataSource({
transport: {
read: {
url: "/baa/contact/getcontacts",
dataType: "json",
type: "GET"
}
},
schema: {
model: {
id: "Id",
fields: {
Id: { type: "number", editable: false, nullable: true },
CompanyName: { type: "string" },
ContactName: { type: "string" },
ContactPhone: { type: "string" },
ContactEmail: { type: "string" },
ImageUrl: { type: "string" },
Website: { type: "string" },
RecentBaas: [
{
Name: { type: "string" },
StatusDisplay: { type: "string" },
Status: { type: "number" },
LastModDate: { type: "date" }
}
]
}
}
}
})
And then I have a template on my view that looks like the following:
<script type="text/x-kendo-templ" id="contactTemplate">
<div class="row">
<div class="col-md-12">
# for (var i = 0; i < RecentBaas.length; i++) { #
# if (RecentBaas[i].Status == 1) { #
<div class="alert alert-success" role="alert">
<p>#=kendo.toString(RecentBaas[i].LastModDate, "F")#</p>
</div>
# } #
# } #
</div>
</div>
</script>
I'm not getting any errors in my console when I load this page, but the date is not formatted at all. It still just shows as /Date(1461203814927)/ for example.
I've read the Kendo Documentation on how to use the toString function to format DateTime objects and as far as I can tell I'm doing everything right. But maybe I'm still missing something?
Please try with the below code snippet.
<script type="text/x-kendo-templ" id="contactTemplate">
<div class="row">
<div class="col-md-12">
# for (var i = 0; i < RecentBaas.length; i++) { #
# if (RecentBaas[i].Status == 1) { #
<div class="alert alert-success" role="alert"> <p>#=kendo.toString(kendo.parseDate(RecentBaas[i].LastModDate), 'yyyy-MM-dd')#</p>
</div>
# } #
# } #
</div>
</div>
</script>
Let me know if its not working
Related
I am using a custom template for kendo grid popup Add / Edit form. Here is my working DEMO
I want to implement conditional validation on form fields such as if any value is entered for Address (not left empty) then the fields City and Postal Code should become required, otherwise they can be empty. Also I want to ise a custom validation rule for PostCode so that its length should always be equal to 4 else it should show a custom error message as "Postcode must be four digits"
I have referred these links:
Validation rules in datasource.model
Custom validation rules and error messages
but I can't figure out how can I implement validations in my datasource model?
Here is my code:
HTML:
<h3>I want to implement conditional validation on Add/Edit form such as if any value is entered for Address then the fields City and Postal Code should become required</h3>
<div id="grid"></div>
<script id="popup-editor" type="text/x-kendo-template">
<p>
<label>Name:<input name="name" required /></label>
</p>
<p>
<label>Age: <input data-role="numerictextbox" name="age" required /></label>
</p>
<p>
<label>Address: <input name="address"/></label>
</p>
<p>
<label>City: <input name="city"/></label>
</p>
<p>
<label>Post Code: <input name="postcode"/></label>
</p>
</script>
JS:
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" },
{ command: "edit" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30 },
{ id: 2, name: "John Doe", age: 33 }
],
schema: {
model: { id: "id" },
fields: {
name:{},
age:{},
address:{},
city:{},
postcode:{},
},
}
},
editable: {
mode: "popup",
template: kendo.template($("#popup-editor").html())
},
toolbar: [{ name: 'create', text: 'Add' }]
});
If i were to do that, i would do these approach where
I will create a custom validator
Override the edit(grid) function place the validator there
Override the save(grid) function use validator.validate() before saving
Here is an example in dojo
basically this is the grid code:
var validator;
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" },
{ command: "edit" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30 },
{ id: 2, name: "John Doe", age: 33 }
],
schema: {
model: { id: "id" },
fields: {
name:{},
age:{},
address:{},
city:{},
postcode:{},
},
}
},
save: function(e) {
if(!validator.data("kendoValidator").validate()){
e.preventDefault();
}
},
edit: function(){
validator = $("#test-form").kendoValidator({
validateOnBlur: false,
rules: {
matches: function(input) {
var requiredIfNotNull = input.data('test');
// if the `data-test attribute was found`
if (requiredIfNotNull) {
// get the input requiredIfNotNull
var isFilled = $(requiredIfNotNull);
// trim the values and check them
if ( $.trim(isFilled.val()) !== "" ) {
if($.trim(input.val()) !== ""){
// the fields match
return true;
}else{
return false;
}
}
// don't perform any match validation on the input since the requiredIf
return true;
}
// don't perform any match validation on the input
return true;
}
},
messages: {
email: "That does not appear to be a valid email address",
matches: function(input) {
return input.data("testMsg");
}
}
});
},
editable: {
mode: "popup",
template: kendo.template($("#popup-editor").html())
},
toolbar: [{ name: 'create', text: 'Add' }]
});
ps: i used to many if statement, you could simplify it i think
Here is the DEMO how I implemented it:
HTML:
<div id="grid"></div>
<script id="popup-editor" type="text/x-kendo-template">
<div id="myForm">
<p>
<label>Name:<input name="name" required /></label>
</p>
<p>
<label>Age: <input data-role="numerictextbox" name="age" required /></label>
</p>
<p>
<label>Address: <input name="address" id="address"/></label>
</p>
<p>
<label>City: <input name="city" id="city"/></label>
</p>
<p>
<label>Post Code: <input name="postcode" id="postcode"/></label>
<!--<span class="k-invalid-msg" data-for="postcode"></span>-->
</p>
</div>
</script>
JS:
var validator;
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" },
{ field: "address" },
{ field: "city" },
{ field: "postcode" },
{ command: "edit" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30, address:'Addr', city:"city", postcode: '1234' },
{ id: 2, name: "John Doe", age: 33, address:'Addr11', city:"city11", postcode: '4321' }
],
schema: {
model: { id: "id" },
fields: {
name:{},
age:{},
address:{},
city:{},
postcode:{},
},
}
},
editable: {
mode: "popup",
template: kendo.template($("#popup-editor").html())
},
toolbar: [{ name: 'create', text: 'Add' }],
save: function(e) {//alert('save clicked');
if(!validator.validate()) {
e.preventDefault();
}
},
edit: function(e){
//alert('edit clicked');
validator = $("#myForm").kendoValidator({
messages: {
postcode: "Please enter a four digit Postal Code"
},
rules: {
postcode: function(input) {
//console.log(input);
if (input.is("[name='address']"))
{
if (input.val() != '')
{
$('#city, #postcode').attr('required', 'required');
//return false;
}
else
{
$('#city, #postcode').removeAttr("required");
}
}
else if (input.is("[name='postcode']")) {
if ($('#address').val() != '' && input.val().length != 4)
return false;
}
return true;
}
},
}).data("kendoValidator");
},
});
How can I get my ListView to loop through object property timetableRecords. I'm googling around but can't find way to do it.
Example of data (swagger response model schema):
{
"from": {
"name": "string"
},
"to": {
"name": "string"
},
"price": 0,
"date": "2016-07-25T11:52:52.674Z",
"timetableRecords": [
{
"departure": "2016-07-25T11:52:52.675Z",
"arrival": "2016-07-25T11:52:52.675Z"
}
],
"fetchedOn": "2016-07-25T11:52:52.675Z"
}
HTML:
<div id="timetableRecords"></div>
<script type="text/x-kendo-template" id="template">
<div class="timetable-record">
<p>#:departure#</p>
<p>#:arrival#</p>
</div>
</script>
JavaScript:
$('#timetableRecords').kendoListView({
template: kendo.template($("#template").html()),
dataSource: {
transport: {
read: {
type: 'GET',
url: 'api/timetable?from=station_name1&to=station_name2',
dataType: 'json'
}
}
}
});
So its been awhile since you posted this, but I have a solution for you (doubtful you will still need it).
The schema.parse() event can help you:
Executed before the server response is used. Use it to preprocess or parse the server response.
Here is your updated Datasource is below:
dataSource: {
transport: {
read: {
type: 'GET',
url: 'api/timetable?from=station_name1&to=station_name2',
dataType: 'json'
}
},
schema:
parse: fucntion(e) {
return e.timetableRecords
}
}
This way your DataSource is processing a list of 'timetableRecords', and your template would be valid.
Good luck,
Grant
I am trying to update a row from a grid in a mobile app , but the model is not sent to the server.
I am using kendo 2015.1.429
My view is this:
<div data-role="view" data-init="initGrid" data-stretch="true">
<div data-role="header">
</div>
<div id="grid">
</div>
</div>
<script type="text/javascript">
function initGrid() {
var dataSource3 = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("GetAll")",
dataType: "json"
},
update: {
url: "#Url.Action("Update")",
dataType: "json"
},
destroy: {
url: "#Url.Action("Destroy")",
dataType: "json"
},
create: {
url: "#Url.Action("Create")",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: false,
schema: {
data:"Data",
model: {
id: "ID",
fields: {
ID: { type: "number", editable: false, nullable: false },
Name: { type: "string" }
}
}
}
});
$("#grid").kendoGrid({
dataSource:dataSource3,
pageable: true,
mobile: "tablet",
height: kendo.support.mobileOS.wp ? "24em" : 430,
resizable: true,
editable: {
mode: "popup"
},
toolbar: ["create"],
columns: [
{ field: "ID", title: "ID", width: 200},
{ field: "Name", title: "Name"},
{ command: ["edit", "destroy"] }
]
});
}
</script>
The Update method in controller is this:
public ActionResult Update([DataSourceRequest] DataSourceRequest request, Model viewModel)
{
return Json(new[] { viewModel }.ToDataSourceResult(request, ModelState));
}
<--EDITED 2 -->
I saw in Fiddler that no data is sent to my method Update.
What am I forgetting to do? What am I doing wrong?
If I remove parameterMap
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
It works fantastic.
Thanks!
I defined a Kendo Data Source as below. It is populating values in a ListView.
var datasourceAppList = new kendo.data.DataSource({
transport: {
create: function(options){
//alert(options.data.desc);
alert(options.data.desc);
var localData = JSON.parse(localStorage.getItem("LsAppList"));
localData.push(options.data);
localStorage.setItem("LsAppList", JSON.stringify(localData)); //localStorage["LsAppList"] = JSON.stringify(localData);
options.success(localData);
},
read: function(options){
var localData = JSON.parse(localStorage["LsAppList"]);
options.success(localData);
},
update: function(options){
var localData = JSON.parse(localStorage["LsAppList"]);
for(var i=0; i<localData.length; i++){
if(localData[i].extappId == options.data.extappId){
localData[i].desc = options.data.desc;
localData[i].deviceNo = options.data.deviceNo;
localData[i].validationKey = options.data.validationKey;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(localData);
},
destroy: function(options){
var localData = JSON.parse(localStorage["LsAppList"]);
localData.remove(options.data.ID);
localStorage["LsAppList"] = JSON.stringify(localData);
options.success(localData);
},
},
schema: {
model: {
extappId: "ID",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}}
},
});
First : I call the following code. it adds the data correctly both to te page listview and localStorage.
datasourceAppList.add({ extappId: "9905", desc: "test", deviceNo: "5", validationKey: "CACACACA"});
datasourceAppList.sync();
Second: I call the folowing code
datasourceAppList.add({ extappId: "9908", desc: "harvest", deviceNo: "7", validationKey: "ppppppp"});
datasourceAppList.sync();
Problems:
the page is showing the first record twice.
The localstorage has 2 times the first record and 1 time the second record.
what am I doing wrong?
--- one problem still exists. though the localStorage is correct, the listview is populating wrong.
First Record Add : ListView is Correct
Second Record Add : ListView is Corract
Third Record Add : First 2 lines shows the first record and the last line shows the last record.
My HTML code is
<div id="applications" data-role="view" data-title="Defined Applications" data-layout="default" data-model="appdetail">
<ul id="applist" data-role="listview" data-style="inset" data-source="datasourceAppList" data-template="tmp" data-click="listViewClick" data-auto-bind="true"></ul>
<p align="center">
<a style="width: 30%" data-role="button" data-rel="modalview" data-click="showModalViewAdd" id="buttonAddApplication" data-icon="ecg-plus">Add</a>
<a style="width: 30%" data-role="button" data-rel="modalview" data-click="refreshApplicationList" id="buttonRefreshApplication" data-icon="refresh">Refresh</a>
</p>
</div>
<script id="tmp" type="text/x-kendo-template">
<a id = "#: extappId #">#: desc # </a>
</script>
It is actually a combined problem:
You schema definition is:
schema: {
model: {
extappId: "ID",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}
}
}
It says extappId: "ID"... what is this? Do you want to say that extappId is the id of that record? If so, the actual definition should be:
schema: {
model: {
id: "extappId",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}
}
}
What happens here is not being (correctly) defined the id, KendoUI expects that id is actually id and since this is not being set during the create next time that you sync it tries to save it, it is equivalent to:
datasourceAppList.add({ extappId: 9905, desc: "test", deviceNo: 5, validationKey: "CACACACA"});
datasourceAppList.add({ extappId: 9908, desc: "harvest", deviceNo: 7, validationKey: "ppppppp"});
datasourceAppList.sync();
But if you try this, you will see that then create is never invoked. Now what happens is that the id of the record (i.e. extappId) is already defined and not null and so KendoUI believes that is already saved.
For solving this second issue my recommendation is defining the schema as:
schema: {
model: {
id: "ID",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}
}
}
Now, the id is a field called ID and this ID should be created on transport.create (cannot be set before invoking add method).
Then, you set it in create and you can use:
create: function(options){
// Set `ID` to kendo.guid
options.data.ID = kendo.guid();
alert(options.data.desc);
var localData = JSON.parse(localStorage.getItem("LsAppList"));
localData.push(options.data);
localStorage.setItem("LsAppList", JSON.stringify(localData)); //localStorage["LsAppList"] = JSON.stringify(localData);
options.success(localData);
},
Check it here : http://jsfiddle.net/OnaBai/n7sNd/3/
I tried use the Kendo Grid and i found some problems.
The button action "edit" and "remove " do nothing when i click, but if i put the "create" command into the transport, the grid send lots of POSTS for the create URL command when i click in delete or click in edit > cancel (the update button do nothing too).
What I doing wrong?
My code:
<div id="grid"></div>
<script type="text/x-kendo-template" id="template">
<div class="toolbar">
<input type="number" min="0" id="item-id" maxlength="10" />
<input type="text" id="name" class="k-textbox" placeholder="..." />
<button style="width: 100px" id="btn-grid-filtrar" class="k-button" >Filter</button>
</div>
</script>
<script>
$(document).ready(function() {
var dataSource = new kendo.data.DataSource(
{
schema:
{
data: "data",
total: "total",
model:
{
id: "data",
fields:
{
id: { editable: false, nullable: false },
nome: { type: "string", validation: { required: true} },
ativo: { type: "boolean" }
}
}
},
transport:
{
read:
{
url: "page",
dataType: "json",
type: "POST",
data: additionalData
},
update: {
url: "update",
dataType: "jsonp"
},
destroy: {
url: "delete",
dataType: "jsonp"
}
/*,
create: {
url: "add",
dataType: "jsonp"
}
*/
},
pageSize: 5,
serverSorting: true,
serverPaging: true,
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
pageable: {
input: true,
numeric: false
},
batch: true,
columns: [
{ field: "id", title: "#", width: "60px" },
{ field: "nome", title: "Nome" },
{ field: "ativo", title: "Ativo", width: "60px", template: "#= ativo ? 'Sim' : 'Não' #" },
{ command: ["edit", "destroy"], title: "Ações", width: "200px" }
],
editable: "inline",
toolbar: kendo.template($("#template").html()),
});
kendo.bind($(".toolbar"));
$("#id").kendoNumericTextBox({
format: "##########",
placeholder: "..."
});
$("#btn-grid-filtrar").click(function() {
grid.data("kendoGrid").dataSource.read();
});
});
function additionalData() {
return {
filtro_id: $("#item-id").val(),
filtro_nome: $("#name").val()
};
}
</script>
First of all, I'm assuming that you server is serving a JSON with the following format:
{
"total": 2,
"data" : [
{
"data" : 23,
"id" : 1,
"ativo": true,
"nome" : "stock-1"
},
{
"data" : 34,
"id" : 2,
"ativo": false,
"nome" : "stock-2"
}
]
}
Correct?
So the first thing is changing the "data" on each row data to something not called data. It turns out that data is a kind-of reserved word in KendoUI commonly used in code structures as:
with (data) {
// Expanded code coming from a grid row data
}
Where this data is a variable referencing a row in your grid. So, in this context data is both the row itself and and a field in that row and then JavaScript cannot correctly solve it.
So you can define your schema as:
schema : {
data : "data",
total: "total",
model: {
id : "_data",
fields: {
id : { editable: false, nullable: false },
nome : { type: "string", validation: { required: true} },
ativo: { type: "boolean" }
}
}
},
NOTE: I've replace data by _data.
Transmitted data is:
{
"total": 2,
"data" : [
{
"_data" : 23,
"id" : 1,
"ativo": true,
"nome" : "stock-1"
},
{
"_data" : 34,
"id" : 2,
"ativo": false,
"nome" : "stock-2"
}
]
}
Just with this small change your Edit button will start working.
You are not supposed to define transport level for local datasources, if understand correctly your code, you are not posting anywhere - you are not binding any remote data, I can't see any url ? Follow this example http://demos.kendoui.com/web/datasource/index.html.