Problem/Motivation

When a View, meant to be sorted in-place, has Views render-caching enabled, sorts are never saved.

Steps to reproduce:

  1. Create a View of fields where sorting is handled by Draggable Views,
  2. Add the Draggable Views sorting handler field to the View, so that it's possible to sort the view in-place,
  3. Enable Views render caching (time-based) under the advanced pane,
  4. Attempt to sort the View in-place.

Not only will the View not change (which is an existing UX issue related to Views caching and draggable views in general), but even if you flush all caches after attempting to sort, your sort order will not be reflected.

If you only enable query caching, the View sort will be reflected, but only after a cache clear (separate issue).

Proposed resolution

At the heart of the issue is the fact that form processing only happens when a form is attempted to be built (and there happens to be form data for processing). When Views render cache is used, the form doesn't have to be re-built (its contents/markup have already been built, rendered, and cached, so there's no need). Because the form is never re-built, it's never processed, and thus, the submitted sort order is never saved.

Workarounds

  • If you must cache your rendered View, instead of using in-place sorting, just create a separate, un-cached View for sorting purposes
  • If Views render caching is less of a priority for you compared to admin UX, then just disable Views render caching for that View

Possible resolutions

  • Reasonable mitigation: Provide some sort of warning to end-users when in-place sorting and Views render cache are used on the same page. Even better, detect when this is attempted and just prevent the user from ever saving this configuration set.
  • Non-ideal solution: Perhaps in a hook_init(), listen for all POST requests and detect when a draggable views sort can be (and has been) submitted. If so, process the form right then and there.
  • Give up: Just document (on the project page and in the README) that Views render cache + in-place sorting is not supported and provide the workarounds described above.

Comments

iamEAP’s picture

Title: In-place sorts not save when Views render cache is used » In-place sorting will not save sort order when Views render cache is used

Issue title grammar fail...

iamEAP’s picture

Issue summary: View changes

Updating the issue summary after further investigation...

nicxvan’s picture

I am getting the same behavior, shutting off caching didn't help.

I'm seeing a lot of issues in the queue relating to this module not working. I feel something should be on the module page.

nicxvan’s picture

Priority: Normal » Critical

Creating a separate view for the sorting didn't work either. I tried both a separate display and a separate view.

Changing priority since I see many related issues that don't seem to be getting attention.

betoscopio’s picture

I have had this same problem. Seems to work well if the view have simple filter criteria. If a have a more complex view, using relationships of any kind the results could be not what you spect.
When you define the "sort criteria" for your view, you must not select any relationship even if you used a relationship as a filter criteria for your view. Changing this, my draggable view started to work again.

dsquaredb’s picture

Same issue on my site with sort order not saving. My view has a relationship but there are no filters using that relationship. However, the site is a view of content that anonymous and authenticated users have flagged (Flag module along with Session API for anonymous flagging), so the Draggableviews: Flags field has the flag relationship. If I use the Draggableviews: Content field, I cannot drag the view, only sort by weight, and still cannot save the order.

dsquaredb’s picture

Updating to 7.x-2.0+56-dev saves the draggable sorting on my site. Others have reported in this issue that it also works for dragging but not for sorting by weight.

istryker’s picture

Priority: Critical » Normal

Stop adding comment when it has nothing to do with the topic (CACHING), it is related to something else.

Moving back to normal priority as there are workarounds.

istryker’s picture

I create a test view of this and confirm that the display is not working

For the Native handler it is saving the order to the database, however it is not display the results.

istryker’s picture

Status: Active » Needs review

Found this in views_bulk_operations_form_alter()

  // Cache the built form to prevent it from being rebuilt prior to validation
  // and submission, which could lead to data being processed incorrectly,
  // because the views rows (and thus, the form elements as well) have changed
  // in the meantime. Matching views issue: http://drupal.org/node/1473276.
  $form_state['cache'] = TRUE;

VBO does a lot of similar things that draggabeviews does, and caching is one of them

istryker’s picture

Status: Needs review » Needs work

Nevermind #10 does not work.

annya’s picture

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

This patch fixes the following:
1.

If you only enable query caching, the View sort will be reflected, but only after a cache clear

Clear views cache after each submit of draggable view. We clear cache only for current view.
2.

Reasonable mitigation: Provide some sort of warning to end-users when in-place sorting and Views render cache are used on the same page. Even better, detect when this is attempted and just prevent the user from ever saving this configuration set.

Validation for draggableviews_handler_field_draggable has been added.

Please test and review this patch.

istryker’s picture

Status: Needs review » Needs work

Before testing.
#1 - We should not prevent the view from being save, rather, displays a warning. The goal is to warn the user that the views display cache will be cleared on each save.

Testing #12 patch - View with caching enabled:
1. Clear cache
2. Go to view and change order works.
3. Repeat #2 works until you refresh the page. Once you refresh the page, it does not fire draggableviews_form_alter() until cache expires and/or cache is cleared. This is where we add the #submit = 'draggableviews_views_submit', which saves the order and, with this patch, clears the cache for the view.

istryker’s picture

I was looking at other modules on how they handle this, and so far, no one has an answer.

Fiverstar - #2297231: Fivestar Not Working for Anonymous Users with Cache Enabled
VBO - #1307360: Node delete action doesn't fire if views cache is enabled.

So maybe we do need to throw an error message.

annya’s picture

3. Repeat #2 works until you refresh the page. Once you refresh the page, it does not fire draggableviews_form_alter() until cache expires and/or cache is cleared. This is where we add the #submit = 'draggableviews_views_submit', which saves the order and, with this patch, clears the cache for the view.

Can't reproduce it. Are you sure you have disabled render cache for view? Because this patch doesn't fix problem with views render cahce, it fix problem with query view cache.

istryker’s picture

How I turned on caching: In your view display -> other -> caching -> time based.

annya’s picture

StatusFileSize
new31.22 KB

Yeah, but Render output should be set as Never cache. See screenshot

istryker’s picture

See your screenshot. That makes sense now. The results are cache but the HTML/form is not. Should work.

annya’s picture

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

With this patch we don't prevent views save and only show a warning message about incompatibility of Draggable Views and view cache render.

istryker’s picture

@ Comment #17 - I see what you mean now. I had both Query and Render set to X time. I double-checked and if you have query set to X, it still works

  • Re-roll patch against latest dev.
  • Added back the validation from #12.
  • Instead of a drupal_set_message() I added HTML markup to the views_ui_edit_form. With #19 it used drupal_set_message which would display message on the next page load. This way the message shows up on when you edit the caching option render value.

Possible improvements

  • throw form error with form_set_error(). This would add 'error' class to field and cache_option element. By default it would make their links red.
  • form validation for cache_options and field draggablviews. I tried the code below with no sucess
    /**
     * Implements hook_form_FORM_ID_alter().
     */
    function draggableviews_form_views_ui_edit_display_form_alter(&$form, &$form_state, $form_id) {
      if (isset($form_state['section']) && $form_state['section'] === 'cache_options') {
        $form['#validate'][] = 'draggableviews_cache_render_check';
      }
    }
    
    function draggableviews_cache_render_check(&$form, &$form_state, $form_id) {
      dsm('test');
      $test = $form;
    }
    
istryker’s picture

StatusFileSize
new2.86 KB

Forgot the patch to #20.

hobie17’s picture

Draggable views does not work when you have a contextual filter. I had one: content type and it did not work. Removing the contextual filter fixed it.