views:

391

answers:

3

Hi guys, i have a problem..

I use the autocomplete plugin, that i edite for make the input text to disappear when the user make the choice.

So, my goal is, when the user select a row from the autocomplete list:

  1. An Ajax request would retrieve additional info about the selected row (no problem here)
  2. A form auto-fillup with those additional info (ok here)
  3. The input-text with the autocomplete disappear, and at it place i put 2 div, one with a X inside (to 'deselect' the previus selection), and another with some short info about the selection itself (no problems here)
  4. If the user click the X div, all must be return as the begin, with the input-text with autocomplete.

What happen to me, is that at the point 4, all works fine, but when the input-text with autocomplete is recreated by

$("div#contact-list-container").html('<input type="text" name="contact-list" id="contact-list" value="" />');

the autocomplete wont work anymore!

So, how can i join the autocomplete function to the field when it is recreated? In order to let the user select and deselect it many times.

p.s: I know that i could simply hide the div with the input-text and show the one with the X, but i'll prefer to keep the html markup minimal and dont mess around with hidden divs. If is possible, i'll like to change the innerHTML on every select and reassociate the autocomplete function.

Thats how my cose is now:

$(document).ready(function(){
    $('input#contact-list').autocomplete('test-db.php', {
        multiple: false,
        dataType: "json",
        width: 400,
        scrollHeight: 300,
        max: 5,
        parse: function(data) {
            return $.map(data, function(row) {
                return {
                    data: row,
                    value: row.azienda,
                    //result that will be used in the text field, while selected
                    result: row.code + ' - ' + row.company + ' | ' + row.name + ', ' + row.surname
                }
            });
        },
        formatItem: function(item) {
            return item.code + ' - ' + item.company + '<br />' + item.name + ', ' + item.surname + '<br />' + item.email;
        }
    }).result(function(e, item) {
        //this will be triggered when the selection has made
        $.ajax({
            type: "POST",
            cache: false,
            data: "idCompany=" + item.id_company + "&idUser=" + item.id_user,
            url: "test-db-02.php",
            success: function(message){
                $("input[rel='ship']").attr("readonly", true).css("background-color", "#DFDFDF");
                $("input[rel='company']").attr("readonly", true).css("background-color", "#DFDFDF");
                var rd = json_parse(message);

                $("input#ship-nome-referente").val(rd.company.nome);
                $("input#ship-cognome-referente").val(rd.company.cognome);
                //[... and so on, i change the val of many fields..]
                //REPLACE THE INPUT-TEXT WITH THE DIVS
                $("div#contact-list-container").html('<div id="deselect-contact">X</div><div id="selected-contact">' + rd.company.code + ' - ' + rd.company.company + ' | ' + rd.company.name + ', ' + rd.company.surname + '</div>');

                $("div#deselect-contact").click(function(){
                //REPLACE THE DIVS WITH THE INPUT-TEXT.. HOW TO REASSOCIATE THE AUTOCOMPLETE?
                    $("div#contact-list-container").html('<input type="text" name="contact-list" id="contact-list" value="" />');
                    $("input[rel='ship']").attr("readonly", false).css("background-color", "#FFFFFF").val('');
                    $("input[rel='company']").attr("readonly", false).css("background-color", "#FFFFFF").val('');
                });
            }
        });
    });
});
+1  A: 

With jQuery 1.3, the live event was added, which allows you to persistently bind events to handles, even if the handles get destroyed and recreated.

See http://docs.jquery.com/Events/live for details.

Fuu
+1  A: 

I wrote a function, that attachs the autocomplete onfocus. So when you have your input like this:

<input type="text" onfocus="attach(this);"/>

Or in your case, add the onfocus part to your input field injection:

$("div#contact-list-container").html('<input type="text" name="contact-list" id="contact-list" value="" onfocus="attach(this);"/>');

you could use a function like the following, to attach the autocomplete plugin. (Note, I set a attribute to prevent multiple attachments)

function attach(element){

 var $element = jQuery(element);

 // check if autocomplete was already attached
 if($element.attr("autocomplete.attached")){
  return;
 }

 // attach autocomplete 
 $element.autocomplete(...);

 // set a marker
 $element.attr("autocomplete.attached", true);
}

What I don't understand is this: why you don't want to hide and show the div? And what do you mean with "mess around with hidden divs"?

Tim Büthe
First was becose i have a much complex markup, and i prefer to replace existing elements instead of change theyr property... now, i understood that i am mistaking and maybe i'll take the hide/show way.
DaNieL
A: 

You can also remove the <input> only from DOM but without using jQuery's remove() method. That function removes element from DOM but also discards any attached event handlers and data.

However don't forget to keep reference to DIV after you delete it. Something like this:

var theField = document.getElementById('contact-list');
// remove it only from DOM
theField.parentNode.removeChild(theField);

// ...

// and later when you want to bring the field back into the game
$('#contact-list-container').append(theField);

N.B. this introduces memory leaks in IE. You can either use jQuery's remove() function on page unload or show and hide field. The latter is by far the cleanest solution and I can't see why you find it "messy".

Damir Zekić
Ehm... i dont use the remove mothod, i simpli change the html inside the div with $('div#mydiv').html(''); ;)
DaNieL
But you don't keep the reference to the input box, do you? The point is that you re-insert it, not create a new one
Damir Zekić