it-swarm.com.ru

динамически включать / отключать сортировку по jquery

У меня есть строки таблицы, которые можно сортировать в зависимости от того, установлены ли определенные переключатели или нет. Сортируемые значения инициализируются в document.ready следующим образом:

$(document).ready(function() {
    // Return a helper with preserved width of cells
    // handy code I got from http://lanitdev.wordpress.com/2009/07/23/make-table-rows-sortable-using-jquery-ui-sortable/
    var fixHelper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    };
    // #opts = table id; tr.ui-state-disabled class = rows not sortable
    $("#opts tbody").sortable({
        items: 'tr:not(.ui-state-disabled)',
        cursor: 'crosshair',
        helper: fixHelper
    }).disableSelection();
});

У меня есть следующая функция, прикрепленная к переключателям (идентификаторы с префиксом "active_") onchange, которые либо добавляют, либо удаляют атрибут класса ui-state-disabled из строк таблицы (динамические идентификаторы с префиксом "opt_"):

    var toggleDrag = function(i){
    if ($('#active_'+i+'-0').is(':checked')) {
        $('#opt_'+i).addClass('ui-state-disabled');
    }
    if ($('#active_'+i+'-1').is(':checked')) {
        $('#opt_'+i).removeClass();
    }
    $("#opts tbody").sortable("option", "items", "tr:not(.ui-state-disabled)");
    //$("#opts tbody").sortable("refresh");
    //alert($('#opt_'+i).attr('class')); - alert indicates that the class attribute is being changed
    //$("#opts tbody").sortable("option", "cursor", "auto"); - this works!
}

Если я выберу переключатель, который должен сделать сортировку ранее несортируемой строки, она сработает, и я смогу перетащить строку. Проблема в том, что если я выберу переключатель, чтобы сделать строку, которая ранее была сортируемой, не сортируемой, я все равно могу перетащить ее. Сеттер .sortable("option", "items", "tr:not..etc") не отображается как "незарегистрированная" строка, если она была ранее сортируемой. Я также попытался .sortable ("обновить") без удачи. И я проверил, если атрибут класса изменяется с предупреждением, и это так.

Любая помощь с этим будет принята с благодарностью.

13
annette

Я столкнулся с той же проблемой, что опция items, похоже, не удаляет элементы, которые были ранее включены.

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

Код здесь частично основан на ответе Бах Баха Агнца, но он был очень аккуратным и упрощенным.

HTML:

<ul id="sorted-list">
   <li>
       <p><input type="checkbox" checked="true" /> Item 1</p>
    </li>
   <li>
       <p class="disabled"><input type="checkbox" /> Item 2</p>
   </li>
   <li>
       <p><input type="checkbox" checked="true" /> Item 3</p>
   </li>
</ul>

JQuery:

$("#sorted-list").sortable({
    cancel:".disabled"
});

// add or remove the 'disabled' class based on the value of the checkbox
$("#sorted-list input").click(function() {
    if (this.checked) {
        $(this.parentElement).removeClass("disabled");
    } else { 
        $(this.parentElement).addClass("disabled");
    }
});

CSS:

li {
  border: 1px solid #aaa;
  background-color: #eee;
  color:#555;
  padding: 5px;
}

.disabled {
  color:#ddd;
}
15
Hannele

У меня была похожая проблема, и я нашел простое решение (но в моем примере я использую сортируемый ul, а не таблицу, так как в ul есть больше свободы с наценкой).

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

<ul id="sorted-list">
    <li>
        <div class="handle sortable">
            <p>Item 1</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
    <li>
        <div class="handle sortable">
            <p>Item 2</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
    <li>
        <div class="handle sortable">
            <p>Item 3</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
    <li>
        <div class="handle sortable">
            <p>Item 4</p>
            <input type="button" value="Disable Sort" />
        </div>
    </li>
</ul>
<script>
    $("#sorted-list").sortable({
        items: "li",
        handle: ".handle.sortable"
    });
    $("#sorted-list").find("input").click(function() {
        if ($(this).closest(".handle").hasClass("sortable"))
            $(this).val("Enable Sort").closest(".handle").removeClass("sortable");
        else $(this).val("Disable Sort").closest(".handle").addClass("sortable");
    });
</script>
6
Bah Bah the Lamb

Попробуйте использовать опцию disabled. http://jqueryui.com/demos/sortable/#option-disabled

4
matthewpavkov

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

Чтобы обойти это, я просто уничтожил и восстановил сортировку. Я адаптировал JSfiddle Ханнели для демонстрации ( http://jsfiddle.net/Sxg8D/140/ ).

$("#sorted-list").sortable({
    items:"li:not(.disabled)"
});

$("#sorted-list input").click(function() {
    if (this.checked) {
        $(this.parentElement).removeClass("disabled");
    } else { 
        $(this.parentElement).addClass("disabled");
    }

    $("#sorted-list")
        .sortable( "destroy" )
        .sortable({
            items:"li:not(.disabled)"
        });
});
2
Lawrence Phillips

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

<div id="sortBlock">
    <div id="noSort class="itemBlock">
        <div class="item">
        <div class="item">
    </div>
    <div id="canSort" class="itemBlock">
        <div class="item">
        <div class="item">
    </div>
</div>

Элементы из noSort можно сортировать где угодно. Элементы из canSort могут сортироваться только в другие блоки canSort.

$("#sortBlock").sortable({
    items: "> div.itemBlock > .item"   // this makes sure only the sub items will be sortable
});

Затем установка этого правила после инициализации, казалось, сделала свое дело.

$("#sortBlock").sortable( "option", "items", "> div:not(#noSort) > .item");

Пыталась сделать это динамически в событиях start/stop, но это помогло, не зная "почему", так что тестируйте хорошо.

0
Rob