UI do jQuery classificável e, em seguida, escreva a ordem em um banco de dados

125

Desejo usar a sortablefunção da interface do usuário do jQuery para permitir que os usuários definam um pedido e, depois de alterados, grave-o no banco de dados e atualize-o. Alguém pode escrever um exemplo de como isso seria feito?

atormentar
fonte
4
toArraydaria uma série de IDs classificados, acho que pode ser útil. api.jqueryui.com/sortable/#method-toArray
MahanGM
1
Você resolveu o seu problema?
Knelis 26/03
De certa forma, perguntas como essa são as melhores no SO. No entanto, essa pergunta seria esmagada em 2020.
Parapluie

Respostas:

223

O sortablerecurso de interface do usuário do jQuery inclui um serializemétodo para fazer isso. É bem simples, realmente. Aqui está um exemplo rápido que envia os dados para o URL especificado assim que um elemento muda de posição.

$('#element').sortable({
    axis: 'y',
    update: function (event, ui) {
        var data = $(this).sortable('serialize');

        // POST to server using $.post or $.ajax
        $.ajax({
            data: data,
            type: 'POST',
            url: '/your/url/here'
        });
    }
});

O que isso faz é que ele cria uma matriz dos elementos usando os elementos id. Então, eu costumo fazer algo assim:

<ul id="sortable">
   <li id="item-1"></li>
   <li id="item-2"></li>
   ...
</ul>

Quando você usa a serializeopção, ela cria uma string de consulta POST como esta: item[]=1&item[]=2etc. Portanto, se você usar, por exemplo, seus IDs de banco de dados no idatributo, poderá simplesmente percorrer a matriz POSTed e atualizar as posições dos elementos de acordo. .

Por exemplo, no PHP:

$i = 0;

foreach ($_POST['item'] as $value) {
    // Execute statement:
    // UPDATE [Table] SET [Position] = $i WHERE [EntityId] = $value
    $i++;
}

Exemplo em jsFiddle.

Knelis
fonte
7
Para gerar IDs automaticamente você pode usar$("#element").children().uniqueId().end().sortable({...
Taylan
12
A documentação diz que, para usar a opção serialize, você deve definir id como formato name_number .
parisssss
5
Você também pode usar esses outros caracteres de acordo com a documentação: Você pode usar um sublinhado, sinal de igual ou hífen para separar o conjunto e o número. Por exemplo "foo = 1", "foo-1" e "foo_1" todos serializam para "foo [] = 1".
Lhoess 29/10
2
Não consigo fazer isso funcionar se estou passando várias variáveis ​​de dados.
PBwebD
11

Achei que isso poderia ajudar também. A) foi projetado para manter a carga útil no mínimo enquanto envia de volta ao servidor, após cada classificação. (em vez de enviar todos os elementos a cada vez ou iterar através de muitos elementos que o servidor pode descartar) B) Eu precisava enviar de volta o ID personalizado sem comprometer o ID / nome do elemento. Esse código obterá a lista do servidor asp.net e, após a classificação, apenas 2 valores serão enviados de volta: O ID do banco de dados do elemento classificado e o ID do elemento ao lado do qual ele foi descartado. Com base nesses 2 valores, o servidor pode identificar facilmente a nova posição.

<div id="planlist" style="width:1000px">
    <ul style="width:1000px">
       <li plid="listId1"><a href="#pl-1">List 1</a></li>
       <li plid="listId2"><a href="#pl-2">List 1</a></li>
       <li plid="listId3"><a href="#pl-3">List 1</a></li>
       <li plid="listId4"><a href="#pl-4">List 1</a></li>
    </ul>
    <div id="pl-1"></div>
    <div id="pl-2"></div>
    <div id="pl-3"></div>
    <div id="pl-4"></div>
