0

I'm trying to make a remote autosuggest with ajax and am having trouble making an ul with an onclick function. What I receive as the ajax response is simply something like

One Name
Another Name

separated by \n

so below is what I have so far. The problems it has: it's very ugly code, AND the line between /////////////// doesn't work. Apparently it saves a reference to the variable, and all elements fill the text input with the value of the last element.

Can anyone help me fix this? either a way to just pass a copy of the string to that function definition, or a hint, link, or whatever to the right way to do this will be highly appreciated.

Thanks

<script type="text/javascript">
    $('.suggestable').live('keyup', ( function() { suggest(this); } ));

    function suggest(inputTextField)
    {
        var inputString = inputTextField.value;
        var lookFor = $(inputTextField).attr('data-lookfor');

        if(inputString.length == 0) {
//            $('#suggestions').fadeOut();
        } else {
            $.post(AjaxVars.url,
                {
                    action: 'suggest-submit',
                    queryString: ""+inputString+"",
                    lookFor: ""+lookFor+""
                },
                function(data)
                {
                    // Clear the target div in a very very ugly way
                    document.getElementById('suggestionsList').innerHTML = "";
                    var myul = document.createElement('ul');
                    data = data.split("\n");
                    for(var index in data)
                    {
                        elem = data[index];
                        if(elem.length > 0)
                        {
                            var myli = document.createElement('li');
                            myli.innerHTML = elem;
//////////////////////////////////////
                            myli.onclick=(function() { fill(inputTextField, elem); });
//////////////////////////////////////
                            myul.appendChild(myli);
                        }
                    }

                    document.getElementById('suggestionsList').appendChild(myul);
                });
            }
    }

    function fill(object, thisValue) {
        object.value = thisValue;
//        setTimeout("$('#suggestions').fadeOut();", 600);
    }
</script>

2 Answers 2

1

Your response function only:

function(data){
    $('#suggestionList').innerHTML = '<ul><li>' + data.split('\n').join('</li><li>') + '</li></ul>';
}

and somewhere outside of all that, inside function suggest(){:

$('#suggestionList').delegate('li', 'click', function(){
    fill(inputTextField, $(this).val());
});

FYI the reason that line didn't work is that the value of elem changes... to show you what I mean, take the following example:

for(var i=0; i<10; i++){
   $('#someDiv').bind('click', function(){ alert(i); });
}

that will show '10' no matter what div you click on because the i variable keeps incrementing to 10 and all the functions reference that one variable. To make this work you need a closure of some sort:

for(var i=0; i<10; i++){
   $('#someDiv').bind('click', (function(x){ return function(){ alert(x); } })(i));
}

now i is passed in to the inner function and referenced as x.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is my attempt to clean it up, untested

<script type="text/javascript">
    $('.suggestable').live('keyup', ( function() { suggest(this); } ));

    function suggest(inputTextField)
    {
        var inputString = inputTextField.value;
        var lookFor = $(inputTextField).attr('data-lookfor');

        if(inputString.length == 0) {
//            $('#suggestions').fadeOut();
        } else {
            $.post(AjaxVars.url,
                {
                    action: 'suggest-submit',
                    queryString: inputString,
                    lookFor: lookFor
                },
                function(data)
                {
                    $('#suggestionsList').html('');
                    var myul = document.createElement('ul');
                    $.each(data.split('\n'), function(k, v) {
                        if(v.length < 0)
                            return true;
                        (function(elem){
                            var myli = document.createElement('li');
                            myli.innerHTML = elem;
                            myli.onclick = function() { fill(inputTextField, elem); };
                            myul.appendChild(myli);
                        })(v);
                    });
                    $('#suggestionsList').appendChild(myul);
                });
            }
    }

    function fill(object, thisValue) {
        object.value = thisValue;
//        setTimeout("$('#suggestions').fadeOut();", 600);
    }
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.