Summary

When using 'Exposed form in block' together with 'Ajax enabled' - the ajax no longer works.

Steps to recreate

Create a new 'Page' view that displays node titles.
Expose the 'Published' field as a filter.
Ensure 'Ajax' is enabled on the View
Test - notice that changing the filter updates the view using ajax: correct

Edit the View and enable 'Exposed form in block'
Place the block on the View page
Test - notice that changing the filter does not update the view using ajax any more

Issue introduced

The issue was introduced in commit: http://cgit.drupalcode.org/views/commit/?id=710a536

This changes the behaviour of the ajax_view.js file and no longer correctly applies ajax to exposed forms in blocks

Reverting this change fixes the issue (but there is probably a better approach!).

Comments

jkingsnorth’s picture

Issue summary: View changes
rocxa’s picture

Component: Miscellaneous » Code

+1

dawehner’s picture

It would be great to find an actual solution ... this code was committed to solve a real existing issue, so just reverting is not the best solution.
Do you mind having a look why it doesn't work? Thank you!

jkingsnorth’s picture

Hi dawehner. There was no issue# against the commit, so I'm not sure what the problem it solves is. Without knowing that I might be putting together a fix that re-introduces the same problem again.

I'll give it a shot anyway, but do you know what the original issue was?

dawehner’s picture

I don't really know, honestly :(

Chmit’s picture

You should replace

this.$view.children('.view-filters').children('form');

by

this.$exposed_form = this.$view.find('.view-filters').children('form');

In custom views, view-filters class can be not directly a child

jkingsnorth’s picture

Status: Active » Needs work

Hi Chmit, the fix you propose does not work for us. Ajax still does not seem to work on Views with their exposed form in a block.

This is because the class '.view-filters' is not present.

Chmit’s picture

Ok, I forgot I wrote these class in tpl.php..... We should replace .view-filters by a class always displayed with a selector always used.

jkingsnorth’s picture

No worries, thanks for the idea though Chmit.

Tyler the Creator’s picture

I really don't think that there was an issue with how the exposed filters were being targeted before the update.

