I’m working on a really simple module in Drupal 8 to get the hang of things. What it does (or rather, what the page I’m asking about in this question does) is grab some data of a bunch of simple article-style entries, and display them.
What I would like to be able to do is to have it only display the first few (say, 5), and then have a “Read more” button, which uses AJAX to display the next 5, lengthening the page so it now shows 10.
Here is the controller as I have it at the moment. The routing.yml
file points to MyController::build
. For the sake of simplicity, I’ve left out exactly how it gets things from the database, and some simple processing (in particular, image
gets converted from a managed_file
in the database into a URL to the image).
class MyController extends ControllerBase {
public function build() {
$stuff = $this->getStuff();
return array(
'#theme' => 'my_theme',
'#stuff' => $stuff,
'#attached' => array(
'library' => array(
'my_theme/style',
'my_theme/readmore',
),
),
);
}
private function getStuff() {
$stuff = getStuffFromDatabase();
$result = array();
foreach($stuff as $key => $item) {
$tmp = new stdClass();
$tmp->id = $item->id;
$tmp->title = $item->title;
$tmp->description = $item->description;
$tmp->image = $item->image;
$result[] = $tmp;
}
}
}
Which then gets sent to a template file:
<section>
<ul>
{% for item in stuff %}
<li>
<h3><a href="stuff/{{ item.id }}">{{ item.title }}</a></h3>
{% if item.image is not empty %}
<a href="stuff/{{ item.id }}">
<img src="{{ item.image }}" />
</a>
{% endif %}
{% if item.description is not empty %}
<p>{{ item.description }}</p>
{% endif %}
</li>
{% endfor %}
</ul>
</section>
<form method="post" action="" onsubmit="readmore()">
<button name="read-more" type="submit">Read more</button>
</form>
What I want is a way to change this set up so that at first the controller only sends a few of the entries, but when the button is pushed, it sends the next few, and the template displays the new ones as well as the old.
Thanks
Okay, I think I may have worked out to at least make a start on this problem. I’ve followed this tutorial, and want to get a small message displaying at the bottom, to at least get a feel for how Ajax works with Drupal 8. I’ve added
<div id="current-msg">
<h2></h2>
<p></p>
</div>
to the bottom of the .html.twig
file.
I created a file identical to his ReadMessageCommand.php
, except named mine MyMessageCommand.php
(and renamed the class inside it accordingly). The function render has myMessage
in place of readMessage
.
I added a method called myMessageCallback
into MyController
, which works the same as in that guide, but with my_module_load_message
and MyMessageCommand
in the appropriate places.
To readmore.js
, I added the function from the above guide, but with readMessage
replaced by myMessage
. I also added the following, just so I can know more easily if the function is at least being called.
console.log(response.subject);
console.log(response.content);
And I added the core/drupal.ajax
dependency to the readmore library.
My question is, how do I actually get this function to be called. As far as I can tell, the guide that I’ve used has no indication of it. How to I get a message to be displayed in the div at the bottom? Once I’ve figured that out, I feel extending it so that the button acts as a “read more” shouldn’t be too much trouble.