Problem/Motivation

When creating a form via form API, ajax API can be used to upate partial form parts using #ajax command. Date element #type does not support that.

Ex.:

$form['date'] = [
  '#type' => 'date',
  '#default_value' => date('Y-m-d'),
  '#ajax' => [
    'callback' => '::dateCallback',
    'wrapper' => 'table-wrapper',
  ],
];

Reproduction scenario

In order to easily test (as a human) that the patch work. Here is a testing module.
Steps:

  1. Install given module
  2. Move to move to /ajax_date page : when you change the date (via keyboard, or via picker), nothing special happens. (useless to submit the form, I did not implement submit method
  3. Apply the given patch
  4. Clean cache and make sure the /ajax_date page is not served from cache.
  5. Now change the date : ajax throbber appears and a line is added beneath the date field: 'Selected date: xx'

Proposed resolution

Allow support of #ajax for Date render element.

API changes

Date FAPI element will now support #ajax.
No break is forcasted for other elements, such as date without #ajax.

Comments

Dom. created an issue. See original summary.

dom.’s picture

Here is a patch attached. The syntax given in issue description is now allowed, and the testing module given refreshes the page via AJAX.

dom.’s picture

Status: Active » Needs review

damn.. forgot "need review" !

dom.’s picture

Issue summary: View changes
anavarre’s picture

Version: 8.2.x-dev » 8.3.x-dev
Category: Bug report » Task
Status: Needs review » Needs work
Issue tags: +date, +ajax callback, +Ajax

Tested against 8.3.x and couldn't get the date selection message to show up via AJAX.

dom.’s picture

Version: 8.3.x-dev » 8.2.x-dev
Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new10.09 KB

Also tested on 8.3.x and confirmed working there too.
Still I would suggest to add this on 8.2.x since it is a simple patch, but a nice to have feature for #ajax and form API consistancy.

Also updated the issue summary to add reproduction steps: @anavarre: did you clear cache after applying patch ? I guess the form rendering get cached.

dom.’s picture

Issue tags: +Novice
anavarre’s picture

Issue summary: View changes

Not sure what happened. Reinstalled 8.3.x, reinstalled the module and applied the patch and now it's working well.

To get this to 8.2.x I think you'll need to get a beta target from a release manager.

dawehner’s picture

Note: This could still land in 8.2.1 for example

dom.’s picture

Add a test-only patch (should fail) and a patch combining the test only and previous patch.
The test defines a date field on a form and test that the callback runs on change.

The last submitted patch, 10: allow_ajax_on_date_element--2781103-10.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 10: allow_ajax_on_date_element--2781103-10--test-only.patch, failed testing.

dom.’s picture

Status: Needs work » Needs review
StatusFileSize
new5.37 KB
new215 bytes

Update test to fix error.

Status: Needs review » Needs work

The last submitted patch, 13: allow_ajax_on_date_element--2781103-13.patch, failed testing.

dom.’s picture

Status: Needs work » Needs review

reroll

dom.’s picture

dom.’s picture

Category: Task » Bug report
Priority: Normal » Major
StatusFileSize
new405.97 KB

Change the issue to Bug since using #ajax on this FAPI element is an announced feature.
Raise this bug to Major because :

  • Block contributed projects with no workaround.
  • Cause a significant admin- or developer-facing bug with no workaround.

Here is a feature example of what cannot be done without this AJAX enabled date field:

Without this issue fixed, you cannot ajax refresh the table when date changes.

dom.’s picture

Component: ajax system » forms system

Change to forms system, since this is more a FAPI then AJAX issue itself.

dawehner’s picture

Its sooooo great to see javascript tests written by people!

  1. +++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
    --- /dev/null
    +++ b/core/modules/system/src/Tests/Ajax/AjaxCallbackTest.php
    
    +++ b/core/modules/system/src/Tests/Ajax/AjaxCallbackTest.php
    @@ -0,0 +1,34 @@
    +/**
    + * Tests an AJAX form elements.
    + *
    + * @group Ajax
    + */
    +class AjaxCallbackTest extends JavascriptTestBase {
    +
    

    The tests should live in core/tests/Drupal/FunctionalJavascriptTests/Ajax to be picked up by the testbot

  2. +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php
    @@ -0,0 +1,48 @@
    +    $object = new Callbacks();
    ...
    +        'callback' => array($object, 'dateCallback'),
    

    Small suggestion: use a maybe slightly better variable name like $callback_object or so

dawehner’s picture

Status: Needs review » Needs work

To be fair it is a bit of a blocker, when we write tests and they aren't actually executed :)

dom.’s picture

Status: Needs work » Needs review
StatusFileSize
new2.78 KB
new5.43 KB

Update test as per @dawehner comments:
- move test to new location
- changed variable name

mpdonadio’s picture

Issue summary: View changes
StatusFileSize
new68.15 KB

The tests should live in core/tests/Drupal/FunctionalJavascriptTests/Ajax to be picked up by the testbot

I was looking at this and thinking the same thing, but oddly enough it is showing up in the logs as being run:

Status: Needs review » Needs work

The last submitted patch, 21: allow_ajax_on_date_element--2781103-20.patch, failed testing.

dom.’s picture

Status: Needs work » Needs review

I just moved the test on #21, nothing else. What means the error "FATAL Drupal\FunctionalJavascriptTests\Ajax\AjaxCallbackTest: test runner returned a non-zero error code (255)." ?
I can't reproduce locally this...

dom.’s picture

Same patch as per #21 just for reroll.

Status: Needs review » Needs work

The last submitted patch, 25: allow_ajax_on_date_element--2781103-25.patch, failed testing.

dom.’s picture

Status: Needs work » Needs review
StatusFileSize
new5.44 KB

OK... I did forgot to change the namespace after changing the test directory... Don't laugh at me... please.. !

Should be better this time.

Status: Needs review » Needs work

The last submitted patch, 27: allow_ajax_on_date_element--2781103-27.patch, failed testing.

dom.’s picture

Status: Needs work » Needs review
lendude’s picture

Status: Needs review » Needs work
Issue tags: +JavaScriptTest

Nice, more javascript tests!

Bit of nitpicking:

  1. +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php
    @@ -0,0 +1,48 @@
    +    // of #2781103: Date FAPI element type do not allow AJAX via #ajax API
    

    I think we use full URLs for this, not just issue numbers.

  2. +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php
    @@ -0,0 +1,48 @@
    +      '#default_value' => date('Y-m-d'),
    

    Wouldn't it make more sense to not have a date by default? Since that is what the message says.

  3. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbackTest.php
    @@ -0,0 +1,34 @@
    +use Drupal\simpletest\ContentTypeCreationTrait;
    +use Drupal\simpletest\NodeCreationTrait;
    

    Unused Use statements

  4. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbackTest.php
    @@ -0,0 +1,34 @@
    + * Tests an AJAX form elements.
    

    Tests AJAX form elements or Tests an AJAX form element, one of the two

dom.’s picture

Status: Needs work » Needs review
StatusFileSize
new5.62 KB

@Lendude: thansk a lot for review !
1. oh.. okay ! Hopefully the change is correct now
2. totally makes sense
3. bad IDE: you should have told me ! bad IDE...
4. indeed, and because of this, to make sense with the test form of (1), I also added the @todo here to make it match.

New patch attached with corrections.

mpdonadio’s picture

Status: Needs review » Needs work

Did a quick look at this; don't have time to manually test this.

  1. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbackTest.php
    @@ -0,0 +1,36 @@
    +  public function testAjaxCallbacks() {
    

    For the long term, I think calling this testDateCallbacks() would be better in the long term so that additional elements can have their own test methods in that class (instead of lumping them all here). Also would adjust the docblock on the method accordingly.

  2. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbackTest.php
    @@ -0,0 +1,36 @@
    +    // @todo: add all FAPI elements to test all AJAX callbacks as a follow-up
    +    // of https://www.drupal.org/node/2781103: Date FAPI elements do not allow
    +    // AJAX via #ajax API.
    +    // @see AjaxFormsTestAjaxElementsForm
    +  }
    

    Nobody is around on IRC right now to verify, I don't think we can commit a patch with a @todo w/o a reference to the followup issue that takes care of the todo. Also elsewhere in the patch.

  3. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbackTest.php
    @@ -0,0 +1,36 @@
    +    $this->drupalGet('ajax_forms_test_ajax_element_form');
    +    $this->assertSession()->responseContains('No date yet selected');
    +    $this->getSession()->getPage()->fillField('edit-date', date('Y-m-d'));
    +    $this->assertSession()->assertWaitOnAjaxRequest();
    +    $this->assertSession()->responseNotContains('No date yet selected');
    

    Two things here. Calling date() is unnecessary; a hardcoded value should be used to make this predictable. Also, negative assertions should be followed by positive ones. So, that responseNotContains() should be followed by asserting that the response contains something expected.

    Setting NW mainly for this bit.

dom.’s picture

Status: Needs work » Needs review
StatusFileSize
new5.49 KB
new2.17 KB

@mpdonadio: Here is a new patch following your review. Here are some comments regarding it:
1- OK. But I rather called the method testDateAjaxCallback(). Also consequently, I changed class name (thus file name) to: AjaxCallbacksTest with an s. Also changed it's docblock thus to
* Tests AJAX callbacks on FAPI elements.
Method docblock changed to :
* Tests if ajax callback works on date element.
2- Remove mention of follow-up. Just added a simple todo. After all, that's all what's needed !
3- Remove the date() as suggested and hardcoded an arbitrary date. Also added a positive responseContains() to double check the correct filled date has been added.

NOTE: also changed mention of AJAX to Ajax for consistency.

dom.’s picture

Up for review

dom.’s picture

Update Issue tags

dom.’s picture

Version: 8.2.x-dev » 8.3.x-dev
StatusFileSize
new5.49 KB

Up version, try re-upload #33 to see if applying to 8.3.x. No changes.

xjm’s picture

Version: 8.3.x-dev » 8.2.x-dev

Note that you can add tests against a particular branch using the "Test with" dropdown when you upload a file or the "Add test" link under the patch. Thanks!

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

martijn houtman’s picture

Note: this seems to work for field type 'date', but not yet for type 'datetime'.

dom.’s picture

Issue tags: +DevDaysSeville

Can we focus on reviewing patch here for 'date' and work on datetime in the appropriate issue ?
#2783615: Datetime FAPI element type do not allow AJAX via #ajax API

tanmayk’s picture

Patch in #36 worked for me. +1 for RTBC.

Status: Needs review » Needs work

The last submitted patch, 36: allow_ajax_on_date_element--2781103-36.patch, failed testing.

mpdonadio’s picture

Component: forms system » ajax system
Issue tags: +Needs reroll

#36 doesn't apply, so it needs to be rerolled.

  1. +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php
    @@ -0,0 +1,47 @@
    +      '#ajax' => array(
    +        'callback' => array($callback_object, 'dateCallback'),
    +      ),
    

    Nits, needs to be updated to [] syntax.

  2. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php
    @@ -0,0 +1,35 @@
    +    // @todo: add tests for all FAPI elements Ajax callbacks.
    +    // @see: AjaxFormsTestAjaxElementsForm
    

    We can remove these; we try to avoid @todo w/o f/up issues to point to.

I think this looks OK, but don't think I know enough about the Ajax subsystem to RTBC this once rerolled.

gaurav.kapoor’s picture

Assigned: Unassigned » gaurav.kapoor
gaurav.kapoor’s picture

Assigned: gaurav.kapoor » Unassigned
Status: Needs work » Needs review
StatusFileSize
new5.3 KB

Reroll and fixed 43.1 and 43.2.

jofitz’s picture

Issue tags: -Needs reroll

Please remember to remove Needs Reroll tag.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

k4v’s picture

Status: Needs review » Reviewed & tested by the community

Works for me!

Also noticed it does not work with datetime, but this should be adressed in https://www.drupal.org/node/2783615. I briefly tried to modify the patch to also work with datetime, but that seems to require more work.

k4v’s picture

The changes to the date logic already are commited to 8.5.x with https://www.drupal.org/node/2783615 now.

All thats left to do here is to add the test for the single date element.

k4v’s picture

I cannot do an interdiff, because the old patch does not apply anymore...

  • catch committed 278c50e on 8.5.x
    Issue #2781103 by Dom., k4v, gaurav.kapoor, mpdonadio, dawehner, Lendude...

catch credited catch.

  • catch committed 55366fa on 8.4.x
    Issue #2781103 by Dom., k4v, gaurav.kapoor, mpdonadio, dawehner, Lendude...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.5.x and cherry-picked to 8.4.x. Thanks!

Status: Fixed » Closed (fixed)

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