web-dev-qa-db-fra.com

Comment filtrer les tables de données en utilisant deux ou plusieurs listes déroulantes dépendantes?

J'essaie d'appliquer des filtres à ma table de données avec des listes déroulantes dépendantes. Mais lorsque j'essaie de sélectionner une valeur dans la liste déroulante, la table de données prend la valeur d'une seule liste déroulante.

Voici mon code:

Script:

<script type="text/javascript">
  $(document).ready(function(){
    var dataTable = $('#exampleProp').DataTable({
      "processing": true,
      "serverSide": true,
      "dom": 'lfrtip',
      "ajax": {
        "url": "<?= base_url('Property/fetchProp'); ?>",
        "dataType": "json",
        "type": "POST"
      },
      "lengthMenu": [[50, 100, 200, -1], [50, 100, 200, "All"]],
      // "ordering": false,
    });

    $('#areaId').on('change', function(){
      if (this.value == 1) {
        dataTable.search("Midlands & East of England").draw();
      } else {
        dataTable.search("North East, Yorkshire & Humberside").draw();
      }
    });
    $('#cluster_id').on('change', function(){
       dataTable.search(this.value).draw();   
    });
    $('#prop_type').on('change', function(){
       dataTable.search(this.value).draw();   
    });
    $('#prop_status').on('change', function(){
       dataTable.search(this.value).draw();   
    });

  });
</script>

En cela, le cluster dépend de la zone, mais si je sélectionne une zone, il filtre en utilisant la zone uniquement et non par cluster.

Voici le code pour choisir une liste de grappes dans la base de données:

$('#areaId').change(function(){
         var form_date =
         $.ajax({
          url: "<?= base_url('Property/clusterlistAddPropertyUse'); ?>",
          data: {areaId:$(this).val()},
          method:'POST',
          dataType: 'html',
          success:function(data){
              // $('#cluster_id option:selected').each(function(){
              // $(this).prop('selected', false);
              // });
              $('#cluster_id').html(data); 
              $('.propcluster').multiselect('rebuild');                 
             }
          }); 
    });

Voici mon code de vue:

<?php if($this->session->flashdata('success_msg')){ ?>
  <div class="alert alert-success">
    <?php echo $this->session->flashdata('success_msg'); ?>
  </div> 
<?php } ?>

<?php if($this->session->flashdata('error_msg')){ ?>
  <div class="alert alert-danger">
    <?php echo $this->session->flashdata('error_msg'); ?>
  </div> 
<?php } ?>

<div class="panel panel-default" id="refresh">
  <div class="panel-heading">
    <b>Property List</b>
  </div>
  <div class="panel-body">
    <div class="col-md-3">
      <label>Area:</label>
      <select class="form-control select2" name="area_id" id="areaId">
        <option>All</option>
        <?php foreach ($areas as $area) { ?>
          <option value="<?= $area->area_id; ?>"><?php echo $area->area_name; ?></option>
        <?php } ?>
      </select>
    </div>
    <div class="col-md-3">
      <label>Cluster:</label>
      <select class="form-control select2" name="cluster_id[]" id="cluster_id">
      <option>All</option>
        <?php foreach ($clusters as $cluster){ ?>
          <option><?php echo $cluster->cluster_name; ?></option>
        <?php } ?>
      </select>
    </div>
    <div class="col-md-3">
      <label>Type:</label>
      <select class="form-control" name="property_type" id="prop_type">
        <option>All</option>
        <?php if ($property_type) { foreach ($property_type as $type) {?>
          <option><?= $type->property_type_name;?></option>
        <?php } } ?>
      </select> 
    </div> 
    <div class="col-md-3">
      <label>Stage:</label>
      <select class="form-control" name="property_status" id="prop_status">
        <option>All</option>   
        <?php foreach ($property_stage as $stage) { ?>  
          <option><?= $stage->stage_name; ?></option>
        <?php } ?>
      </select>
    </div> 
  </div>
  <div class="panel-body">
    <table id="exampleProp" class="table table-striped table-bordered" cellspacing="0" width="100%">
      <thead>
        <tr>
          <th>Code</th>
          <th>Date</th>
          <th>Type</th>
          <th>ASYS</th>
          <th>Address1</th>
          <!-- <th>Area</th> -->
          <th>City</th>
          <th>Status</th>
          <th>Landlord</th>
          <th>Rooms</th>
          <th>Edit</th>
          <th>Action</th>
        </tr>
      </thead>
      <tfoot>
        <tr>
          <th>Code</th>
          <th>Date</th>
          <th>Type</th>
          <th>ASYS No</th>
          <th>Address1</th>
          <!-- <th>Area</th> -->
          <th>City</th>
          <th>Status</th>
          <th>Landlord</th>
          <th>Rooms</th>
          <th>Edit</th>
          <th>Action</th>
        </tr>
      </tfoot>
    </table>
  </div>
  <div class="modal fade" id="myModal">
  <?php include('property_model_view.php'); ?>
  </div>
</div>

Je veux filtrer les données avec la zone et le cluter, puis taper et mettre en scène également.

Modifier:**

Pour plus de détails, j'ajoute le code du contrôleur et du modèle ici:

**

Modèle

