This is a migrated thread and some comments may be shown as answers.

Autocomplete in Grid (Batch Editing Mode)

16 Answers 543 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Roman
Top achievements
Rank 1
Roman asked on 13 Sep 2012, 07:59 AM
Hello,

I can't ge the autocomplete control work in the mvc grid. I created a new Display and Editor template to bind my person object (login and name property). The display template contains a simple Html.DisplayFor control to output the name of the person. Works perfect.

The Editor template contains an autocomplete bound to a server side data source, which populates the autocomplete controls with persons from a data store. So far so good.
Now the problem: When I leave the cell edit mode (with the autocomplete editor shown), a javascript error is thrown in "kendo.web.js". The error pops up in the following line:

that._unbindDataSource();

The error Message:
"Microsoft JScript runtime error: Object doesn't support property or method '_unbindDataSource'".

Any ideas how to get the autocomplete control work together with the grid?

16 Answers, 1 is accepted

Sort by
0
Mathias
Top achievements
Rank 1
answered on 18 Sep 2012, 03:16 PM
We found out that this problem only occurs in the latest internal build (2012.2.831) --> as soon as you have an AutoComplete-Control in an Grid with inCell-Edit-Mode (Batch Edit mode)

Please check this out. I hope this will be fixed soon.
0
Mathias
Top achievements
Rank 1
answered on 19 Sep 2012, 08:31 AM
Hi,

I added a little sample MVC3-solution which should make you easier to reproduce the problem. Just run the application, look for something in the autocomplete column and then leave the edit mode of the cell. The error occurs in the kendo.web.min.js

Hope this makes it easier to understand our problem :)
0
Accepted
Georgi Krustev
Telerik team
answered on 24 Sep 2012, 12:06 PM
Hello Mathias,

 
This is a known issue, which is fixed in the latest internal build (2012.2.924). I will suggest you download it and give it a try.

Kind regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Ryan
Top achievements
Rank 1
answered on 24 Sep 2012, 09:57 PM
I had the same problem.  I downloaded the latest build and got an autocmplete to render in the grid cell and I can select from searched drop down.

However, when I click away from the cell the grid is not updated with the value I selected from the autocomplete.  Would you be able to send a working example of the project Mathias posted?

Thanks!!!

Ryan
0
Mathias
Top achievements
Rank 1
answered on 25 Sep 2012, 07:32 AM
Hi Georgi, thanks for your help. With the latest internal build everything seems to work fine.

Like Ryan said there seems to be a bug using the binding of the autocomplete. We had similar issues after leaving the edit mode of a cell. Right now we are not using the standard binding. We updating the dataItem of the Row manually to prevent this issue.

function updateGridAfterLookup(id, userInputValue)
{
var grid = $('#Lookup').closest(".k-grid").data("kendoGrid");
var tr = $('#Lookup').closest("tr");
var dataItem = grid.dataItem(tr);
grid = $('#Lookup').closest(".k-grid").data("kendoGrid");
if (dataItem)
{
dataItem['@ViewData.TemplateInfo.GetFullHtmlFieldName("")'].ID = id;
dataItem['@ViewData.TemplateInfo.GetFullHtmlFieldName("")'].Name = userInputValue;
}
grid.refresh();
}


We are using this method for example in the Select-Event of our Lookup. He should always find the right dataItem based on the fact that only one lookup can exist in batch edit grids.

Hope this can be a workaround for you as long as the binding doesn't work correctly.
0
Ryan
Top achievements
Rank 1
answered on 25 Sep 2012, 09:32 PM
Thanks again guys.

I can't get my javascript to refresh my grid. I have something like below on any event and my grid doesn't refresh. 

        var grid $('#CashMatches').data("kendoGrid");
        grid.refresh();
Does this have something to do with how my grid is defined:



