search result from sql error with codeigniter's pagination index - codeigniter

I have a table with the pagination. First, i select all data from my DB, and the pagination works perfectly.
Then, i started to filter the data (search certain data, example : using WHERE in SQL). The pagination's 1st index is working perfectly (showing only certain data) but when i click the next index (2nd, 3rd) the data is going back to default (the filter (WHERE, LIKE) is not working).
This is my model that used for the pagination (I think i made a mistake here) :
public function get_umat() {
$this->db->select('*')->from('msumat')->limit(10, $this->uri->segment(3));
$this->db->join('mskelas', 'msumat.kelas_id = mskelas.kelas_id');
$search = $this->input->post('ddl_search');
$kelas = $this->input->post('ddl_kelas');
$kelas1 = $this->input->post('ddl_kelas1');
$kelas2 = $this->input->post('ddl_kelas2');
$nama = $this->input->post('txt_nama');
$alamat = $this->input->post('txt_alamat');
$bulan = $this->input->post('ddl_bulan');
$bulan1 = $this->input->post('ddl_bulan1');
$bulan2 = $this->input->post('ddl_bulan2');
if($this->input->post('btn_search'))
{
if($search === 'nama')
$this->db->like('nama', $nama);
else if($search === 'kelas')
$this->db->where('mskelas.kelas_id', $kelas);
else if($search === 'range_kelas')
$this->db->where("mskelas.kelas_id BETWEEN $kelas1 AND $kelas2");
else if($search === 'alamat')
$this->db->like('alamat', $alamat);
else if($search === 'bulan_lahir')
$this->db->where("MONTH(tanggal_lahir) = $bulan");
else if($search === 'range_tanggal_lahir')
$this->db->where("MONTH(tanggal_lahir) BETWEEN $bulan1 AND $bulan2");
}
return $this->db->get()->result();
}
public function count_umat(){
return $this->db->count_all('msumat');
}
Then this is my pagination in controller (I think i need to modify the $config['total_rows']):
$config['base_url'] = site_url('/backend_umat/index');
$config['total_rows'] = $this->umat_m->count_umat();
$config['per_page'] = 10;
$config['uri_segment'] = 3;
$config['full_tag_open'] = '<div id="pagination">';
$config['full_tag_close'] = '</div>';
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
I think the problems are :
I need to COUNT the search results (for each search) for $config['total_rows']
Somehow, i need to modify the model (get_umat()) to get things working
Any help is appreciated. Thanks :D

well in CI if you want to apply search with multiple filters it works for the first page and ci always look for url segments, for 2nd or 3rd page you need to send your all search parameters which you send for the first page through form, means you url should contain url segments then you can filter your search record because you are not submitting form for 2nd and 3rd page. i will suggest you to have look on this tutorial it has nice way to use search records with multiple filters and work perfect with pagination
CI Search on Tutorial Nettuts

Related

Load view by current URL last segment in Codeigniter

I'm trying to load view content page when url last segment matched. When click a link which get link in url like http://192.168.20.2/vtp/attendance/rawAttendance then load the rawAttendance view and when I click other link which last segment is getAttendance then it's also load the same same view not getAttendance. How do get this done?
$last = $this->uri->total_segments();
$lastSegment = $this->uri->segment($last);
if ($this->input->post("fromAjax")) {
if($lastSegment == "rawAttendance"){
$this->load->view('attendance/rawAttendance', $data);
}else if($lastSegment == "getAttendance"){
$this->load->view('attendance/getAttendance', $data);
}else {
}
}
CI has its inbuilt helper for knowing controller name and method name.
$classname = $this->router->fetch_class();
$methodname = $this->router->fetch_method();
if ($this->input->post("fromAjax")) {
if($classname == "attendance" && $methodname == "rawAttendance"){
$this->load->view('attendance/rawAttendance', $data);
}else if($classname == "attendance" && $methodname == "getAttendance"){
$this->load->view('attendance/getAttendance', $data);
} else {
}
}
CodeIgniter is a basic MVC framework - so everything starts with the controller. From the code you've written, I assume you already have your routes, etc configured to point at the method you've placed in your question.
You can simplify things quite a bit from the way you have them. Using the CI helper for controller/method is a bit helpful, but I think you're looking for something a little more elastic in your approach to dynamically load a view based on your last URI segment.
Try something like this:
// Get your last URI segment
$last = $this->uri->total_segments();
$lastSegment = $this->uri->segment($last);
/**
* Do whatever logic you need to do to calculate your data
*/
// ...
/**
* Load the view
*/
$this->load->view( 'attendance/' . $lastSegment, $data );
This could probably be better architected using the CI routes capability though. For instance, if you have several view folders and view files within, it would be best practice to organize those and better cement your URI structures so that each URI segment plays a specific role:
CI routes.php
$route["vtp/(:any)/(:any)"] = "path_to_method";
Method
$dir = $this->uri->segment(2);
$view = $this->uri->segment(3);
$this->load->view( $dir . "/" . $view, $data );

