I'm working with a project that uses jqGrid in the most recent version.
The thing is that this project is PHP(5.6) and uses JSON to "translate/talk" to jqGrid framework, and colModel parameters are all inside PHP arrays. It works flawlessly but i'm unable to trigger dataInit of colModel "criacao" using the actual project's code.
public function laudos($section)
{
$table = 'laudos';
$fields = array('id','laudo','nome_fantasia','cliente','cadastro_id','email','senha','exame','descricao','criacao','exclusao','arquivo');
$tabela = array(
'colNames' => array('ID','Laudo','Clínica','Nome','Cadastro','Email','Senha','Exame','Descrição','Criação','Exclusão','Arquivo'),
'colModel' => array(
array('name'=>'id','hidden'=>true,'search'=>true,'key'=>true),
array('name'=>'laudo','index'=>'laudo','width'=>70,'align'=>'center','search'=>true,'editable'=>true,'editrules'=>array('required'=>true),'sorttype'=>'integer','searchoptions'=>array('sopt'=>'[eq,cn]', 'clearSearch'=>false)),
array('name'=>'nome_fantasia','search'=>true,'width'=>170,'align'=>'center','editable'=>false,'sorttype'=>'text','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false),'editrules'=>array('required'=>true)),
array('name'=>'cliente','search'=>true,'width'=>170,'align'=>'center','editable'=>false,'sorttype'=>'text','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false),'editrules'=>array('required'=>true),),
array('name'=>'cadastro_id','search'=>true,'hidden'=>true,
'editable'=>true,'edittype'=>'text','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false),'editrules'=>array('edithidden'=>true,'required'=>true),
'editoptions'=>array('dataInit'=>'[]')),
array('name'=>'email','search'=>true,'hidden'=>true,'editable'=>true,'sorttype'=>'email','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false),'editrules'=>array('edithidden'=>true)),
array('name'=>'senha','search'=>true,'hidden'=>true,'editable'=>true,'editrules'=>array('edithidden'=>true)),
array('name'=>'exame','search'=>true,'width'=>50,'align'=>'center','editable'=>true,'sorttype'=>'text','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false),'formatter'=>'select','edittype'=>'select',
'editoptions'=>array('value'=>array('Biópsia'=>'Biópsia','Necrópsia'=>'Necrópsia','Citologia'=>'Citologia'))
),
array('name'=>'descricao','search'=>true,'width'=>200,'align'=>'center','editable'=>true,'sorttype'=>'text','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false)),
array('name'=>'criacao','search'=>true,'width'=>70,'formatter'=>'date','fixed'=>true,'resizable'=>false,'align'=>'center','sorttype'=>'date','searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false), 'editoptions'=>array('dataInit'=>'function (elem) { $(elem).datepicker();')),
array('name'=>'exclusao','search'=>true,'width'=>70,'formatter'=>'date','sorttype'=>'date','fixed'=>true,'resizable'=>false,'editable'=>true,'searchoptions'=>array('sopt'=>'[eq,cn]','clearSearch'=>false),'align'=>'center'),
array('name'=>'arquivo','search'=>false,'width'=>60,'formatter'=>'arquivo','classes'=>'tabela_laudo_arquivo','editable'=>true,'searchoptions'=>array('sopt'=>false,'clearSearch'=>false))
),
'sortname' => 'id',
'caption' => 'Registros de Laudos Cadastrados',
);
This is the PHP function that returns a responce to jqgrid framework:
private function tabelas($table, $fields, $where = '1 = 1')
{
$page = isset($_REQUEST['page']) ? $_REQUEST['page'] : 1; // get the requested page
$limit = isset($_REQUEST['rows']) ? $_REQUEST['rows'] : 99999; // get how many rows we want to have into the grid
$sidx = isset($_REQUEST['sidx']) ? $_REQUEST['sidx'] : 'id'; // get index row - i.e. user click to sort
$sord = isset($_REQUEST['sord']) ? $_REQUEST['sord'] : 'desc'; // get the direction
if(!$sidx) $sidx =1;
$count = $this->db->get_var("SELECT COUNT(*) AS count FROM $table WHERE $where");
if($count > 0)
{
$total_pages = ceil($count/$limit);
}
else
{
$total_pages = 0;
}
if ($page > $total_pages) $page = $total_pages;
$start = $limit * $page - $limit; // do not put $limit*($page - 1)
$sql = "SELECT " . implode(',',$fields) . " FROM $table WHERE $where ORDER BY $sidx $sord LIMIT $start, $limit";
$result = $this->db->get_results($sql);
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i = 0;
foreach($result as $row)
{
$responce->rows[$i]['id'] = $row->id;
foreach($fields as $field)
{
$responce->rows[$i]['cell'][] = $row->$field;
}
$i++;
}
return $responce;
}
Using $.extend in my jQGrid script did the job.
Question already answered here.
So basically I am trying to get the sum of AveragePrice of every single page on this api. Right now it only gets first page the things i've tried have only gotten it to go on an endless loop crashing wamp. Heres my code for 1 page of working.
I am just really unsure how I can get it to loop through pages and get sum of every page.
<?php
function getRap($userId){
$url = sprintf("https://www.roblox.com/Trade/InventoryHandler.ashx?userId=" . $userId . "&filter=0&page=1&itemsPerPage=14");
$results = file_get_contents($url);
$json = json_decode($results, true);
$data = $json['data']['InventoryItems'];
$rap = 0;
foreach($data as $var) {
$rap += $var['AveragePrice'];
}
echo $rap;
}
$userId = 1;
getRap($userId);
?>
You may get better answers by looking into the API you are working with regarding how many pages to look for. You want to loop until you hit the max pages. There should be an value in the result of your request that tells you that you've asked for a page that doesn't exist (ie. no more results). If you can get a total number of results to search for then you could do a for loop with that as your limit.
//Change the function to accept the page number as a variable
function getRap($userId, $i){
$url = sprintf("https://www.roblox.com/Trade/InventoryHandler.ashx?userId=" . $userId . "&filter=0&page=" . $i . "&itemsPerPage=14");
//work out how many pages it takes to include your total items
// ceil rounds a value up to next integer.
// ceil(20 / 14) = ceil(1.42..) == 2 ; It will return 2 and you will look for two pages
$limit = ceil($totalItems / $itemsPerPage);
// Then loop through calling the function passing the page number up to your limit.
for ($i = 0; $i < $limit; $i++) {
getRap($userId, $i);
}
If you cannot get the total number of items, you could loop while a fail state hasn't occured
// look for a fail state inside your getRap()
function getRap($userId, $i) {
if ($result = error) { //you will have to figure out what it returns on a fail
$tooMany = TRUE;
}
}
for ($i = 0; $tooMany !== TRUE ; $i++) {
getRap($userId, $i);
}
Edit: Reviewing my answer, looking for the fail state inside your function is poor form (and won't work because of the scope of the variable in this case). You could pass the variable back and forth, but I'll leave that part up to you.
To get the total, make sure that your function doesn't print the result (echo $rap) but returns it for further use.
Full example
<?php
function getRap($userId, $i){
$url = sprintf("https://www.roblox.com/Trade/InventoryHandler.ashx?userId=" . $userId . "&filter=0&page=" . $i . "&itemsPerPage=25");
$results = file_get_contents($url);
$json = json_decode($results, true);
if ($json['msg'] == "Inventory retreived!") {
$data = $json['data']['InventoryItems'];
$rap = 0;
foreach($data as $var) {
$rap += $var['AveragePrice'];
}
return $rap;
} else {
return FALSE;
}
}
$total = 0;
$userId = 1;
for ($i = 0; $i < 1000 /*arbitrary limit to prevent permanent loop*/ ; $i++) {
$result = getRap($userId, $i);
if ($result == FALSE) {
$pages = $i;
break;
} else {
$total += getRap($userId, $i);
}
}
echo "Total value of $total, across $pages pages";
?>
Below are the functions that am using to make reusable pagination. If you see the code below, theirs a function
generate_pages()
which is taking parameters from function
paged_controls()
But I would like to call the function generate_pages() without passing any parameters on body.php.
This is the error message am getting on body.php when calling function
generate_pages()
Warning: Missing argument 1 for generate_pages(), called in
E:\admin\snippets\body.php on line 11 and defined in
E:\admin\cores\pages.php on line 12
Notice: Undefined variable: limit in E:\xampp\htdocs\projects\hoplate\admin\cores\pages.php on line 16
Is that possible?
pages.php
<?php
function page_count(){
global $db;
$sql = "SELECT COUNT(pages_id) FROM pages";
$query = $db->SELECT($sql);
$rows = $db->FETCH_ROW();
foreach($rows as $row){
return $row[0];
}
}
function generate_pages($limit){
/* Run actual query now to get the records from database */
global $db;
$sql = "SELECT * FROM pages " . $limit;
$query = $db->SELECT($sql);
return $rows = $db->FETCH_OBJECT();
}
function paged_controls($page_rows = 1){
global $db;
/* Call the function page_count to get the total page count */
$row_count = page_count();
/* We use the ceil function to round the number to whole number */
$last = ceil($row_count / $page_rows);
/* Make sure that the last page cannot be less then 1 */
if($last < 1){
$last = 1;
}
/* Est. the page number variables */
$pagenum = 1;
/* Set the pagenum variables from URL else set it to 1*/
if(isset($_GET["paged"])){
$pagenum = preg_replace('#[^0-9]#', '', $_GET["paged"]);
}
/* Make sure page number canoot be less then 1 */
if($pagenum < 1){
$pagenum = 1;
} else if($pagenum > $last){
$pagenum = $last;
}
/* Set the range of query to be excuted depend on our variables values set*/
$limit = 'LIMIT '.($pagenum - 1) * $page_rows . ','. $page_rows;
generate_pages($limit);
$paged_controls = "";
/* Only if theirs more then 1 page of results */
if($last != 1){
if($pagenum > 1){
$previous = $pagenum - 1;
$paged_controls .= 'Previous ';
/* Renders the left paged numbers */
for($i = $pagenum - 4; $i < $pagenum; $i++){
if($i > 0){
$paged_controls .= ''.$i.' ';
}
}
}
/* Render the current page the user is at */
$paged_controls .= ''.$pagenum.' ';
/* Renders the right paged numbers */
for($i = $pagenum + 1; $i <= $last; $i++){
$paged_controls .= ''.$i.' ';
if($i >= $pagenum + 4){
break;
}
}
if($pagenum != $last){
$next = $pagenum + 1;
$paged_controls .= 'Next ';
}
return $paged_controls;
}
}
?>
body.php
<?php
$pages = generate_pages();
foreach($pages as $page){
echo $pages_id = $page->pages_id . "<br/>";
}
?>
Only way I would see this working is adding a check.
function generate_pages($limit = null){
/* Run actual query now to get the records from database */
$gloab $db;
$sql = "SELECT * FROM pages " . isset($limit) ? "LIMIT $limit" : "";
$query = $db->SELECT($sql);
return $rows = $db->FETCH_OBJECT();
}
So now it could be run one of two ways
generate_pages();
or:
generate_pages(10);
Compare both of your function headers:
function generate_pages($limit)
function paged_controls($page_rows = 1)
PHP offers you to specify default arguments, just like C++ (you have to scroll down a bit to see the section).
Your paged_controls-function already does this and it is a great way of achieving what you want without editing the business logic within the function.
A default argument kicks in whenever you call a function without any parameters.
So, if you edit
function generate_pages($limit)
to (for example)
function generate_pages($limit = 'LIMIT 0,18446744073709551615')
and call the function via generate_pages(), PHP will automatically assume $limit = 'LIMIT 0,18446744073709551615'.
In this specific case, calling generate_pages without a parameter will retrieve all entries in the table you select from, as we tell the database to give us 18446744073709551615 entries from the beginning.
See the MYSQL manual on select/limit.
I am trying to set up a jqgrid and I am having difficulty in constructing the controller that generates the json data to populate the grid. I am using codeigniter 2.0+ and I am not sure how to build the query for php in codeigniter.
I followed this guid under "Loading Data -> JSON Data" for the jqgrid. I also consulted codeigniter docs on data selection. The thing is I am not sure how to write the second query to sort and limit according to the jqgrid paramiters. Here is my controller.
public function applicantdata(){
$page = $this->input->get('page');// get the requested page
$limit = $this->input->get('rows');// get how many rows we want to have into the grid
$sidx = $this->input->get('sidx');// get index row - i.e. user click to sort
$sord = $this->input->get('sord');// get the direction
if(!$sidx){ $sidx =1; }
$this->db->select('*');
$this->db->from('applicant');
$this->db->join('transaction', 'transaction.applicant_id = applicant.id');
$query = $this->db->get();
$count = $query->num_rows();
$limit = 10;
if( $count > 0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages){ $page=$total_pages; }
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
//NOT SURE HOW TO DO THIS IN CODEIGNITER ENVIRONMENT
//$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id ORDER BY $sidx $sord LIMIT $start , $limit";
//$result = mysql_query( $SQL ) or die("Couldn t execute query.".mysql_error());
$result = $query->result_array();
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i=0;
foreach ($result as $myrow){
$responce->rows[$i]['id']=$myrow['id'];
$responce->rows[$i]['cell']=array($myrow['id'],$myrow['firstname'],$myrow['lastname'],$myrow['amount'],$myrow['status']);
$i++;
}
echo json_encode($responce);
}
With the above code, the grid is populating and its is working to a greater extent. Only thing is the pagination stuff not working properly in that the data on page one shows when I move to page 2, 3, etc.
Her is the final working thing. For anyone who may need it.
public function applicantdata(){
$page = $this->input->get('page');// get the requested page
$limit = $this->input->get('rows');// get how many rows we want to have into the grid
$sidx = $this->input->get('sidx');// get index row - i.e. user click to sort
$sord = $this->input->get('sord');// get the direction
if(!$sidx){ $sidx =1; }
$this->db->select('firstname');
$this->db->from('applicant');
$this->db->join('transaction', 'transaction.applicant_id = applicant.id');
$query = $this->db->get();
$count = $query->num_rows();
if( $count > 0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages){ $page=$total_pages; }
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
$this->db->select('*');
$this->db->from('applicant');
$this->db->join('transaction', 'transaction.applicant_id = applicant.id');
$this->db->order_by("applicant.id", $sord);
$this->db->limit($limit, $start);
$query2 = $this->db->get();
$result = $query2->result_array();
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i=0;
foreach ($result as $myrow){
$responce->rows[$i]['id']=$myrow['id'];
$responce->rows[$i]['cell']=array($myrow['id'],$myrow['firstname'],$myrow['lastname'],$myrow['amount'],$myrow['status']);
$i++;
}
echo json_encode($responce);
}
I am trying to create a dynamic page links created based on the number of rows in a mysql table. I would like to display 10 results per page and wish to have the php script create links to additional pages.
So I was thinking of using the num_rows and dividing it by 10 however if I have 53 rows the return would be 5.3 where as I would need 6 pages and not 5. I am thinking of using the round function and looping it through a for I statement until $pages > $rows_rounded. And every 10 rows add a link to pages($i) Is this the best method to acheive this or there an alternative simpler route to take?
pagenator class I made. getCurrentPages() returns all the pages you should be displaying in an array. so if you are on page one, and you want to display a total of 9 pages, you would get an array 1-9. if you were on page 10 however, your would get back an array 6-14. if there are 20 total pages and you are on page 20, you would get back an array 11-20.
<?php
class Lev_Pagenator {
private $recordsPerPage;
private $currentPage;
private $numberOfTotalRecords;
private $lastPage = null;
public function __construct($current_page, $number_of_total_records, $records_per_page = 25) {
$this->currentPage = $current_page;
$this->numberOfTotalRecords = $number_of_total_records;
$this->recordsPerPage = $records_per_page;
}
public function getCurrentStartIndex() {
return ($this->currentPage - 1) * $this->recordsPerPage;
}
public function getCurrentPages($number_of_pages_to_display = 9) {
$start_page = $this->currentPage - floor($number_of_pages_to_display / 2);
if ($start_page < 1) $start_page = 1;
$last_page = $this->getLastPage();
$pages = array($start_page);
for ($i = 1; $i < $number_of_pages_to_display; $i++) {
$temp_page = $start_page + $i;
if ($temp_page <= $last_page) {
$pages[] = $temp_page;
} else {
break;
}
}
return $pages;
}
public function getPreviousPage() {
if ($this->currentPage === 1) return false;
return $this->currentPage - 1;
}
public function getNextPage() {
if ($this->currentPage === $this->getLastPage) return false;
return $this->currentPage + 1;
}
public function getLastPage() {
if ($this->lastPage === null) $this->lastPage = ceil($this->numberOfTotalRecords / $this->recordsPerPage);
return $this->lastPage;
}
}
?>
EDIT (USAGE):
<?php
$pagenator = new Lev_Pagenator($current_page, $number_of_total_records, $records_per_page);
$pages_array = $pagenator->getCurrentPages($number_of_pages_to_display);
?>
The idea of a for loop sounds like a good one, you would use something like:
$rows_rounded = ceil(mysql_num_rows($result) / 10);
for($x = 1; $x <= $rows_rounded; $x++){
echo 'Page '.$x.'';
}
But you need to consider detecting the current page, so if, for example, the current page was 3, it might be a good idea to test for that in your for loop and if echoing the 3rd link maybe add some extra class to enable you to style it.