The only problem with how it was before:
this.$exposed_form = $('form#views-exposed-form-'+ settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-'));

was probably the worry that the form id was going to change at some point to not match the view_name + view_display_id approach.

Currently looking into a way to maybe pass the view's dom_id to the exposed filter form as a class... or some other solution.

It's a little silly that this update wasn't even fully tested though. It seems like the committer just decided to change it on a whim.

Tyler the Creator’s picture

Status: Needs work » Needs review
StatusFileSize
new880 bytes

Here's a patch to add a dom_id class to the exposed form and target that class instead of the View's child ".view-filters"

Status: Needs review » Needs work

Status: Needs work » Needs review

Status: Needs review » Needs work
Tyler the Creator’s picture

Status: Needs work » Needs review
StatusFileSize
new1.1 KB

Re-diffed the patch, hopefully this one tests well.

Status: Needs review » Needs work
Tyler the Creator’s picture

I guess Views 7.x-3.x is failing testing? I have no idea what the problem is... sorry :\

Status: Needs work » Needs review

Status: Needs review » Needs work
clfer’s picture

Hi Tyler
I join you on your bug diagnostic and resolution.

Here should be your corrected patch (it seems that there was some commit since you made it, that's why it fails testing)

clfer’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
clfer’s picture

Ok mine is incomplete and also fail testing so i'll just hide it
Sorry for the intervention

Tyler the Creator’s picture

Version: 7.x-3.10 » 7.x-3.x-dev

Status: Needs work » Needs review
jkingsnorth’s picture

Hi Tyler, you might need to re-roll the patch and re-add it to the issue, otherwise the latest (incomplete) patch will continue to get tested?

Tyler the Creator’s picture

My bad, sorry for the spam.

I actually just found this test page: https://qa.drupal.org/pifr/test/27332 so it does seem like 7.x-3.x is the thing that is broken since the last commit on the 13th and my patch should be fine (since it only adds/changes 2 lines). Anyone willing to try it out even though the automated tester is having a rough time?

jkingsnorth’s picture

Will do tomorrow Tyler, sorry not to have done sooner.

drikc’s picture

Are we going to keep the "strict" select as follow:
this.$exposed_form = this.$view.children('.view-filters').children('form');

This mean that the above wont be able to select if one want to alter the exposed form by adding a wrapper!...

Could we soften this selector with something like:
this.$exposed_form = this.$view.find('.view-filters form');

jkingsnorth’s picture

Hi drikc, this was suggested above. Unfortunately the class .view-filters is not always present on the form, as mentioned in #8.

However the patch in #16 works for me, and seems like a good approach? Could you re-submit the patch Tyler, to bring it to the latest spot in the queue?

One more review for RTBC?

drikc’s picture

Yes, just tried the patch in #16 and works for me also.

jkingsnorth’s picture

Status: Needs review » Reviewed & tested by the community

Marking #16 as RTBC then

chase.’s picture

Status: Reviewed & tested by the community » Needs review

When the exposed form (block) is shown on a site without the view:

Notice: Undefined property: view::$dom_id in views_exposed_form()
(line 2035 of modules/views/views.module).

This doesn't exactly have to do with AJAX, but was introduced with the patch from #16

Tyler the Creator’s picture

Ahhh, in patch #12 I had the dom_id code inside the if statement checking to see if ajax is being used. For some reason in #16 I moved it out. I guess the form isn't getting the view's dom_id if ajax isn't being used.

This new patch adds that code back in to the if statement.

chase.’s picture

Working like before, just without the notice for me!

kuangshi.yan’s picture

I had the same issue after the 7.x-3.10 update, the patch #35 works for me!

jkingsnorth’s picture

Status: Needs review » Reviewed & tested by the community

Patch applies OK on simplytest.me, and still seems to work =] Couldn't detect any php notices. RTBC.

justindodge’s picture

#35 worked well for me, no php notices - looks good.

thulenb’s picture

#35 works for me, too.

nicholasthompson’s picture

#35 works for me too

erichomanchuk’s picture

I am still having issues. I'm using panels to display a panel view with an exposed form block and views is doing some rather strange behaviours.

Basically Im filter articles by a taxonomy using ajax. I add the panel view to the page and the exposed filters to the page. If I have the exposed filters before the panel view the ajax update does not work If I move the exposed filters after the panel view then ajax works. debugging the view in views_exposed_form shows me it runs twice. When the exposed filters are after the panel view there is a dom_id in the first view object when the filters are before the view there is no dom_id in either $view object so no class is added.

Anyone else experiencing issues with views update 7.10 and panels.

Debugging the views_exposed_form $view object in 7.8 and it is the same if the filters are before the panel view there is no dom_id in the either of the $view objects so adding it as a class is not working.

jkingsnorth’s picture

Tyler the Creator’s picture

Status: Reviewed & tested by the community » Needs work

Changing this to Needs work until we figure out a solution that works with Panels. With the dom_id solution, I thought that the exposed form would have the entire view object that it belonged to, but that's only the case when the view is pre-rendered before the form... not after.

vaibhav571’s picture

The issue can be fixed by this patch

Tyler the Creator’s picture

While reverting the commit that broke this in the first place in #46 does fix the problem, it was changed to allow for a "safer way of finding the exposed form". #46 is a good stop gap but I still think that there could be a better way to fix the entire problem.

vaibhav571’s picture

Using other solutions may fix the problem but they will still fail if using the filters inside quick tabs. Till now this the only that I could find to get the things work.

vaibhav571’s picture

Status: Needs work » Needs review
jkingsnorth’s picture

Status: Needs review » Needs work

As dawehner also said near the top then, just reverting the commit probably isn't the best solution.

jkingsnorth’s picture

Marked #2449531: Exposed Filter Ajax broken as a duplicate - but there is a possible patch in that thread up for review

FiLeVeR10’s picture

Status: Needs work » Needs review
StatusFileSize
new665 bytes

Here's the patch from #2449531 . I did not write this code, @ben.bunk posted it on that issue, I just made it a patch to post here to hopefully move along this being added into views so I can get my exposed filters with ajax back.

@John.K said there that the patch should go here.

jkingsnorth’s picture

Status: Needs review » Needs work

I'm not sure the code in #52 is the right approach, since it still re-implements the code that was originally removed. Falling back to this code is probably just as undesirable as using it in the first place.

So I'm going to set this as needs work again.
#35 looks promising but does not work with Panels (see #42).

This issue also has implications for custom templates as described in #2320661: Make js selector for finding exposed forms for AJAX more forgiving.

FiLeVeR10’s picture

@John.K is the problem with panels a views vs. panels issue, or a dom loading order issue for exposed filters in general; where if the form loads before the view is in the dom it's unable to attach?

Tyler the Creator’s picture

@FiLeVeR10 The problem is a dom loading order issue. The exposed filters form loads and the view does not go through its pre_execute function (where dom_id is set) until the view itself is loaded. Due to that issue I'm not sure that my patch at #35 is the correct direction to take in fixing this problem... because moving where the dom_id is set or pre_executing the view on the exposed filters form would not be ideal.

I'd like to get this fixed asap, but I haven't had any more time to look into it.

FiLeVeR10’s picture

@tyler ok, I'll check it out tonight and see if I can put together something to work with that will cover both bases.

ParisLiakos’s picture

#52 works for me, using it w panels..
maybe it should be commited as intermediate step, since, this is a regression?

mustanggb’s picture

FiLeVeR10’s picture

I did recreate the issue and look into a few ways around it.

I'm trying to find a good way to make it run after both elements are in the dom.

I'll try to get a working patch in soon.

plach’s picture

Status: Needs work » Needs review
StatusFileSize
new1.29 KB

What about this? It preserves the "intent" of the current code but only as a fallback, since the .view-filters class may no longer be there if markup was altered. By default it uses a plain class to identify the exposed form. I tried to figure out why the class is commented out in HEAD, but git blame does not help.

FiLeVeR10’s picture

I feel like using .find() is the wrong approach altogether, since it only checks inside of that object for the element.

Isn't the whole point of the id on the form to tie it to the view, why isn't it being used anymore?

plach’s picture

I don't know why the id is no longer used, but using a class this way is the closest thing I can think of.

mustanggb’s picture

Perhaps exposed filters need their own dom_id

dawehner’s picture

Asked merlinofchaos on IRC

zmove’s picture

#52 works for me
#60 not

k.skarlatos’s picture

Status: Needs review » Reviewed & tested by the community

#52 works for me, RTBC

mustanggb’s picture

Status: Reviewed & tested by the community » Needs work

As per #53

merlinofchaos’s picture

I think there was a problem with views within views or multiple of the same view on the page that I was running into when using a modified version of the entity reference module, and this commit fixed that. If that helps.

jkingsnorth’s picture

views within views or multiple of the same view on the page that I was running into when using a modified version of the entity reference module

This sounds like more of an edge case than using an exposed form in a block with AJAX. But it would still be good to find an approach that fixed all cases of this, rather than just reverting to the original code.

FiLeVeR10’s picture

Well .find()'s never going to work if the exposed filters are not in the main view container, so reverting it to be selected by id instead seems like a good option. Is there a better way to target the exposed form when it's outside of the view container?

For the DOM loading issue, does it only affect panels or does it affect blocks with exposed filters being loading after a view in the dom as well.

If it's just panels, wouldn't that make it a different issue?

Tyler the Creator’s picture

It affects every instance where the external exposed filters form is loaded before the view display I believe.

Renee S’s picture

#35 worked for me, with Panels. #52 did not.

nedjo’s picture

.find()'s never going to work if the exposed filters are not in the main view container

Indeed, on my testing, the latest patch fixes AJAX in a block display that includes an exposed filter and on a page display that includes an exposed filter, but when I expose the page display's form in a block, as indicated AJAX isn't applied.

rooby’s picture

There really should be a unique class or ID based on the view name and display that can be directly targeted.
Anything else is really asking for future problems IMO.

recrit’s picture

See #1809958: Views with exposed filter (ajax enabled) inside modal window (ctools) - That fix has been committed and addresses this issue using the form id which is set in views_exposed_form().

thulenb’s picture

Until this bug is fixed what do you guys do in the meanwhile. I can't update Views due to this bug but the status reports keeps telling me "urgent security update" for Views. Is waiting the right way for a non-coder like me?

mustanggb’s picture

@ThuleNB
I'm running the latest stable version (3.11 at the time of writing), but have just manually reverted the commit that "broke things".

i.e. Changed this one line back to what it was before: http://cgit.drupalcode.org/views/commit/?id=710a5368c0f71100aaa51de01695...

As per #68 this wasn't a security fix, but rather a bug fix for a rare occurrence, so if you're not using that use-case then everything should be fine.

rooby’s picture

I'm using the patch from #52.

For my site it fixes the problem and doesn't cause any issues.

thulenb’s picture

ok thanks, that helps :-)

