jQuery: как сохранить функции элемента, даже если элемент был удален и воссоздан? - PullRequest
0 голосов
/ 18 июня 2009

У меня проблема ..

Я использую плагин автозаполнения, который я редактирую, чтобы сделать так, чтобы вводимый текст исчез, когда пользователь делает выбор.

Итак, моя цель, когда пользователь выбирает строку из списка автозаполнения:

  1. Ajax-запрос будет извлекать дополнительную информацию о выбранной строке (здесь нет проблем)
  2. Автозаполнение формы с этой дополнительной информацией (хорошо здесь)
  3. Вводимый текст с автозаполнением исчезает, и на его место я помещаю 2 div, один с X внутри (чтобы «отменить выделение» выделенного выделения), а другой с некоторой краткой информацией о самом выделении (здесь нет проблем) )
  4. Если пользователь нажимает X div, все должно быть возвращено как начало, с вводом текста с автозаполнением.

Что случилось со мной, так это то, что в точке 4 все работает нормально, но когда текст ввода с автозаполнением воссоздается с помощью

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

автозаполнение больше не будет работать!

Итак, как я могу присоединить функцию автозаполнения к полю, когда оно воссоздается? Чтобы позволить пользователю многократно выбирать и отменять выбор.

ps: Я знаю, что могу просто скрыть div с вводимым текстом и показать тот с X, но я бы предпочел, чтобы разметка html была минимальной и не возиться со скрытым дивы. Если возможно, я хочу изменить innerHTML при каждом выборе и заново связать функцию автозаполнения.

Вот как теперь мой козел:

$(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('');
                });
            }
        });
    });
});

Ответы [ 3 ]

1 голос
/ 18 июня 2009

Я написал функцию, которая прикрепляет автозаполнение на фокусе. Поэтому, когда у вас есть такой вклад:

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

Или, в вашем случае, добавьте часть onfocus к вашей инъекции поля ввода:

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

Вы можете использовать функцию, подобную следующей, чтобы подключить плагин автозаполнения. (Обратите внимание, я установил атрибут для предотвращения нескольких вложений)

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);
}

Чего я не понимаю, так это почему вы не хотите прятаться и показывать div? И что ты имеешь в виду под "возиться со скрытыми div"?

1 голос
/ 18 июня 2009

Начиная с jQuery 1.3, событие live () обладает необходимой функциональностью, которая позволяет постоянно связывать события с дескрипторами, даже если дескрипторы уничтожаются и воссоздаются.

Редактировать: live был объявлен устаревшим в jQuery 1.7 и удален в 1.9, поэтому теперь вы должны использовать on () вместо того, чтобы добиться того же эффекта.

Подробнее см. http://api.jquery.com/on/.

0 голосов
/ 18 июня 2009

Вы также можете удалить <input> только из DOM, но без , используя метод jQuery remove(). Эта функция удаляет элемент из DOM, но также отбрасывает все подключенные обработчики событий и данные.

Однако не забудьте сохранить ссылку на DIV после его удаления. Примерно так:

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. это приводит к утечкам памяти в IE. Вы можете использовать функцию удаления () jQuery при выгрузке страницы или показать и скрыть поле. Последнее, безусловно, самое чистое решение, и я не понимаю, почему вы находите его " грязным ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...