I'm displaying a search result obtained via $this->paginate() for the view. Pagination works well, and I want to display the row number of the search result for each row on the view for the user. I simply do <?php echo $i; ?>, where $i is my counter, but on every page, the number starts from 1. So, if I'm on page one of the search result, it will show 1 ~ 10 (10 rows of data per page). I move to page two, and it will still show 1 ~ 10, and so on.
How can I make this so that it shows 1~10 on page one, 11~20 on page two, etc. on the fly? And why does it reset, even though I'm going through my search result array elements one by one and doing $i++ in every iteration?
You want to use counter() as part of the Paginator helper.
$start = $this->Paginator->counter(array('format' => '%start%'));
foreach( $records as $record ) {
$start++;
...
}
See if that helps!
Related
I want to send a value from a controller to a view on each iteration of a foreach loop.
Context:
I have an array that has 100 elements as an example. In the controller, I want to loop the array and for each iteration send a value to the view. How can I do that in Symfony
Here is the code example
$myArray = ["val1", "val2", "val100"];
foreach ($myArray as $key => $val) {
// here I want to send the data (val1 to val100) to the view on each iteration
}
Note:
With return this->json(...) or new JsonResponse(...), in the loop, the loop stops after the first iteration. If you put it outside of the loop, only the last val (val100 in this example) is rendered.
Why do I want to do that?
Let's say I am working on a symfony project to insert data into a database from excel file or something similar. After reading the file in the controller, I'm inserting the data one by one into the related table via a foreach loop and I aslo want to feed a progress bar which is in the view to let the user know that data is inserting like (1/100, 2/100 ... 100/100). How can I pass the data on each iteration from the loop to reach the view.
Data is inserted into the db successfully, but I still can't find a way to feed the progress bar in the view on each iteration of the loop
In advance, many thanks.
I am trying to find all products in random order using pagination. But getting an unexpected result.
This is my controller code:
$this->paginate = ['maxLimit' => 20];
$articlesData = $this->Products->find('all');
$articlesData->order('RAND()');
$articles = $this->paginate($articlesData);
So I get random result every time, this is the demand of the page. I have 200 products. Suppose first item is item-12 on page one then if I go to the next page and again go to the previous page then the first item should be item-12 but it changed randomly. Is there any solution for this?
I need pagination because products number going to be 1000 soon. And need random results because I don't want that user to see the same first product on the first page. The first product should be on the first page but not on the same location every time. Is there any way that I make paginated array of 20 items in random order?
All suggestions are welcomed.
Example of how to rearrange results in view template. In the controller select from the latest Articles, but in the template display these 20 results in a different place each time.
#Controller
$this->paginate = ['maxLimit' => 20];
$articlesData = $this->Products->find();
$articlesData->orderDESC('creates');
$articles = $this->paginate($articlesData);
$this->set(compact('articles'));
#template
foreach(shuffle($articles->toArray() as $article) {
echo $article['name'];
}
https://www.w3schools.com/php/func_array_shuffle.asp
When you order them randomly, they are ordered randomly. Every page load will be a new random order. See this for an example of how to make the order predictable; you might seed the generator with the user ID for example, then the order will always be the same for a given user. Or with some combination of user details and the date to give them a different random order tomorrow. Or randomly generate a seed and then save that in the session to control the duration more precisely.
I want to display count of no of items fetched per page using pagination like
Displaying 10 items
Although limit is set to pagination to 20 but It will not always fetch 20 items when there are only 15 items or 10 items or 25 items.
In these cases it will either have one page result for items count 15 and 10 or two pages result for items count 25.
I want to print the no of items showing on each page. Like for total items 25.
It will show Displaying 20 items on first page and Displaying 5 items on second page.
How is it possible in CakePHP 3.2 ?
This is how I get it working in CakePHP 3.2
There are two ways you can do it.
Using Helpers
create a file paginator-counter.php in /config directory with your tokens and string and add a line in /src/view/AppView.php
public function initialize()
{
$this->loadHelper('Paginator', ['templates' => 'paginator-counter']);
}
This will load the file located at config/paginator-templates.php
And then use it in your view.
For more : http://book.cakephp.org/3.0/en/views/helpers/paginator.html
Using direct string
Just print in view where you want to print the counter
<?= $this->Paginator->counter('Showing {{current}} results out of {{count}}') ?>
More tokens can be found Here : http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-a-page-counter
I'm using 2nd way to print counter ie., using sting directly
I have an array that I collected:
array= #browser.ul(:class => 'parent').links
I am then trying to access the text on a specific element in the array iterating over the array like this:
array.each_with_index do |i, index|
If I do something like:
array[index]
I get back the anchor element object. And if I do:
array[index].element
I will get back an HTML element object. But if I try to get anything element specific such as:
array[index].text
array[index].value
then I get an "unable to locate element" error.
I am using Watir, Page Object, and Ruby.
Here is the scope of the entire array iteration, it's fairly simple:
array= #browser.ul(:class => 'parent').links
array.each_with_index do |i, index|
if index == array.length-1
sleep 1
#browser.button(:text => 'Complete').when_present.click
else
sleep 1
#browser.button(:text => 'Complete').when_present.click
#browser.a(:text => 'Next').when_present.click
end
end
I am trying to add an elsif that checks for the text of a link, so that if it's on that particular page/link it does something specific while on that page.
For example, in pseudo-code:
If array element text = "Instructions", then dont click the complete button, just click next.
I suppose I would be open to solving this in any way that lets me identify the link it is currently on, so that I can perform a set action, but I figured grabbing the text of the current link would be easiest, hence the question.
How can I access the text or specific attributes of an element in this array?
Most probably the DOMs of your elements are changing after some interaction (like clicking 'Complete' button).
My suggestion is to find all the elements once again after each interaction.
Try something like that:
array = #browser.ul(:class => 'parent').links
index = 0
array.length.times do
sleep 1
if index == array.length-1
#browser.button(:text => 'Complete').when_present.click
array = #browser.ul(:class => 'parent').links #We are finding new array after possible change
elsif array[index].text == 'Instructions'
#browser.a(:text => 'Next').when_present.click
else
#browser.button(:text => 'Complete').when_present.click
#browser.a(:text => 'Next').when_present.click
end
array = #browser.ul(:class => 'parent').links #And once again
index = index+1
end
Attention: I can not guarantee that the code above will work because I've got no page to test it on to be sure. If it is not working - try to modify it using the idea
Iterating over a list of links and just pulling out information on them is fairly simple and should work reliably as long as the DOM is not changing. Once you start clicking things, or taking actions that cause some or all of the page to update, all bets are off as your collection may contain references to elements in the UI that have been deleted or replaced.
You also seem a bit confused over how the .each iterator works. The basic form of that method returns you each object in the collection in turn. The with_index version returns each object plus its index within the array. In most cases, unless you care what the index is, you would not use the with_index form.
For example, to walk your collection and output the text of each link, you could simply do
links_list = #browser.ul(:class => 'parent').links
links_list.each do |link|
puts "the link text is: #{link.text}"
end
If you wanted to indicate the index of each link, then you could do
links_list = #browser.ul(:class => 'parent').links
links_list.each_with_index do |link, index|
puts "the text for link number #{index} is: #{link.text}"
end
If you want to work your way through a list of links like that and do things with them that might cause page updates, then you are better off to use a tactic like that presented in the other answer where you create a loop based off the size of the list, but re-fetch the list inside the loop so that it will always be 'fresh' and not potentially contain references to objects that are no longer in the DOM.
I want to limit the counter that is visible in pagination in cakephp? What should I do...? Currently its default showing as 1-9 as pages link. I tried limit but as it limits my post per page. I want to limit the counter not post per page. Please help me.
Modified...
I tried modulus according to answers..
I want my Pagination should be this way. If it is on first Page then.
1 2 3 ... Last
If it is on Middle of page then..
First ... 6 7 8 ... Last
If it it on last then.
First ... 11 12 13
My tried code is.
<?php echo $this->Paginator->numbers(array('modulus' => '2', 'tag' => 'span','first'=>'First','ellipsis'=>'...', 'separator' => ' ', 'last'=>'Last' )); ?>
Check out the documentation for the pagination helper: http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
I think want you want is "modulus - how many numbers to include on either side of the current page, defaults to 8."
So in your View, you'd have something like:
// Limit numbers to 4 either side of current page
echo $this->Paginator->numbers(array('modulus' => 4));
Hope that helps.