Here is my page with the code and the script, basically the validator does not validate the date. I don't know how to make the control get validated by the custom rule. You can do control F $("#service").kendoValidator to see the where the validation is called and configured.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Edit Service - My ASP.NET MVC Application</title>
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
<link href="/Content/KendoUI/styles/kendo.common.min.css" rel="stylesheet"/>
<link href="/Content/KendoUI/styles/kendo.metro.min.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
</head>
<body>
<input type="hidden" id="RootUrl" value="http://localhost:64728/"/>
<div class="page">
<div class="header">
<div class="title">
<h1>
Provider Site Maintenance
</h1>
</div>
</div>
<div style="clear: both;">
</div>
<div id="mainMenu">
</div>
<div class="main">
<h2>Edit Service</h2>
<input type="hidden" id="serviceId" value="12" />
<input type="hidden" id="getServiceUrl" value="/Services/GetService"/>
<input type="hidden" id="saveServiceUrl" value="/Services/SaveService"/>
<form id="service" name="service" action="">
<fieldset>
<legend>Service</legend>
<input type="hidden" name="serviceId" id="serviceId" data-bind="value: serviceId"
class="k-textbox" />
<label for="serivceName">
Service Name :
</label>
<input type="text" id="serivceName" name="serviceName" data-bind="value: serviceName"
class="k-textbox" required="true" maxlength="255" validationmessage="Service Name is required" />
<span class="k-invalid-msg" data-for="serivceName"></span>
<br />
<label for="serviceDescription">
Service Description :
</label>
<input type="text" id="serviceDescription" name="serviceDescription" data-bind="value: serviceDescription"
class="k-textbox" required="true" maxlength="1000" validationmessage="Service Description is required" />
<span class="k-invalid-msg" data-for="serviceDescription"></span>
<br />
<label for="serviceCode">
Service Code :
</label>
<input type="text" id="serviceCode" name="serviceCode" data-bind="value: serviceCode" maxlength="20"
class="k-textbox" validationmessage="Service Code is required" required="true" />
<span class="k-invalid-msg" data-for="serviceCode"></span>
<br />
<label for="baseCostAmount">
Cost :
</label>
<input type="text" id="baseCostAmount" name="baseCostAmount" required="true" min="1"
data-bind="value: baseCostAmount" validationmessage="Cost Must be greater than 0" />
<br/>
<label for="newEffectiveDate">
Effective Date :
</label>
<input id="newEffectiveDate" name="newEffectiveDate" required="true" type="date" data-bind="value: newEffectiveDate"
/>
<span data-bind="text: newEffectiveDateMessage" class="warning"> </span>
</fieldset>
<br/>
<button class="k-button" id="editServiceSaveButton" data-bind="click : validateAndSave">Save</button>
<span style="margin-left:5px; color:green" id="saveComplete" name="saveComplete" data-bind="text : SaveComplete, visible : ShowSaveComplete" ></span>
<span style="margin-left:5px; color:red" id="saveError" name="saveError" data-bind="text : SaveError, visible : ShowSaveError" ></span>
</form>
</div>
</div>
<script src="/Content/KendoUI/JS/jquery.min.js"></script>
<script src="/Content/KendoUI/JS/kendo.web.min.js"></script>
<script src="/Scripts/Views/Common.js"></script>
<script src="/Scripts/Views/Shared/_Layout.js"></script>
<script>
$(document).ready(function () {
//local variables
var getServiceUrl = $("#getServiceUrl").val();
var saveServiceUrl = $("#saveServiceUrl").val();
var serviceId = $('#serviceId').val();
var viewModel = kendo.observable({
toJSON: function () {
// This hack is because .net controllers don't like dates.
// call the original toJSON method from the observable prototype
var result = kendo.data.ObservableObject.prototype.toJSON.call(this);
result.currentEffectiveDate = common.dateFormat(this.get("currentEffectiveDate"), "mm/dd/yyyy HH:MM:ss");
result.newEffectiveDate = common.dateFormat(this.get("newEffectiveDate"), "mm/dd/yyyy HH:MM:ss");
return result;
},
saveComplete: '',
showSaveComplete: function () {
return this.get("saveComplete") != '';
},
saveError: '',
showSaveError: function () {
return this.get("saveError") != '';
},
isNew: null,
serviceId: null,
serviceName: "",
serviceDescription: "",
baseCostAmount: null,
currentEffectiveDate: null,
newEffectiveDate: null,
newEffectiveDateMessage: function () {
return "Effective date must be greater than or equal to " + common.getDateString(this.get("currentEffectiveDate"));
},
validateAndSave: function (e) {
e.preventDefault();
var validator = $("#service").kendoValidator().data("kendoValidator");
if (!validator.validate())
return false;
$.ajax({
type: "POST",
url: saveServiceUrl,
data: viewModel.toJSON(),
cach: false
}).done(function (result) {
if (!result.Success) {
viewModel.set("saveComplete", '');
viewModel.set("saveError", "Update Failed " + result.Message);
} else {
viewModel.set("SaveError", '');
viewModel.set("currentEffectiveDate", viewModel.get("newEffectiveDate"));
viewModel.set("caveComplete", 'Save Successful');
}
});
return false;
}
});
//local functions
function initControls() {
$("#baseCostAmount").kendoNumericTextBox({
format: "c",
decimals: 2
});
$('#newEffectiveDate').kendoDatePicker({ format: "MM/dd/yyyy" });
$("#service").kendoValidator({
rules: {
//implement your custom date validation
dateValidation: function (e) {
var currentDate = Date.parse($(e).val());
//Check if Date parse is successful
if (!currentDate) {
return false;
}
return true;
}
},
messages: {
//Define your custom validation massages
required: "Date is required message",
dateValidation: "Invalid date message"
}
});
}
function loadViewModelFromController() {
$.ajax({
type: "GET",
contentType: 'application/json',
url: getServiceUrl,
data: { id: serviceId },
cach: false
}).done(function (o) {
viewModel.set("isNew", o.IsNew);
viewModel.set("serviceId", o.ServiceId);
viewModel.set("serviceName", o.ServiceName);
viewModel.set("serviceDescription", o.ServiceDescription);
viewModel.set("serviceCode", o.ServiceCode);
viewModel.set("baseCostAmount", o.BaseCostAmount);
viewModel.set("newEffectiveDate", new Date(common.getDateString(o.NewEffectiveDate)));
viewModel.set("currentEffectiveDate", new Date(common.getDateString(o.CurrentEffectiveDate)));
kendo.bind($("#service"), viewModel);
});
}
function addNew() {
viewModel.set("isNew", true);
kendo.bind($("#service"), viewModel);
}
//Init the form
initControls();
if (serviceId > 0) {
loadViewModelFromController();
} else {
addNew();
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Edit Service - My ASP.NET MVC Application</title>
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
<link href="/Content/KendoUI/styles/kendo.common.min.css" rel="stylesheet"/>
<link href="/Content/KendoUI/styles/kendo.metro.min.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
</head>
<body>
<input type="hidden" id="RootUrl" value="http://localhost:64728/"/>
<div class="page">
<div class="header">
<div class="title">
<h1>
Provider Site Maintenance
</h1>
</div>
</div>
<div style="clear: both;">
</div>
<div id="mainMenu">
</div>
<div class="main">
<h2>Edit Service</h2>
<input type="hidden" id="serviceId" value="12" />
<input type="hidden" id="getServiceUrl" value="/Services/GetService"/>
<input type="hidden" id="saveServiceUrl" value="/Services/SaveService"/>
<form id="service" name="service" action="">
<fieldset>
<legend>Service</legend>
<input type="hidden" name="serviceId" id="serviceId" data-bind="value: serviceId"
class="k-textbox" />
<label for="serivceName">
Service Name :
</label>
<input type="text" id="serivceName" name="serviceName" data-bind="value: serviceName"
class="k-textbox" required="true" maxlength="255" validationmessage="Service Name is required" />
<span class="k-invalid-msg" data-for="serivceName"></span>
<br />
<label for="serviceDescription">
Service Description :
</label>
<input type="text" id="serviceDescription" name="serviceDescription" data-bind="value: serviceDescription"
class="k-textbox" required="true" maxlength="1000" validationmessage="Service Description is required" />
<span class="k-invalid-msg" data-for="serviceDescription"></span>
<br />
<label for="serviceCode">
Service Code :
</label>
<input type="text" id="serviceCode" name="serviceCode" data-bind="value: serviceCode" maxlength="20"
class="k-textbox" validationmessage="Service Code is required" required="true" />
<span class="k-invalid-msg" data-for="serviceCode"></span>
<br />
<label for="baseCostAmount">
Cost :
</label>
<input type="text" id="baseCostAmount" name="baseCostAmount" required="true" min="1"
data-bind="value: baseCostAmount" validationmessage="Cost Must be greater than 0" />
<br/>
<label for="newEffectiveDate">
Effective Date :
</label>
<input id="newEffectiveDate" name="newEffectiveDate" required="true" type="date" data-bind="value: newEffectiveDate"
/>
<span data-bind="text: newEffectiveDateMessage" class="warning"> </span>
</fieldset>
<br/>
<button class="k-button" id="editServiceSaveButton" data-bind="click : validateAndSave">Save</button>
<span style="margin-left:5px; color:green" id="saveComplete" name="saveComplete" data-bind="text : SaveComplete, visible : ShowSaveComplete" ></span>
<span style="margin-left:5px; color:red" id="saveError" name="saveError" data-bind="text : SaveError, visible : ShowSaveError" ></span>
</form>
</div>
</div>
<script src="/Content/KendoUI/JS/jquery.min.js"></script>
<script src="/Content/KendoUI/JS/kendo.web.min.js"></script>
<script src="/Scripts/Views/Common.js"></script>
<script src="/Scripts/Views/Shared/_Layout.js"></script>
<script>
$(document).ready(function () {
//local variables
var getServiceUrl = $("#getServiceUrl").val();
var saveServiceUrl = $("#saveServiceUrl").val();
var serviceId = $('#serviceId').val();
var viewModel = kendo.observable({
toJSON: function () {
// This hack is because .net controllers don't like dates.
// call the original toJSON method from the observable prototype
var result = kendo.data.ObservableObject.prototype.toJSON.call(this);
result.currentEffectiveDate = common.dateFormat(this.get("currentEffectiveDate"), "mm/dd/yyyy HH:MM:ss");
result.newEffectiveDate = common.dateFormat(this.get("newEffectiveDate"), "mm/dd/yyyy HH:MM:ss");
return result;
},
saveComplete: '',
showSaveComplete: function () {
return this.get("saveComplete") != '';
},
saveError: '',
showSaveError: function () {
return this.get("saveError") != '';
},
isNew: null,
serviceId: null,
serviceName: "",
serviceDescription: "",
baseCostAmount: null,
currentEffectiveDate: null,
newEffectiveDate: null,
newEffectiveDateMessage: function () {
return "Effective date must be greater than or equal to " + common.getDateString(this.get("currentEffectiveDate"));
},
validateAndSave: function (e) {
e.preventDefault();
var validator = $("#service").kendoValidator().data("kendoValidator");
if (!validator.validate())
return false;
$.ajax({
type: "POST",
url: saveServiceUrl,
data: viewModel.toJSON(),
cach: false
}).done(function (result) {
if (!result.Success) {
viewModel.set("saveComplete", '');
viewModel.set("saveError", "Update Failed " + result.Message);
} else {
viewModel.set("SaveError", '');
viewModel.set("currentEffectiveDate", viewModel.get("newEffectiveDate"));
viewModel.set("caveComplete", 'Save Successful');
}
});
return false;
}
});
//local functions
function initControls() {
$("#baseCostAmount").kendoNumericTextBox({
format: "c",
decimals: 2
});
$('#newEffectiveDate').kendoDatePicker({ format: "MM/dd/yyyy" });
$("#service").kendoValidator({
rules: {
//implement your custom date validation
dateValidation: function (e) {
var currentDate = Date.parse($(e).val());
//Check if Date parse is successful
if (!currentDate) {
return false;
}
return true;
}
},
messages: {
//Define your custom validation massages
required: "Date is required message",
dateValidation: "Invalid date message"
}
});
}
function loadViewModelFromController() {
$.ajax({
type: "GET",
contentType: 'application/json',
url: getServiceUrl,
data: { id: serviceId },
cach: false
}).done(function (o) {
viewModel.set("isNew", o.IsNew);
viewModel.set("serviceId", o.ServiceId);
viewModel.set("serviceName", o.ServiceName);
viewModel.set("serviceDescription", o.ServiceDescription);
viewModel.set("serviceCode", o.ServiceCode);
viewModel.set("baseCostAmount", o.BaseCostAmount);
viewModel.set("newEffectiveDate", new Date(common.getDateString(o.NewEffectiveDate)));
viewModel.set("currentEffectiveDate", new Date(common.getDateString(o.CurrentEffectiveDate)));
kendo.bind($("#service"), viewModel);
});
}
function addNew() {
viewModel.set("isNew", true);
kendo.bind($("#service"), viewModel);
}
//Init the form
initControls();
if (serviceId > 0) {
loadViewModelFromController();
} else {
addNew();
}
});
</script>
</body>
</html>