Пользовательский интерфейс jQuery и jQuery.each () - PullRequest
2 голосов
/ 27 августа 2011

На этот раз у меня (надеюсь) быстрый вопрос, хотя сейчас он немного беспокоит меня.

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

В рамках этой настройки у меня есть следующий код:

$( ".draggable" ).each( function(){
    $(this)
    .html( $(this).attr('title') )
    .draggable({
        revert: "invalid"
    });
});

Каждый .draggable на самом деле является элементом <li>, который изначально содержит три радиоблока для назначения поля одной из трех уникальных категорий. Используя jQuery-UI, я заменяю эти 30 наборов из 3 радиоблоков списком перетаскиваемых элементов и 3 списками сбрасывания, по одному для каждой из трех уникальных категорий. Мне пришлось использовать метод .each(), чтобы правильно установить переменную this, чтобы я мог использовать $(this).attr('title').

Моя проблема в четвертой строке: .draggable({. Первый элемент <li> правильно становится перетаскиваемым элементом, однако после этого JavaScript умирает со следующей ошибкой:

Uncaught TypeError: у объекта field2 нет метода «перетаскивания»

Есть ли причина, по которой у одного элемента будет метод, а у всех последующих нет?

РЕДАКТИРОВАТЬ -

В соответствии с запросом, вот HTML до и после того, как он был изменен моим JavaScript ...

перед:

<ul id="form-fields">
    <li class="draggable" title="field1">
        <input type="radio" name="form-field-1" value="criteria" />
        Criteria
        <input type="radio" name="form-field-1" value="entry" />
        Entry
        <input type="radio" name="form-field-1" value="default" />
        Default
    </li>
    <li class="draggable" title="field2">
        <input type="radio" name="form-field-2" value="criteria" />
        Criteria
        <input type="radio" name="form-field-2" value="entry" />
        Entry
        <input type="radio" name="form-field-2" value="default" />
        Default
    </li>
    <li class="draggable" title="field3">
        ...
    </li>
    ...
    <div style="clear:both;"></div>
</ul>
<div class="droppable no-js">
    <h4>Criteria:</h4>
    <ul id="form-field-criteria">
    </ul>
</div>
<div class="droppable no-js">
    <h4>Entries:</h4>
    <ul id="form-field-entry">
    </ul>
</div>
<div class="droppable no-js">
    <h4>Defaults:</h4>
    <ul id="form-field-default">
    </ul>
</div>
<div style="clear:both;"></div>

(Обратите внимание, что класс no-js установлен в display:none; в моем CSS, и в самом верху моего JavaScript у меня есть следующее: $( ".no-js" ).removeClass("no-js");)

после

<ul id="form-fields">
    <li class="draggable" title="field1">field1</li>
    <li class="draggable" title="field2">field2</li>
    <li class="draggable" title="field3">...</li>
    ...
    <div style="clear:both;"></div>
</ul>
<div class="droppable ">
    <h4>Criteria:</h4>
    <ul id="form-field-criteria">
    </ul>
</div>
<div class="droppable ">
    <h4>Entries:</h4>
    <ul id="form-field-entry">
    </ul>
</div>
<div class="droppable ">
    <h4>Defaults:</h4>
    <ul id="form-field-default">
    </ul>
</div>
<div style="clear:both;"></div>

Так что HTML-разметка работает отлично. Радиоблоки удаляются и заменяются именем поля (как указано в атрибуте title). Однако только поле field1 становится перетаскиваемым до того, как я получаю сообщение об ошибке.

РЕДАКТИРОВАТЬ -

Я определил источник настоящей ошибки. Оказывается, что у field2 не было заголовка, поэтому он запутался в строке $(this).attr('title'). Хотя я полагаю, что это, вероятно, ошибка с jQuery (отсутствие заголовка должно привести к тому, что $(this).attr('title') вернет ноль или пустую строку, а не сломает весь мой скрипт), я хотел бы найти способ справиться с этой ошибкой, не разрушая весь сценарий.

Будет ли что-то простое, как:

if( $(this).attr('title').len > 0 ) {
    $(this).html( $(this).attr('title') );
} else {
    $(this).html('');
}

выполнимо?

1 Ответ

0 голосов
/ 27 августа 2011

Вы пробовали эту альтернативу:

$(".draggable").each(function(index, elem) {
    $(elem).html($(elem).attr('title')).draggable({
        revert: "invalid"
    });
});

Кроме того, какую версию jQuery и jQuery UI вы используете?Возможно, используемая вами версия jQuery и пользовательского интерфейса jQuery несовместимы друг с другом.

...