public function prop_query()
{
    # code...
    $this->db->select('property_id, property_code, property_added_date, property_updated_date, property_type, tbl_property_type.property_type_name as type, property_ASYS_no, property_address_1, property_area, tbl_area.area_name as area, property_cluster, tbl_cluster.cluster_name as cluster, property_status, tbl_property_stage.stage_name as stage, property_landlord_id, concat(tbl_landlord.landlord_first_name, tbl_landlord.landlord_middle_name, tbl_landlord.landlord_last_name) as landlord, property_postcode, count(tbl_rooms.room_property_id) as rooms,');
    $this->db->from($this->property);

    $this->db->join('tbl_property_type', 'tbl_property.property_type = tbl_property_type.property_type_id', 'left');
    $this->db->join('tbl_area', 'tbl_property.property_area = tbl_area.area_id', 'left');
    $this->db->join('tbl_cluster', 'tbl_property.property_cluster = tbl_cluster.cluster_id', 'left');
    $this->db->join('tbl_property_stage', 'tbl_property.property_status = tbl_property_stage.stage_id', 'left');
    $this->db->join('tbl_landlord', 'tbl_property.property_landlord_id = tbl_landlord.landlord_id', 'left');
    $this->db->join('tbl_rooms', 'tbl_property.property_id = tbl_rooms.room_property_id', 'left');

    // $whereArray = array('tbl_property.property_type' => $propertyType, 'tbl_property.property_area' => $area, 'tbl_property.property_status' => $stageId, 'tbl_property.property_cluster' => '$clusterString');

    // $this->db->where('tbl_property.property_type', $propertyType);
    // $this->db->where('tbl_property.property_area', $area);
    // $this->db->where('tbl_property.property_status', $stageId);
    // $this->db->where('tbl_property.property_cluster', $clusterString);

    $this->db->group_by('tbl_property.property_id');
    // $this->db->order_by("tbl_property.property_updated_date", "DESC");

    if (isset($_POST["search"]["value"])) {
        # code...
        $this->db->like("property_id", $_POST["search"]["value"]);
        $this->db->or_like("property_code", $_POST["search"]["value"]);
        $this->db->or_like("property_added_date", $_POST["search"]["value"]);
        $this->db->or_like("tbl_property_type.property_type_name", $_POST["search"]["value"]);
        $this->db->or_like("property_ASYS_no", $_POST["search"]["value"]);
        $this->db->or_like("property_address_1", $_POST["search"]["value"]);
        $this->db->or_like("tbl_area.area_name", $_POST["search"]["value"]);
        $this->db->or_like("tbl_cluster.cluster_name", $_POST["search"]["value"]);
        $this->db->or_like("tbl_property_stage.stage_name", $_POST["search"]["value"]);
        $this->db->or_like("concat(tbl_landlord.landlord_first_name, tbl_landlord.landlord_middle_name, tbl_landlord.landlord_last_name)", $_POST["search"]["value"]);
        $this->db->or_like("property_postcode", $_POST["search"]["value"]);
    }

    if (isset($_POST["order"])) {
        # code...
        // $this->db->order_by("tbl_property.property_updated_date", "DESC");
        $this->db->order_by($this->order_column[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
    } else {
        # code...
        $this->db->order_by("tbl_property.property_updated_date", "DESC");
        // $this->db->order_by($this->order_column[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
    }
}

public function prop_datatables()
{
    # code...
    $this->prop_query();

    if ($_POST["length"] != -1) {
        # code...
        $this->db->limit($_POST["length"], $_POST["start"]);
    }

    $query = $this->db->get();

    return $query->result();
}

public function prop_filtered_data()
{
    # code...
    $this->prop_query();
    $query = $this->db->get();

    return $query->num_rows();
}

public function prop_all_data()
{
    # code...
    $this->db->select("*");
    $this->db->from($this->property);

    return $this->db->count_all_results();
}

Manette:

public function fetchProp()
{
    # code...
    $user = $this->ion_auth->user()->row();
    $data['username'] = $user->username;

    $data['user_id'] = $user->id;
    $user_id = $user->id;
    $data['groupId'] = $this->l->groupId($user_id);
    $data['group'] = $data['groupId']['0']->group_id;

    $fetch_prop = $this->pm->prop_datatables();

    $data = array();

    foreach ($fetch_prop as $row) {
        # code...
        $sub_array = array();
        $sub_array[] = $row->property_code;
        $sub_array[] = $row->property_added_date;
        $sub_array[] = $row->type;
        $sub_array[] = $row->property_ASYS_no;
        $sub_array[] = $row->property_address_1;
        // $sub_array[] = $row->area;
        $sub_array[] = $row->cluster;
        $sub_array[] = $row->stage;
        $sub_array[] = $row->landlord;
        $sub_array[] = $row->rooms;

            }
        }


        // $sub_array[] = '<a style="text-decoration: none;" href="'.base_url('Property/propertyDetails/'.$row->property_id).'" class="btn-warning btn-xs">View</a>&nbsp;
        // <a style="text-decoration: none;" href="'.base_url('Property/viewRoom/'.$row->property_id).'" class="btn-success btn-xs">Rooms</a>';


        $data[] = $sub_array;
    }

    $output = array(
        "draw" => intval($_POST["draw"]),
        "recordsTotal" => $this->pm->prop_all_data(),
        "recordsFiltered" => $this->pm->prop_filtered_data(),
        "data" => $data
    );

    echo json_encode($output);
}

Je suis passé par ce lien Data-Tables , mais il donne le résultat des colonnes de table seulement, je ne montre pas la colonne de zone dans la table.

Edit_2:

Alors que je cherchais dans Google, j'ai eu ce lien, API de recherche (expressions régulières) , Filtre de colonne spécifique au tableau de données avec liste déroulante à sélection multiple , Recherche de colonne individuelle (sélection d’entrées) , j'essaie d'obtenir un résultat comme celui-ci, mais avec une boîte déroulante.

Toute aide est la bienvenue. Merci d'avance.

8
Ganesh Aher

Merci pour votre réponse. Je travaille sur Data-Table avec PHP et je veux que Server-Side Processing récupère les données de la base de données.

Je poste mon code ici,

J'ai trouvé une solution pour cela:

