如何为Codeigniter表创建可排序表THEAD链接

时间:2014-10-19 06:51:08

标签: php codeigniter

我似乎无法使我的链接能够整理我的数据。我已经尝试了许多不同的方法,现在不知道该怎么做。

例如如果用户点击用户ID thead链接,它将按用户ID asc或desc对用户进行排序,依此类推。用户名,日期添加链接相同。我已尝试使用源代码脚本,但因为它是由控制器控制不起作用。

使用我的代码

我想要实现的是用户列表表头区域有 5 thead ,我想这样做,所以当我点击其中任何一个时,它会根据该列表对列表进行排序字段由asc和or或dsc。尝试使其与当前分页一起使用分页正常

某些图书馆是自动加载的。

Codeigniter用户控制器

protected function getList() {
    $data['heading_title'] = $this->lang->line('heading_title');

    $data['breadcrumbs'] = array();

    $data['breadcrumbs'][] = array(
        'text' => '<i class="fa fa-home"></i>' .' '.  $this->lang->line('text_home'),
        'href' => site_url('admin/dashboard')
    );

    $data['breadcrumbs'][] = array(
        'text'      => $this->lang->line('heading_title'),
        'href'      => site_url('admin/users')
    );

    $data['text_enabled'] = $this->lang->line('text_enabled');
    $data['text_disabled'] = $this->lang->line('text_disabled');

    $data['column_user_id'] = $this->lang->line('column_user_id');
    $data['column_name'] = $this->lang->line('column_name');
    $data['column_status'] = $this->lang->line('column_status');
    $data['column_last_updated'] = $this->lang->line('column_last_updated');
    $data['column_date_added'] = $this->lang->line('column_date_added');
    $data['column_action'] = $this->lang->line('column_action');

    $data['delete'] = site_url('admin/users/delete');
    $data['insert'] = site_url('admin/users/add');

    $data['text_confirm'] = $this->lang->line('text_confirm');

    $data['button_insert'] = $this->lang->line('button_insert');
    $data['button_edit'] = $this->lang->line('button_edit');
    $data['button_delete'] = $this->lang->line('button_delete');

    $this->load->library('setting'); 

    $this->load->library('pagination'); 

    $config = array(); 
    $config["base_url"] = base_url('admin/users'); 
    $config['total_rows'] = $this->db->get('user')->num_rows(); 
    $config["per_page"] =  $this->setting->get('config_limit_admin');
    $config["uri_segment"] = 3;  

    $config['full_tag_open'] = "<ul class='pagination'>";
    $config['full_tag_close'] ="</ul>";
    $config['num_tag_open'] = '<li>';
    $config['num_tag_close'] = '</li>';
    $config['cur_tag_open'] = "<li class='disabled'><li class='active'><a href='#'>";
    $config['cur_tag_close'] = "<span class='sr-only'></span></a></li>";
    $config['next_tag_open'] = "<li>";
    $config['next_tagl_close'] = "</li>";
    $config['prev_tag_open'] = "<li>";
    $config['prev_tagl_close'] = "</li>";
    $config['first_tag_open'] = "<li>";
    $config['first_tagl_close'] = "</li>";
    $config['last_tag_open'] = "<li>";
    $config['last_tagl_close'] = "</li>";

    $this->pagination->initialize($config);

    $data['users'] = $this->db->get('user', $config["per_page"], $this->uri->segment(3));

    if (isset($this->request->post['selected'])) {
        $data['selected'] = (array)$this->request->post['selected'];
    } else {
        $data['selected'] = array();
    }

    return $this->load->view('user/users_list', $data);
}

查看

<form action="<?php echo $delete; ?>" method="post" enctype="multipart/form-data" id="form-user">

