lundi 21 janvier 2019

Datatable with server-side processing with check-boxes (Rails)

I have replace a dataTable on rails that was working perfectly well, with check-boxes to select rows and send them to another page. Due to the size of the table (>20,000) I was told to use server-size processing.

I have build the table, and manage to load my data within a second, all good. Search function, filtering etc all work. I display the check-boxes with no problem.

My view:

<div class="col-md-12">
  <table id="distrib_table" class="table table-striped" data-source="<%= distribs_url(format: "json") %>">
    <thead>
    <th scope="col"></th>
    <th scope="col"> First Name</th>
    <th scope="col"> Last Name</th>
    <th scope="col"> Email</th>
    <th scope="col"> Company</th>
    <th scope="col"> Ind. Delete</th>
    </thead>
    <tbody>


    </tbody>

  </table>
</div>
<script>

    $(document).ready(function (){
        var table = $('#distrib_table').DataTable({
            "searching": true,
            "limit": 5,
            "lengthMenu": [[5, 10, 25, 50, 100, 250, -1], [5, 10, 25, 50, 100, 250, "All"]],
            "bProcessing": true,
            "bServerSide": true,
            "sAjaxSource": $('#distrib_table').data('source'),
            'columnDefs': [{
                'targets': 0,
                'searchable':false,
                'orderable':false,
                'className': 'dt-body-center',
                'render': function (data, type, full, meta){
                    return '<input type="checkbox" name="id[]" value="'
                        + $('<div/>').text(data).html() + '">';
                }
            }],
            'order': [1, 'asc']
        });

        // Handle click on "Select all" control
        $('#distrib_table').on('click', function(){
            // Check/uncheck all checkboxes in the table
            var rows = table.rows({ 'search': 'applied' }).nodes();
            $('input[type="checkbox"]', rows).prop('checked', this.checked);
        });

        // Handle click on checkbox to set state of "Select all" control
        $('#distrib_table tbody').on('change', 'input[type="checkbox"]', function(){
            // If checkbox is not checked
            if(!this.checked){
                var el = $('#distrib_table-select-all').get(0);
                // If "Select all" control is checked and has 'indeterminate' property
                if(el && el.checked && ('indeterminate' in el)){
                    // Set visual state of "Select all" control
                    // as 'indeterminate'
                    el.indeterminate = true;
                }
            }
        });

        $('#distrib_table').on('submit', function(e){
            var form = this;

            // Iterate over all checkboxes in the table
            table.$('input[type="checkbox"]').each(function(){
                // If checkbox doesn't exist in DOM
                if(!$.contains(document, this)){
                    // If checkbox is checked
                    if(this.checked){
                        // Create a hidden element
                        $(form).append(
                            $('<input>')
                                .attr('type', 'hidden')
                                .attr('name', this.name)
                                .val(this.value)
                        );
                    }
                }
            });

            // FOR TESTING ONLY

            // Output form data to a console
            $('#distrib_table').text($(form).serialize());
            console.log("Form submission", $(form).serialize());

            // Prevent actual form submission
            e.preventDefault();
        });
    });
</script>

my controler:

class DistribsController < ApplicationController
  before_action :authenticate_user!, except: [:index, :show, :new, :edit_multiple, :update_multiple]
  before_action :find_distrib, only: [:show, :edit, :update, :destroy]
  respond_to :html, :json

  def index
    respond_to do |format|
      format.html {}
      format.json {render json: DistribsDatatable.new(view_context)}
    end

  end

  def show
    @distribs = Distrib.all.order("created_at DESC")

  end

  def new
    @distrib = current_user.distribs.build
  end

  def edit
    @distrib = Distrib.find params[:id]

  end

  def destroy
    @distrib = Distrib.find params[:id]
  end

  def distrib_params
    params.require(:distrib).permit(:first_name, :last_name, :email, :user_id)
  end

  def update
    @distrib = Distrib.find params[:id]
    @groups = Group.where(user_id: current_user.id)


    respond_to do |format|
      if @distrib.update(distrib_params)
        format.html {redirect_to(@distrib, :notice => 'Updated was successfull.')}
        format.json {respond_with_bip(@distrib)}
      else
        format.html {render :action => "edit"}
        format.json {respond_with_bip(@distrib)}
      end

    end
  end

  def create
    @distrib_ids = params[:selected_distribs]
    @groups = Group.where(user_id: current_user.id)

    @distrib = current_user.listdedistributions.build(listdedistribution_params)
    if @distrib.save
      redirect_to distribs_path
    else
      render 'new'
    end
  end

  def edit_multiple
    @distribs = Distrib.find(params[:distrib_ids])
    puts("Edit multiple", @distribs)
  end

  def find_distrib
    @distrib = Distrib.find(params[:id])
  end

  def listdedistribution_params
    params.require(:listdedistribution).permit(:distrib_id, :user_id, :group_id, :origine)
  end
  def group_params
    params.permit(:name, :user_id, :description)
  end
end

I would like to be able to fix the following issues:

  1. Checked box disappear when navigating from one page to the other,
  2. I could not put a select ALL check box on top the column,
  3. I no longer have a button to validate the selected boxes to pass the them to edit_multiple.html.erb

Aucun commentaire:

Enregistrer un commentaire