<div class="panel panel-default" id="refresh">
    <div class="panel-heading">
        <b>Defects List</b>
    </div>
    <div class="panel-body">
        <form id="form-filter" class="form-horizontal">
            <div class="row">
                <div class="col-md-3">
                  <label>Area:</label>
                  <?php echo $form_area; ?>
                </div>
                <div class="col-md-3">
                  <label>Cluster:</label>
                  <?php echo $form_cluster; ?>
                </div>
                <div class="col-md-3">
                    <label>Timeframe:</label>
                    <?php echo $form_timeframe; ?>
                </div>  
                <div class="col-md-3">
                    <label>Status:</label>
                    <?php echo $form_defect_status; ?>
                </div>
            </div><br>
            <div class="row">
                <div class="col-md-3" style="display: none;">
                    <label>FUP Start Date:</label>
                    <div class="input-group date">
                        <div class="input-group-addon">
                            <i class="fa fa-calendar"></i>
                        </div>
                        <input type="text" name="startdate" class="form-control" id="datepickerfilter1" placeholder ="dd/mm/yyyy"/>
                    </div>
                </div>
                <div class="col-md-3" style="display: none;">
                    <label>FUP End Date:</label>
                    <div class="input-group date">
                        <div class="input-group-addon">
                            <i class="fa fa-calendar"></i>
                        </div>
                        <input type="text" name="enddate" class="form-control" id="datepickerfilter2" placeholder ="dd/mm/yyyy"/>
                    </div>
                </div>
                <div class="col-sm-6 pull-right" style="text-align: right;">
                    <label>&nbsp;</label><br>
                    <button type="button" id="btn-filter" class="btn btn-primary" style="margin: 0 0px;">Filter</button>
                    <button type="button" id="btn-reset" class="btn btn-default" style="margin: 0 30px;">Reset</button>
                </div>
            </div>
        </form>
    </div>
    <div class="panel-body">
    <table id="defect_view" class="table table-striped table-bordered" cellspacing="0" width="100%">
        <thead>
                <tr>
                <th>ID</th>
                <th>Date</th>
                <th>Subject</th>
                <th>Address1</th>
                <th>Cluster</th>
                <th>Assign to</th>
                <th>FUP-Date</th>
                <th>Timeframe</th>
                <!-- <th>Landlord</th> -->
                <th>Status</th>
                <th>Action</th>

                </tr>
            </thead>
            <tfoot>
                <th>ID</th>
                <th>Date</th>
                <th>Subject</th>
                <th>Address1</th>
                <th>Cluster</th>
                <th>Assign to</th>
                <th>FUP-Date</th>
                <th>Timeframe</th>
                <!-- <th>Landlord</th> -->
                <th>Status</th>
                <th>Action</th> 
            </tfoot>
        </table>
    </div>
</div>

SCRIPT:

<script type="text/javascript">
  var defect_view_var;

$(document).ready(function() {

    defect_view_var = $('#defect_view').DataTable({ 

        "processing": true, //Feature control the processing indicator.
        "serverSide": true, //Feature control DataTables' server-side processing mode.
        "order": [], //Initial no order.

        // Load data for the table's content from an Ajax source
        "ajax": {
            "url": "<?php echo site_url('Property/ajax_list_for_defects')?>",
            "type": "POST",
            "data": function ( data ) {
                data.area = $('#area').val();
                data.cluster = $('#cluster').val();
                data.timeframe = $('#timeframe').val();
                data.defect_status = $('#defect_status').val();
                data.startdate = $('#datepickerfilter1').val();
                data.enddate = $('#datepickerfilter2').val();
            }
        },
        "lengthMenu": [[50, 100, 200, -1], [50, 100, 200, "All"]],
        //Set column definition initialisation properties.
        "columnDefs": [
        { 
            "targets": [ 0, 9 ], //first column / numbering column
            "orderable": false, //set not orderable
        },
        ],

    });

    $('#btn-filter').click(function(){ //button filter event click
        defect_view_var.ajax.reload();  //just reload table
    });
    $('#btn-reset').click(function(){ //button reset event click
        $('#form-filter')[0].reset();
        // document.getElementById('form-filter').reset();
        // defect_view_var.ajax.reload();  //just reload table
        window.location.reload();
    });

});
</script>

Modèle Codeigniter:

