<p>Your <code>block.headshots</code> is not an array of all images, you have to understand what craft does in order to work properly with it.</p>

<p><code>block.headshots</code> and all other relations (Matrix elements, images, category links...) are all <code>elementCriteriaModels</code> so instead of having an array of objects - your <code>block.headshots</code> is just a single object that has an iterator interface.</p>

<p>So when you execute <code>{% for headshot in block.headshots %}</code> it performs the <code>.find()</code> function and returns an array.
Unfortunately I'm not on my computer currently so I can't provide the exact code so maybe the syntax of something of the following might be wrong, but if you know how to search entries with <code>craft.entries.find()</code> <a href="https://craftcms.com/classreference/models/ElementCriteriaModel#find-detail" rel="nofollow noreferrer">click</a> you can correct it, here you have more examples <a href="https://craftcms.com/docs/templating/elementcriteriamodel" rel="nofollow noreferrer">elementCriteriaModel</a>. Your code should look like </p>

<p><code>{% for headshot in block.headshots.find({limit: 10}) %}</code></p>

<p>It does not matter if you are searching pages (entries), assets, matrix blocks, sections, categories or whatever.. Craft does always the same, building an elementCriteriaModel that is executed as soon as you loop through it.</p>

<p>edit: your controller to load the assets could look like this</p>

<pre><code>public function actionLoadAssets(){
    $this-&gt;requireAjaxRequest();
    $response = array(
        'success'   =&gt; false,
        'message'   =&gt; ''
    );

    // config how many entries should be loaded
    $config = craft()-&gt;globals-&gt;getSetByHandle('config');
    $limit = $config['countReloadImages'];
    // offset.. how many did we load already
    $offset = craft()-&gt;request-&gt;getPost('offset');
    // which block is it
    $matrixIndex = craft()-&gt;request-&gt;getPost('matrixIndex');
    // entryId
    $entryId = craft()-&gt;request-&gt;getPost('entryId');

    if($entry = craft()-&gt;elements-&gt;getElementById($entryId)){
        // search for the correct field -&gt; we just insert an offset
        // this is untested, maybe you have to play around with the correct number
        // I'm not sure if you can just send the id of the matrixfield and use 'id' =&gt; $matrixIndex
        // you could to try it out...
        $matrix = $entry-&gt;team-&gt;find([
            'offset'    =&gt; $matrixIndex
        ]);
        $html = '';
        if($matrix &amp;&amp; ($assets = $matrix-&gt;headshot-&gt;find(['offset' =&gt; $offset, 'limit' =&gt; $limit]))){
            // build a template to render the images, you'll return the html
            $html = $this-&gt;renderTemplate('some tempalte here', array(
                'asset' =&gt; $assets
            ));
        }
        // you could include your logic if you found less entries than configured ($limit) and return a "hide reload button"
        $response['html'] = $html;
        $response['success'] = true;
    }else{
        $response['message'] = Craft::t('could not find entry with Id ' . $entryId);
    }

    return $response;
}
</code></pre>

<p>Edit2: I found a better solution:</p>

<pre><code>public function actionLoadMore(){
    $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Asset);
    // id of your field headtshot
    $field = craft()-&gt;fields-&gt;getFieldById(5);

    $criteria-&gt;relatedTo = array(
        'sourceElement' =&gt; //your matrix ID,
        'field'         =&gt; $field-&gt;id
    );
    $criteria-&gt;offset = //your offset;
    $criteria-&gt;limit = //your limit;
    $assets = $criteria-&gt;find();

    // render template -&gt; return html look at the first example
}
</code></pre>

