Problem/Motivation

This module is passing the field definition min and max values to the step input on the settings form.

    $element['step'] = [
      '#type' => 'number',
      '#required' => TRUE,
      '#title' => $this->t('Step'),
      '#step' => (float) $step,
      '#min' => $this->fieldDefinition->getSetting('min'),
      '#max' => $this->fieldDefinition->getSetting('max'),
      '#description' => $this->t('The value for what each step between the slider should be.'),
      '#default_value' => $this->getSetting('step'),
    ];

This makes no sense. If I want a numeric field to allow integer values between 50 and 150, this will make "50" as the minimum possible step and the range would only allow three stops: 50, 100 and 150. This is coupling two completely unrelated settings.

The step configuration should be completely agnostic from the min/max settings of the field.

Steps to reproduce

- Set a range (min/max) for a numeric field.
- Try to use a step lower than the min value, i.e., a 2 step for an integer field ranging between 200 and 1000.
- You can't - you can only pass 200 and up as the step value.

Proposed resolution

Remove the min/max constraints from the step field.

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

idiaz.roncero created an issue. See original summary.

idiaz.roncero’s picture

Issue summary: View changes

idiaz.roncero’s picture

Status: Active » Needs review
idiaz.roncero’s picture

Version: 1.0.1 » 1.0.x-dev

gueguerreiro made their first commit to this issue’s fork.

gueguerreiro’s picture

Thanks for reporting. The calculations for #min and #max steps are for sure not correct right now.

But I don't think the #min and #max for the "Step" configuration value should be agnostic from the field. A range element is, by definition, an element that *must* have a minimum value and a maximum value. And we don't want to allow a "Step" value that can go over the difference between the maximum and minimum value. Otherwise the final slider element is essentially broken and cannot be interacted with.

For example, if a Number allows for values between 50 and 250, but it has a step value of 500, then you can't really use the slider. It will only allow you to use it's previous value, or 50, if it had no value before.

I see it as, the #min and #max step value should allow for, at the very least, 1 "slide" on the input element.

The #min is actually something we're already calculating just a bit above that code:

    $scale = $this->fieldDefinition->getFieldStorageDefinition()->getSetting('scale');
    $minimum_step = isset($scale) ? "0." . str_repeat("0", $scale - 1) . "1" : 1;

Which is usually 1, unless it's a decimal field, in which case it takes into account how many decimal cases ("scale") the field permits. (So, a field with 2 decimal cases should have a minimum of 0.01, the lowest amount possible within that scale).

For the maximum, we do need some further calculations that I had overlooked. Particularly when a minimum is already set, and it is *not* 0.

I am now calculating to ensure the maximum value allows for at least 1 "slide" of the element, and ensure it cannot go over that.

One edge-case that I found, not related to this specifically, is that having a "Maximum" value in the number field, of a negative number (E.g. -100), but having no minimum set, will break the slider element.

I added a safeguard in the "Step" configuration, to always default to 1 if the $maximum_step is calculated as less than or equal to 0.

However, the problem isn't really in the configuration but on the actual rendered form element. Drupal defaults to a #min of 0 and a #max of 100 in the "range" form element: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21....

But we can't have a minimum of 0, and a maximum of -100. That just breaks the element completely, as it can never have a valid value. You can't interact with it, nor save any form that has that broken element in it.

It's out of scope for this issue, so I'll be opening a separate issue for that. Ideally we prevent the number range slider to be added in those circumstances, as there really is no way for us to have a sensible #min default value, when we're dealing with negative numbers.

I tested my change with a bunch of different situations, and it seems to be working correctly on all cases. So I'm confident this is OK to add to a new Release. But do tell me if you run into any issues please.

  • gueguerreiro committed 58c12c57 on 1.0.x
    fix: #3591872 Fixes how #min and #max step values are calculated.
    
gueguerreiro’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

gueguerreiro’s picture

Version: 1.0.x-dev » 1.0.2

This is now available on the 1.0.2 release.

gueguerreiro’s picture

Title: Do not use field config #min and #max for the widget step » Fix #min and #max calculations for the widget "step" configuration

idiaz.roncero’s picture

Many thanks!

Status: Fixed » Closed (fixed)

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