I created a Quick Tabs instance with several Views blocks as tabs. I added the filter in the view to exclude if that view's single field is NULL. I checked the option in the Quick Tabs instance to hide empty tabs. But the tabs with no content are still displaying. How can I fix this issue? (I am using Drupal 9)

Issue fork quicktabs-3238148

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

hockey2112 created an issue. See original summary.

anaconda777’s picture

I have same issue

The problem only comes when the "ajax setting: load only the first tab on page view" is selected.
If you have only 1 tab, it is then hidden and the feature works.
But if you have more than one tab, only the first one is hidden and the rest are visible.

Steps to reproduce:
1. create 3 views and one quick tabs and add the views to the quicktabs
2. select "Load only the first tab on page view"
3. select "hide empty tabs"
4. result is, only the first tab is hidden, the 2 tabs are still visible even they are empty

Workaround: Select "Load all tabs on page view"
result: all tabs are hidden if they are empty
But if any of the view gets content, it is only displayed if the caches are cleared

I have these patches applied:
https://www.drupal.org/files/issues/2021-01-15/quicktabs-direct_link_to_...
https://www.drupal.org/files/issues/2020-12-10/empty_view_tabs_still_bei...

Version: Drupal D9.2.6 Module: 8.x-3.0-alpha5

I am not sure, but if I look the HTML source code, could the problem be that the rest of the tabs have "loading content... "
so maybe the module looks that those tabs are not empty? I am probably wrong..

hockey2112’s picture

I tried your workaround, but it had no effect. I do have the second patch you mentioned installed, but not the first patch.

lubwn’s picture

This might work. But ajax needs to be disabled.

It is not ideal but seeing there is no proper solution this works:

$('.quicktabs-wrapper').each(function() {
	
	var quicktabs_wrapper = $(this);
	
	$(this).find('.quicktabs-tabs li').each(function() {

		var id = $(this).attr("id");
		
		if (quicktabs_wrapper.find(".quicktabs-main [aria-labelledby='" + id + "']").text().trim() == "") {
			
			 $(this).hide();
			
		}
		
	});
  
});
hockey2112’s picture

@lubwn, how and where did you apply this fix?

hockey2112’s picture

I "fixed" the issue for my use-case. I have a node type with four fields. I then created a View with four block displays (one for each field). I then used those Views blocks as "Block" quicktab Tab Type content. This was causing the empty tabs to appear, probably because the block existed even though the block itself was empty.

I changed my tabs' Tab Type to "View", and selected those Views directly from the Quicktabs settings. This allowed the empty tabs to disappear as desired.

delacosta456’s picture

hi
i confirm that #6 is a nice workaround that worked for me . thanks @hockey2112

Foxy-vikvik made their first commit to this issue’s fork.

foxy-vikvik’s picture

StatusFileSize
new1.22 KB

Added patch only hide content if Views are empty

foxy-vikvik’s picture

StatusFileSize
new1.56 KB

Added arguments to the view in the patch.

foxy-vikvik’s picture

StatusFileSize
new1.76 KB
shalini_jha’s picture

hii , #6 is working for me .

smustgrave’s picture

Version: 8.x-3.0-alpha5 » 4.0.x-dev

Lets ad some test coverage for this please.

loze made their first commit to this issue’s fork.

loze’s picture

Status: Active » Needs review
StatusFileSize
new3.06 KB

This wasn't working for me, empty views loaded with ajax were still showing, so I made some adjustments and rebased for 4.0.x

MR 42 is for 4.0.x

Here is a patch for composer

Still no test coverage.

loze’s picture

While digging into this I had a thought.

There is a difference with an empty view because views permission/argument validation fails vs. a view with no results.
And do we want to hide the tab in both cases? There are times when you would want the content of the no results handler to display on certain views.

Perhaps there could be a setting per views tab allowing them to specify no results vs no access?

smustgrave’s picture

Status: Needs review » Needs work

Thanks for working on this. Wonder if small test coverage could be added

loze’s picture

Thanks for taking a look. Unfortunately I'm not very good with writing tests and could use some help with that. Otherwise I would.

smustgrave’s picture

Can you least provide steps that are triggering this? Actually working for me

loze’s picture

Status: Needs work » Needs review

The bug only triggers when AJAX is on AND the empty Views tab isn't the default tab. The default tab gets rendered server-side so the existing empty check catches it. Non-default tabs in AJAX mode get a "loading content..." placeholder instead, and the placeholder is non-empty, so the check never fires and the empty tab's title stays in the list.

To reproduce: AJAX on, hide empty on, an empty Views tab that isn't the first one.

Test added at tests/src/Kernel/HideEmptyViewsTabsTest.php. Pipeline 826157 has the fail-before-pass-after pair on the same commit:

- phpunit (test with the fix) passes: https://git.drupalcode.org/issue/quicktabs-3238148/-/jobs/9922383
- test-only changes (same test against unpatched 4.0.x) fails: https://git.drupalcode.org/issue/quicktabs-3238148/-/jobs/9922387

Worth flagging on performance: this fix has to execute each non-default Views tab on the initial page load to know whether it's empty, which partly works against AJAX's lazy-load. So a tab with content ends up running its view twice on initial load (once inside ViewContent::render via views_get_view_result, once explicitly here) and again when the AJAX callback fires after a click. Pre-MR42, non-default tabs ran zero times on initial load. It's only when hide_empty_tabs is enabled, but it's a real cost

On what counts as "empty": the fix uses empty($view->result) after preExecute + execute. That collapses three cases into one: no rows returned, failed argument validation, and access denied with no result. Probably fine for most uses, but per my comment #18 there might be times you'd want a denied or argument-restricted view to keep rendering its "no results" handler text instead of hiding the tab entirely. Worth a follow-up issue with a per-tab toggle I think, separate from this fix.

joelpittet made their first commit to this issue’s fork.

joelpittet’s picture

@loze thanks again for the fix and for adding the test coverage.

I kept your fix, but cleaned up the shape around it a bit:

  • flattened the hide-empty condition into helper methods (too many indents/nesting)
  • added a comment explaining the AJAX Views behavior
  • updated the regression test to be more integration-like by using real Views data(was debating JS functional... one day).

The test now protects both sides of the behaviour: empty AJAX Views tabs are hidden, while populated ones are not.

joelpittet’s picture

Ok for the Views tab is working great with and without AJAX on manaul testing. One thing I tested along side is for a block, specifically a Views block with block_hide_empty enabled. I think the scope needs to include that as well and with a test. It's a different TabType but rendering the same thing. Also I want to move the logic to the TabTypeInterface.

joelpittet’s picture

Status: Needs review » Fixed

Credit to @hockey2112 for reporting and clarifying the Views block use case, @anaconda777 for the AJAX reproduction, @Foxy-vikvik for the early patches, @loze for the 4.0.x fix and test coverage, and @smustgrave for review and test-coverage guidance.

Thank you all! The merge train has left the station 🚂

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • joelpittet committed a938a9fc on 4.0.x authored by loze
    fix: #3238148 Tabs still displayed even when empty
    
    By: foxy-vikvik
    By:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.