I have a method in the model to search and receive messages
public function getAllMessages()
{
$allMessages = Message::find()
->where(['=', 'phone', $this->phone])
->all();
return $allMessages;
}
Then I display all received messages in the view
<div class="message-history">
<?php foreach ($messageModel->getAllMessages() as $index => $message) { ?>
<?php $hide = '';
if ($index > 4) {
$hide = 'hidden';
} ?>
<div class="message <?= $hide ?>">
<div class="panel">
<p><?= $message->date ?></p>
<p><?= $message->data ?></p>
</div>
</div>
<?php } ?>
<?php if (count($messageModel->getAllMessages()) > 4) { ?>
<div class="show-all-message">
<div class="show-all-message-btn">Show all message history</div>
</div>
<?php } ?>
</div>
As a result, I get a data page like this
$( ".show-all-message-btn" ).click(function() {
$('.message').removeClass('hidden');
$('.show-all-message').addClass('hidden');
});
.hidden {
display: none;
}
.show-all-message-btn {
cursor: pointer;
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="message-history">
<div class="message">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message hidden">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message hidden">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message hidden">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message hidden">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="message hidden">
<div class="panel">
<p>06-02-2023</p>
<p>some message</p>
</div>
</div>
<div class="show-all-message">
<div class="show-all-message-btn">Show all message history</div>
</div>
</div>
The bottom line here is that when we get more than 4 messages, only the first 5 are displayed, the rest are assigned the hidden
class. To show the rest, you need to click the button and they will all open
But I would like to redo all this, because 100 or more messages can be received, and it turns out that all of them will be loaded and hang on the page with the hidden
class, while opening them is not a fact that you have to
I heard that I can use the offset
method in php
, and load the route through js
, displaying 5-10 messages on the page when necessary
In php
I need to do something like this
Message::find()->offset($offset)->where(['=', 'Phone', $this->phone])->all();
But how then to interact with js
and make it so that initially there were 5 messages on the page, and then with each click on some button, let’s say 10 messages were loaded. So that they do not initially hang on hidden on the page, but are loaded only when I need to see them
4
Answers
Because you’re not calling an API to fetch the additional messages, you have to hold onto them somewhere in the browser. This could be in the DOM (as you’re doing now with the
hidden
class), or in a JS array, e.g.Then you can add/remove the messages to the DOM as you please.
Limit and offset would work for you.
The best way would be to use Pjax. Load 5 initially and on the click you can load rest of them.
Pjax
A Little how to
One way to achieve this is that you can save the offset value in your
show-all-message-btn
div using data-attr and whenever you need to load more data you can just get the offset from there and use ajax call to fetch the required rows and again update the offset in your button.Some changes you can do in your code :
Your current html code :
Your current route function :
Now, you will see only 5 rows and button which has offset set to 6.Next , you need to write some jquery code which will get the offset and send to your backend code to query next 10 or more records and then append them in your UI.
Your jquery code will somewhat look like below :
Now, your ajax will call some of the function in your backend there you can fetch the next 10 records and send back to UI.
Your controller code will somewhat look like this :
*Note : This is not the actual code but, this will help you to get started .
I think I have a simple solution for you.
Think of it as a basic pagination.
A video recording of the outcome can be found here.
The controller class looks like this:
and the view file looks like this
For Partial Page Update (Ajax)