How to pass an array to a view as Contextual Filter

I am new in Drupal. I am currently developing an e-commerce site using drupal 7. I want to know how can i pass an array of nid to views_embed_view('view_name','display_name',contextual filter) contextual filters. Here is my sample code-
foreach($result as $record)
{
$querystring .= "+";
$querystring .= $record->nid;
}
$querystring = ltrim($querystring, '+');
views_embed_view('tours_listings', 'page_2',$querystring);
You can add accomplish this by:
Checking the
Allow multiple values on the view contextual settings page.
If selected, users can enter multiple values in the form of 1+2+3. Due
to the number of JOINs it would require, AND will be treated as OR
with this filter.
Then instead of code above:
$recordIds = array();
foreach($result as $record)
{
$recordIds[] = $record->nid;
}
$querystring = implode('+', $recordIds);
//Do not forget to print this out.
print views_embed_view('tours_listings', 'page_2', $querystring);

Codeigniter load different site content foreach possible filter selection

I have 2 input fields. In the first filter user can select category, subcategory and in the second filter user can choose product.
Upon submitting the form, the user gets redirected to the site based on his selection in the input fields.
$category = $this->input->post('category', true);
$product = $this->input->post('product', true);
if(isset($category) && $sub_category == ''){
redirect(base_url().'/category/'.$category);
}elseif(isset($category) && isset($product)){
redirect(base_url().'/category/'.$category.'/product/'.$product);
}else{
$this->session->set_flashdata('error', 'You must select a category');
redirect($_SERVER['HTTP_REFERER']);
}
Creating the urls and redirecting to them based on the user's input selection works fine. What I cannot get my head around is how to get a different view-content for each site. Each possible combination of category and product has its own content. How can I load the individual content for each possible url?
Thanks for any hint!
try this to get url
$category = $this->input->post('category', true);
$product = $this->input->post('product', true);
$url =array();
if($category){
$url[] = 'category/'.$category;
}
if($product){
$url[] ='product/'.$product;
}
$newurl = implode('/',$url);
redirect($newurl);

codeigniter count_all_results

