I'm trying to embed a view in a page with exposed filters as a block.

The view works fine if I embed with the following code :

print views_embed_view('myview');

But I need to render the filters block in a separate place of the page. The following code renders the block correctly and everything works fine :

$block = block_load('views', '-exp-myview-page'); 
$output = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));       
print $output; 

My problem is : the block is rendered by the first snippet, which is logical since it's supposed to render the whole view, but I need it to disappear since my view will be managed by the second snippet.

My question : what is the better way to render the filters block separately from the views' content ?

Any hint would be welcome.

Comments

Countzero’s picture

I upgraded to ctools-dev and the block is not displayed in the view anymore. Sorry for the bad behaviour.

Now the problem is the page redirect when the form auto-submits itself on change. The view is not AJAX refreshed but redirected to a page result with arguments etc.

I guess is has to do with the way the block is rendered, but didn't find the solution yet.

merlinofchaos’s picture

Status: Active » Fixed

To change the path that the form goes to, you'll need to set $view->override_path -- of course, that means you can't use the rendering method you're using.

Something like this will work, I think: (Untested, just typing this out so might need tweaking):

  $view = views_get_view('viewname');
  $view->override_path = $_GET['q'];
  $view->set_display('page'); // I'm assuming 'page' based on the block name above. You may need to adjust.
  $output = $view->display_handler->view_special_blocks('exp');
  $view->destroy();

$output will be the standard block array with a title and a content, I believe, so you'll need to format that as appropriate.

Countzero’s picture

Thank you.

This code works. Mean : it displays the block as expected, with all the interaction with the view content.

I had to

    if ($view->name == 'myview') {
      unset($view->exposed_widgets);
   }

... in views_pre_render to prevent the form from displaying in the view content part.

Unfortunately, this solution triggers a page reload, which looses a lot of the AJAX benefit. I'm building a very complex page with lots of dynamic parts showing or hiding depending on user interaction, and a page reload implies a context analysis for each state of the page, which is a lot less practical than just changing a few classes with JQuery calls.

The ideal solution would be to have the external block behave exactly as the internal one, but I read elsewhere it's not possible. Can you confirm it's always the case ?

I also thought of a pure JQuery solution, using .detach() method to move the block from the view to somewhere else in the DOM but didn't try it yet. The problem would be to execute the detach on each view load. I'll update this thread if I find a satisfying solution.

Countzero’s picture

Title: Exposed filter and views_embed_view » Ajax Exposed filters in block force page reload
Category: support » feature
Status: Fixed » Active

With all due respect, I reopen this issue and change the title and category to match the real demand.

The goal is to have a clear answer to the following question : is it possible to have an exposed Ajax enabled filter block which behaves exactly like the filters embeded in the view, mean : without page reload ?

I reopen just because I think this is a feature that would be useful to many, beside the urgent need I feel for it myself.

Thanks for your patience.

dawehner’s picture

Countzero’s picture

I agree it's probably related, but the other issue you mention has a tendancy to involve other modules and form_alter stuff which renders it confusing.

Also, the op mentioned a block view while I'm speaking of a page view here.

One thing seems accurate to me in this issue though, that is the confusion created by the fact the filters block needs AJAX while it doesn't behave as what's expected from an AJAX feature. But that's minor stuff compared to the main purpose of this thread.

As I badly need this feature, I'll continue investigating in the next few days.

Countzero’s picture

I found a workaround to solve my use case.

Using the ajaxComplete event, I can handle the showing or hiding of the embeded form.

So, if anyone is interested, you can leave the filters form exposed inside the view (without block), and then make it disappear with :

$('#views-exposed-form-yourform-default').ajaxComplete(function() {
    $('.view-yourview .view-filters').hide();
 });

So the form will autohide when the view is refreshed. Not Ideal, but it does the job.

It doesn't solve the issue of the block not behaving as expected, but it does what I needed this time, and hopefuly will help readers with resembling use cases.

siva.thanush’s picture

Me too have the same problem.
Its working in one instance but not in another.
I dont want to handle the showing or hiding of form, I just want the content of the view to show in the same block itself instead of reloading the pages.
do the above code will solve this issue.
Do i need to put it in my module.
or in the export/import view?

phponwebsites’s picture

Issue summary: View changes

When i click apply button in exposed filters, it refresh the page 2 times. It has occurred only in back end. I can't see this in front end. When i tested using console.log() message in my js file, it printed 2 times for every click. How to solve this?