nedjo’s picture

Status: Needs work » Closed (duplicate)

As noted in #75, this issue was fixed in #1809958: Views with exposed filter (ajax enabled) inside modal window (ctools) by reverting the commit that introduced the bug (while addressing a different bug).

Closing as a duplicate.

For those wanting this fix before the next stable release of Views, one way is to apply the patch that was applied. See for example the instructions for manually applying a patch.

alauddin’s picture

Can confirm patch from #52 works ..but is no longer needed.

The current 7.x-3.11+14-dev has another patch committed that solves this issue.
https://www.drupal.org/node/1809958#comment-9905847

W.M.’s picture

Reverting to the original code solved the issue for me.

jelo’s picture

With Views 7.x-3.13 the exposed forms work for me again, with and without panels. However, it only works as long as the exposed form is only included once in the page.

There are a number of issues with views (I, II, III) where users try to separate these options: sort, search and filter to improve the user experience. The only workarounds so far have been to suggest re-using the same exposed form multiple times on the page and hiding elements with CSS in each of those forms to generate one form dedicated for search, one for filters, one for sorting. Then each form can be placed independently in the UI.

With panels it is very easy to place the exposed form multiple times on the same page. As soon as the same form is added a second time, AJAX stops working though, I assume because the form ID is not unique any more. Panels allows setting CSS properties such as element class and ID, however, that only affects the wrapper of the form, but not the form ID itself. If I manually adjust the form IDs in the browser, AJAX works again, but then the forms don't sync any more, i.e. adjusting an option in one form is not reflected in the same secondary form.

Is there any possibility to have the best of both worlds, i.e. the ability to expose the form, place it multiple times on a page and have AJAX working?

i.bajrai’s picture

Applying this patch solved the issue for me.

http://cgit.drupalcode.org/views/commit/?id=96a54e0