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

MVVM autocomplete dropdownlist

5 Answers 946 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
toppo
Top achievements
Rank 1
toppo asked on 10 Aug 2018, 12:33 AM

Hi,

I've got a MVVM kendo dropdownlist for my single page application that gets rendered with a layout.showIn(), all is fine and the dropdownlist is populated from my viewmodels datasource but the autocomplete filtering always passes null back to my controller method.

<script type="text/x-kendo-template" id="ddlEventDescrTemplate">
    <input id="ddlEventDescription"
           data-role="dropdownlist"
           data-value-primitive="true"
           data-filter="contains"
           data-auto-bind="false"
           data-bind="source: autoCompleteDataForEventDescr, value: apdEventCode"
           data-text-field="APDEventCode"
           data-value-field="APDEventCode" />
</script>
 
 
<script type="text/javascript">
     var mainViewModel = kendo.observable({
        value: "1",
        apdEventCode: "None",
        selectedEventName: null,
        items: [
            { id: "1", name: "Email Addresses" },
            { id: "2", name: "User IDs" }
        ],
        getSelectedEventName: function () {
            var selectedEventName = this.get("selectedEventName");
            return kendo.stringify(selectedEventName, null, 4);
        },
        getInputValue: function () {
            return this.get("value");
        },
        getEventCodeValue: function () {
            return this.get("apdEventCode");
        },
        autoCompleteDataForEventDescr: new kendo.data.DataSource({
            serverFiltering: true,
            transport: {
                type: "json",
                read: {
                    url: '@Url.Action("GetEventCodes", "SupportTools")'
                }
            }
        }),
        autoCompleteDataForEventName: new kendo.data.DataSource({
            serverFiltering: true,
            transport: {
                read: {
                   url: '@Url.Action("GetEventNames", "SupportTools")'
                }
            }
        })
    });
 
    var router = new kendo.Router();
       router.route("/", function () {
          mainLayout.render(".panel-body");
          mainLayout.showIn("#ddlInputFormat", inputFormatView);
          mainLayout.showIn("#ddlEventDescription", eventDescriptionView);
          mainLayout.showIn("#ddlEventName", eventNameView);
          mainLayout.showIn("#numericCpdHours", cpdHoursView);
 
          kendo.bind($("#mainView"), mainViewModel);
      });
      router.route("/CPDBulkHourUploadStep2", function () {
          mainLayout.destroy();
          step2Layout.render(".panel-body");
          step2Layout.showIn("#cpdStep2View", cpdGridView);
      });
 
      router.start();
</script>

 

Controller method:

public JsonResult GetEventCodes(string text)
{
    var eventCodes = _repo.GetEventCodes(text);
    return Json(eventCodes, JsonRequestBehavior.AllowGet); // eventCodes is returned as an IEnumerable<ViewModel>
}

 

My dropdownlist gets populated fine, but when I try to type in something the autocomplete never gets filtered, upon debugging it turns out that the parameter text is always null it doesn't seem to be passing anything back to the GetEventCodes controller method. Am I missing something here? I've looked at the demos and documentation and it doesn't seem like I'm missing anything.

Side Note: I can't seem to get my templates to render when I move the script/templates to another location e.g. remove it locally, I want to have a separate .cshtml file preferably that will have all my templates and I can call that from my javascript file instead of having it all in one file which creates a lot of clutter.

Thanks.

 

5 Answers, 1 is accepted

Sort by
0
Accepted
Dimitar
Telerik team
answered on 13 Aug 2018, 10:39 AM
Hi Stanley,

In general, in order for the server filtering functionality to work correctly, there are two requirements:


In addition to the above, important to note is that the the filter is sent to the server following jQuery's conventions. What this means is that in the current scenario, the filter will be sent in the query string in a similar format to the below snippet:
filter[logic]: and
filter[filters][0][field]: name
filter[filters][0][operator]: startswith
filter[filters][0][value]: Jane

In order to convert the request parameters to a format suitable for the remote service, the dataSource's transport.parameterMap() method could be used as follows:
products: new kendo.data.DataSource({
  serverFiltering: true,
  transport: {
    read: {
      dataType: "jsonp"
    },
    parameterMap: function (data, type) {            
      return kendo.stringify($.extend({ "text": $(data.filter.filters).get(0).value }, data));
    }
  }
})

