Users of the Field as Block module have reported that the block's configuration breaks when used in the Context UI. This seems to be caused by the fact that the form uses an AJAX callback, as shown in #2738765-5: Doesn't work with Context module.

Do you think that this is a problem in Field as Block, or in the Context module? In the first case, I hope you can advice how to implement AJAX inside block forms in a way that supports Context. In the latter, I hope you can add support for AJAX to your module.

CommentFileSizeAuthor
#6 2760125-6.patch1.2 KBjzavrl

Comments

marcvangend created an issue. See original summary.

steveoliver’s picture

Version: 8.x-4.x-dev » 8.x-1.x-dev

Don't know why a 8.x-4.x branch even exists. That's 7.x code. This is a 8.x-1.x issue.

marcvangend’s picture

Sorry, you're right. Indeed it is reported that this problem occurs with the 8.x-1.x-dev of Context.

NormySan’s picture

Ajax is extremely tricky in Drupal especially when you include partial forms in another form. I myself will most likely not have time to look at this so if anybody solves it please submit a pull request on github.

guschilds’s picture

I did encounter this same issue when using the Field as Block module and I do think it is a general bug with Context when a block's blockForm() uses Ajax. I added basic Ajax to a custom block outside of Field as Block and the same thing happens when I use the Ajax on that form.

The Steps to Reproduce are:

  1. Create a custom block with Ajax in its blockForm() method (or use the Field as Block module and one of its blocks)
  2. Create a context and on its "Edit context" page, click "Place block" (after adding the block reaction)
  3. Select the block from Step 1 and on it's configuration form, use whatever activates the Ajax functionality
  4. Click "Add block" to add it to the context

Expected result is for the block to be added to the context. Actual result is that the page reloads with no hint of the block being added.

I did some debugging with Xdebug, but I'm new to D8/OOP and back-end development isn't my specialty so I couldn't quite solve the problem. When using Ajax in the block, it looks like everything is still correct (including the settings chosen after using Ajax) when calling $this->context->save(); within Drupal\context\Reaction\Blocks\Form\BlockFormBase's submitForm(). It seems like the variables/properties with the new block somehow get fumbled in the pre-saving that gets called from there (it has been a few days since I stepped through the code so I forget exactly where that is) and so when it actually gets saved, the new block is lost.

jzavrl’s picture

Status: Active » Needs review
StatusFileSize
new1.2 KB

Have taken a look into this. I was indeed able to reproduce the steps and the issue described.

After some investigation I've found this:
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21Fo...
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21...

The main thing to note here is:

A prominent example is an Ajax-enabled form, in which \Drupal\Core\Render\Element\RenderElement::processAjaxForm() enables form caching for all forms that include an element with the #ajax property.

If I understand correctly here this means the first time context generates the form it has no caching enabled. But after the settings from the block configuration are added and some elements have the #ajax property that fires processAjaxForm() which also enables caching on the form.

So once AJAX fires on the form it gets messed up as the original form was not cache, but the new AJAX returned one is.

If I explicitly enable cache on the form I can reproduce the same issue for all blocks. So I explicitly disabled cache on the form, and now all blocks are added properly. Even the ones that fire AJAX during their configuration.

Attached patch to fix this.

guschilds’s picture

Status: Needs review » Reviewed & tested by the community

Awesome! Your patch worked for me! While it has been a while since I was digging through this code, your explanation makes sense and your solution seems appropriate. Marking this as RTBC.

I am also going to make a note of this in #2738765: Doesn't work with Context module, as this finally allows the Field as Block module to be used in tandem with Context in D8.

  • jzavrl authored b098831 on 8.x-1.x
    Issue #2760125 by jzavrl, guschilds: AJAX callback in blockForm() breaks...
boshtian’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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

kienan’s picture

Hi,

I just ran into this with context 8.x-4.0-beta2+19-dev, which includes the above patch and fieldblock 8.x-2.0-alpha4 and had a similar issue. When the block was saved, the formatter and formatter options selected were not properly saved with it.

Steps:

* activate the media entity in the fieldblock config
* add a media field block to a context
* select a formatter for the field, eg. entity_reference_entity_view and a corresponding entity view mode
* save

When I exported the configuration to yaml, both the formatter_id and formatter_options were empty