KendoUI grid filter not working - asp.net-mvc-3

I am just starting with Kendo UI. I have a .NET MVC Razor project that will include a Kendo Grid. My page loads fine and looks good-the data is in the grid, but I have two issues:
when I click the "filter" icon, nothing happens (no pop-up, nothing)
when I run the page I get an error in visual studio inside the kendo.all.min.js file (Error: Microsoft JScript runtime error: Object doesn't suport this action. Code highlighted reads "d.transport=new n.data.transports[a.type](c(h,{data:i}))" Running in firebug gives this error: "n.data.transports[a.type] is not a constructor"
I am using a Model that is of type List(CustomViewModel). I have added the following scripts and css to my _Layout partial view:
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/kendo.all.min.js")" type="text/javascript"></script>
(I tried using "kendo.web.min" and "kendo.aspnetmvc.min" in the place of "kendo.all.min" and I get the same result, but the error is in kendo.web.min.js)
My page looks like this:
#model List<CustomViewModel>
...
#(Html.Kendo().Grid(Model)
.Name("applicantGrid")
.Columns(columns =>
{
columns.Bound(p => p.ApplicationID);
columns.Bound(p => p.FirstName);
columns.Bound(p => p.LastName);
})
.Sortable()
.Filterable()
.Pageable()
)
My View Model looks like this:
public class CustomViewModel
{
[ScaffoldColumn(false)]
public Guid CustomViewModelID { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
}
I've noticed that in the Kendo examples (http://demos.kendoui.com/web/grid/local-data.html) the cursor is a hand when it's over the filter icon. On my page, the cursor is an arrow when it's over the filter icon.
Sorting works fine. I've also adjust this example a bit to get select and edit buttons working fine, but the filter just won't work.
I tried posting on the Kendo forums, but haven't gotten a response.

Try this:
Add to your ASP.NET MVC layout page:
<script src="#Url.Content("~/Scripts/kendo.web.min.js")"></script>
<script src="#Url.Content("~/Scripts/kendo.aspnetmvc.min.js")"></script>
For more information see this: http://www.kendoui.com/documentation/asp-net-mvc/introduction.aspx
And download the last scripts version. Apparently earlier versions of kendo.web.mindont have .Filterable() option.

Related

How to use knockout.js in MVC 3 Razor?

i am newbie knockout.js. Also i ama upper intermadiate in asp.net mvc 3. i really want to learn how to use knockout js in mvc 3 razor? but below code is not working also return to me empty total price. There is no error. Help please thanks...
Model:
public class GiftModel
{
public string Title { get; set; }
public double Price { get; set; }
}
View:
#using System.Web.Script.Serialization;
#model IEnumerable<knockout1.Models.GiftModel>
#{
ViewBag.Title = "Index";
}
<script src="/Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script type="text/javascript">
var initialData = #(new JavaScriptSerializer().Serialize(Model));
var viewModel = {
gifts : ko.observableArray(initialData)
};
ko.applyBindings(viewModel);
</script>
<h2>Index</h2>
<p>You have asked for <span data-bind="text: gifts().length"> </span> gift(s)</p>
Controller:
public class TestController : Controller
{
//
// GET: /Test/
public ActionResult Index()
{
var initialState = new[] {
new GiftModel { Title = "Tall Hat", Price = 49.95 },
new GiftModel { Title = "Long Cloak", Price = 78.25 }
};
return View(initialState);
}
}
I guess you are following this tutorial.
You have a couple of errors. First replace:
var initialData = #(new JavaScriptSerializer().Serialize(Model));
with:
var initialData = #Html.Raw(Json.Encode(Model));
This ensures that your model is properly JSON encoded. In the original article Steven Sanderson is using the WebForms view engine but you seem to be using the Razor view engine. So make sure that you adapt your syntax accordingly (don't forget that the # razor function automatically html encodes the output contrary to the <%= WebForms syntax).
And the second problem with your code is that you attempted to bind your knockout model before your DOM is ready (i.e. you have placed the ko.applyBindings(viewModel); call before the actual span containing the bindings). So either wrap your call in a $(document).ready or place your scripts at the end of the document, just before closing your </body> tag (recommended).
Also I would recommend you using url helpers to reference your scripts, don't just hardcode those urls, your application will break as soon as you publish in IIS:
#model IEnumerable<GiftModel>
<h2>Index</h2>
<p>You have asked for <span data-bind="text: gifts().length"> </span> gift(s)</p>
<script src="#Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
<script type="text/javascript">
var initialData = #Html.Raw(Json.Encode(Model));
var viewModel = {
gifts : ko.observableArray(initialData)
};
ko.applyBindings(viewModel);
</script>
So as you can see the 2 problems you were having have strictly nothing to do with knockoutjs. So what I would recommend you if you want to learn some framework is to learn it independently. Don't mix up technologies or you will get mixed up.
So go ahead over the knockoutjs site and start the tutorials working on static HTML pages. Forget about ASP.NET MVC for the moment. Forget about Entity Framework. Just learn the framework starting from a static HTML page. This way you will better understand how it works.

How use Kendo UI Editor in asp.net mvc3 with razor?

I'm using editor from Kendo UI, so I have big problem.
I don't know how display items which are returned by editor.
Editor convert something like:
<img src="someurl" />
to:
lt;p><img src="someurl"/></p>
and I keep converted string in database, and try display it with:
#Html.Raw(item.description)
where description is string returned by kendo.
So I have no idea how display it correctly in my View
Any help would be appreciated.
There is an option of the KendeUI editor called encoded which configures whether the Editor should submit encoded HTML tags or not.
The default value for encoded is true
If you wan't to store the unencoded text use this sniplet when creating your editor:
$("#Editor").kendoEditor({
encoded: false
});
But because you are not sending encoded text to the server the Asp.net request validator kicks in and it will abort your request.
If you are using strongly typed views what you can do is to use the AllowHtmlAttribute on your model property:
View:
#model MyModel
#using(Html.BeginForm("SomeAction", "SomeController"))
{
#Html.TextAreaFor(m => m.Editor)
<input type="submit" value="Save" />
}
<script type="text/javascript">
$(function(){
$("#Editor").kendoEditor({
encoded: false
});
});
</script>
Model:
public class MyModel
{
[AllowHtml]
public string Editor { get; set; }
}
Controller action
public ActionResult SomeAction(MyModel myModel)
{
//Save to db, etc.
}
You also need to set the following in your web.config or this attribute won't have effect in .NET 4.0:
<httpRuntime requestValidationMode="2.0"/>
I found this solution for MVC:
in View
<div class="editor-field">
#(Html.Kendo().EditorFor(model => model.HtmlField).Encode(false))
#Html.ValidationMessageFor(model => model.HtmlField)
</div>
in model:
[DataType(DataType.Html)]
[AllowHtml]
public string HtmlField{ get; set; }
That was enough
Simplier way to do it is make changes in controller, no in view and model. So:
View
$("#Editor").kendoEditor();
Model
public class MyModel
{
public string Editor { get; set; }
}
Controller
Editor = Server.HtmlDecode(Editor);
HtmlDecode
The editor templates generated from the .NET Wrappers aren't working any more. Here is a fix.
http://pknopf.com/blog/kendo-ui-editor-templates-for-asp-net

Rectify the input at client side using RemoteValidation

Is there any possibility of rectifying the input at client side using Remote Validation?
For example, the user will enter the date as 010101 which means 01-Jan-2001, can Remote Validation reflect/pass the rectified value (010101 into 01-Jan-2001) at/to client side?
I have a scenario where i have JS to format the input into correct date format. Later on i had to use RemoteValidation. My remote validation receives date in ddmmyy format (RemoteValidation gets called before JS), it first converts it into correct date and then perform validation, and then my JS does not get called at all and so 010101 is not get converted into 01-Jan-2001.
Edit
There are two things i would like to get help for
1- Is there anyway a remote validation function can modify the model/data passed to it for validation and then pass it back to the view so that user can see the modified version of the model/data
[Deleted:2- I have JavaScript for a date field which formats the date when focus is lost. It is working fine. When i used Remote validation along with JS, the script does not get called at all.]
Edit
Model
public class master
{
public string sometext { get; set; }
public child mychild { get; set; }
}
public class child
{
public child()
{
thedate = DateTime.MaxValue;
}
[Remote("ValidateDate", "Test", ErrorMessage = "Invalid Date")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:mm/dd/yyyy}", NullDisplayText = "Enter Date")]
public DateTime? thedate { get; set; }
}
View
#model Models.master
#using Web.Framework
#{
Layout = null;
}
<html>
<head>
<title>Test - My ASP.NET MVC Application</title>
<script src="#Url.Scripts("jquery-1.7.1.min.js")" type="text/javascript"></script>
<script src="#Url.Scripts("jquery-ui-1.8.11.js")" type="text/javascript"></script>
<script src="#Url.Scripts("modernizr-2.0.6-development-only.js")" type="text/javascript"></script>
<script src="#Url.Scripts("AjaxLogin.js")" type="text/javascript"></script>
<script src="#Url.Scripts("jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Scripts("jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Scripts("jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="#Url.Scripts("MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Scripts("MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="#Url.Scripts("myScripts.js")" type="text/javascript"></script>
</head>
<body>
#using (Html.BeginForm("testSubmit", "Test"))
{
#Html.LabelFor(m => m.sometext)
<br />
#Html.TextBoxFor(m => m.sometext)
<br />
#Html.LabelFor(m => m.mychild.thedate)
<br />
#Html.TextBoxFor(m => m.mychild.thedate, new { onblur = "doDate(this, '');" })
#Html.ValidationMessageFor(m => m.mychild.thedate)
<br />
<input type="submit" value = "Submit me" />
}
</body></html>
Controller
public ActionResult testSubmit(master model)
{
#ViewBag.Message = "OK";
return View("response");
}
public JsonResult ValidateDate(DateTime? thedate)
{
return Json(HttpContext.Request.QueryString["mychild.thedate"].ToString(), JsonRequestBehavior.AllowGet);
}
My remote validator always receives null in thedate, but i can access the value from query string but the value is unformatted i.e. Remote validation gets called before JS which means i have to format the date first in remote function and then validate, once validated then this input is formatted again by JS and both have to be synced.
Now, how can i get the formatted value in Remote function OR pass the formatted value from Remote function to the View ?
Since i didn't get any answer so the answer, so far, is "No".

Bind <select> to viewmodel in ASP.NET MVC 3

I have the following view model
public class FooViewModel
{
public int SelectedCategoryId { get; set; }
public IEnumerable<CategoryDto> AvailableCategories { get; set; }
}
in my view I am using jquery template to bind my data to a select tag
<script type="text/javascript">
$(document).ready(function () {
var categories = #Model.AvailableCategories.ToJson();
var categoryMarkup = '<option value="${Id}"${Selected}>${Name}</option>';
$.template("categoryTemplate", categoryMarkup);
$.tmpl("categoryTemplate", categories).appendTo($('#categories'));
});
</script>
<select id="categories"></select>
What would I need to do to make sure my SelectedCategoryId viewmodel property gets populated on the POST? I'd prefer not to use the Html.DropDownList if I can get away with it
Simply add it in your form using the html helpers. Ex.
Html.HiddenFor(o=>o.SelectCategoryId)
If your combo box is changing this then simply set an onchange event
("#selectId").change(function(){
//something like this - untested
$("#SelectCategoryId").val(this.value);
});
Unless you are using an explicit jQuery .ajax() call in that case you will need to add this value to the data. Which are you using when you post? I don't see your form above anywhere

MVC 3 Razor #Html.ValidationMessageFor not working in partial loaded via jquery.load()

I have put together a small example here just to replicate the problem.
I have a strongly typed partial view _Name.cshtml:
#model ValidationInPartial.ViewModels.MyViewModel
<h2>#ViewBag.Message</h2>
<fieldset>
<legend>Name</legend>
<div class="editor-label">
#Html.LabelFor(model => model.MyName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MyName)
#Html.ValidationMessageFor(model => model.MyName)
</div>
Reload Name
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<script type="text/javascript">
$(document).ready(function () {
$("#reload").click(function () {
$("#divName").load("Home/NameReload");
});
});
</script>
that is initially loaded and displayed inside the main Index.cshtml
<div id="divForm">
#using (Html.BeginForm()) {
<div id="divName">
#Html.Partial("_Name")
</div>
}
</div>
The field MyName is required and validation is implemented through Required attribute in MyViewModel
namespace ValidationInPartial.ViewModels
{
public class MyViewModel
{
[Required(ErrorMessage = "Please enter a Name.")]
public string MyName { get; set; }
}
}
After the page is loaded the first time, if you click the Create button leaving the field empty the validation message "Please enter a Name." shows beside the field and the field itself turns pink, which is the expected behaviour.
Now by clicking the "Reload Name" link, which makes an ajax call (jquery.load(...)), the partial is reloaded, here is controller code:
public PartialViewResult NameReload()
{
MyViewModel myViewModel = new MyViewModel();
ViewBag.Message = "Name Reloaded";
return PartialView("_Name", myViewModel);
}
This time if you click the Create button leaving the field empty the validation message does not appear beside the field, although the field turns pink.
It turns out that when reloading the partial the #Html.ValidationMessageFor doesn't render the validation message as the first time.
Here is the jquery files I use
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
I wonder if this is a bug in the way the Razor engine renders the #Html.ValidationMessageFor or is that a problem with jquery?
Any idea why this happens?
I have also read somewhere that the ajax call looses all the scripts for the page, in fact I have to keep any javascript code inside the partial so that they can be rendered and used again.
In the meantime I found a workaround which is to manually render in the partial what was supposed to be rendered by #Html.ValidationMessageFor which is:
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="MyName"></span>
However this workaround means that if we change the type of validation or just the validation message inside the Required attribute in the ViewModel, we need to modify this hard-coded piece of html in the view.
#NickBork has a great answer here. The key is that ASP.NET's MVC rendering engine does not output the validation script if it doesn't think that there is a form. The example given hacks it buy putting in a form and then selection an inner section of HTML from was was returned, essentially throwing the outer wrapper of the form away.
There is another method so that you can just get your view:
ViewContext.FormContext = new FormContext();
With this method, there won't actually be FORM code output, but the validation markup will be there.
Thanks,
John
Validation markup (span tags, custom field attributes, etc) are not rendered unless your fields are contained within a FORM. The validation plugin itself does not work with elements outside of a form.
When ASP.NET renders your Partial View the controls are not within a form and thus do not get the elements rendered.
When you load you're partial content you'll need to parse the HTML using a jQuery selector.
In my sample below I have a TBODY on the parent View page that contains rows. When I need to add additional rows, I make a call to a View which had a form, table, tbody and collection of rows.
$.ajax({
type: "POST",
url: "/controller/action",
data: ({Your: 'dataHere'}),
dataType: "html",
success:
function(response){
$('tbody').append($('tbody',$(response)).html());
//The validation plugin can't bind to the same form twice.
//We need to remove existing validators
$('form').removeData("validator");
//Refresh the validators
$.validator.unobtrusive.parse(document);
},
error:
function(){
alert('An error occured while attempting to add the new content');
}
});
Note that I'm using a jQuery selector to select the rows that are inside of the View/PartialView that are loaded in by using AJAX:
$('tbody',$(response)).html()
The rest of the wrapper just appends the rows from the AJAX View/PartialView to the calling parents tbody:
$('tbody').append($('tbody',$(response)).html());
A couple other notes, after the validator plugin has been run on a form, it can not be called again without re-adding it (see jquery.validate.unobtrusive not working with dynamic injected elements)
To fix this, I first call the following method to remove all validators:
$('form').removeData("validator");
$("form").removeData("unobtrusiveValidation");
I then refresh the validators using the following:
$.validator.unobtrusive.parse(document);
I can't remember where I found the solution. The reason is because you are loading a PartialView into a View that has already been parsed by the jquery.validator.unobtrusive library. You need to re-parse the unobtrusive library
function ReparseValidation(){
jQuery.validator.unobtrusive.parse("#yourcontainer");
}

Resources