What the above snippet will do is to also send a variable "text" along with the query string that holds the current filter value. You can check out the following Dojo example, where this is demonstrated in action. If you open the browser's network tab and inspect the request that is sent to the server after typing in the AutoComplete, you will notice that the "text" variable is successfully appended to the query string. Thus, this will allow to correctly receive the value in the controller end-point:
public JsonResult GetEventCodes(string text)
{
    var eventCodes = _repo.GetEventCodes(text);
    return Json(eventCodes, JsonRequestBehavior.AllowGet); // eventCodes is returned as an IEnumerable<ViewModel>
}

Alternatively, you could parse the "filter" object on the server and extract the required information for the filter operator, field and value. 

I hope this resolves the issue.

Regards,
Dimitar
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
toppo
Top achievements
Rank 1
answered on 13 Aug 2018, 07:02 PM

Thanks got everything to work, one last thing is I have a kendo grid that's bound to an MVVM datasource like so:

 

How would I escape it so that my hidden can return true/false based on my value from my viewmodel like #if(showEmail) {# true #} else {# false #} because this is inside a nested quote where its a single quote inside a double quote i can't seem to escape it properly to get the if statement to work.

<div id="ifnoGrid"
      data-role="grid"
      data-editable="true"
      data-bind="source: gridData"
      data-filterable="true"
      data-sortable="true"
      data-columns="[
         {
           'field': 'EmailAddress',
           'title': 'Email Address'
           'hidden': conditional statement here \\#if()
         },
         { field: 'PersonName',
           title: 'Name'
         },
         { 'field': 'Hours',
           'title': 'Hours'
         }
      ]">
 
 </div>
0
Accepted
Dimitar
Telerik team
answered on 14 Aug 2018, 06:17 AM
Hi Stanley,

The columns.hidden option is not suitable for achieving the desired result, as it accepts only boolean values. Instead, the recommended approach to render different column content is through the columns.template option

More extensive discussion on the same topic can be found on the following forum thread:


Regards,
Dimitar
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
toppo
Top achievements
Rank 1
answered on 15 Aug 2018, 09:13 PM

Hi Dimitar,

Thought I'd just post in this thread again since it's already made, I'm having trouble passing the server filtered values to the controller using typescript. My observable viewmodel is as follows:

class MainViewModel extends kendo.data.ObservableObject {
    value: string = "1";
    eventCode: string = "None";
    items: InputItems[] = [
        { id: "1", name: "Email Addresses" },
        { id: "2", name: "User IDs" }
    ];
    getInputValue: any = function () {
        return this.get("value");
    };
    getEventCodeValue: any = function () {
        return this.get("eventCode");
    };
    autoCompleteDataForEventDescr: any = new kendo.data.DataSource({
        serverFiltering: true,
        transport: {
            read: {
                url: '/SupportTools/GetEventCodes',
                dataType: 'json'
                }
            },
            parameterMap: function (data, type) {
                if (data.filter.filters.length > 0) {
                    return kendo.stringify($.extend({ "text": data.filter.filters[0].value }, data));
                }
            }
        }
    });
 
    constructor() {
        super();
        super.init(this);
    }
}

 

Controller Method:

public JsonResult GetEventCodes(string text)
 {
        var eventCodes = _repo.GetEventCodes(text);
        return Json(eventCodes, JsonRequestBehavior.AllowGet);
 }

 

No matter what I do the parameter text is always null, I've also tried specifying a data field in the datasource read property and set a hard coded value just to test if it will pass it to the controller and it's still null.

 

0
Dimitar
Telerik team
answered on 17 Aug 2018, 06:40 AM
Hello Stanley,

Check out the following Dojo example, where the AutoComplete's dataSource is configured to force the filtering behavior on the server. With it, when text is typed in the filter input, an ajax request is being sent to the remote end-point that contains the "text" variable. The parameterMap configuration of the dataSource is as follows:
parameterMap: function (data, type) {            
  return kendo.stringify($.extend({ "text": $(data.filter.filters).get(0).value }, data));
}

I would suggest to debug the application using the browser developer tools. To do this, simply open the "Network" tab of the browser and start typing in the filter input of the AutoCompelete. Then, inspect the request headers in order to verify if the "text" variable is correctly passed to the controller end-point. If this is the case, then the next step is to check the server implementation in order to make sure that the value is received correctly.

Regards,
Dimitar
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
DropDownList
Asked by
toppo
Top achievements
Rank 1
Answers by
Dimitar
Telerik team
toppo
Top achievements
Rank 1
Share this question
or