2

I am trying to create an auto-suggestion from scratch. I am using canjs controller to control the DOM elements (ul and li). I want smart and short code to implement this. I have tried with filter but I want Ajax filter method to use for this purpose.

I have tried the following thing:

can.Model:

 var SearchDomainModel = can.Model.extend({
    findAll: function(){
        return this.getDomains;
    }
}, { domainList: null,
    getDomains: function(params, callback) {
        var promise = $.ajax({
            url: '/scripts/models/domains.json',
            type: 'GET',
            dataType: 'json',
            dataFilter: function(data, type){
               var parsed_data = JSON.parse(data);
                var regex = new RegExp(params, 'gi')
                var temp = []; 
                $.each(parsed_data, function(i, item){
                    for(var j in item)
                      if ((item[j].url).toLowerCase().indexOf(params) >= 0){
                        temp.push(item[j].url);
                        console.log(temp);
                    }
                });
                return temp;
            }

});

This is my can.controller:

var DomainController = can.Control.extend({
    defaults: {
        view: 'views/domainSearch.hbs'
    }
}, {
    searchList: new can.List(),
    domainModel: new DomainModel(),
    init: function(element, options) {
        this.element.html(can.view(this.options.view, this.searchList));
        $('html,body').css({
            percentWidth: 100,
            percentHeight: 100
        });
        $('.error').hide();
    }, // control domain filter on keyup event

'input keyup': function(element, event) {
        var self = this;
        var searchText = element.val();

        if (searchText !== "") {


            this.domainModel.getDomains(searchText, function (response, error) {

                   self.searchList.attr("domains",response);
                   console.log(error);
             })     

I am trying and searching from last two days. I could not have done it. Can anybody suggest me where is my mistake in the code and how to solve it?

Thanx in advance!!

Terry
  • 989
  • 8
  • 29
Dipesh Raichana
  • 1,008
  • 3
  • 18
  • 36
  • 1
    Because you are not doing anything with the "params" (searchText) parameter. And sending a whole ajax request everytime you release a key is not that good either, especially when the searchtext doesn't change at all. – Sebastian Nette Jun 25 '15 at 05:14
  • @SebastianNette: Thanx for your reply. Actually I have done filtering already but I want less and accurate code. I have updated my code. Please suggest me is there any option to reduce this code? – Dipesh Raichana Jun 25 '15 at 05:39
  • 1
    It would be better if you filter on the serverside, instead of the client. But if you want to filter clientside, then cache the response instead of retrieving the whole unchange document all the time. Now you are creating an regex but you are not using it. if(regex.test(item[j].url)) temp.push(item[j].url); – Sebastian Nette Jun 25 '15 at 05:45
  • @SebastianNette: thanx to point out about regex. I just forgot about test function. second thing can you tell me more about caching or suggest me some resource from where I could complete my requirement – Dipesh Raichana Jun 25 '15 at 05:51
  • It just means that after you retrieve the list for the first time, you keep it in the memory and then just refer to it the next time a key was released instead of retrieving it again – Sebastian Nette Jun 25 '15 at 06:07

1 Answers1

1

I would probably do something like this:

var SearchDomainModel = can.Model.extend({
    findAll: function(){
        return this.getDomains;
    }
}, { domainList: null,
    getDomains: (function() {
        var domains = null;

        function search(searchText, callback){
            var regex = new RegExp(searchText, 'gi')
            var temp = []; 
            $.each(domains, function(i, item){
                for(var j in item)
                    if (regex.test(item[j].url))
                        temp.push(item[j].url);
            });
            callback(temp);
        }

        return function(searchText, callback) {

            if( domains ) {
                search(searchText, callback);
                return;
            }

            $.ajax({
                url: '/scripts/models/domains.json',
                type: 'GET',
                dataType: 'json',
                success: function(data) {
                    domains = data;
                    search(searchText, callback);
                }
            });

        };

    })()

});

I didn't test the code but it doesn't spawn one ajax request everytime you release a key but instead grabs the data once and then refers to the same data.

Sebastian Nette
  • 7,364
  • 2
  • 17
  • 17