Autocomplete Server Filtering and WebApi2 Controller

4 posts, 0 answers
  1. Ricard Bertran Vall
    Ricard Bertran Vall avatar
    18 posts
    Member since:
    Sep 2009

    Posted 22 Sep 2016 Link to this post

    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!

     

     

  2. Lawrence
    Lawrence avatar
    14 posts
    Member since:
    Jul 2013

    Posted 23 Jun in reply to Ricard Bertran Vall Link to this post

    Excellent example.  Thank you sharing!!
  3. Neelima
    Neelima avatar
    16 posts
    Member since:
    Oct 2017

    Posted 08 Nov Link to this post

    $("#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."}

     

  4. Neli
    Admin
    Neli avatar
    53 posts

    Posted 10 Nov Link to this post

    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.
Back to Top