0

Novice here. I'm on Drupal 7.

I have a content type with a title, image and body field. I've created two views to display that content. The two views are on a page and I need help connecting them so that clicking/tapping on the image in View 2 will change content in View 1. Ideally this happens without page reload and View 1 fades in as new image in View 2 is clicked/tapped.

This seems like a filtering thing but I can't filter using images, I don't think!? Are Views the best way to set this up? If yes, what specifically needs to happen for the two Views to connect? If there is an easier way to set this up, what would it be? Help all! Any direction is appreciated.

Views

5
  • See How to use Drupal 7's built-in Ajax Framework
    – No Sssweat
    Commented Jun 2, 2020 at 21:26
  • Thx. No way to set this up without small custom code bit? It's just something I can't use in my environment. Commented Jun 2, 2020 at 21:51
  • I'm afraid there isn't.
    – No Sssweat
    Commented Jun 2, 2020 at 21:56
  • I would start by filtering view 2 with the content id then you need to make that view use ajax then you need to wrap the image in view 1 with a link or span data-id="contentd" that has the content id then you need custom Js to capture the click event grab the data id and pass to the ajax filter this is the only real way to do it good luck
    – taggartJ
    Commented Jun 3, 2020 at 0:09
  • An alternative to the excellent Jaypan's answer you can also try it with the great Views Reference Filter module. This answer shows how: Filtering one View with another View.
    – prkos
    Commented Jun 4, 2020 at 22:08

1 Answer 1

1

Edit: I wrote this for Drupal 8 before reading that the question is for D7. Hopefully it works in D7 as well.

You can do this using a views attachment. I'm basing it off the image you provided.

Set up

  1. Create a new content type, call it Person, give it a title, image and body field. Set up the teaser for that content type according to how you want the selected person to display in the top view.
  2. Install the Ajax links API module. This is required for this solution to work.

View 1, the list

The list is the bottom half of the image, which is a list of the people, showing a thumbnail of the image, and the title of the person.

Create a new view of the people content type. Create a page for this view.

  • Set 'format' to 'grid'
  • Set 'show' to 'fields'
  • Add a field for Content: ID. Check 'exclude from display'
  • Add a field for Content: Image (or whatever you named the image). Make sure it comes AFTER the Content: ID above. Rewrite the results to <a href="/node/{{ nid }}/teaser" class="ajax-link" rel=".view-[VIEW ID] .attachment">{{ [FIELD_NAME] }}</a>. Note that you have to replace [FIELD_NAME] with the name of the field, and [VIEW ID] with the machine name of your view.
  • Add a field for Content: Title. Make sure it comes AFTER the Content: ID above. Rewrite the results to <a href="/node/{{ nid }}/teaser" class="ajax-link" rel=".view-[VIEW ID] .attachment">{{ title }}</a>. Note that you have to replace [VIEW ID] with the machine name of your view.
  • Set up a pager if necessary, and customize the number of items to be shown in the grid.

Now you have a page that lists off your items in a grid, with both the title and the image ajaxified using the Ajax links Api module, ready to load content into a div. The final thing to do is to load the content into the div.

View 2, the attachment

Next, a View's attachment is created. This will display the teaser for the first person in the list, when the page is loaded.

  • Click the "+Add" Link, and select "Attachment"
  • Set 'Format' to 'Unformatted list'
  • Set 'Show' to 'Content', and select 'Teaser' as the view mode.
  • Under 'Attachment Settings', set 'Attach to' to the first view you created (the page view).
  • Set 'Attachment Position' to 'Before'
  • Set 'Inherit contextual filters' to 'Yes'
  • Set the pager type to 'Display a specified number of items', and set it to show a single item.

Now, when the page from the first view is loaded, the teaser for the first person will be loaded. You can alter the display of the teaser of the person content type accordingly, to show whichever fields you need.

View 3, the ajax-loaded content

The first view is set up with ajaxified links, set to display the content of the path /node/%/teaser. This page does not yet exist. The final step is to set up this page, so that the links can load this content into the container specified in the ajax links.

  • Click the "+Add" Link, and select "Page"
  • Set the title to <none>
  • Set the format to 'Unformatted list'
  • Set 'Show' to 'Content' with the 'view mode' to 'teaser'
  • Set the 'path' to /node/%/teaser
  • Set the 'pager' to 'Display a set number of items' and set it to show 1 item.
  • Add a contextual filter for Content: ID. 'When the value is not in the URL' set it to 'show page not found'

Now you should be able to access the page created in the first view, and click on the links to ajax load the content replacing the attachment that is initially shown on page load.

3
  • Thanks for the detailed explanation. This is exactly the type of walk-through a novice like myself can follow. I did run into an issue: --- TypeError: xhr.response is undefined ajax_links_api.js:49:20 --- error: function (xhr) { var data = xhr.response.replace("?ajax=1", ""); ajaxAfter(selector, url, data, window, document); } --- Everything loads as I need it but when an image is clicked, View 1 disappears and there is just a loading gif in its place. Thoughts? Commented Jun 4, 2020 at 23:14
  • This CSS selector is likely incorrect, as I was using D8 output to determine it: .view-[VIEW ID] .attachment. Replace this with the actual CSS selector of the container that holds the initial view attachment.
    – Jaypan
    Commented Jun 4, 2020 at 23:36
  • @Jaypan - Can you please share the same scenario how should we achieve in Drupal 10? This is not working in D10 as module not supported.
    – latikas
    Commented May 15 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.