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

[Solved] Grid Edit - DropDownList

22 Answers 971 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jigar
Top achievements
Rank 1
Jigar asked on 14 Sep 2010, 02:16 PM
Hi There,

I have DropDownList in Grid, DropDownList bind the data using ajax call.

when I try to edit the row, I don't see the value in DropDownList; Instead It gives error, like this.data.length is not defined in telerik.list.js.

I have used following code:
function onEdit(e) {
$(e.form).find('#aId').data('tDropDownList').select(function (dataItem) { if (dataItem.Text == e.dataItem['aId']) return true; else return false; });
}

It seems this happens because this dropdown is being bind to data using ajax call and while editing it doesn't have any data. This might be reason for this; but I also tried this
function onEdit(e){
    $(e.form).find('#aId').data('tDropDownList').reload();
    $(e.form).find('#aId').data('tDropDownList').select(function (dataItem) { return (dataItem.Text == e.dataItem['aId']); });
}

Please suggest a way to do this.

thanks a lot.
Jigar.

22 Answers, 1 is accepted

Sort by
0
Daniel
Top achievements
Rank 1
answered on 14 Sep 2010, 02:27 PM
0
Jigar
Top achievements
Rank 1
answered on 14 Sep 2010, 05:11 PM
Hi Deniel,

Thanks for your input, though I have already applied that patch.

Any Other guess what could be the problem?

Thanks.
0
Daniel
Top achievements
Rank 1
answered on 14 Sep 2010, 08:34 PM
Can post your Model, Combobox partial view and your View?

Thanks.
0
Jigar
Top achievements
Rank 1
answered on 14 Sep 2010, 08:44 PM

Model:

<UIHint("DropDownList")>
Public Property abcId As String

Partial View
<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
    Dim controlName = ViewData.TemplateInfo.GetFullHtmlFieldName(String.Empty)
    Html.Telerik().DropDownList().Name(controlName).DataBinding(Sub(binding)                
binding.Ajax().
Select("_FillDropDownList", "MutualFund", New With {.controllerName = controlName})
                                                  End Sub).Render()
%>

the view is being rendered by grid edit popup.

Thanks,

Jigar.
0
Daniel
Top achievements
Rank 1
answered on 15 Sep 2010, 05:02 AM
As say the example (and my implementation), try to use the same name in Model Property and Combobox.

Example:

Model

<UIHint("DropDownList")>
Public Property abcId As String

The Name of the Telerik DropDownList should be "abcId".

The grid colum should be "columns.Bound(p => p.abcId);"

Remember to add in the grid ".ClientEvents(events => events.OnEdit("onEdit"))"

And the Javascript shoud be:

function onEdit(e) {
    if ((typeof e.dataItem != 'undefined') && (e.dataItem != null)) {
        $(e.form).find('#abcId').data('tDropDownList').select(function(dataItem) {
            return dataItem.Text == e.dataItem['abcId'];
        });
    }
}

The "if" condition in the javascript is optional. I added because if I insert a new row the "e.dataItem" not exists. In the javascript function, the "abcId" match the Model Property and the DropDownList Name.

Try this.

Daniel.
0
Jigar
Top achievements
Rank 1
answered on 15 Sep 2010, 06:06 PM
Hi Daniel,

thanks a lot for your reply. Will try it out and let you know..

thanks,

Jigar.

0
Joan Vilariño
Top achievements
Rank 2
answered on 16 Sep 2010, 08:39 AM
Hi Jigar.

I've fixed this problem the following way... (i'm using javascript on the combobox/dropdownlist template instead on the grid itself).

Here is my template for the dropdownlist column:

<%=Html.Telerik().ComboBox().Name("myComboBox")
        .Filterable(ft => ft.FilterMode(AutoCompleteFilterMode.Contains).MinimumChars(5))
        .DataBinding(db => db.Ajax().Select("_getComboItems", "myController"))
%>
  
<script type="text/javascript">
    $(document).ready(function() { bindGridComboBox("myComboBox","myEntity"); });
</script>

And here is the javascript function I'm using:

function bindGridComboBox(combo, entity) {
    var combo = $('#'+combo);
    if (combo.length > 0) {
        var tr = combo.closest('tr:has(form)');
        if (tr.length > 0) {
            var row = $(combo.closest('div.t-grid')).data('tGrid').dataItem(tr);
            if (row && row.Id && row.Id != 0) {
                var name = eval('row.' + entity + '.Name);
                var id = eval('row.' + entity + '.Id');
                combo = combo.data('tComboBox');
                var datasource = [{ Text: name, Value: id, Selected: true}];
                combo.dataBind(datasource);
                combo.value(id);
                combo.text(name);
            }
        }
    }
}

In a nutshell, this function runs on template's document.ready (so everytime the template is created at edit time, by clicking edit in a row). Finds the control (dropdown/combo) and looks for the row containing it (so, the current edit row). Then, using that row, accesses the data collection in the grid to get the row's bound Json entity.

When it has access to the entity, usess it to create a "dummy" selectlist on the combobox, and sets the value to the current entity's value... maybe here you should change this "dummy" list for a real one, giving that combobox calls server again when you type anything on it, rebuilding the "real" list, but I don't know if dropdownlist will do it, so maybe you need to force a bind of the control or make an ajax call and populate it by yourself... give it a try.

This works perfect for me, but I don't know how will that be with DropDownList...

Cheers!!
0
Jigar
Top achievements
Rank 1
answered on 21 Sep 2010, 08:41 AM
Hi Joan,

Thanks a lot for your reply. It's really late to reply but just started to implement what you suggest.

Can you please tell me what does "entityName" here? What does it refers to?

Thanks,

Jigar
0
Joan Vilariño
Top achievements
Rank 2
answered on 21 Sep 2010, 09:00 AM
Hi Jigar... don't worry about being late, I'm in Spain and it's 9:50am atm XD. I just started to work 1 hour ago.

Yes, I forgot to clarify what is entity... entity is the class for the template model, in other words, the class for what you are showing that combobox... the one you declare in the template header like this:

<%

@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<myEntity>" %>

I post you here an example of my viewmodel and the grid that uses the template to clarify the situation.

This would be the viewmodel's classes:

 

// Entity for the combobox
public class myEntity {
    public long Id { get; set; }
    public long Name { get; set; }
}
  
// entity for the rows
public class myVMClass {
   public long Id { get; set; }
   // list of properties...
  
   // this is the property that will get combobox column
   public myEntity Entity { get; set; }
  
   public myVMClass() {
        Entity = new myEntity();
   }
}

And this is the main view's grid:

<%= Html.Telerik().Grid<myVMClass>()
     .Name("myGrid")
     // Rest of the properties of the grid...
     .Columns(columns =>
     {
         columns.Command(cm =>
                           {
                             cm.Edit();
                             cm.Delete();
                           }).Width(180);
         columns.Bound(o => o.Entity).ClientTemplate("<#= Entity.Name #>");
                    // Rest of the columns
     })
     .Editable(conf => conf.Enabled(true))
%>

I hope this helps ...

Cheers

PS: The name you should use in my first example to apply to this one I just gave you, should be "myEntity" instead "entityName" ..

 

0
Carson
Top achievements
Rank 1
answered on 23 Sep 2010, 05:40 PM
Joan,
I am trying to follow your example, but still cannot get the combobox displaying in the grid.

When my js code runs, 
var tr = combo.closest('tr:has(form)');
        if (tr.length > 0) {
always fails.

Where, exactly, should I put the combobox template? Inside a grid column or somewhere else?
What does 'form' have to do with it? Should the entire grid be inside a form? I didn't think that was the case, but not sure.
Any help is appreciated.
Thanks!

0
Joan Vilariño
Top achievements
Rank 2
answered on 24 Sep 2010, 11:19 AM
The template must be a separate .ascx file in a folder called "EditorTemplates" inside the grid view's folder.

This ascx must be named after the class name of the property you bound to that column.
 
In my sample, the combo shows items of the class "myEntity", so it must be named "myEntity.ascx" ... this is where your template goes.

So, in the grid you just have to bind your entity to the column, and the MVC "magic" will find the template for that type like this:

.Columns(cl => cl.Bound(o=>o.Entity).ClientTemplate("<#=Entity.Name#>") // Entity is a property of class "myEntity"

Anyway, the .closest('tr:has(form)') only will work if you're using inline editing... I haven't tested this in Popup editing mode.

I hope this helps you.

Joan
0
Jigar
Top achievements
Rank 1
answered on 27 Sep 2010, 06:06 PM
Hi there,

Thanks a lot for you inputs; I think I got the solution for this.

Solution: ( i am using popup mode )

Bind Grid's OnEdit event:
.ClientEvents(Sub(ev)
                  ev.OnEdit("OnGridEdit")
              End Sub)

Java Script Function:
function OnGridEdit(e) {
        if (e.mode == 'edit') {
            var objName = e.dataItem['name'];
            var cComboBox = $('#name').data('tComboBox');
            cComboBox.value(objName.id);
            cComboBox.text(objName.name);
       }
}

I hope this helps.

@Joan
Thanks a lot for you inputs.

Regards,

Jigar.
0
Jigar
Top achievements
Rank 1
answered on 28 Sep 2010, 01:46 PM
Hi,

There is a change in java-script code; It should be like this
function OnGridEdit(e) {
        if (e.mode == 'edit') {
            var objName = e.dataItem['name'];
            var cComboBox = $('#name').data('tComboBox');
            var id = objName.id;
            var name = objName.name;
            var datasource = [{ Text: name, Value: id, Selected: true}];
            cComboBox.dataBind(datasource);
            cComboBox.value(objName.id);
            cComboBox.text(objName.name);
       }
}

This works for me for both combobox and dropdownlist.

Thanks & Regards,

Jigar.
0
Joan Vilariño
Top achievements
Rank 2
answered on 28 Sep 2010, 02:05 PM
Nice approach using onEdit event and the dataItem property.... much more cleaner than mine... I'm thinking of refactoring XD

Thank you Jigar
0
Jigar
Top achievements
Rank 1
answered on 28 Sep 2010, 02:17 PM
Hi Joan,

Thanks to you, I got this idea from your code only.

I am really interested to know How the client side validation should be done in case of Combo Box when we put text which is not belong to the list?

Thanks,

Jigar.
0
Joan Vilariño
Top achievements
Rank 2
answered on 28 Sep 2010, 03:25 PM
I'm using this function in the onChange evento of the combobox:

// Checks for values on the combobox's internal list
// if it's empty, the user has typed something that wasn't in the list...
// so we wipe the control's value
function checkComboBox(e) {
    e.preventDefault();
    $(e.target).find('t-input').removeClass('input-validation-error');
    var combo = $(e.target).data('tComboBox');
    if (combo.dropDown.$items.length == 0) {
        combo.value('');
        combo.text('');
        $(e.target).find('.t-input').addClass('input-validation-error');
    }
}

This function assumes that the internal list of the combobox will be empty as you have typed something that's not in the list. If it finds that list empty, just adds the css class marking it red, and empties the values on the combobox.

Then I just have to check at onSave on my grid, not allowing to save if the combobox is empty:

function onSave(e) {
    return (e.values["myComboFieldName"] != "");  
}

Combining those two functions, onChange marks the field as required, and onSave prevents posting without having a valid value.

I hope this helps you ...

Cheers
0
Jigar
Top achievements
Rank 1
answered on 30 Sep 2010, 07:56 PM
Hi Joan,

Indeed a good idea. Thanks a lot.

Ok, here there is one more problem, in case of DropDownList. While editing I am able to show the value in dropDownList like I mentioned before, But now dropDownList has only that selected value. When we click on drop down list it won't fire the ajax request to populate it.

So while editing user has only one choice which he has selected while inserting the record.

I hope I have explained it clearly. Can you please suggest what should be the work around for the same?

Thanks,

Jigar.
0
Joan Vilariño
Top achievements
Rank 2
answered on 04 Oct 2010, 01:34 PM
Hi Jigar, and sorry for the late reply... weekends are hard, you know XD

For that case, I think you should consider trapping the "OnOpen" event and rebind your data as needed...

Tell me if you need a example ... 

Cheers
0
Rafael
Top achievements
Rank 1
answered on 13 Oct 2010, 10:09 AM
To position on the "right" Text in drop down list in Edit mode I use next JS
function employee_OnEdit(e) {
            $(e.form).find('#EmployeeId').data('tDropDownList').select(function (dataItem) {
                if (e.mode != 'insert') {
                    return dataItem.Value == e.dataItem['EmployeeId'];
                }
            });
 
But, eventually that this script doesn't work for second or third drop down list in the same row
Any advise?
0
Joan Vilariño
Top achievements
Rank 2
answered on 13 Oct 2010, 10:16 AM
From what I see .. this function you're placing at OnEdit returns a boolean value?? what's the reason of doing that? I don't get what you're trying there... can you re-state the problem and the solution?
0
Rafael
Top achievements
Rank 1
answered on 13 Oct 2010, 11:07 AM
look
I have  ClientTemplate on three columns on Ajax binding
All three columns have tempaltes like this one: 
.ClientTemplate
                            (
                                "<select id='EmployeeDDL'  class='t-state-default' disabled = 'disabled' style='Width: 180px; color:black' > " +
                                "<option value = " + "<#=EmployeeId#>" + ">" + "<#=EmployeeName#>" + "</option>" +
                                "</select>"
                            ).Width(200);
In edit mode I use JS to keep current displayed text in dropdownlist for Employee column

function employee_OnEdit(e) {
            $(e.form).find('#EmployeeId').data('tDropDownList').select(function (dataItem) {
                if (e.mode != 'insert') {
                    return dataItem.Value == e.dataItem['EmployeeId'];
                }
            });

I need some solution which keeps displayed values in Edit mode for another two columns with dropdown list
0
Gaurav
Top achievements
Rank 1
answered on 11 Nov 2010, 11:46 AM
Hi,

As described, onSave(e) can be used to return if any value from dropdown is not selected.
I want to alert message if nothing in selected. But when i put alert() in onSave(e) function alert is not called.

Please advice how do i put validation or show alert message on save when none of value is selected in the telerik dropdownlist.

Thanks,
Gaurav Garg
Tags
Grid
Asked by
Jigar
Top achievements
Rank 1
Answers by
Daniel
Top achievements
Rank 1
Jigar
Top achievements
Rank 1
Joan Vilariño
Top achievements
Rank 2
Carson
Top achievements
Rank 1
Rafael
Top achievements
Rank 1
Gaurav
Top achievements
Rank 1
Share this question
or