This is a migrated thread and some comments may be shown as answers.
Autocomplete Server Filtering and WebApi2 Controller
3 Answers 181 Views
This is a migrated thread and some comments may be shown as answers.
Ricard Bertran Vall
Top achievements
Rank 1
Ricard Bertran Vall asked on 22 Sep 2016, 07:19 AM

For those who're wondering how to catch KendoUI autocomplete filter on server side webapi2 controller without having to deal with filter.filters[0] query string prarameters.

This is how I've solved it:

JS:

$("#values").kendoAutoComplete({
    minLength: 3,
    enforceMinLength: true,
    dataTextField: "value",
    dataValueField: "id",
    dataSource: {
        type: "json",
        severFiltering: true,
        serverPaging: true,
        transport: {
            read: "/api/values",
            parameterMap: function (data, type) {
                return { filter: $('#values').val() };
            }
        }
    },
    filtering: function (e) {
        if (!e.filter.value) {
            e.preventDefault();
        }
    }
});

 

The trick here is to use  parameterMap to change request url.

 

WebApi2:

public class ValuesController : ApiController
{
    // GET api/values
    [HttpGet]
    [Route("api/values", Name = "r2", Order = 2)]
    public IEnumerable<ValueModel> Get()
    {
        //var filters = new AutoCompleteFilters(Request.GetQueryNameValuePairs());
        return new List<ValueModel>() {
            new ValueModel() { id = 1, value = "item 1" },
            new ValueModel() { id = 2, value = "item 2" },
            new ValueModel() { id = 3, value = "item 3" },
        };
    }
    //GET api/values?filter=item
    //GET api/values/ite
    [HttpGet]
    [Route("api/values/{filter?}", Name = "r1", Order = 1)]
    public IEnumerable<ValueModel> Get(string filter)
    {
        return new List<ValueModel>() {
            new ValueModel() { id=1, value="item 1" },
            new ValueModel() { id=2, value="item 2" },
            new ValueModel() { id=3, value="item 3" },
        }.Where(m => m.value.StartsWith(filter, StringComparison.CurrentCultureIgnoreCase));
    }
}

The trick on WebApi2 is to use "named" Route attributes with optional {filter?} parameter

 

This solution allows either :

http://localhost:11989/api/values?filter=item

or

http://localhost:11989/api/values/ite

What is cool in case your api is exposed to third-party applications.

Happy coding!

 

 

3 Answers, 1 is accepted

Sort by
0
Lawrence
Top achievements
Rank 2
answered on 23 Jun 2017, 08:07 PM
Excellent example.  Thank you sharing!!
0
Neelima
Top achievements
Rank 1
answered on 09 Nov 2017, 01:48 AM

$("#txtPartNumbers").kendoAutoComplete({
            dataSource: {
                serverFiltering: true,
                enforceMinLength: true,
                transport: {
                    read: {
                        url: ApiBaseUrl.val + 'inventoryLocation/getParts',
                        type: "get",
                        dataType: "json",
                        parameterMap: function (data, type) {
                            return { filter: $scope.autoCompleteText };
                        }
                    }
                },
            },
            change: function(e) {
                $scope.autoCompleteText = this.value();;
            },
            filtering: function (e) {
                if (!e.filter.value) {
                    e.preventDefault();
                }
            },
            filter: "startswith",
            placeholder: "Select Inventory Parts..",
            minLength: 3,
            separator: ", "
        });

 

 

Controller:

 [HttpGet]
        [Route("getParts/{filter?}", Name = "r1", Order = 1)]
        public IHttpActionResult GetInventoryParts(string filter)
        {
            string partNumber = filter; //Request.Params["filter[filters][0][value]"];
            return Execute(() => this.InventoryLocationSearchService.GetInventoryParts(partNumber));
        }

 

 

This seems to be not working for me. Am I missing something else?? Appreciate your help.

Below is the error message I get:

{"message":"No HTTP resource was found that matches the request URI 'https://localhost/WarpInventoryAPI/inventoryLocation/getParts?filter[logic]=and&filter[filters][0][value]=200&filter[filters][0][operator]=startswith&filter[filters][0][field]=&filter[filters][0][ignoreCase]=true'.","messageDetail":"No action was found on the controller 'InventoryLocationSearch' that matches the request."}

 

0
Neli
Telerik team
answered on 10 Nov 2017, 02:10 PM
Hi Neelima,

Please note that the parameterMap is part of the transport configuration, not the transport.data configuration. 

I have already sent a reply in the support ticket, that you opened on the same subject.

For convenience I will paste my reply here as well. I would suggest keep the conversation in only one thread. 

You could configure the transport.read.data configuration to retrieve the result from function. 
In the function you could retrieve and return the value, entered by the user.
transport: {
    read: {
        dataType: "json",
        data: function (){
            return { partNumber: $('#partNumber').val() };          
        }                       
    }     
}

As you could see in the attached screencast, the value is send with the request as parameter.

I hope that the enclosed Dojo will help.


Regards,
Neli
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Asked by
Ricard Bertran Vall
Top achievements
Rank 1
Answers by
Lawrence
Top achievements
Rank 2
Neelima
Top achievements
Rank 1
Neli
Telerik team
Share this question
or