Combobox a custom read Datasource as Grid Editor

8 posts, 1 answers
  1. Bryan
    Bryan avatar
    28 posts
    Member since:
    Oct 2014

    Posted 28 Oct 2014 Link to this post

    Hi,
    I've added code so that the combobox datasource reads from a cached set of data initially, then makes a server call if more than a couple of letters are typed in and refreshes the data (sort of a combined Combobox and Autoselect):

    <img height="20px" width="20px" src="ASSETS/IMAGES/jumpArrow.svg" id="jumpMovie" /><input id="movies"/><br />

    $("#movies").kendoComboBox({
    dataTextField: "Display",
    dataValueField: "CPSWGUID",
    select: onSelect,
    dataSource: new kendo.data.DataSource({
    serverFiltering: true,
    transport: {
    read: function (operation) {
    var url = "/api/Lookup/2/";

    var cashedData = localStorage.getItem("moviesData");
    //alert($(this).attr('id'));

    var combobox = $("#movies").data("kendoComboBox");

    if (cashedData === null) {
    $.getJSON(url, function (json) {
    localStorage.setItem("moviesData", JSON.stringify(json));
    operation.success(json);
    });
    }
    else {
    if (combobox.text() == '' || combobox.text() == undefined) {
    var retval = $.parseJSON(cashedData);
    operation.success(retval);
    } else {
    $.getJSON(url, { searchvalue: combobox.text() }, function (json) {
    operation.success(json);
    });
    }
    }

    }
    },
    schema: { data: "Table" }
    }),
    ShowToggleImage: false,
    headerTemplate: '<div class="dropdown-header">' +
    '<span class="k-widget k-header"><a onclick="addNewRecord(\'movies\')">Add New</a></span>' +
    '<span class="k-widget k-header"><a onclick="clearComboVal(\'movies\')">Clear</a></span></div>',
    template: '<span class="k-state-default"><h3>#: data.Display #</h3><p>#: data.Display2 #</p></span>',
    });

    var combobox = $("#movies").data("kendoComboBox");

    combobox.input.keyup(function (event) {
    if (combobox.text().length == 0) {
    combobox.dataSource.read();
    combobox.value('');
    } else if (combobox.text().length >= 3) {
    if (event.keyCode != 40 && event.keyCode != 38 && event.keyCode != 13) {
    combobox.dataSource.read();
    }
    }
    });

    $(document).off('click', '#jumpMovie').on('click', '#jumpMovie', function () {
    if (combobox.value() != '') {
    alert(combobox.value());
    }
    });

    function clearComboVal(ctrlname) {
    var me = $('#' + ctrlname).data("kendoComboBox");
    me.value('');
    }

    function addNewRecord(ctrlname) {
    var me = $('#' + ctrlname).data("kendoComboBox");

    me.dataSource.add({ CPSWGUID: "3FB46FDE-E333-424B-8690-2B4D9EC20090", Display: "Record, New" });
    me.value("3FB46FDE-E333-424B-8690-2B4D9EC20090");
    }

    This is something I'm hoping to use as a standalone control several places in the application and would ideally also like to have it embedded in grids. My questions are:
    1. Is it possible to wrap something like this in an editor in a grid so that the datasources are individual to the cells being looked at?
    2. How would I refer to the data("kendoCombobox") in the datasource of the combobox in a generic way where I wouldn't have to specify the id of control itself? This would probably be necessary for anywhere that "movies" is explicitly stated.

    Thanks for your help.
  2. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3707 posts

    Posted 30 Oct 2014 Link to this post

    Hello Bryan,

    Straight up to your questions:

    #1:
    You can create a custom editor function that will create an unique editor on every call. Check this demo that demonstrates how to define a custom grid editor.

    #2:
    The best approach will be to use function currying. Thus you will be able to pass the id of the widget to a function that returns a DataSource instance. Here is a demo that shows how to do this.

    Regards,
    Georgi Krustev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. Bryan
    Bryan avatar
    28 posts
    Member since:
    Oct 2014

    Posted 03 Nov 2014 in reply to Georgi Krustev Link to this post

    Fantastic. Just what I was looking for.
    A quick follow up: is there a way of creating a unique id for a column editor in the column? Is there an options.id or something similar? I'm using this code:

    function selectorcolumneditor(container, options) {
    $('<input id="xx" required data-text-field="Display" data-value-field="CPSWGUID" data-bind="value:' + options.field + '"/>')
    createDDSelector("xx", 2)
    }

    where createDDSelector creates the control I've been working on for the input with that id and an extra variable.
    There's a rowID in the grid that I could pass somehow that'd be unique or something else so I know that the individual controls will get handled correctly.
    Thanks for your help, Georgi.

  5. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3707 posts

    Posted 04 Nov 2014 Link to this post

    Hello Bryan,

    Well, the options pass only field name, which can be used if you believe that there won't be any other elements created with the same ID. The best solution is to use a unique id (guid for instance) created manually in the selectorcolumneditor function.

    Regards,
    Georgi Krustev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. Bryan
    Bryan avatar
    28 posts
    Member since:
    Oct 2014

    Posted 04 Nov 2014 in reply to Georgi Krustev Link to this post

    Great. Thanks again.
    Last question.
    If I use a column like this:
    { field: "CPSWGUID", editor: selectorcolumneditor, title: "Person" },
    It shows the data value. I can include the Display from a different column in the header template, (template: "${Display}"), but if I do that, once I change the data value selected in the editor, the Display value doesn't change (it changes in the editor, but not in the grid column if I move out of the cell). Is there a way of updating that cell value or do I need to change a second column as well.
  7. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3707 posts

    Posted 05 Nov 2014 Link to this post

    Hello Bryan,

    I am afraid I didn't quite catch the problem with the header template update. Could you please elaborate more on this problem? Any widget configuration/implementation that will shed more light on this is much appreciated.

    Looking forward to hearing from you.

    Regards,
    Georgi Krustev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  8. Bryan
    Bryan avatar
    28 posts
    Member since:
    Oct 2014

    Posted 05 Nov 2014 in reply to Georgi Krustev Link to this post

    Hi, Georgi.
    Sorry I wasn't clear.
    I have a grid with two columns:

    { field: "Display", title: "Display", dataType: "string", hidden: true },
    { field: "CPSWGUID", editor: selectorcolumneditor, title: "Person", template: "${Display}" },

    selectorcolumneditor implements the combined dropdown/lookup control I've been working on (with your help). The control uses the Display field for the text and the CPSWGUID field for the value. When I select a different value, the CPSWGUID value is updated correctly, but the Display is not. I realize I'm not updating the Display column at the same time, so I've been trying to use a function in the template field:

    "#= getDisplayVal(Display, CPSWGUID) #"

    Where Display is the initial value and CPSWGUID is the new value, but I'm not quite sure how to retrieve the editor display value to update the grid's display, if that makes sense. I've also tried using the Display column with the editor, but since the important data value is the GUID field, I feel like that's what needs the editor, if that makes sense.
    Thanks again for all your help.
  9. Answer
    Georgi Krustev
    Admin
    Georgi Krustev avatar
    3707 posts

    Posted 06 Nov 2014 Link to this post

    Hello Bryan,

    If my understanding is correct, you need to update two model properties where the "Display" is related to the "CPSWGUID" one. There two cases, I can think of, where this could happen (as this is not cleared in your last message):
    • Choose different "CPSWGUID" value from the ComboBox in the grid editor form. At this moment, the "Display" field will not be updated. If you would like to update it on the client before saving the changes, then you will need to perform this operation manually. Wire the change event of the widget and update the corresponding model property:
      //grid edit event handler
      function edit(e) {
        var widget = e.container("[name=CPSWGUID]").data("kendoComboBox"); //note that you will need to find the correct widget
        var model = e.model;
       
        widget.bind("change", function() {
           model.set("Display", widget.text());
        });
      }
    • The other option is to update the Display value after update. The model.Display update needs to be done on the server and then the updated model should be returned to the client as a response to the Update datasource operation. This will be sufficient for the data source to update the saved model and rebind the grid (the new data will be rendered).

    If I'm missing something, I will ask you for a repro demo as it will help to understand the implementation and follow you up with more concrete solution.

    Regards,
    Georgi Krustev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready