Autocomplete in Kendo UI MVC Scheduler Editor Template not working - kendo-ui

I added a autocomplete in the scheduler editor template. It returns the correct data when I input the first char in the textbox, but after that, read action is not called anymore (it won't reach the break point in controller) and it seems the autocomplete cached the results from the first char input.
For example, in the database, I have 2000 client names. Among them 100 whose name starts with 'a'. When the editor launched from scheduler, I input 'a', it shows 100 names. Then, I delete the 'a', input 'c'. Nothing shows up, but I have 200 names starts with 'c'. And this time, it did not hit the breakpoint in the controller.
Here is the autocomplete in editor template:
<div data-container-for="client" class="k-edit-field">
#(Html.Kendo().AutoComplete()
.Name("client")
.DataTextField("ClientName")
.Placeholder("Please fill in Name")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetClientList", "Scheduler").Data("onAdditionalClientData");
});
})
.HtmlAttributes(new { style="width:100%" })
.MinLength(1)
.Height(300)
)
</div>
The scheduler is in index.cshtml, I put the javascript in index.cshtml. If I put it in the template file, it shows error.
<script>
function onAdditionalClientData() {
return {
query: $("#client").val()
};
}
</script>
In the controller, I have
public JsonResult GetClientList(string query)
{
....
var ret = doctors.OrderBy(x => x.Name).Take(20).ToList();
return Json(ret, JsonRequestBehavior.AllowGet);
}
I searched, it seems we can use autocomplete in the scheduler edit template. But all sample code I can find is for Kendo UI and loads data from static list. I need to load the data from the database using Json call.
Any thoughts? Thanks

oh, well, figured it out.
source.Read(read =>
{
read.Action("GetClientList", "Scheduler").Data("onAdditionalClientData");
}).ServerFiltering(true);
The only change needs is to add ServerFiltering(true). otherwise, it will do the Read action once and use Client side filtering, which is exactly what I saw.
Maybe Kendo can improve the doc for UI for MVC a little.

Related

Using a custom window with ajax form to add new grid row

I need to create a more advanced method of adding new elements to a kendo grid, so in short I have replicated the following example as it does exactly what I needed:
https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/window/KendoWindow-Ajax-Form
And it works just fine. Only difference is the new row is added in it's correct spot in the grid, and not on the top as per usual. How can I, using the example linked to, place the new row on the top?
(I'm thinking it's not necessary to show my code here as it very closely resembles the code given in the link above)
So If you want to add a row up top I am thinking you could use a custom template. I may not be very clear on what you are doing but , I will attempt to help you.
Here is the grid in the code:`
#(Html.Kendo().Grid<OrderViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Message).EditorTemplateName("MessageEditor");
}
.DataSource(datasource => datasource
.Ajax()
.Read(read => read.Action("GetOrders", "OrdersData"))
)
)`
Then write the template like this:
<script type="text/x-kendo-template" id="MessageEditor">
<div class="k-header k-grid-toolbar">
<div style="display: inline-block; font-size:1.25em; padding:
</div>
</div>
</script>
Well this may not be the best solution , however it is the only way I know to create a custom column in a Kendo grid
Ended up finding the solution myself eventually. Going by the example in the link I made in the original post, this is what I did:
Firstly when a new "order" is made, I make sure that the model returned in the "Create" method in OrdersDataController has an ID from when the model is added to the DB.
So when this part gets executed in "_OrdersCreate.cshtml":
#if (Model != null && ViewData.ModelState.IsValid)
{
<script>
closeCreatePopup();
</script>
}
I send information on the new Order created. So to that end I have modified "closeCreatePopup()" to handle arguments.
So for the finished results I will just use a piece of code from my own project, the following is my implementation of "closeCreatePopup()":
function closeCreateEmployeeWindow(name, rHPersonID, personID, organizationID) {
if (name !== undefined
&& rHPersonID !== undefined
&& personID !== undefined
&& organizationID !== undefined) {
var grid = $("#grid").data("kendoGrid");
grid.dataSource.insert({ Name: name, RHPersonID: rHPersonID, PersonID: personID, OrganizationID: organizationID });
grid.dataSource.sync();
}
var wnd = $("#createEmployeeModal").data("kendoWindow");
wnd.refresh({ url: '#Url.Action("CreateEmployee", "Employee", new { Area = "Administration" })' });
wnd.close();
}
The important part is this:
var grid = $("#grid").data("kendoGrid");
grid.dataSource.insert({ Name: name, RHPersonID: rHPersonID, PersonID: personID, OrganizationID: organizationID });
grid.dataSource.sync();
What is happening here is I use the "insert" method from the grid, and add a new object. "Insert" inserts the new object to the very top of the grid. Remember to call the "sync" method right after.
By doing it like this, the normal "create" method built into the grid is replicated.