CC BY-SA 3.0
2017-10-21T12:23:42.553Z
Thanks Robin, that's extremely detailed, so I appreciate the effort you've put in. However, I didn't realise that I'd need to create a plugin for it. Seems a lot to do for a load more button. So I'll need to continue to investigate if there's any simpler options maybe via javascript instead.
mention79
CC BY-SA 3.0
2017-10-21T12:29:49.720Z
well its only one function. You only need to create a plugin with pluginfactory.io and insert it.
Robin Schambach
CC BY-SA 3.0
2017-10-21T12:32:47.130Z
Ok thanks, will give it a go. But it's not something I've done before, so hard to get my head around. But I'm always willing to learn. So will try.
mention79
CC BY-SA 3.0
2017-10-21T12:43:04.917Z
Ok I see... The first time with craft might be a little bit confusing. It took me a  long time until I understood it (especially the routings sometimes) but once you learn how it works, things will get much easier. For example searching entries in twig (like you want) will be clearer. Btw I found a better solution to search for the images, the logic for finding the assets is in my 2. edit.
Robin Schambach
CC BY-SA 3.0
2017-10-21T12:49:20.583Z
I've found a javascript way that works too. https://jsfiddle.net/cse_tushar/6FzSb/
mention79
CC BY-SA 3.0
2017-10-21T13:07:15.203Z
of course you can use that too, but this is not an answer to your question. You don't lazy load  your images, you just hide them. It`s up to you but for example I have limited traffic so I would not visit your page if I have to download 40+ images every time even if I don't even want to see them (that's the reason for ajax calls to load content dynamically). 
The page will take much more time to load if you have (let's say) 80 images per call instead of only 10
Robin Schambach
CC BY-SA 3.0
2017-10-21T13:11:54.527Z
I agree and will definitely try to implement the better way in future, but in this case, I've got no time, and it's just some headshots, so only will be a few hundred kilobytes, and so will solve the immediate issue at least. And then I can work in the background to do it the better way once I have a bit more time.
mention79
CC BY-SA 3.0
2017-10-21T10:56:11.220Z
2017-10-21T12:40:43.157Z
2017-10-21T12:40:43.157Z
Robin Schambach
<p>I have a matrix block called team that has an assets field within it that has all of the companies headshots. However, there are more than 30 images, but the design is to only have 6 showing on load, and then on click of a load more button the next 6 will show, etc.</p>

<p>However, I'm not sure how to achieve this within a matrix block as all the examples I've seen elsewhere are for pages and sections. But I just need to load the images from within the matrix block.</p>

<p>Below is my code for the images. Can someone help?</p>

<pre><code>{% for headshot in block.headshots %}
&lt;figure class="team__headshots"&gt;
  {% if headshot | length %}
  {% set transformedImages = craft.imager.transformImage(headshot,
      [
          { width: 180, ratio: 4/5 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          jpegQuality: 80,
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  {% set tabletl = craft.imager.transformImage(headshot,
      [
          { width: 142, ratio: 4/5 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          jpegQuality: 80,
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  {% set tabletp = craft.imager.transformImage(headshot,
      [
          { width: 230, ratio: 4/5 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          jpegQuality: 80,
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  {% set mobile = craft.imager.transformImage(headshot,
      [
          { width: 360, ratio: 4/5, jpegQuality: 65 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  &lt;picture&gt;
  &lt;source srcset="{{ craft.imager.srcset(mobile) }}" media="(max-width: 767px)"&gt;
  &lt;source srcset="{{ craft.imager.srcset(tabletp) }}" media="(min-width: 768px) and (max-width: 991px)"&gt;
  &lt;source srcset="{{ craft.imager.srcset(tabletl) }}" media="(min-width: 992px) and (max-width: 1199px)"&gt;
  &lt;img class="img-responsive"
       src="{{ transformedImages[0].url }}"
       sizes="(min-width: 768px) 33.3vw, 50vw"
       alt="{% if headshot.altTag|length %}{{ headshot.altTag }}{% else %}{{ headshot.title }}{% endif %}"
       width="100%"&gt;
  &lt;/picture&gt;
  {% endif %}
  &lt;div class="team__headshots-overlay"&gt;
    &lt;div class="team__headshots-captions"&gt;
      &lt;h4&gt;{{ headshot.title }}&lt;/h4&gt;
      &lt;p&gt;{{ headshot.jobTitle }}&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/figure&gt;
{% endfor %}
</code></pre>

<matrix><search><elementcriteriamodel>
Load more images in matrix block
# Load more images in matrix block

(Asked by: username_0 on 2017-10-21)

I have a matrix block called team that has an assets field within it that has all of the companies headshots. However, there are more than 30 images, but the design is to only have 6 showing on load, and then on click of a load more button the next 6 will show, etc.
However, I'm not sure how to achieve this within a matrix block as all the examples I've seen elsewhere are for pages and sections. But I just need to load the images from within the matrix block.
Below is my code for the images. Can someone help?
{% for headshot in block.headshots %}

  {% if headshot | length %}
  {% set transformedImages = craft.imager.transformImage(headshot,
      [
          { width: 180, ratio: 4/5 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          jpegQuality: 80,
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  {% set tabletl = craft.imager.transformImage(headshot,
      [
          { width: 142, ratio: 4/5 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          jpegQuality: 80,
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  {% set tabletp = craft.imager.transformImage(headshot,
      [
          { width: 230, ratio: 4/5 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          jpegQuality: 80,
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  {% set mobile = craft.imager.transformImage(headshot,
      [
          { width: 360, ratio: 4/5, jpegQuality: 65 },
      ],
      {
          format: 'jpg',
          allowUpscale: false,
          mode: 'crop',
          position: headshot.focalPoint,
          interlace: true
      }
  ) %}
  
  
  
  
  
  
  {% endif %}
  
    
      {{ headshot.title }}
      {{ headshot.jobTitle }}
    
  

{% endfor %}

**Tags:** matrix, search, elementcriteriamodel


---

## 1 answers

### Answer by username_1 on 2017-10-21. Score: 2 | Accepted answer

Your block.headshots is not an array of all images, you have to understand what craft does in order to work properly with it.
block.headshots and all other relations (Matrix elements, images, category links...) are all elementCriteriaModels so instead of having an array of objects - your block.headshots is just a single object that has an iterator interface.
So when you execute {% for headshot in block.headshots %} it performs the .find() function and returns an array.
Unfortunately I'm not on my computer currently so I can't provide the exact code so maybe the syntax of something of the following might be wrong, but if you know how to search entries with craft.entries.find() click you can correct it, here you have more examples elementCriteriaModel. Your code should look like 
{% for headshot in block.headshots.find({limit: 10}) %}
It does not matter if you are searching pages (entries), assets, matrix blocks, sections, categories or whatever.. Craft does always the same, building an elementCriteriaModel that is executed as soon as you loop through it.
edit: your controller to load the assets could look like this
public function actionLoadAssets(){
    $this->requireAjaxRequest();
    $response = array(
        'success'   => false,
        'message'   => ''
    );

    // config how many entries should be loaded
    $config = craft()->globals->getSetByHandle('config');
    $limit = $config['countReloadImages'];
    // offset.. how many did we load already
    $offset = craft()->request->getPost('offset');
    // which block is it
    $matrixIndex = craft()->request->getPost('matrixIndex');
    // entryId
    $entryId = craft()->request->getPost('entryId');

    if($entry = craft()->elements->getElementById($entryId)){
        // search for the correct field -> we just insert an offset
        // this is untested, maybe you have to play around with the correct number
        // I'm not sure if you can just send the id of the matrixfield and use 'id' => $matrixIndex
        // you could to try it out...
        $matrix = $entry->team->find([
            'offset'    => $matrixIndex
        ]);
        $html = '';
        if($matrix && ($assets = $matrix->headshot->find(['offset' => $offset, 'limit' => $limit]))){
            // build a template to render the images, you'll return the html
            $html = $this->renderTemplate('some tempalte here', array(
                'asset' => $assets
            ));
        }
        // you could include your logic if you found less entries than configured ($limit) and return a "hide reload button"
        $response['html'] = $html;
        $response['success'] = true;
    }else{
        $response['message'] = Craft::t('could not find entry with Id ' . $entryId);
    }

    return $response;
}

Edit2: I found a better solution:
public function actionLoadMore(){
    $criteria = craft()->elements->getCriteria(ElementType::Asset);
    // id of your field headtshot
    $field = craft()->fields->getFieldById(5);

    $criteria->relatedTo = array(
        'sourceElement' => //your matrix ID,
        'field'         => $field->id
    );
    $criteria->offset = //your offset;
    $criteria->limit = //your limit;
    $assets = $criteria->find();

    // render template -> return html look at the first example
}

> **Comments:**
> **username_0**: Thanks Robin, that's extremely detailed, so I appreciate the effort you've put in. However, I didn't realise that I'd need to create a plugin for it. Seems a lot to do for a load more button. So I'll need to continue to investigate if there's any simpler options maybe via javascript instead.  
> **username_1**: well its only one function. You only need to create a plugin with pluginfactory.io and insert it.  
> **username_0**: Ok thanks, will give it a go. But it's not something I've done before, so hard to get my head around. But I'm always willing to learn. So will try.  
> **username_1**: Ok I see... The first time with craft might be a little bit confusing. It took me a  long time until I understood it (especially the routings sometimes) but once you learn how it works, things will get much easier. For example searching entries in twig (like you want) will be clearer. Btw I found a better solution to search for the images, the logic for finding the assets is in my 2. edit.  
> **username_0**: I've found a javascript way that works too. https://jsfiddle.net/cse_tushar/6FzSb/  
> **username_1**: of course you can use that too, but this is not an answer to your question. You don't lazy load  your images, you just hide them. It`s up to you but for example I have limited traffic so I would not visit your page if I have to download 40+ images every time even if I don't even want to see them (that's the reason for ajax calls to load content dynamically).  The page will take much more time to load if you have (let's say) 80 images per call instead of only 10  
> **username_0**: I agree and will definitely try to implement the better way in future, but in this case, I've got no time, and it's just some headshots, so only will be a few hundred kilobytes, and so will solve the immediate issue at least. And then I can work in the background to do it the better way once I have a bit more time.  

---

