Почему мой обработчик событий jQuery завершается ошибкой при подключении к нескольким элементам? - PullRequest
1 голос
/ 04 января 2010

Я использую jquery для добавления нескольких новых элементов формы «addTask» к «ul» на странице при каждом нажатии на ссылку.

  $('span a').click(function(e){
    e.preventDefault();

     $('<li>\
     <ul>\
     <li class="sTitle"><input type="text" class="taskName"></li>\
     <li><input type="button" value="saveTask" class="saveTask button"></li>\
     </ul>\
     </l1>')
     .appendTo('#toDoList');
    saveTask();
});

Все эти новые вложенные элементы ul имеют кнопку с тем же классом "saveTask". Затем у меня есть функция, которая позволяет сохранить задачу, нажав на кнопку с классом «saveTask».

// Save New Task Item 
function saveTask() {
    $('.saveTask').click(function() {
        $this = $(this);
        var thisParent = $this.parent().parent()

        // Get the value
        var task = thisParent.find('input.taskName').val();

        // Ajax Call 
        var data = {
            sTitle: task,
            iTaskListID: 29
        };

        $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', 
            data, function(data) {

            var newTask = '<a>' + task + '</a>'
            thisParent.find('li.sTitle').html(newTask);
        });
        return false;
    });
}

Это, по сути, позволяет пользователю вводить некоторый текст в форму ввода, нажимать кнопку Сохранить, а затем задача сохраняется в базе данных с помощью ajax и отображается на странице с помощью jQuery.

Это прекрасно работает, когда на странице есть только один элемент с классом «saveTask», но если у меня более 1 элемента формы с классом «saveTask», он перестает работать правильно, как показывает переменная «var task» как "неопределенное", а не фактическое значение ввода формы.

Ответы [ 5 ]

3 голосов
/ 04 января 2010

Не полагайтесь на метод .parent(). Вместо этого используйте .closest('form'). Итак, следующая строка:

var thisParent = $this.parent().parent()

должно выглядеть примерно так:

var thisParent = $this.closest('form');

EDIT: Судя по предоставленной вами обновленной информации, похоже, что при попытке зарегистрировать обработчик события щелчка по какой-то причине происходит сбой. Вместо этого попробуйте этот javascript, так как он будет использовать событие live, чтобы все вновь добавленные элементы на странице автоматически получали событие click для них.

$(function(){
    $('span a').click(function(e){
        e.preventDefault();

         $('<li>\
             <ul>\
             <li class="sTitle"><input type="text" class="taskName"></li>\
             <li><input type="button" value="saveTask" class="saveTask button"></li>\
             </ul>\
             </l1>')
             .appendTo('#toDoList');

    });

    $('.saveTask').live('click', function() {
        $this = $(this);
        var thisParent = $this.closest('ul');

        // Get the value
        var task = thisParent.find('input.taskName').val();

        // Ajax Call 
        var data = {
            sTitle: task,
            iTaskListID: 29
        };

        $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', 
            data, function(data) {

            var newTask = '<a>' + task + '</a>'
            thisParent.find('li.sTitle').html(newTask);
        });
        return false;
    });
});
1 голос
/ 04 января 2010

Сначала превратите задачу сохранения в функцию:

(function($){
  $.fn.saveTask= function(options){


   return this.each(function(){

     $this = $(this);
     $this.click(function(){

       var thisParent = $this.parent().parent()
                 //get the value
       var task = thisParent.find('input.taskName').val();
        // Ajax Call 
        var data = {
        sTitle: task,
        iTaskListID: 29
      };
      $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', data, function(data){

        var newTask = '<a>' + task + '</a>'

        thisParent.find('li.sTitle').html(newTask);
      });
    });
  });
  return false;
})(jQuery)

Когда приложение запускается, измените селектор saveTask на это:

function saveTask(){
  $('.saveTask').saveTask();
}

Затем добавьте функцию:

function addTask(){
  $newTask = $("<div>Some Task stuff</div>");
  $newTask.saveTask();
}

Этот код написан очень быстро и не проверен, но по сути создает расширение jQuery, которое обрабатывает для отправки данных, а затем при создании задачи применяет к ней расширение задачи сохранения.

0 голосов
/ 04 января 2010

Вы можете попробовать обернуть вашу функцию щелчка в each ()

е

function saveTask(){
$('.saveTask').each (function () {

     $this = $(this);

     $this.click(function() {

         var thisParent = $this.parent().parent()
                     //get the value
         var task = thisParent.find('input.taskName').val();
            // Ajax Call 
            var data = {
            sTitle: task,
            iTaskListID: 29
        };
        $.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', data, function(data){

             var newTask = '<a>' + task + '</a>'

            thisParent.find('li.sTitle').html(newTask);


        });
        return false;
      });
  })
}

Я считаю, что это иногда помогает, когда у вас есть проблемы с несколькими элементами, имеющими один и тот же класс

0 голосов
/ 04 января 2010

Какая у вас структура HTML?

Похоже, ваш код не может найти элемент input.taskName.

Попробуйте установить thisParent на что-то вроде $this.closest('form'). (В зависимости от вашего HTML)

0 голосов
/ 04 января 2010

Я думаю, вы ищете живое событие .

Кроме того, ваш код немного неудобен, так как событие click добавляется только при вызове функции saveTask (). На самом деле функция saveTask () на самом деле ничего не сохраняет, она просто добавляет событие click к элементам с классом .saveTask.

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