private function _get_datatables_query()
    {

        //add custom filter here
        // if($this->input->post('startdate') && $this->input->post('enddate'))
        // {
        //  $this->db->where("'FUPdate' BETWEEN 'startdate' AND 'enddate'");
        // }
        if($this->input->post('area'))
        {
            $this->db->like('area_name', $this->input->post('area'));
        }
        if($this->input->post('cluster'))
        {
            $clustersID['cluster']=$this->input->post('cluster');
            if(!empty($clustersID['cluster'])){
              // Array contains values, everything ok
              $clusterString = implode(',', $clustersID['cluster']);
            }
            foreach ($clustersID['cluster'] as $clusterStr) {
                $this->db->like('cluster_name', $clusterStr);
            }

        }
        if($this->input->post('timeframe'))
        {
            $this->db->like('timeframe_name', $this->input->post('timeframe'));
        }
        if($this->input->post('defect_status'))
        {
            $this->db->like('defect_status_name', $this->input->post('defect_status'));
        }
        if($this->input->post('startdate'))
        {
            $this->db->like('FUPdate', $this->input->post('startdate'));
        }
        if($this->input->post('enddate'))
        {
            $this->db->like('FUPdate', $this->input->post('enddate'));
        }

        $this->db->from($this->Property_Defect_View);
        $i = 0;

        foreach ($this->Property_Defect_search as $item) // loop column 
        {
            if($_POST['search']['value']) // if datatable send POST for search
            {

                if($i===0) // first loop
                {
                    $this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
                    $this->db->like($item, $_POST['search']['value']);
                }
                else
                {
                    $this->db->or_like($item, $_POST['search']['value']);
                }

                if(count($this->Property_Defect_search) - 1 == $i) //last loop
                    $this->db->group_end(); //close bracket
            }
            $i++;
        }

        if(isset($_POST['order'])) // here order processing
        {
            $this->db->order_by($this->Property_Defect_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
        } 
        else if(isset($this->order))
        {
            $order = $this->order;
            $this->db->order_by(key($order), $order[key($order)]);
        }
    }

Manette:

public function DefectList()
    {   
        $user = $this->ion_auth->user()->row();
        $data['username'] = $user->username;

        $data['user_id'] = $user->id;
        $user_id = $user->id;
        $data['groupId'] = $this->l->groupId($user_id);
        $data['group'] = $data['groupId']['0']->group_id;
        $data['title'] = 'Defect List';

        $areas = $this->defects->get_list_areas();
        $clusters = $this->defects->get_list_clusters();
        $timeframes = $this->defects->get_list_timeframes();
        $defect_statuss = $this->defects->get_list_defect_statuss();

        $areaList = array('' => 'All Areas');
        foreach ($areas as $area) {
            $areaList[$area] = $area;
        }
        $data['form_area'] = form_dropdown('',$areaList,'','name="area" id="area" class="form-control select2"');

        $clusterList = array('' => 'All Clusters');
        foreach ($clusters as $cluster) {
            $clusterList[$cluster] = $cluster;
        }
        $data['form_cluster'] = form_dropdown('',$clusterList,'','name="cluster" id="cluster" class="form-control select2" multiple=""');

        $timeframeList = array('' => 'All Timeframes');
        foreach ($timeframes as $timeframe) {
            $timeframeList[$timeframe] = $timeframe;
        }
        $data['form_timeframe'] = form_dropdown('',$timeframeList,'','name="timeframe" id="timeframe" class="form-control select2"');

        $defect_statusList = array('' => 'All Status');
        foreach ($defect_statuss as $defect_status) {
            $defect_statusList[$defect_status] = $defect_status;
        }
        $data['form_defect_status'] = form_dropdown('',$defect_statusList,'','name="defect_status" id="defect_status" class="form-control select2"');


        $this->load->view('template/header', $data);
        $this->load->view('Property/defect_view', $data);
        $this->load->view('template/footer');
    }

    public function ajax_list_for_defects()
    {
        $list = $this->defects->get_datatables();
        $data = array();
        // $no = $_POST['start'];
        foreach ($list as $defects) {
            // $no++;

            $start= $defects->defect_start_date; 
            $start_date = str_replace('/', '-', $start); 
            $startdate=date('d/m/Y', strtotime($start_date)); 

            $follow= $defects->defect_followup_date; 
            $followup = str_replace('/', '-', $follow); 
            $followupdate=date('d/m/Y', strtotime($followup));

            $row = array();
            $row[] = $defects->defect_id;
            $row[] = $startdate;
            $row[] = $defects->defect_subject;
            $row[] = $defects->property_address_1;
            $row[] = $defects->cluster_name;
            $row[] = $defects->users;
            $row[] = $followupdate;
            $row[] = $defects->timeframe_name;
            $row[] = $defects->defect_status_name;
            $row[] = '<a href="'.base_url('property/defectDetails/'.$defects->defect_id).'" style="text-decoration: none;" class="btn btn-info btn-xs">View 
                    <!-- <i class="fa fa-eye" aria-hidden="true" title="View Defect" ></i> -->
                    </a>';

            $data[] = $row;
        }

        $output = array(
                        "draw" => $_POST['draw'],
                        "recordsTotal" => $this->defects->count_all(),
                        "recordsFiltered" => $this->defects->count_filtered(),
                        "data" => $data,
                );
        //output to json format
        echo json_encode($output);
    }

Je mets tout mon code ici, donc cela aidera les autres.

Merci.

0
Ganesh Aher

Il est important de reconnaître la différence entre .search() et .column().search()

L'un des problèmes que vous avez ici est que vous utilisez .search() comme s'il agit de manière soustractive sur l'ensemble de données actuellement filtré. En réalité, chaque appel de la fonction .search() s'exécute simplement sur l'ensemble de données original, de sorte qu'il ne renverra jamais qu'un jeu de données avec 1 filtre appliqué. 

Pour résoudre ce problème, la meilleure option consiste à rechercher des valeurs spécifiques dans des colonnes spécifiques et à tirer parti du chaînage disponible dans .column().search().

Je suggérerais de modifier votre approche des menus déroulants pour utiliser des attributs de données pour la colonne qu'ils souhaitent filtrer, par exemple:

<select class="table-filter" name="area_id" data-column-filter="2">
    <option></option>
</select>
<select class="table-filter" name="cluster_id" data-column-filter="3">
    <option></option>
</select>

Où l'attribut data-column-filter est l'index de la colonne que vous souhaitez filtrer.

Vous pouvez ensuite écrire un écouteur d'événement simple pour les modifications sur toutes les zones de sélection pertinentes. Nous pouvons même tester la zone de sélection pour voir s’il s’agit d’une zone de sélection multiple et réagir en conséquence - nous pouvons obtenir un tableau des valeurs choisies, puis les associer dans une déclaration rationnelle rationnelle:

$('.table-filter').on('change',function(){
    $('.table-filter').each(function(){

        var filterColumn = $(this).data('column-filter');
        var filterValue = $(this).val();

        if($(this).is('[multiple]'])){
            var filterValuesExpression = filterValue.join('|');
            dataTable.column(filterColumn).search(filterValuesExpression, true, false );
        }else{
            dataTable.column(filterColumn).search(filterValue);
        }
    });

    dataTable.draw();
});

En termes de logique que vous utilisez pour déterminer quelles boîtes doivent et ne doivent pas faire partie du filtre à un moment donné (lesquelles dépendent de quelles autres), cela est tout à fait distinct de DataTables lui-même.

