Pergunta

Você sempre quis ter uma tabela HTML classificável por arrastar e soltar, na qual você pudesse classificar linhas e colunas?Eu sei que é algo pelo qual eu morreria.Existem muitas listas classificáveis, mas encontrar uma tabela classificável parece impossível de encontrar.

Eu sei que você pode chegar bem perto das ferramentas que o script.aculo.us fornece, mas tive alguns problemas entre navegadores com elas.

Foi útil?

Solução

eu usei dhtmlxGrid no passado.Entre outras coisas, ele suporta arrastar e soltar linhas/colunas, classificação do lado do cliente (string, número inteiro, data, personalizado) e suporte a vários navegadores.

Resposta ao comentário:Não, não encontrei nada melhor - apenas saí desse projeto.:-)

Outras dicas

Usei o plugin classificável do jQuery UI com bons resultados.Marcação semelhante a esta:

<table id="myTable">
<thead>
<tr><th>ID</th><th>Name</th><th>Details</th></tr>
</thead>
<tbody class="sort">
<tr id="1"><td>1</td><td>Name1</td><td>Details1</td></tr>
<tr id="2"><td>2</td><td>Name1</td><td>Details2</td></tr>
<tr id="3"><td>3</td><td>Name1</td><td>Details3</td></tr>
<tr id="4"><td>4</td><td>Name1</td><td>Details4</td></tr>
</tbody>
</table>

e depois no javascript

$('.sort').sortable({
    cursor: 'move',
    axis:   'y',
    update: function(e, ui) {
        href = '/myReorderFunctionURL/';
        $(this).sortable("refresh");
        sorted = $(this).sortable("serialize", 'id');
        $.ajax({
            type:   'POST',
            url:    href,
            data:   sorted,
            success: function(msg) {
                //do something with the sorted data
            }
        });
    }
});

Isso envia uma versão serializada dos IDs dos itens para o URL fornecido.Esta função (PHP no meu caso) atualiza os pedidos dos itens no banco de dados.

Eu recomendo Classificáveis em jQuery.Você pode usá-lo em itens de lista ou em praticamente qualquer coisa, incluindo tabelas.

jQuery é muito amigável para vários navegadores e eu o recomendo o tempo todo.

A resposta de David Heggie foi a mais útil para mim.Pode ser um pouco mais conciso:

var sort = function(event, ui) {
  var url = "/myReorderFunctionURL/" + $(this).sortable('serialize');
  $.post(url, null,null,"script");  // sortable("refresh") is automatic
}

$(".sort").sortable({
  cursor: 'move',
  axis: 'y',
  stop: sort
});

funciona para mim, com a mesma marcação.

A maioria dos frameworks (Yui, MooTools, jQuery, Prototype/Scriptaculous, etc.) possui funcionalidade de lista classificável.Faça uma pequena pesquisa sobre cada um e escolha aquele que mais se adapta às suas necessidades.

Se você não se importa com Java, existe uma biblioteca muito útil para GWT chamada GWT-DND confira a demonstração online para ver como ela é poderosa.

Que tal classificável?Isso parece atender perfeitamente às suas necessidades.

É bastante fácil de usar - carregue o arquivo Javascript classificável e, em seguida, para cada tabela que você deseja tornar classificável, aplique class="sortable" à tag <table>.

Ele entenderá imediatamente como classificar a maioria dos tipos de dados, mas se houver algo que não funciona, você poderá adicionar uma chave de classificação personalizada para informar como classificar.A documentação explica tudo muito bem.

Se você descobrir que .serialize() retorna nulo na solução de David Heggie, defina os valores de id para os TRs como 'id_1' em vez de simplesmente '1'

Exemplo:

<tr id="id_1"><td>1</td><td>Name1</td><td>Details1</td></tr>
<tr id="id_2"><td>2</td><td>Name1</td><td>Details2</td></tr>
<tr id="id_3"><td>3</td><td>Name1</td><td>Details3</td></tr>
<tr id="id_4"><td>4</td><td>Name1</td><td>Details4</td></tr>

O texto acima será serializado como "id[]=1&id[]=2&id[]=3"

Você pode usar '=', '-' ou '_' em vez de '_'.E qualquer outra palavra além de "id".

Estou usando JQuery Sortable para fazer isso, mas caso você esteja usando Vue.js como eu, aqui está uma solução que cria uma diretiva Vue personalizada para encapsular a funcionalidade Sortable, estou ciente do Vue arrastável, mas ele não classifica as colunas da tabela como por questão AQUI Para ver isso em ação, VERIFIQUE ISSO

Código JS

Vue.directive("draggable", {
  //adapted from https://codepen.io/kminek/pen/pEdmoo
  inserted: function(el, binding, a) {
    Sortable.create(el, {
      draggable: ".draggable",
      onEnd: function(e) {
        /* vnode.context is the context vue instance: "This is not documented as it's not encouraged to manipulate the vm from directives in Vue 2.0 - instead, directives should be used for low-level DOM manipulation, and higher-level stuff should be solved with components instead. But you can do this if some usecase needs this. */
        // fixme: can this be reworked to use a component?
        // https://github.com/vuejs/vue/issues/4065
        // https://forum.vuejs.org/t/how-can-i-access-the-vm-from-a-custom-directive-in-2-0/2548/3
        // https://github.com/vuejs/vue/issues/2873 "directive interface change"
        // `binding.expression` should be the name of your array from vm.data
        // set the expression like v-draggable="items"

        var clonedItems = a.context[binding.expression].filter(function(item) {
          return item;
        });
        clonedItems.splice(e.newIndex, 0, clonedItems.splice(e.oldIndex, 1)[0]);
        a.context[binding.expression] = [];
        Vue.nextTick(function() {
          a.context[binding.expression] = clonedItems;
        });

      }
    });
  }
});

const cols = [
  {name: "One", id: "one", canMove: false},
  {name: "Two", id: "two", canMove: true},
  {name: "Three", id: "three", canMove: true},
  {name: "Four", id: "four", canMove: true},
]

const rows = [
  {one: "Hi there", two: "I am so excited to test", three: "this column that actually drags and replaces", four: "another column in its place only if both can move"},
  {one: "Hi", two: "I", three: "am", four: "two"},
  {one: "Hi", two: "I", three: "am", four: "three"},
  {one: "Hi", two: "I", three: "am", four: "four"},
  {one: "Hi", two: "I", three: "am", four: "five"},
  {one: "Hi", two: "I", three: "am", four: "six"},
  {one: "Hi", two: "I", three: "am", four: "seven"}
]

Vue.component("datatable", {
  template: "#datatable",
  data() {
    return {
      cols: cols,
      rows: rows
    }
  }
})

new Vue({
  el: "#app"
})

CSS

.draggable {
  cursor: move;
}

table.table tbody td {
  white-space: nowrap;
}

HTML do modelo Pug

#app
  datatable

script(type="text/x-template" id="datatable")
  table.table
    thead(v-draggable="cols")
      template(v-for="c in cols")
        th(:class="{draggable: c.canMove}")
          b-dropdown#ddown1.m-md-2(:text='c.name')
            b-dropdown-item First Action
            b-dropdown-item Second Action
            b-dropdown-item Third Action
            b-dropdown-divider
            b-dropdown-item Something else here...
            b-dropdown-item(disabled='') Disabled action

    tbody
      template(v-for="row in rows")
        tr
          template(v-for="(col, index) in cols")
            td {{row[col.id]}}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top