how to get selected value for Kendo DropDownList

I can't figure out how to determine which item is selected in the my kendo dropdownlist. My view defines it's model as:
#model KendoApp.Models.SelectorViewModel
The ViewModel is defined as:
public class SelectorViewModel
{
//I want to set this to the selected item in the view
//And use it to set the initial item in the DropDownList
public int EncSelected { get; set; }
//contains the list if items for the DropDownList
//SelectionTypes contains an ID and Description
public IEnumerable<SelectionTypes> ENCTypes
}
and in My view I have:
#(Html.Kendo().DropDownList()
.Name("EncounterTypes")
.DataTextField("Description")
.DataValueField("ID")
.BindTo(Model.ENCTypes)
.SelectedIndex(Model.EncSelected)
)
This DropDownList contains the values I expect but I need to pass the selected value back to my controller when the user clicks the submit button. Everything works fine except I don't have access to which item was selected from the controller's [HttpPost] action. So, how do i assign the DropDownList's value to a hidden form field so it will be available to the controller?
For anyone who found this wondering how to get the selected value in JavaScript, this is the correct answer:
$("#EncounterTypes").data("kendoDropDownList").value();
From the documentation: http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#methods-value
when select a value from a dropdown list, and in the selec event , we can get the selected value as following ,
#(Html.Kendo().DropDownList()
.Name("booksDropDown")
.HtmlAttributes(new { style = "width:37%" })
.DataTextField("BookName")
.DataValueField("BookId")
.Events(x => x.Select("onSelectBookValue"))
.DataSource(datasource => datasource.Read(action => action.Action("ReadBookDropDow", "PlanningBook").Type(HttpVerbs.Get)))
.OptionLabel("Select"))
javascript function like following ,
function onSelectBookValue(e) {
var dataItem = this.dataItem(e.item.index());
var bookId = dataItem.BookId;
//other user code
}
I believe this will help someone
Thanks
Hello I was just going through this problem,kept on searching for 2 hours and came up with a solution of my own.
So here is the line to fetch any data bidden to the kendo drop down.
$("#customers").data("kendoDropDownList").dataSource._data[$("#customers").data("kendoDropDownList").selectedIndex].colour;
Just change the id customers to the id you have given tot he kendo drop down.
Maybe you should be using the DropDownListFor construct of the Kendo DropDownList like so in your view:
#(Html.Kendo().DropDownListFor(m => m.EncSelected)
.Name("EncounterTypes")
.DataTextField("Description")
.DataValueField("ID")
.BindTo(Model.ENCTypes)
.SelectedIndex(Model.EncSelected)
)
This way, when you submit, it will be availble on the POST request and you won't need to put an hidden field anywhere.
BUT should you need to use the hidden field for some reason, put it there, subscribe the the select event of the dropdown list and put using JQuery (for instance) put the selected item on the hidden field.
It's your choice :)
If you want to read also out the text of the dropdown, you can get or set the value by using the following kendo function:
$('#EncounterTypes').data("kendoDropDownList").text();
REFERENCE TO THE DOCUMENTATION
Using this .val() as #Vivek Parekh mentions will not work - there is no function .val() in the kendo framework.
If you want you could use jQuery and get the value back: $('#EncounterTypes').val()
Updated DEMO
$("#EncounterTypes").kendoDropDownList().val();
You can get the selected item like following code and then use item.property to get further information
var selectedFooType = $("#fooType").data("kendoDropDownList").dataItem();
selectedFooType.name
//OR
selectedFooType.id

MVC3 C# TextArea/CkEditor validation issue