5
Perran Mitchell

L'approche suivante s'appuie sur un ensemble aléatoire de données comprenant des relations fictives entre Zone et Ville/Cluster afin de remplir à nouveau la liste de sélection de villes chaque fois qu'une zone différente est sélectionnée.

J'ai commenté le code pour expliquer la procédure le mieux possible.

HIH

var infoText = "";
            var relationships = {};
            $(document).ready(function() {
                var columns = [
                    {"data": "Date"},
                    {"data": "Type"},
                    {"data": "ASYS"},
                    {"data": "Address1"},
                    {"data": "Area"},
                    {"data": "City"},
                    {"data": "Status"},
                    {"data": "Landlord"},
                    {"data": "Rooms"}
                ];
                /*generate random relationships between area and cities*/
                generateRelationships();

                var data = generateRandomData(columns);
                var dataTable = $('#exampleProp').DataTable({
                    "data": data,
                    "columns": columns,
                    ordering: false
                });

                $('#areaId').on('change', function() {
                    var selectedAreaId = $(this).val();
                    if (this.value !== '') {
                        if (this.value == 1) {
                            dataTable.column(4).search("Midlands & East of England").draw();
                        } else {
                            dataTable.column(4).search("North East, Yorkshire & Humberside").draw();
                        }

                        /*trigger city filter*/
                        /*make the options related to this area become "selected"*/
                        $('#cluster_id option').each(function() {
                            if ($(this).val() !== '')
                                if (relationships[selectedAreaId].includes($(this).val())) {
                                    $(this).css('display', 'block');
//                                $(this).prop('selected', true);
                                }
                                else {
                                    $(this).css('display', 'none');
//                                $(this).prop('selected', false);
                                }
                        });
                    }
                    else {
                        $('#cluster_id option').css('display', 'block');
                        dataTable.column(4).search('').draw();
                    }
                });
                $('#cluster_id').on('change', function(e) {

                    var searchString = 'City (';
                    /*here we catch the currently selected cities to pass to the search() method*/
                    var selectedOptions = $(this).children('option').filter(':selected');
                    selectedOptions.each(function(i) {
                        searchString += $(this).val();
                        /*i use | assuming you need OR instead of AND for the city multiselect*/
                        searchString += (i === selectedOptions.length - 1 ? ''/*^_^*/ : '|');
                    });
                    //DON'T INCLUDE NEXT LINE THERE -> /*^_^*/, I'LL THROW ERROR WHEN SELECTION IS EMPTY
                    searchString += ")";
                    /*search for selected values using regex is the way to filter in multi select*/
                    dataTable.column(5).search(searchString, true).draw();
                });
                $('#prop_type').on('change', function() {
                    dataTable.column(1).search(this.value).draw();
                });
                $('#prop_status').on('change', function() {
                    dataTable.column(6).search(this.value).draw();
                });
                /*area-city relationship info - NOT NECESSARY*/
                var infoP = $('<p style="background: lightblue"><b>FICTICIOUS RELATIONSHIPS INFO</b><br></p>');
                infoP.append(infoText);
                $('#exampleProp_wrapper').after(infoP);
            });

            /*relate each area to a (in this case random) group of cities*/
            /*maybe the relationships generated by the following code are not near your real life scenarios,
             * for example, I'm assuming there exist only 2 areas and a city can be related to more than 1 area,
             * again this is just for testing purposes, you have to device a way (if you don't have it already
             * of relating these two entities on the client side in order to make the cascading filter work */

            function generateRelationships() {
                $('#areaId option').each(function() {
                    var areaId = $(this).val();
                    if (areaId !== '') {
                        infoText += ("Area <b>" + $(this).text() + "</b> is related to cities ");
                        relationships[areaId] = [];
                        $('#cluster_id option').each(function() {
                            var clusterId = $(this).val();
                            if (clusterId !== '')
                                if (Math.random() > .5) {
                                    relationships[areaId].Push(clusterId);
                                    infoText += ("<b><u>" + clusterId + "</u></b> ");
                                }
                        });
                        infoText += "<br>";
                    }
                });
            }

            /*generate test data set*/
            function generateRandomData(columns) {
                
                var data = [];
                var colCount = columns.length;
                for (var i = 0; i < 6; i++) {
                    var tr = {};
                    for (var j = 0; j < colCount; j++) {
                        var area;
                        if (columns[j].data === 'Area') {
                            var r = Math.random();

                            tr['Area'] = r < .5 ? "Midlands & East of England" : "North East, Yorkshire & Humberside";
                            area = r < .5 ? 1 : 2;
                        }
                        else if (columns[j].data === 'City') {
                            
                            var randomCity = relationships[area][Math.floor(Math.random() * relationships[area].length)];
                            tr[columns[j].data] = columns[j].data + " " + randomCity;
                        }
                        else
                            tr[columns[j].data] = columns[j].data + " " + Math.ceil(Math.random() * 6);
                    }
                    data.Push(tr);
                }
                return data;
            }