<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<td style="width: 1px;" class="text-center"><input type="checkbox" onclick="$('input[name*=\'selected\']').prop('checked', this.checked);" /></td>
<td class="text-center" style="color: #1E91CF; font-size: 14px; font-weight: bold;"><?php echo $column_user_id; ?></td>
<td class="text-center" style="color: #1E91CF; font-size: 14px; font-weight: bold;"><?php echo $column_name; ?></td>
<td class="text-center" style="color: #1E91CF; font-size: 14px; font-weight: bold;"><?php echo $column_status; ?></td>
<td class="text-center" style="color: #1E91CF; font-size: 14px; font-weight: bold;"><?php echo $column_last_updated; ?></td>
<td class="text-center" style="color: #1E91CF; font-size: 14px; font-weight: bold;"><?php echo $column_date_added; ?></td>
<td class="text-center" style="color: #1E91CF; font-size: 14px; font-weight: bold;"><?php echo $column_action; ?></td>
</tr>
</thead>
<tbody>
<?php foreach ($users->result() as $user) { ?>  
<td class="text-center"><?php if (in_array($user->user_id, $selected)) { ?>
<input type="checkbox" name="selected[]" value="<?php echo $user->user_id; ?>" checked="checked" />
<?php } else { ?>
<input type="checkbox" name="selected[]" value="<?php echo $user->user_id ?>" />
<?php } ?>
</td>
<td class="text-center"><?php echo $user->user_id; ?></td>
<td class="text-center"><?php echo $user->username; ?></td>
<td class="text-center"><?php if ($user->status == TRUE) { echo $text_enabled; } else { echo $text_disabled ; } ?></td>
<td class="text-center"><?php echo $user->last_updated; ?></td>
<td class="text-center"><?php echo $user->date_added; ?></td>
<td class="text-center"><?php echo anchor("admin/users/edit/" . $user->user_id, '<div class="btn btn-primary text-right" role="button"><i class="fa fa-pencil"></i>
 Edit</div>');?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<div class="row">
<div class="col-sm-6 text-left">
<?php echo $this->pagination->create_links();?>
</div>
</div>
</form>

模型获取用户

public function getUsers() {
  $this->db->select('*');
  $this->db->from($this->db->dbprefix . 'user');
  $query = $this->db->get();

  if ($query->num_rows() > 0) {
      return $query->result();
      return true;
  } else {
      return false;
  }
}

4 个答案:

答案 0 :(得分:2)

好的,我们订购并分页!

首先,分页工作如何

当你分页时,你说:

  

“有(比方说)25个元素。我想显示第2页,所以,如果我是   (让我们说)每页显示5个元素,我必须先订购它们   从元素6到10显示“

这样,如果你想要显示第3页,你可以通过(比方说)id来命令,然后从元素11到15中显示。总结一下,你必须知道:

  • 您要展示多少元素
  • 您要列出的页面(稍后您将在偏移中进行转换,继续阅读)
  • 您用来列出的订单。

示例:我将使用下表,将其插入DDBB并运行查询以查看我的意思:

CREATE TABLE IF NOT EXISTS `elements` (
  `id` int(11) DEFAULT NULL,
  `letter` char(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `elements` (`id`, `letter`) VALUES
    (10, 'a'),(9, 'b'),(8, 'c'),(7, 'd'),   (6, 'e'),   (5, 'f'),   (4, 'g'),   (3, 'h'),   (2, 'i'),   (1, 'j');

现在,让我们分页!

想象一下,你想要显示第3页,每页2个元素,按ascendent id排序。你必须显示id为5和6的元素,因为第1页有id 1和2,而page 2有id 3和4.所以,我们的偏移量将是:

$offset = ($elements_per_page) * ($page – 1);
// In this example: $offset = 2 * (3 – 1 ) = 4.

并且知道,要按ID排序并显示您必须运行的页面中的元素:

SELECT *
FROM elements
ORDER BY id ASC
LIMIT 4, 2

您将按此顺序获得:(5,'f') and (6, 'e')

如果你想通过信件订购,你就可以运行

SELECT *
FROM elements
ORDER BY letter ASC
LIMIT 4, 2

按此顺序给你:(6, 'e') and (5, 'f')

说明:limit子句允许您指定偏移量以及要显示的元素数。

  

来自http://dev.mysql.com/doc/refman/5.0/en/select.html,“有两个   参数,第一个参数指定第一行的偏移量   return,第二个指定要返回的最大行数。   初始行的偏移量为0(不是1)“

那么,现在,您知道如何构建查询,因此,让我们使用CI构建它。

使用CI

构建分页

您的模型需要知道您要显示的内容:订单,您要显示的页面以及元素的数量,因此,它必须是:

MODEL users_model.php

public function getUsers( $offset, $elements_per_page, $order_field, $order_direction ) 
{    
    $this->db->select('*');
    $this->db->from($this->db->dbprefix . 'user');

    $this->db->order_by( $order_field, $order_direction )

    // Be careful, the order is differente here than in real MySQL query LIMIT: LIMIT $OFFSET, $ELEMENTS_PER_PAGE
    $this->db->limit($elements_per_page, $offset );  


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

    if ($query->num_rows() > 0) {
        return $query->result();
    } else {
        // This just to keep allways the same kind of data returned, ;D
        return array();
    }
}

// We'll use this to know how many users there are.
public function countUsers() 
{
    return $this->db->count_all_results( $this->db->dbprefix . 'user' );
}

使用上面的代码,您有一个模型类库,可以开始从数据库向控制器发送值,但您还必须使用控制器。它必须处理页面以确保你在范围内,以确保你想要订购的值是真正存在的字段......好吧,控制器工作,你知道吗?

CONTROLLER:users.php

public function user_results()
{
    // To control the page you're sending is ok, you have to count first the number of elements
    $page   = $this->input->get( $page );

    $elements_per_page  = 3; // You could also send it in your request

    $this->load->model('users_model');  
    $total      = $this->users_model->countUsers();
    $get_offset =  ( $page – 1 ) * $elements_per_page;
    // And you have to control the offset:
    $min_offset = 0; 
    $max_offset = floor( $total / $elements_per_page ); 
    $offset = ( ( get_offset > $max_offset ) ? $max_offset : ( ( $get_offset < $min_offset ) ? $min_offset : $get_offset ) ); 

    // Then, you have to control the fields to order. I'd recommend you white list filter:
    $get_order_field    = $this->input->get('order_field');
    $order_fields   = array( 'id', 'letter');
    $order_field    = in_array( $get_order_field, $order_fields ) ? $get_order_field : 'id';

    $get_order_direction    = $this->input->get('order_direction');
    $order_directions   = array( 'asc', 'desc');
    $order_field        = in_array( $get_order_direction, $order_directions ) ? $get_order_direction : 'asc';

    // And now, you can show a list of the elements you want to show from the page:       
    $data['users'] = $this->users_model->getUsers( $offset, $elements_per_page, $order_field, $order_direction );

    $this->load->view('table_users_view', $data );
}

要完成后端,我会将所有表值放在视图中:

查看:table_users_view.php

<table>
  <tr>
    <th>Id</th>
    <th>Name</th>
  </tr>
  <?php if ( !empty( $users ) : ?>
      <?php foreach ( $users as $user ) : ?> 
  <tr>
    <td><?=$user->id?></td>
    <td><?=$user->name?></td>   
  </tr>
      <?php endforeach; ?> 
  <?php endif; ?>
</table>

嗯,这是开始回答你的问题。现在您可以进行分页,但需要自动添加分页链接,可能看起来像BASE_URL/users/?page=1&order_field=id&order_direction=asc。而且,你必须在JS中编写一个通过你的html中的锚点触发的AJAX调用。如果您了解上述所有代码,则后续步骤为:

  • 将AJAX调用及其锚点写入表格的标题中。
  • 根据所选页面的值和这些值重新加载内容:为此,您需要一个控制器方法,它接受AJAX参数并返回tbody,而不是整个表。

或多或少:

$(document).ready(function({
    $('.order').click( function(){
        var field = $(this).data('field');
        var dir   = $(this).data('dir');       
        var page  = $('.pagination active').data('page');
        $.ajax({
            type: 'get',
            dataType: 'json'
            url:  BASE_URL + 'users/ajax/?page=' + page + '&order_direction=' + dir + '&order_field=' + field,
            success: function(data) {
                $('table.users tbody').html(data.tbody);
            }
        });
    })   
});

您的观点应更改为:

<div class="pagination">
    <span class="active" data="1">1</span>
    <span data="2">2</span>
    <span data="3">3</span>
</div>

<table>
  <tr>
    <th>
      <span class="order" data-field="id" data-dir="asc">Up</span>
      <span class="order" data-field="id" data-dir="desc">Down</span>
      ID
    </th>
    <th>
      <span class="order" data-field="name" data-dir="asc">Up</span>
      <span class="order" data-field="name" data-dir="desc">Down</span>
      Name
    </th>
  </tr>
  <tbody>
  <?php if ( !empty( $users ) : ?>
      <?php foreach ( $users as $user ) : ?> 
  <tr>
    <td><?=$user->id?></td>
    <td><?=$user->name?></td>   
  </tr>
      <?php endforeach; ?> 
  <?php endif; ?>
  </tbody>
</table>

你需要一个“局部视图”来加载只有tbody的数据:

查看:table_users_partial_view.php

      <?php if ( !empty( $users ) : ?>
          <?php foreach ( $users as $user ) : ?> 
      <tr>
        <td><?=$user->id?></td>
        <td><?=$user->name?></td>   
      </tr>
          <?php endforeach; ?> 
      <?php endif; ?>

如果要发送AJAX请求,则必须修改控制器以显示部分视图:

CONTROLLER:已修改为仅返回部分数据:

public function user_results()
{
    // To control the page you're sending is ok, you have to count first the number of elements
    $page  = $this->input->get( $page );

    $elements_per_page = 3; // You could also send it in your request

    $get_offset    =  ( $page – 1 ) * $elements_per_page;
    // And you have to control the offset:
    $min_offset    = 0; 
    $max_offset    = floor( $total / $elements_per_page ); 
    $offset    = ( ( get_offset > $max_offset ) ? $max_offset : ( ( $get_offset < $min_offset ) ? $min_offset : $get_offset ) ); 

    // Then, you have to control the fields to order. I'd recommend you white list filter:
    $get_order_field   = $this->input->get('order_field');
    $order_fields  = array( 'id', 'letter');
    $order_field   = in_array( $get_order_field, $order_fields ) ? $get_order_field : 'id';

    $get_order_direction   = $this->input->get('order_direction');
    $order_directions  = array( 'asc', 'desc');
    $order_field       = in_array( $get_order_direction, $order_directions ) ? $get_order_direction : 'asc';

    // And now, you can show a list of the elements you want to show from the page:
    $this->load->model('users_model');

    $data['users'] = $this->users_model->getUsers( $offset, $elements_per_page, $order_field, $order_direction );
    if ( !$this->input->is_ajax_request() ) {
        $this->load->view('table_users_view', $data );
    } else {
        $return = array( 
            'tbody' => $this->load->view('table_users_partial_view
        );  
        // This is to give back the value as a JSON the JS will understand. In fact, in the AJAX call we indicated it.
        echo json_encode( $return );
    }
}

免责声明:从一开始只有SQL是经过测试的代码,如果只是复制/粘贴,上述所有内容都可以正常工作。代码是为了澄清并为您提供一条遵循的路径:您必须首先理解并在之后编写代码。以上所有内容都是希望它有用,如果您有任何疑问,请写评论。玩得开心!

答案 1 :(得分:0)

看看这个例子:

查看:

<thead>
  <tr>
    <td class="text-center"><input type="checkbox" onclick="$('input[name*=\'selected\']').prop('checked', this.checked);" /></td>
    <td class="text-center asc" data-orderby="column_user_id"><?php echo $column_user_id; ?></td>
    <td class="text-center asc" data-orderby="column_name"><?php echo $column_name; ?></td>
    <td class="text-center asc" data-orderby="column_status"><?php echo $column_status; ?></td>
    <td class="text-center asc" data-orderby="column_last_updated"><?php echo $column_last_updated; ?></td>
    <td class="text-center asc" data-orderby="column_date_added"><?php echo $column_date_added; ?></td>
    <td class="text-center asc" data-orderby="column_action"><?php echo $column_action; ?></td>

假设您有显示数据的页面:

controller/model/page/1

让我们找到Javascript的网址:

$url = $this->input->server('REQUEST_URI');
if( preg_match('/\?/', $url) ) 
    $url = strstr($url, "?", true);

更改URL的JQuery代码:

$('.table thead td').click(function(e){
    var $this = $(this), 
        order_by = $this.data('orderby'), 
        myURL = '<?php echo $url ?>', 
        order='';

    // Handle Asc and Desc
    if( $this.hasClass('asc') ) {
        $this.removeClass('asc');
        $this.addClass('desc');
        order = 'desc';
    }
    else {
       $this.removeClass('desc');
        $this.addClass('asc');
        order = 'asc';
    }


    // change url on click
    document.location.href = myURL + '?orderby='+order_by+'&order='+order;
});

现在您将获得以下网址:

controller/model/page/1?orderby={data_element}&order={asc|desc}

现在处理控制器中的QUERY STRING并将其传递给Model。

控制器:

// Return Query String else return empty
$QS = $this->input->server('QUERY_STRING');
$Page = $this->uri->segment(3);

$Start = ! empty($Page) ? $Page : 0;

// Pass this string to your model
$data['users'] = $this->mymodel->getUsers($Start, $config["per_page"], $QS);

模型

public function getUsers($Start=0, $Limit=10, $QS=null) {


  $this->db->select('*');
  $this->db->from('users');

  // Handle Order By
  if( ! is_null($QS) ) {
      parse_str($QS);

      if( isset($order_by) && ! empty($order_by) && isset($order) && ! empty($order) ) { 
          $this->db->order_by($order_by, $order);
      }

  }

  $this->db->limit($Start, $Limit);
  $query = $this->db->get();

  return $query->num_rows() > 0 ? $query->result_array() : false;

}

如需有效记录帮助,请关注this link。希望这有助于您理解和实施。

答案 2 :(得分:0)

首先将您所使用的页面放在要传递给控制器​​的参数中:

protected function getList($offset = 0, $order_by = 'id', $order_direction = 'asc') {

,如https://ellislab.com/codeigniter/user-guide/general/controllers.html 请记住将默认值设置为这些值,以便仍然可以访问链接而无需提供它们。

第二件事是传递这些数据进行查看,将其添加到数据变量中。

接下来将$order_by$order_direction传递给模型作为参数public function getUsers($order_by, $order_direction) {不需要设置默认值,因为它们将始终由控制器设置。

之后在模型中你应该做出一些用户可以排序的东西,这只是一个很好的做法。您将使用活动记录与控制器内的以下行$this->db->order_by($order_by, $order_direction);进行排序,也不要忘记将$order_direction限制为asc或desc,这样用户就无法破坏应用程序(如果无法识别,则将默认值设置为默认值)。

在视图中做好准备后再做

site_url('admin/users/getList/'.$offset.'/user_id/'.(($order_direction==='asc')?'desc':'asc'));

将user_id更改为您拥有的任何其他列并使用它创建链接,您可以创建用于创建这些链接的良好功能。

site_url()来自url_helper(https://ellislab.com/codeigniter/user-guide/helpers/url_helper.html

另外,不要忘记使用从模型中的url传递的偏移量,并在需要时修改分页模块。

概述了如何在codeigniter中实现这一点,我正在为我的应用程序使用类似的东西,所以我知道它有效。你需要编写自己的代码,但是你知道从哪里开始。

答案 3 :(得分:0)

到目前为止,我找到了最好的程序,它可以完成我所追求的所有程序https://datatables.net/examples/styling/bootstrap.html

我不得不使用它,因为codeigniter分页不适用于排序方法。