</div>
<script type="text/javascript" language="javascript">
    $(function () {
        var tabs = $("#planlist").tabs();
        tabs.find(".ui-tabs-nav").sortable({
            axis: "x",
            stop: function () {
                tabs.tabs("refresh");
            },
            update: function (event, ui) {
                //db id of the item sorted
                alert(ui.item.attr('plid'));
                //db id of the item next to which the dragged item was dropped
                alert(ui.item.prev().attr('plid'));

                //make ajax call
            }
        });
    });
</script>
Kalpesh Popat
fonte
4
As tags ASP podem ser confusas para aqueles que não estão familiarizados com elas e isso é um problema puramente jQuery / HTML.
ggdx
1
Dois anos depois! Está ocupado?
ggdx
O que acontece se o item movido for descartado como o primeiro item da lista?
Edson Horacio Junior
1
se algum item for descartado, o id "próximo a" = 0, action = del e plid = id do item que está sendo processado; else action = sort e existem 2 parâmetros, item sendo classificado e próximo ao qual ele será descartado . essas são as informações mínimas que o servidor pode usar para executar o restante das operações. é experimentado e teste padrão. Eu até adicionei e inseri usando o mesmo padrão - apenas o jogo de ação e os outros 2 parâmetros.
Kalpesh Popat
9

Você está com sorte, eu uso exatamente no meu CMS

Quando você deseja armazenar o pedido, basta chamar o método JavaScript saveOrder(). Ele fará uma POSTsolicitação do AJAX para saveorder.php, mas é claro que você sempre poderá publicá-la como um formulário regular.

<script type="text/javascript">
function saveOrder() {
    var articleorder="";
    $("#sortable li").each(function(i) {
        if (articleorder=='')
            articleorder = $(this).attr('data-article-id');
        else
            articleorder += "," + $(this).attr('data-article-id');
    });
            //articleorder now contains a comma separated list of the ID's of the articles in the correct order.
    $.post('/saveorder.php', { order: articleorder })
        .success(function(data) {
            alert('saved');
        })
        .error(function(data) { 
            alert('Error: ' + data); 
        }); 
}
</script>
<ul id="sortable">
<?php
//my way to get all the articles, but you should of course use your own method.
$articles = Page::Articles();
foreach($articles as $article) {
    ?>
    <li data-article-id='<?=$article->Id()?>'><?=$article->Title()?></li>
    <?
}               
?>   
</ul>
   <input type='button' value='Save order' onclick='saveOrder();'/>

Em saveorder.php; Lembre-se de que removi toda a verificação e verificação.

<?php
$orderlist = explode(',', $_POST['order']);
foreach ($orderlist as $k=>$order) {
  echo 'Id for position ' . $k . ' = ' . $order . '<br>';
}     
?>
Hugo Delsing
fonte
7

Este é o meu exemplo.

https://github.com/luisnicg/jQuery-Sortable-and-PHP

Você precisa capturar o pedido no evento de atualização

    $( "#sortable" ).sortable({
    placeholder: "ui-state-highlight",
    update: function( event, ui ) {
        var sorted = $( "#sortable" ).sortable( "serialize", { key: "sort" } );
        $.post( "form/order.php",{ 'choices[]': sorted});
    }
});
luisnicg
fonte
0

Eu posso alterar as linhas seguindo a resposta aceita e o exemplo associado no jsFiddle. Mas, devido a alguns motivos desconhecidos, não foi possível obter os IDs após as ações "parar ou alterar". Mas o exemplo publicado na página da interface do usuário do JQuery funciona bem para mim. Você pode verificar esse link aqui.

Web_Developer
fonte
0

Tente com esta solução: http://phppot.com/php/sorting-mysql-row-order-using-jquery/ em que o novo pedido é salvo em algum elemento HMTL. Em seguida, você envia o formulário com esses dados para algum script PHP e itera-o através do loop for.

Nota: Eu tive que adicionar outro campo db do tipo INT (11) que é atualizado (registro de data e hora) em cada iteração - serve para o script saber qual linha é atualizada constantemente, ou então você acaba com resultados embaralhados.

TomoMiha
fonte