.SideNav{
                position: fixed;
                height: 100vh;
                width: 20vw;
                background: red;
                top: 0;
                left: 0
            }
            span{
                margin-left: 30vw
            }

            td{
                text-align: center
            }

            #cluster_id{
                height: 140px
            }
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<div class="panel panel-default" id="refresh">
            <div class="panel-heading">
                <b>Property List</b>
            </div>
            <div class="panel-body">
                <div class="col-md-3">
                    <label>Area:</label>
                    <select class="form-control select2" name="area_id" id="areaId">
                        <option value="">ALL</option>
                        <option value="1">Midlands & East of England</option>
                        <option value="2">North East, Yorkshire & Humberside</option>
                    </select>
                </div>
                <div class="col-md-3">
                    <label>Cluster:</label>
                    <select multiple="multiple" class="form-control select2" name="cluster_id[]" id="cluster_id">
                        <option value="">ALL</option>
                        <option value="1">City 1</option>
                        <option value="2">City 2</option>
                        <option value="3">City 3</option>
                        <option value="4">City 4</option>
                        <option value="5">City 5</option>
                        <option value="6">City 6</option>
                    </select>
                </div>
                <div class="col-md-3">
                    <label>Type:</label>
                    <select class="form-control" name="property_type" id="prop_type">
                        <option value="">ALL</option>
                        <option>Type 1</option>
                        <option>Type 2</option>
                        <option>Type 3</option>
                        <option>Type 4</option>
                        <option>Type 5</option>
                        <option>Type 6</option>
                    </select>
                </div>
                <div class="col-md-3">
                    <label>Stage:</label>
                    <select class="form-control" name="property_status" id="prop_status">
                        <option>ALL</option>
                        <option>Stage 1</option>
                        <option>Stage 2</option>
                        <option>Stage 3</option>
                        <option>Stage 4</option>
                        <option>Stage 5</option>
                        <option>Stage 6</option>
                    </select>
                </div>
            </div>
            <div class="panel-body">
                <table id="exampleProp" class="table table-striped table-bordered" cellspacing="0" width="100%"></table>
            </div>
            <div class="modal fade" id="myModal">

            </div>
        </div>

2
Scaramouche

Ceci est un exemple comment cela peut être fait avec angular.js

Définir ng-app dans votre tag html

    <html ng-app="myApp">

Définir le fichier angular.js requis 

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>

css

<style>
.pagination a {
    color: black;
    float: left;
    padding: 8px 16px;
    text-decoration: none;
    transition: background-color .3s;
}

.pagination a.active {
    background-color: #4CAF50;
    color: white;
}

th > input[type='text']
{
    width: 90%;
}

.table {
  //border-collapse: collapse;
  border-collapse: separate;

}

thead th,tbody th {
  border-bottom: 1px solid;
    border-color: #eae7e7;

}

