How to create a "read more" button using AJAX in a module?

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.

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

How to create a "read more" button using AJAX in a module?

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.