I have an MVC3 C# .Net Web App. We are using the ckEditor library to enhance the TextAreas in our app. When using a standard TextArea, the Validation operates correctly. However, in the enhanced TextAreas (implementing the ckEditor), when submitting the page, the Validation fires an error. "Description is Required" even when though there is data present in the TextArea. Upon a second click of the Submit, the form submits fine.
Domain class property:
[Display(Name = "Description")]
[Required(ErrorMessage = "Description is required.")]
public virtual string Description { get; set; }
HTML:
<td style="border: 0;text-align:left " >
#Html.TextAreaFor(model => model.Description,
new
{
rows = 5,
cols = 100,
#class = "celltext2 save-alert"
})
#Html.ValidationMessageFor(model => model.Description)
</td>
I think that applying the ckEditor attributes is messing it up somehow. Ideas?`
Let me clarify more. We have a .js file that queries the controls and then does ckEditor initialzation. when I remove the $(this).ckeditor({}) it works fine.
JS File:
$('textarea').each(function () {
$(this).ckeditor({});
});
Something like this might work:
$('textarea').each(function () {
var textarea = $(this);
$(this).ckeditor({}).on('blur', function() {
textarea.html( $(this).html() );
});
});
EDIT(I've never used the jQuery adapter, after a small lesson I found this to work, the above the blur never fires and $(this).html() is not defined):
$('textarea').each(function () {
var textarea = $(this);
textarea.ckeditor(function () {
textarea.ckeditorGet().on('blur', function () {
textarea.html( this.getData() );
});
});
});
I think it's a little simpler than that. CKE creates an iframe that it is used instead of the actual textarea and you do correctly need to update the contents of the textarea with the data inside CKEditor before submitting. I would suggest, however, that you do this on submit instead of on blur. I would recommend setting an id to the relevant DOM elements but you get the idea.
// Replace textarea(s)
$('textarea').each(function () {
$(this).ckeditor({});
});
// Bind on submit event to update the text
$('form').submit(function() {
// Upate textarea value with the ckeditor data
$('textarea').val(CKEDITOR.instances.ValueCKE.getData());
});

How to properly disable an Html Helper Textbox or TextBoxFor?

I have a razor display that is being used for entry. In one case, I would like the user to be able to populate the text box, in the other case, I would like to prevent the user from populating it. I am using code like:
#Html.TextBoxFor(model => model.Goop, new { #class = "text-box", maxlength = 2, onfocus = "javascript:this.select();" })
if (Model.Review.ReviewType.Equals("M"))
{
<script type="text/javascript">
$(function () {
$("#Goop").prop("disabled", true);
});
</script>
}
I have tried to do this several ways, jQuery (above), CSS attribs, javascript, ASP.NET... but all have the same issue: When the form is submitted, if the Goop textbox is disabled, the value for Goop in the model is Null. Ideas?
Thanks in advance!
Maybe it's not as cool without jQuery, but when I do this in my apps I do something along the lines of
if (Model.Review.ReviewType.Equals("M"))
{
#Html.DisplayFor(model => model.Goop)
#Html.HiddenFor(model => model.Goop)
}
else
{
#Html.TextBoxFor(model => model.Goop)
}
If a form element is disabled, it does not post a value. That's how it's supposed to work.
To work around this, you will need to do one of several things. You can enable the fields just before posting by intercepting the submit method. You can use a hidden field to store the data in addition to the disabled control. Or you can just assume the values on the controller side.
by the way, it should be .prop("disabled", "disabled"), which renders as disabled="disabled", that's standards compliant.

Lost: Getting a fully rendered view via Ajax in ASP.NET MVC3 / jQuery

All,
I am very new to MVC3 / jQuery combo and have been reading tutorials. While I kind of get the concept, razor syntax etc. I'm still a bit confused on how to implement a basic concept that I'm trying to.
I have a textarea and when someone enters some text into it and hits enter, I want to trigger a ajax call to the server with the content of the text area, and get back a fully formed HTML blurb that I can put in a div. Now as I understand in MVC3 this would be a view, so in a sense I'm rendering a view on the server and sending it back so I can put it in HTML.
Is this possible? Any examples that I can look up to see how this done? I know how to capture keystrokes, get the value etc., it's this partial rendering of a fully formed HTML via ajax that I'm struggling to understand.
Thanks,
You can do with jQuery. This is how it works. you listen for the keydown event of the text area and when there is a keydown, check what key it is.if it is enter key, then make a jQuery ajax post call to a server page (action method in your controller with the data).Save the data there to your tables and return the markup of what you want and return that. in your script load it to your relevant div.
HTML
//Load jQuery library in your page
<textarea id="txtComment" > </textarea>
<div id="divComment"></div>
Javascript
$(function(){
$("#txtComment").keydown(function (event) {
if (event.keyCode == 10 || event.keyCode == 13) {
var comment=$("#txtComment").val();
comment=encodeURIComponent(comment);
$.post("yourcontroller/actionmethod?data="+comment,function(response){
$("#divComment").html(response);
});
}
});
});
and your controller action method
public ActionResult actionmethod(string data)
{
//Do some sanitization on the data before saving.
// Call your method to save the data to your tables.
CommentViewModel objCommentVM=new CommentViewModel();
objCommentVM.Comment=data;
return View("PartialCommentView",objCommentVM);
}
You should have a ViewMolde class called "CommentViewModel" like this
public class CommentViewModel
{
public string Comment{ set; get; }
}
and you should have a View called PartialCommentView which is strongly typed to CommentViewModel
#model FlashRack.ViewModel.RackViewModel
#{
Layout = null;
}
<div>
#Model.Comment
</div>
If you are simply returning a string, instead of returning a View, you can simply return the string using Return Content("your string here") method as well. But i prefer returning the ViewModel via View because it is more scalable and clean approach to me.
Your action method will return the markup you have in your PartialCommentView with the data.
Keep in mind that you have to take care of the special characters and escaping them properly.

Resources