thead tr:first-child {

    height: 30px;
    background: white; /* For browsers that do not support gradients */
    background: -webkit-linear-gradient(white, #f2f2f2); /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(white, #f2f2f2); /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(white, #f2f2f2); /* For Firefox 3.6 to 15 */
    background: linear-gradient(white, #f2f2f2); /* Standard syntax (must be last) */
}
thead tr:nth-child(2), tfoot tr:first-child  {

    height: 30px;
    background: white; /* For browsers that do not support gradients */
    background: -webkit-linear-gradient(#f2f2f2, white); /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(#f2f2f2, white); /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(#f2f2f2, white); /* For Firefox 3.6 to 15 */
    background: linear-gradient(#f2f2f2, white); /* Standard syntax (must be last) */
}


thead td, thead th, tbody td,tbody th{
  border-left: 1px solid;
  border-color: #eae7e7;
  padding: 5px 10px;

}
.table td:first-child, .table th:first-child {
  border-left: none;
}

.icon-sort {

    background-position: -313px -119px;
}
.icon-sort.reverse {

    background-position: -288px -120px;
}


.icon-unsorted {
    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAABGUlEQVR4AZWQAUfEYBzGC07fILfrbnfgqG1jmxliDitmYIaxb9Y3CEIEVHDaUGMfYF8gIyBqbd7eH7wWofB6/J7nN+x/IIRQbz6fH8p3slgsrkl4uv8QNU071XX9wTAMQcLTD6bi2WazubUsq3ddV5AwPftU1tbr9Z0UPhGDIHgjYXp2JS+Xy71t2wNCFEV113UxCdOzKznLshvf9z+SJHlp23ZHR8L07Er+6/u/LO96td1u3zmX/BmdjoTp2ZUchmHted4o/16sVqt7KR6TMD27kpumOc/z/EkOvWmaQp7rlYTp2ZU8juOsqqqLoij2UvhyHEeQMD27knl93x+VZXmZpukz9yVh+l+vMQzDrK7rXRzHjyQ83b8BlglBGLw1Kb4AAAAASUVORK5CYII=);
    background-position: center center;
    }
</style>

HTML

<div class="row background-white boxshadows"  ng-controller="myCtrl" > 

    <div class="span12" style="margin-bottom:10px">
        <div style="text-align: center;">
            <select name="singleSelect" id="singleSelect" ng-model="kategori">
                <option value="">SET</option> <!-- not selected / blank option -->
                <option value="TO">TO</option> <!-- interpolation -->
                <option value="FR">FR</option>
                <option value="FE">FE</option>
            </select>
                <select name="singleSelect2" id="singleSelect2" ng-model="sit">
                <option value="">LA</option> <!-- not selected / blank option -->
                <option value="101">J</option> <!-- interpolation -->
                <option value="104">B</option>
                <option value="105">J2</option>
                <option value="102">G</option>
                <option value="201">S</option>
                <option value="203">S2</option>
                <option value="205">O</option>
                <option value="106">A</option>
                <option value="108">H</option>
            </select>
        </div>  
   </div>                             
    <table class="table" style="background-white">
        <thead class="background-white">
            <tr>
                <th ng-click="sortBy('id')">        
                    ID
                    <i class="icon-sort" ng-show="propertyName === 'id'" ng-class="{reverse: reverse}"></i>

                    <i class="bootstrap-icon icon-unsorted" ng-hide="propertyName === 'id'" ></i>
                </th>
                <th ng-click="sortBy('l_namn')">
                    L namn
                    <span class="icon-sort" ng-show="propertyName === 'l_namn'" ng-class="{reverse: reverse}"></span>
                    <i class="bootstrap-icon icon-unsorted" ng-hide="propertyName === 'l_namn'" ></i>

                </th>
                <th ng-click="sortBy('ldag')">
                    Leveransdag
                    <span class="icon-sort" ng-show="propertyName === 'ldag'" ng-class="{reverse: reverse}"></span>
                    <i class="bootstrap-icon icon-unsorted" ng-hide="propertyName === 'ldag'" ></i>

                </th>
                <th ng-click="sortBy('l_nr')">
                    L nr
                    <span class="icon-sort" ng-show="propertyName === 'l_nr'" ng-class="{reverse: reverse}"></span>
                    <i class="bootstrap-icon icon-unsorted" ng-hide="propertyName === 'l_nr'"  ></i>
                </th>
                <th ng-click="sortBy('b_nr')">
                    Beställnings nr
                    <span class="icon-sort" ng-show="propertyName === 'b_nr'" ng-class="{reverse: reverse}"></span>
                    <i class="bootstrap-icon icon-unsorted" ng-hide="propertyName === 'b_nr'" ></i>
                    <span class="triangle"  ></span>
                </th>
                <th ng-click="sortBy('f_nr')">
                    F nr
                    <span class="icon-sort" ng-show="propertyName === 'f_nr'" ng-class="{reverse: reverse}"></span>
                    <i class="bootstrap-icon icon-unsorted" ng-hide="propertyName === 'f_nr'"  ></i>
                </th>
            </tr>
            <tr>
                <th>
                    <input ng-model="search.id" id="sok" type="text" />
                </th>
                <th>
                    <input ng-model="search.l_namn" id="sok" type="text" />
                </th>
                <th>
                    <input ng-model="search.ldag" id="sok" type="text"  />
                </th>
                <th>
                    <input ng-model="search.l_nr" id="sok" type="text" />
                </th>
                <th>
                    <input ng-model="search.b_nr" id="sok" type="text" />
                </th>
                <th>
                    <input ng-model="search.f_nr" id="sok" type="text" />
                </th>
            </tr>
        </thead>
        <tfoot>
                <tr>
                    <td>
                    </td>
                    <td>
                        <select name="singleSelect3" id="singleSelect3" ng-model="rows">
                            <option value="">10</option> <!-- not selected / blank option -->
                            <option value="50">50</option><!-- interpolation -->
                            <option value="100">100</option>
                        </select>
                        </td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </tfoot>
        <tbody ng-repeat="x in records | filter:search | orderBy:propertyName:reverse">
            <tr ng-class-odd="'odd'" ng-class-even="'even'">
                <td ng-style="{'background-color': (bgcolor == 'id') ? ($index % 2 === 0 ? '#f2f2f2 ' : '#dbdbdb') : 'auto'}" >
                    <a href="document/{{x.id}}" title="{{x.id}}">{{x.id}} /{{x.sit}} / {{x.kategori}} </a>
                </td>
                <td ng-style="{'background-color': (bgcolor == 'l_namn') ? ($index % 2 === 0 ? '#eeeeee' : '#dbdbdb') : 'auto'}" >
                    <a href="document/{{x.id}}" title="{{x.l_namn}}">{{x.l_namn}}</a>
                </td>
                <td ng-style="{'background-color': (bgcolor == 'ldag') ? ($index % 2 === 0 ? '#eeeeee' : '#dbdbdb') : 'auto'}" >
                    <a href="document/{{x.id}}" title="{{x.ldag}}">{{x.ldag}}</a>
                </td>
                <td ng-style="{'background-color': (bgcolor == 'l_nr') ? ($index % 2 === 0 ? '#eeeeee' : '#dbdbdb') : 'auto'}">
                    <a href="document/{{x.id}}" title=" {{x.l_nr}}"> {{x.l_nr}}</a>
                </td >
                <td ng-style="{'background-color': (bgcolor == 'b_nr') ? ($index % 2 === 0 ? '#eeeeee' : '#dbdbdb') : 'auto'}" >
                    <a href="document/{{x.id}}" title="{{x.b_nr}}"> {{x.b_nr}} </a>
                </td>
                <td  ng-style="{'background-color': (bgcolor == 'f_nr') ? ($index % 2 === 0 ? '#eeeeee' : '#dbdbdb') : 'auto'}" >
                    <a href="document/{{x.id}}" title="{{x.f_nr}}"> {{x.f_nr}} 
                    <i ng-if="x.images > 0"  class="icon-picture pull-right"></i></a>
                </td>
            </tr>
        </tbody>

    </table>

</div>

Javascript

<script>

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http) {

    //Session data to remember site 
    if("<?= $this->session->userdata('sit'); ?>" != "empty"){
         $scope.sit = "<?= $this->session->userdata('sit'); ?>";
    }
    //Session data to remember kategori 
    if("<?= $this->session->userdata('kategori'); ?>" != "empty"){
         $scope.kategori = "<?= $this->session->userdata('kategori'); ?>";
    }
        //Session data to remember rows 
    if("<?= $this->session->userdata('rows'); ?>" != "empty"){
         $scope.rows = "<?= $this->session->userdata('rows'); ?>";
    }    

    /*
     *To watch single $scope attributes use:
     *$scope.$watch('search.id', function(val) {
     */
    $scope.$watchCollection('[search.id, search.ldag, search.l_nr, search.l_namn, search.b_nr, search.f_nr, kategori, sit, rows ]', function(val){ 
        if (val) {  
        // This is so it works with PHP.. 
        val[6] = angular.isUndefined(val[6]) ? "empty" : val[6];
        val[6] = val[6] == "" ? "empty" : val[6];   
        val[7] = angular.isUndefined(val[7]) ? "empty" :  val[7];
        val[7] = val[7] == "" ? "empty" : val[7];   

          $http({
             method: 'GET',
             url: '<?= base_url('lista/bazooka/') ?>',
             params: {
                 id: val[0], 
                 ldag: val[1], 
                 l_nr: val[2], 
                 l_namn: val[3],
                 b_nr: val[4],
                 f_nr: val[5], 
                 kategori: val[6],
                 sit: val[7],
                 rows: val[8]
                 },
             headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
            }).then(function(response) { 

            var lager = 
                {   
                '101': 'Jo',
                '104' : 'Bo',
                '105' : 'Jö',
                '102' : 'Gö',
                '201' :'Sk',
                '203' : 'Sä',
                '205' : 'Ö',
                '106': 'AH',
                '108' : 'He'
                };

            var data = [];
            if(response.data[0].id){
            angular.forEach(response.data,function(value,index){
                data.Push({ 
                    "id" : ""+value.id, 
                    "l_namn" : ""+ value.l_namn,
                    "b_nr" : ""+ value.b_nr, 
                    "f_nr" : ""+  value.f_nr,
                    "ldag" : ""+ value.ldag,
                    "l_nr" : ""+ value.l_nr,
                    "sit" : ""+ lager[value.sit],
                    "kategori" : ""+ value.kategori,
                    "images" : ""+ value.images,
                    });

                });
                }
                $scope.records = data;      
                $scope.sortBy = function(propertyName) {
                    $scope.bgcolor = propertyName;
                    console.log($scope.reverse);
                    $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false;
                    $scope.propertyName = propertyName;

                };
            });

        }
    });
});

</script>

manette

function bazooka(){

    $this->db->select('f.id, f.ldag, f.l_nr, f.l_namn, f.b_nr, f.f_nr, users.sit, users.kategori');
    $this->db->from('f');

    $this->db->join('users', 'users.id = f.user', 'left');


    if ($this->input->get('kategori') != 'empty') {
        $this->db->where('users.kategori', $this->input->get('kategori'));
    }
    if ($this->input->get('sit') != 'empty') {
        $this->db->where('users.sit', $this->input->get('sit'));
    }
    if($this->input->get('id') OR $this->input->get('id') != ""){
        $this->db->where("f.id" , $this->input->get('id'));
    }
    if($this->input->get('ldag') OR $this->input->get('ldag') != "" ){
        $this->db->like("ldag" , $this->input->get('ldag'));
    }
    if($this->input->get('l_nr') OR $this->input->get('leverantors_nr') != "" ){
        $this->db->like("l_nr" , $this->input->get('l_nr'));
    }
    if($this->input->get('b_nr') OR $this->input->get('b_nr') != "" ){
        $this->db->like("b_nr" , $this->input->get('b_nr'));
    }
    if($this->input->get('l_namn') OR $this->input->get('l_namn') != "" ){
        $this->db->like("l_namn" , $this->input->get('l_namn'));
    }
    if($this->input->get('f_nr') OR $this->input->get('f_nr') != "" ){
        $this->db->like("f_nr" , $this->input->get('f_nr'));
    }
    if($this->input->get('rows') OR $this->input->get('rows') != "" ){
         $rows = $this->input->get('rows');
    }else $rows = 10;
        $this->db->limit($rows);

        $this->db->order_by("id", "DESC");
        $query = $this->db->get();

    foreach ($query->result_array() as $key=>$val) {

        $row[$key] = array(
        "id"=>$val['id'], 
        "ldag"=>$val['ldag'], 
        "l_nr"=>$val['l_nr'],
        "l_namn"=>$val['l_namn'],   
        "b_nr"=>$val['b_nr'],
        "f_nr"=>$val['f_nr'],
        "sit"=>$val['sit'],
        "kategori"=>$val['kategori'],
        "images"=>$this->entries->images_in_file($val['id']));


     }
    $data["my_data"]  =  $row;
    $this->load->view('json/json_example_view', $data);


}
1
Stefan Avramovic

J'ai trouvé une solution utilisant uniquement du javascript.
J'ajoute ceci:
<th class="filtro"></th>
En second lieu .. Exemple:

<thead>
                        <tr style="text-align: center;">
                            <th><b>Name</b></th>
                            <th><b>Description</b></th>
                            <th><b>Value</b></th>
                        </tr>
                    </thead>
                    <thead>
                        <tr style="text-align: center;">
                            <th class="filtro"></th>
                            <th class="filtro"></th>
                            <th></th>
                        </tr>
                    </thead>

De cette façon, je ne filtre que par mes deux premières colonnes
cal est mon datatable.

C'est le javacript:

$("#cal thead th.filtro").each( function ( i) {
            var select = $('<select id="cmba'+i+'" class="combo"><option value="">All</option></select>')
            .appendTo( $(this).empty() )
            .on( 'change', function () {
             var cal = $('#cal').DataTable();
                cal.column( i )
                .search( $(this).val() )
                .draw();
                readRecord();
                $("#cal thead th.filtro").each( function (x) {
                    if (x > i){//empty all the selects at the right of the current
                        $("#cmba"+x).empty();
                        cal.column(x).search("").draw();//i clear all filters of the selects to the right of the current one.
                    }
                });
                $("#cal thead th.filtro").each( function (x) {
                    if (x > i){//i add all option with empty value so no filter
                        $("#cmba"+x).append("<option value=''>All</option>");
                        cal.column(x, { search:'applied' } ).data().unique().sort().each(function(value, index) {//add filtered values to the select
                            $("#cmba"+x).append( '<option value="'+value+'">'+value+'</option>' )
                        });
                    }
                });
            } );

        var cal = $('#cal').DataTable();

        cal.column( i ).data().unique().sort().each( function ( d, j ) {
            select.append( '<option value="'+d+'">'+d+'</option>' )
            } );
        } );

Je ne vous montre que la partie filtre, vous devez initialiser vos données comme toujours

0
user3486626