I'm working with the latest codeIgniter released, and i'm also working with jquery datatables from datatables.net
I've written this function: https://gist.github.com/4478424 which, as is works fine. Except when I filter by using the text box typing something in. The filter itself happens, but my count is completely off.
I tried to add in $res = $this->db->count_all_results() before my get, and it stops the get from working at all. What I need to accomplish, if ($data['sSearch'] != '') then to utilize the entire query without the limit to see how many total rows with the search filter exists.
If you need to see any other code other than whats in my gist, just ask and I will go ahead and post it.
$this->db->count_all_results() replaces $this->db->get() in a database call.
I.E. you can call either count_all_results() or get(), but not both.
You need to do two seperate active record calls. One to assign the results #, and one to get the actual results.
Something like this for the count:
$this->db->select('id');
$this->db->from('table');
$this->db->where($your_conditions);
$num_results = $this->db->count_all_results();
And for the actual query (which you should already have):
$this->db->select($your_columns);
$this->db->from('table');
$this->db->where($your_conditions);
$this->db->limit($limit);
$query = $this->db->get();
Have you read up on https://www.codeigniter.com/userguide2/database/active_record.html#caching ?
I see you are trying to do some pagination where you need the "real" total results and at the same time limiting.
This is my practice in most of my codes I do in CI.
$this->db->start_cache();
// All your conditions without limit
$this->db->from();
$this->db->where(); // and etc...
$this->db->stop_cache();
$total_rows = $this->db->count_all_results(); // This will get the real total rows
// Limit the rows now so to return per page result
$this->db->limit($per_page, $offset);
$result = $this->db->get();
return array(
'total_rows' => $total_rows,
'result' => $result,
); // Return this back to the controller.
I typed the codes above without testing but it should work something like this. I do this in all of my projects.
You dont actually have to have the from either, you can include the table name in the count_all_results like so.
$this->db->count_all_results('table_name');
Count first with no_reset_flag.
$this->db->count_all_results('', FALSE);
$rows = $this->db->get()->result_array();
system/database/DB_query_builder.php
public function count_all_results($table = '', $reset = TRUE) { ... }
The
$this->db->count_all_results();
actually replaces the:
$this->db->get();
So you can't actually have both.
If you want to do have both get and to calculate the num rows at the same query you can easily do this:
$this->db->from(....);
$this->db->where(....);
$db_results = $this->get();
$results = $db_results->result();
$num_rows = $db_results->num_rows();
Try this
/**
* #param $column_name : Use In Choosing Column name
* #param $where : Use In Condition Statement
* #param $table_name : Name of Database Table
* Description : Count all results
*/
function count_all_results($column_name = array(),$where=array(), $table_name = array())
{
$this->db->select($column_name);
// If Where is not NULL
if(!empty($where) && count($where) > 0 )
{
$this->db->where($where);
}
// Return Count Column
return $this->db->count_all_results($table_name[0]);//table_name array sub 0
}
Then Simple Call the Method
Like this
$this->my_model->count_all_results(['column_name'],['where'],['table name']);
If your queries contain a group by, using count_all_results fails. I wrote a simple method to work around this. The key to preventing writing your queries twice is to put them all inside a private method that can be called twice. Here is some sample code:
class Report extends CI_Model {
...
public function get($page=0){
$this->_complex_query();
$this->db->limit($this->results_per_page, $page*$this->results_per_page);
$sales = $this->db->get()->result(); //no table needed in get()
$this->_complex_query();
$num_results = $this->_count_results();
$num_pages = ceil($num_results/$this->results_per_page);
//return data to your controller
}
private function _complex_query(){
$this->db->where('a', $value);
$this->db->join('(subquery) as s', 's.id = table.s_id');
$this->db->group_by('table.column_a');
$this->db->from('table'); //crucial - we specify all tables here
}
private function _count_results(){
$query = $this->db->get_compiled_select();
$count_query = "SELECT count(*) as num_rows FROM (".$query.") count_wrap";
$r = $this->db->query($count_query)->row();
return $r->num_rows;
}
}

Codeigniter Pagination bug

I think that there is a bug in the codeigniter pagination library. For some reason when I generate the pagination links, it generates the links as:
1 2 3 4
Where page 3 is linking to 4.
Here is the config variables code in case anyone is curious:
$config['base_url'] = base_url() . "index.php/test/$query_string";
$config['total_rows'] = $search_results->num_rows();
$config['per_page'] = $items_per_page;
And here is a sample of my query string:
?q=sample_query_string&per_page=1
Is there a way to fix this?
I wouldn't bother with the query string, use a variable passed straight from the url/controller. Also, I think your base url is wrong. It should be (assuming your are on the default index function page)
$config['base_url'] = site_url("test/index");
You don't need to put the vars at the end of the base url. If you have query strings enabled (i don't think you do though), this would be the same, CI should handle all the renaming, just extracting the variables will be different.
So controller should be
class Test extends Controller {
function index($offset = 0)
{
$this->load->library('pagination');
$config['base_url'] = site_url("test/index");
$config['total_rows'] = $search_results->num_rows();
$config['per_page'] = 20;
$config['uri_segment'] = 3;
$this->pagination->initialize($config);
// DO OTHER STUFF
}
}
You can set the limit in your config. Do you need to do it from the URL?

Resources