I am not sure of the reason why the RRule form is build completely in JS. I had a small alteration for a client to remove the "Never" option and to do this I had to alter the library and copy the date_recur_rrule.widget.js file and remove the 3 lines.

If this was a standard Drupal form then I could just unset the never option on the form array and it is all done.

Basically creating a new form element type would be the best way to create this form. This way if other module want the rrule element it is very easy to change.

CommentFileSizeAuthor
#31 interdiff-date_recur-2866563-27-30.txt37.63 KBchOP
#31 date_recur-rrule_field_drupal_form-2866563-30.patch116.98 KBchOP
#30 interdiff-date_recur-2866563-27-30.txt37.63 KBchOP
#30 date_recur-rrule_field_drupal_form-2866563-30.patch116.98 KBchOP
#27 date_recur-make-rrule-jsfield-drupal-form-2866563-27.patch113.68 KBrealityloop
#21 date_recur-make-rrule-jsfield-drupal-form-2866563-21.patch113.28 KBrealityloop
#20 interdiff-2866563-19-20.txt846.52 KBgordon
#20 2866563-20.patch114.84 KBgordon
#19 date_recur-make-rrule-jsfield-drupal-form-2866563-19.patch942.07 KBrealityloop
#18 date_recur-make-rrule-jsfield-drupal-form-2866563-18.patch942.07 KBrealityloop
#16 date_recur-make-rrule-jsfield-drupal-form-2866563-16.patch942.5 KBrealityloop
#13 date_recur-make-rrule-jsfield-drupal-form-2866563-13.patch941.7 KBrealityloop
#12 date_recur-make-rrule-jsfield-drupal-form-2866563-12.patch941.7 KBrealityloop
#11 date_recur-make-rrule-jsfield-drupal-form-2866563-11.patch941.7 KBrealityloop
#10 interdiff-2866563-7-9.txt421 bytesgordon
#9 date_recur-make-rrule-jsfield-drupal-form-2866563-10.patch941.7 KBrealityloop
date_recur-make-rrule-jsfield-drupal-form-2866563-9.patch943.58 KBrealityloop
#8 turn-RRule-field-into-a-drupal-form-2866563-8.patch44.15 KBrealityloop
#7 0001-Issue-2866563-by-gordon-Turn-the-RRule-field-into-a-.patch943.68 KBgordon
#6 0001-Issue-2866563-by-gordon-Turn-the-RRule-field-into-a-.patch943.35 KBgordon
#5 0001-Issue-2866563-by-gordon-Turn-the-RRule-field-into-a-.patch942.89 KBgordon
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gordon created an issue. See original summary.

Frando’s picture

The reason for having the widget in JS is that the form is quite interactive, and that I could reuse existing code for a jQuery-based RRULE widget (see rrule.widget.js).

Of course you're right that a new Drupal form element would be best. I don't know if I have time soon to get to it, so feel free to work on this. I wouldn't actually create the individual form elements in Drupal (due to them being highly interconnected in JS, and the JS also includes custom logic to parse out the values by their names, which correspond to the matching properties in rrule.js). Instead, I'd create an element that has all relevant options, which are then passed to JS as settings, and then adapt rrule.widget.js to behave differently (or exclude/include form fields) based on these options.

gordon’s picture

Working on this change now, found that there is a relation to the issue https://www.drupal.org/node/2419131 so #states will work on datetime fields.

gordon’s picture

gordon’s picture

Assigned: Unassigned » gordon
Status: Active » Needs review
FileSize
942.89 KB

Here is a patch which replaces the current javascript form with a Drupal based form. Other than some difficulties from the templates and having to do some fun things it is all working.

There is also some workarounds to allow it to work with the datetime_tweaks module it is all working.

Also there is going to need some work on it as well, but I think all the heavy lifting has been done. Now it should just be some cleaning up and chasing some bugs.

gordon’s picture

Here is a small cleanup of the title of the widget not being repeated twice.

gordon’s picture

Some more changes so that you can set values in the rrule element during hook_form_alter() before the process() has been run.

realityloop’s picture

The UNTIL value doesn't get converted on storage so the conversion to the site timezone when loading the value was causing the value to increment/decrement on edit and save of content using this field depending on your site timezone settings. I've removed this conversion in this updated patch.

realityloop’s picture

Patch missing added files and wouldn't apply, reroll.

gordon’s picture

FileSize
421 bytes

Bugger, I was originally setting the timezone because I was thought I was working with a text date time instead of a DateTime object.

Attached is the interdiff.txt

I also need to add back in the excluded/included datetimes.

realityloop’s picture

Reroll to fix typo in libraries link to moment.min.js (instead of moment-min.js)

realityloop’s picture

Added fix for js issue with monthly reoccuring droppdown that contains checkboxes.

realityloop’s picture

gordon’s picture

Just checking #13 and I can't see any difference between #12 and #13

realityloop’s picture

@gordon looks like Victor sent me the wrong file.. will update tomorrow

realityloop’s picture

update, closes the monthly dropdown when you defocus it.

gordon’s picture

This is a good fix, I just ported over the old and it was a PIA to work with.

However the file assets/date_recur_rrule.js has had it line endings changed to ^M

realityloop’s picture

hopefully this fixes that.

realityloop’s picture

Lets try that one more time.

gordon’s picture

FileSize
114.84 KB
846.52 KB

I have done some more work on this. I cleaned up the js a bit to comply with the Drupal Javascript coding standards.

Also added back in the dependency on the start date so that you are required to enter a start date to enter the RRule. I did run into an issue with this with the datetime and using the Form API #states. I described this in #2419131-58.

I do need to do some more changes to put back in the excluded/included dates as well. which I will start working on next.

realityloop’s picture

Reroll of #20 (wouldn't apply as part of composer.json for me)

@gordon any idea why the patch is drastically smaller than #19?

gordon’s picture

I removed all the versions of moment which were not being used.

thinkV’s picture

Have noticed a few other bugs @gordon, if you select monthly/weekly and choose some days, and save, and return to the form and select daily instead, it still applies the other rules.

gordon’s picture

@thinkV yes I have noticed these bugs. I am planning to get these fixed soon, but this only effects the javascript and hopefully will not get posted to the server.

thinkV’s picture

they don't get posted to the server @gordon however the results do not represent the settings saved, ie. editing the page draft will display the wrong information.

gordon’s picture

@thinkV yes I know and I am still working on this patch to get it all built correctly and for the js to work like the server side.

realityloop’s picture

Upated to add a fix for dates that were strings instead of date objects, was throwing error in line 338 of DateRecurRRule.php

borisson_’s picture

I haven't tested this yet, but I had some nitpicks from just reading the code.

  1. +++ b/assets/date_recur_rrule.css
    @@ -64,20 +74,13 @@
    \ No newline at end of file
    

    Needs newline

  2. +++ b/assets/date_recur_rrule.js
    @@ -3,71 +3,283 @@
    +  //
    +  RRule.FREQUENCY_CODES = [
    

    This comment should either be removed or something should be written here.

  3. +++ b/assets/date_recur_rrule.js
    @@ -3,71 +3,283 @@
    +  // add helpful constants to RRule
    +  RRule.FREQUENCY_NAMES = [
    

    Needs to start with a Capital and end with a period.

  4. +++ b/assets/date_recur_rrule.js
    @@ -3,71 +3,283 @@
    +}(jQuery, Drupal, RRule, moment));
    \ No newline at end of file
    

    Needs newline

  5. +++ b/composer.json
    @@ -11,6 +11,7 @@
    +    "moment/moment": "2.*"
    

    This is a javascript library, right? I don't think we can get those via composer. At least not with a default setup. It's possible only when extending composer to also do front-end packages.

    This should be removed from composer.json and committed (if the license allows it) or fixed in another way.

  6. +++ b/src/DateRecurDefaultRRule.php
    @@ -45,7 +45,7 @@ class DateRecurDefaultRRule extends RRule {
         $daynames = DateHelper::weekDays(TRUE);
    -    array_push($daynames, $daynames[0]);
    +    array_push($daynames, $daynames[0]); // Move Sunday to the end of the week as day 7.
    

    This needs to respect 80 cols rule and the comment should be before the actual action. So:

    Move sunday to the end of the week as day 7
    array_push($daynames, $daynames[0]);
  7. +++ b/src/DateRecurRRule.php
    @@ -121,6 +121,18 @@ class DateRecurRRule implements \Iterator {
    +   * return the current rule.
    

    This comment should be expanded, to have an @return statement and it should also start with uppercase.

  8. +++ b/src/DateRecurRRule.php
    @@ -320,6 +332,12 @@ class DateRecurRRule implements \Iterator {
    +      $date = date_create_from_format('Y-m-d\TH:i:s',$date);
    

    Space after comma (H:i:s', $date)

  9. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +    // If no rule is set then use a default of rule of weekly but turn repeating off.
    

    Needs to respect 80 cols rule.

  10. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +      '#value' => isset($parts['UNTIL']) ? [ 'date' => $date->format(DateFormat::load('html_date')->getPattern()), 'time' => $date->format(DateFormat::load('html_time')->getPattern()), 'object' => $date ]  : NULL,
    

    This line is really long and hard to understand, can we extract this variable and make it simpler by not using an inline if here?

  11. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +   *
    +      ],
    

    This doesn't look right.

  12. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +   * @todo There seems to be an issue where the object is not being saved to the datetime field. I am not sure if this is an issue with datetime_tweaks module or some other weird thing.
    

    80 cols

  13. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +  public static function getRRule($element, $value, FormStateInterface $form_state) {
    

    Needs a docblock.

  14. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +  protected static function buildParts($element, $input, FormStateInterface $form_state) {
    

    Needs a docblock

  15. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +    $parts = array_change_key_case(array_intersect_key($input, array_flip(['freq', 'interval', 'byday', 'byhour', 'byminute', 'bysecond'])), CASE_UPPER);
    

    I think I had to read this line 4 times before I understood what's going on in here :D. Looks real nice though, good work!

  16. +++ b/src/Element/RRule.php
    @@ -0,0 +1,501 @@
    +      if ($pos = array_filter($input['pos'])) {
    +        $new_pos = [];
    

    This is very, very personal, but I dislike setting a variable in an if statement, can this be refactored to be something like this.

    $pos = array_filter($input['pos']);
    if (!empty($pos)) { ...
    

    This improves readability, is stricter and less prone to others (espcially me ;)) fucking up (by thinking that it should be 2*=, changing that and everything breaking)

  17. +++ b/templates/rrule-byday-pos-wrapper.html.twig
    @@ -0,0 +1,20 @@
    + * Theme override for a 'checkboxes' #type form element.
    

    /s/checkboxes/rrule-byday-pos-wrapper/

  18. +++ b/templates/rrule-end.html.twig
    @@ -0,0 +1,25 @@
    + * Default theme implementation for a 'radios' #type form element.
    

    /s/radios/rrule-end/ ?

  19. +++ b/templates/rrule-end.html.twig
    @@ -0,0 +1,25 @@
    \ No newline at end of file
    

    Needs newline

chOP’s picture

Title: Turn the RRule field into a standard Drupal form. » Date Recur RRule field Drupal form
Status: Needs work » Needs review
FileSize
116.98 KB
37.63 KB

I'm uploading a new patch, re-rolled against the current branch and addressing many of the issues listed. This patch also fixes

  • Drupal Coding standards violations
  • PHP Notices generated in some use cases
  • Defensive code to avoid uncaught exception errors
chOP’s picture

OMG, same names used in the files, that was stupid.

My apologies. Second patch and interdiff are correct ones, in spite of the duplicate names. I found an error in the JavaScript for a data attribute and corrected it.

It's too late now to rename the patch files, now they're uploaded with an incorrect comment number.

sleepingmonk’s picture

Patch from #31 mostly works. Thanks all!

There are two issues I've noticed so far when selecting "Monthly". It will ignore the Month selection but save the Day selection.
i.e.
If I choose Day: Sunday and Month: Aug, Oct
Summary: every August and October on Sunday
RRule: FREQ=MONTHLY;BYDAY=SU;BYMONTH=8,10

The result of saving is repeat on every Sunday, every month. The month is ignored.

Editing the node again shows the month(s) are not selected and the Summary does not show a month selection.

Summary: On the Sunday each month at 22:59
RRule: FREQ=MONTHLY;BYDAY=SU

The second thing as a comment about the summary. Should the summary read [day] in [months] instead?
Summary: every Sunday in August and October

sleepingmonk’s picture

Also noticed Summary time is way off: Set 00:00:00, but it shows 23:48. Just in the summary. The data is saved correctly.

joelpittet’s picture

Assigned: gordon » Unassigned

Can someone explain the need for the moment library dependency? I see it's called twice, once for the moment.ISO_8601 standard and the other for the format.

I know there's not a consistent mechanism for including libraries in Drupal with a contrib module but having it as an external library would be ideal so it doesn't conflict with other projects (hopefully) using the same library.

MrPaulDriver’s picture

Good work; this is a big improvement all round.

As with the D7 Date module and Option to hide end date, keeping time, imposing a hard requirement for an end date is undesirable. I note that alpha 4 version does not require a time, although the input field remains visible, but this seems to have been overlooked with this patch.

Like D7 Date, I do think the option to hide the time field would make for the best UX and compatibility with a good third party date picker would round it off nicely.

shortspoken’s picture

I'm very interested in testing the patch but it does not apply to the current dev version of date_recur.

sjpeters79’s picture

A bunch of things have changed in the newest dev version so it'll take time to refactor.

dpi’s picture

Component: Code » Widget
dpi’s picture

Title: Date Recur RRule field Drupal form » [Ideas] New interactive widget
Version: 8.x-1.x-dev » 8.x-2.x-dev
Status: Needs review » Needs work

As noted above many things have changed since the last round of work on patches here. Before going further I'd encourage working on the widget in a new project, similar to the other widget issue: #2933796-21: [Ideas] Add new Drupalized widget. Notably dependencies like rrule.js are no longer in the main project so theyd need to be re-introduced.

Theres good work here, keep it going!

dpi’s picture

Category: Feature request » Plan
Status: Needs work » Closed (outdated)

There seems to be little momentum or interest in this issue, so closing.