@(Html.Kendo().Grid(Model.cashMatches).Name("CashMatches")
    .Columns(c =>
    {
        c.Bound(ct => ct.cashTransactionID).Title("ID").ClientTemplate("<a id=\"tranID-#=cashTransactionID#\">#=cashTransactionID#</a>").Width(210);
        c.Bound(ct => ct.companyName).Title("Company");
        c.Bound(ct => ct.tranReceivedDate).Title("Cash Date");
        c.Bound(ct => ct.cashAmount).Title("Cash Amount").Format("{0:N2}");//.Format("#= kendo.format('{0:c}', Price) #");
 
        c.Bound(ct => ct.cashTransactionID).Title("").ClientTemplate("<a id=\"searchID-#=cashTransactionID#\" onclick=\"premiumSearch('#=cashTransactionID#')\" class=\"k-icon k-i-search\"></a>").Filterable(false);
        c.Bound(ct => ct.policySearch).ClientTemplate("#=policySearch.policyDesc#").Title("Policy").Width(260);
        c.Bound(ct => ct.premShceduledDate).Title("Scheduled Date");
        c.Bound(ct => ct.premDue).Title("Scheduled Amount").Format("{0:N2}");
        c.Bound(ct => ct.offset).Title("Offset").ClientTemplate("<span style=\"color:#=offsetColor#\">#=offset#</span>").Format("{0:N2}");
        c.Template(@<text></text>).ClientTemplate("<input type='checkbox' #= IsInBatch ? checked='checked':'' # class='chkbx' />")
                .HeaderTemplate("<input type='checkbox' id='masterCheckBox' onclick='checkAll(this)'/>");                
    })
    .ToolBar(toolbar =>
    {
        //toolbar.Save().SaveText("Update Batch");
        //toolbar.Template(@<text>@{ Html.RenderPartial("CashBatches");}</text>);
        toolbar.Template(@<text>@{ Html.RenderPartial("CashToolbar");}</text>);
 
    })
 
    .Pageable()
    .Editable(editable => editable.Mode(GridEditMode.InCell))
        .Editable(editing => editing.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
    .Sortable()
    .Filterable()
    .Selectable()
    .DataSource(d => d.Ajax().PageSize(100).ServerOperation(false)
                .Batch(true)
                .Read  (r => r.Action("getCashMatches""Cash"))
                .Update(r => r.Action("UpdateBatch""Cash"))                
                .Model(model =>
                {
                    model.Id(p => p.cashTransactionID);
                    model.Field(p => p.cashTransactionID).Editable(false);
                    model.Field(p => p.companyName).Editable(false);
                    model.Field(p => p.tranReceivedDate).Editable(false);
                    model.Field(p => p.cashAmount).Editable(false);
                    model.Field(p => p.premShceduledDate).Editable(false);
                    //model.Field(p => p.policyDesc).Editable(false);
                    model.Field(p => p.premDue).Editable(false);
                    
                })
        )
      .Resizable(resize => resize.Columns(true))
 
)




0
Georgi Krustev
Telerik team
answered on 26 Sep 2012, 10:12 AM
Hello,

 
Mathias, the name of the AutoComplete is not correct. You are setting it to "Person", which actually is the object and not the shown property. Here is how you need to define the AutoComplete.

@model SampleApplication.ViewModels.ResultEntryViewModel
 
@(Html.Kendo().AutoComplete()
    .Name(ViewData.TemplateInfo.GetFullHtmlFieldName("Name"))
    .DataTextField("Name")
    .DataSource(dataSource => dataSource.Read(read => read.Action("GetAutocomplete", "Home")).ServerFiltering(true))
    .HtmlAttributes(new { @class = "k-widget k-autocomplete k-input", style = string.Format("width:200px") })
    .Delay(500)
    .HighlightFirst(true)
)

Ryan, refresh method will just redraw the grid and will not re-fetch the data. If you need to reload the grid use the read method. If the problem still persist I will ask you open another thread as the problem is not related to this one.

Regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Mathias
Top achievements
Rank 1
answered on 26 Sep 2012, 10:30 AM
Ok but if I set the name to the shown property, only this property will be bound. Am I right with this? What we need in our case is to bind the whole object against the autocomplete. Actually I think that this isn't possible right now.

I give you a little example:
My object is called Person. Every Person has an ID and a Name. We need the ID based on the fact that there are people with the same name. The grid should only show the name of the person. And also the AutoComplete looks only for the name of a person. But it isn't enough that only the name gets rebound to the grid. We also need the ID to safe it into the DataBase.

I think in your solution we bind only the name and just the name will be rebound to the grid. We need something like a key-value-pair in this (I think the dropdown provides the key-value-stuff (.DataValueField("ID")) and it would be nice if the AutoComplete would do the same)

As you can see in my current solution (3 posts above) we rewrite the ID and Name property of our object manually to the dataItem of the grid, because of the fact that the AutoComplete doesn't support binding the whole object.

This is the reason why I set Person as the Name of the AutoComplete. I wanted to try to bind the whole object against it. The ClientTemplate of the grid should do the rest by showing only the name of the object.
0
Georgi Krustev
Telerik team
answered on 27 Sep 2012, 11:00 AM
Hello Mathias,

Yes, if you change the name of the AutoComplete to "Person.Name", then only this property will be updated. If you need to bind the AutoComplete to model, then you will need to set the name to "Person", as you did in the test application. The AutoComplete widget supports binding to object, but you need to select item from the suggestions. If you enter custom value, then the MVVM will not be able to find such item in the DataSource of the AutoComplete and will set the Person property to the custom string. That is why you see undefined after this. This is expected behavior. I believe that in this case, you will need to DropDownList widget as it does not allow custom values:

@model SampleApplication.ViewModels.ResultEntryViewModel
 
@(Html.Kendo().DropDownList()
    .Name(ViewData.TemplateInfo.GetFullHtmlFieldName(""))
    .DataTextField("Name")
    .DataValueField("Name")
    .DataSource(dataSource => dataSource.Read(read => read.Action("GetAutocomplete", "Home")))
    .HtmlAttributes(new { style = string.Format("width:200px") })
)

Check this screencast, which shows what I mean.

Regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Mathias
Top achievements
Rank 1
answered on 27 Sep 2012, 02:02 PM
Hi Georgi,

thanks for your answer. We still have a few DropDownLists in use but for this special case we need an AutoComplete. The fact is, that the amount of data is way too big for a DropDownList. Our case is very complicated. We made a Lookup-Control for some Grid-columns. This control consists of an AutoComplete, a few Buttons, a Window, 1-2 Grids in the Window,... and so on.

Right now everything still works fine. The only thing is, that we change the DataItems of the Grid manually based on the fact that the AutoComplete doesn't support the binding we need. Probably this will be supported in the future...
0
Georgi Krustev
Telerik team
answered on 27 Sep 2012, 04:07 PM
Hello Mathias,

As I pointed, currently the AutoComplete supports binding to an object, but the end-user should select some of the available suggestions. There is no way, how to support object binding to a value which does not exist in the DataSource.

All the best,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Mathias
Top achievements
Rank 1
answered on 05 Oct 2012, 09:24 AM
Okay Georgi. I tried it out and now I know what you mean.

A few more questions then:

1. I have a MVC view which gets a Model. The autocomplete is in a form - so is it possible to bind the AutoComplete (however) against the model to provide on a postback getting the changed item back? Doesn't seems to work as I expect it to.

2. Is there a dataitem of the AutoComplete? I don't mean the dataItems of the dropDown-items... i mean a dataItem of the current "value". The current object which is chosen. I only get access to the value - but I need the whole json-object which has been selected earlier.

This is the current version of the AutoComplete:
@(Html.Kendo().AutoComplete()
    .Name(ViewData.TemplateInfo.GetFullHtmlFieldName(""))
    .DataTextField("Name")
    .DataSource(dataSource => dataSource.Read(read => read.Action("GetLookupPersonAutocomplete", "Shared").Data("onLookupData")).ServerFiltering(true))
    .Events(events => events.Open("onLookupOpen").Select("onLookupSelect"))
    .HtmlAttributes(new { @class = "k-widget k-autocomplete k-input", style = string.Format("width:200px") })
    .MinLength(Model.MinimumChars)
    .Delay(200)
)


ad1: So... in a Grid it is bound to the grids-property. If I change the item of the AutoComplete everything seems to perfectly get bound to the grid (yeah the whole object seems to be in the grids dataitem!!! --> which is the goal). That actually doesn't work if a call the View by the EditorFor-call.... @Html.EditorFor(m => m.Person) --> the value doesn't get bound back... the Person property on my model is null on a postback.

ad2: I manually want to change the selected Item of the AutoComplete --> which should also get bound back to the grid/model.. Any possibility? There should be a way... it still works when selecting an item of the suggestions... so how does it work manually?
0
Georgi Krustev
Telerik team
answered on 10 Oct 2012, 07:38 AM
Hello Mathias,

 
Straight up to your questions:

#1:
The AutoComplete is a simple input element and the form will post its value. If the widget is used as an editor template (like in your case), the MVVM will get the whole object depending on the selected item in the AutoComplete. Then it will post the model corresponding to the row (depending on the edit mode). If you need to post whole object (outside of the grid), you need to do it manually.

#2:
It has a dataItem(index) method which will return value at dataSource.at(index). The AutoComplete does not persist the selected indexes and that is why you can get the index in the select event. Check this online demo for more information.

RE: ad1: 
I believe that the @Html.EditorFor(m => m.Person) will render the autocomplete (input element) with incorrect name and the MVVM will not be able to bind the input value to the row model.

RE: ad2:
Use the select method. Please note that the MVVM depends on the change event, which will be raised when the API is used. Trigger change event manually:

$("#id").data("kendoAutoComplete").trigger("change");

Regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Leon
Top achievements
Rank 1
answered on 25 Sep 2013, 06:38 PM
Your example solution posted here has the same issue that I am experiencing.  When you click the Add button for a new row in the grid, the "Person" object is undefined.  Is there a solution to this?
0
Georgi Krustev
Telerik team
answered on 30 Sep 2013, 08:28 AM
Hello Leon,

 
I will need more information about your current implementation. A runnable test project will be of great help.

Regards,
Georgi Krustev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Leon
Top achievements
Rank 1
answered on 30 Sep 2013, 01:53 PM
I found the solution to my issue.  Don't use complex data types (i.e. a model object) to bind to a grid column!  Flatten out your Model object from your data objects such that the grid columns are being bound to simple types (strings, integers, etc.).
Tags
Grid
Asked by
Roman
Top achievements
Rank 1
Answers by
Mathias
Top achievements
Rank 1
Georgi Krustev
Telerik team
Ryan
Top achievements
Rank 1
Leon
Top achievements
Rank 1
Share this question
or