-
Notifications
You must be signed in to change notification settings - Fork 111
WIP/Extended options - Add slider form control #2220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 1 commit
26b5b66
523826d
f20ffd5
1bd2d1f
2c80ee3
9305eed
73ded47
a0d5fb0
1ce3092
02d3e00
1320399
9c54381
2546f87
641c54b
62a001b
91eed9e
27c5895
07790e8
313f118
3718627
946f736
c51fe87
fe4ce8d
03dfb2a
0c0a7db
7f5ae5a
817ddf2
7f40ad0
99b314e
e853926
5b68c47
48aa458
faa508f
a3d8366
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,215 @@ | ||||||||||||||
| <?php | ||||||||||||||
|
|
||||||||||||||
| declare(strict_types=1); | ||||||||||||||
|
|
||||||||||||||
| namespace Atk4\Ui\Form\Control; | ||||||||||||||
|
|
||||||||||||||
| use Atk4\Ui\View; | ||||||||||||||
| use Atk4\Ui\Js\JsExpression; | ||||||||||||||
| use Atk4\Ui\Js\JsFunction; | ||||||||||||||
| use Atk4\Ui\Js\JsReload; | ||||||||||||||
|
|
||||||||||||||
| class Slider extends Input | ||||||||||||||
| { | ||||||||||||||
| public string $inputType = 'hidden'; | ||||||||||||||
|
|
||||||||||||||
| /** The lowest value the slider can be. */ | ||||||||||||||
| public int $min = 0; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we limited to integers by something?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I've changed this to float, but then the result is also returned in float.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can easily allow |
||||||||||||||
|
|
||||||||||||||
| /** The max value the slider can be. */ | ||||||||||||||
| public int $max = 10; | ||||||||||||||
|
|
||||||||||||||
| /** @var float|null The slider step. Set to 0 to disable step. */ | ||||||||||||||
| public $step = 0; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a question for now - how feasible is histogram below the slider and non-liner steps or even non-numeric values (XS-S-M-L...)?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's possible! As a matter of fact, all the options I've implemented, except this one is directly from Fomantic. I just broke out ticked, bottom align and labeled from the class and made those options. If some of them are funky, yes, I know, they can be removed if we deem the don't add anything. I just added it for completness for now.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mvorisek, I think I need your help on this one. It seems that the function (interpretLabel) need to be existing before semantic.js (Fomantic-UI) is loaded. I've hacked a version of semantic.js to try this and it indeed added the custom labels then. This is not acceptable though as I know very well, it was just done for test.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That seems weird to me. All user JS is evaluated "after page is fully loaded", so the elements are guaranteed to exists. And you can define a JS function before you setup the FUI slider by JS. I do not understand the issue you are facing here.. If you need to define global JS code - to deduplicate long JS code - you can put the code in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mvorisek I fixed it... Using JsFunction and JsExpression was the way to go but I had trouble with the array but using slice instead of addressing the item directly solved it. |
||||||||||||||
|
|
||||||||||||||
| /** The value the slider will start at. */ | ||||||||||||||
| public int $start = 0; | ||||||||||||||
|
|
||||||||||||||
| /** @var int|null The second value to set in case of a range slider. */ | ||||||||||||||
| public $end = null; | ||||||||||||||
|
|
||||||||||||||
| /** @var int|false Makes sure that the two thumbs of a range slider always need to have a difference of the given value. */ | ||||||||||||||
| public $minRange = false; | ||||||||||||||
|
|
||||||||||||||
| /** @var int|false Makes sure that the two thumbs of a range slider don't exceed a difference of the given value. */ | ||||||||||||||
| public $maxRange = false; | ||||||||||||||
|
|
||||||||||||||
| /** @var 'number'|'letter' The type of label to display for a labeled slider. Can be number or letter. */ | ||||||||||||||
| public $labelType = 'number'; | ||||||||||||||
|
|
||||||||||||||
| /** @var array|null An array of label values which restrict the displayed labels to only those which are defined. */ | ||||||||||||||
| public $restrictedLabels = null; | ||||||||||||||
|
|
||||||||||||||
| /** Whether a tooltip should be shown to the thumb(s) on hover. Will contain the current slider value. */ | ||||||||||||||
| public bool $showThumbTooltip = false; | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Tooltip configuration used when showThumbTooltip is true | ||||||||||||||
| * Refer to Tooltip Variations for possible values. | ||||||||||||||
| * | ||||||||||||||
| * @var array|null | ||||||||||||||
| */ | ||||||||||||||
| public $tooltipConfig = null; | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Show ticks on a labeled slider. | ||||||||||||||
| *'always'will always show the ticks for all labels (even if not shown) | ||||||||||||||
| * true will display the ticks only if the related label is also shown. | ||||||||||||||
| * | ||||||||||||||
| * @var 'always'|bool | ||||||||||||||
| */ | ||||||||||||||
| public $showLabelTicks = false; | ||||||||||||||
|
|
||||||||||||||
| /** Define smoothness when the slider is moving. */ | ||||||||||||||
| public bool $smooth = false; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's for the movement of the thumb, if it's in steps between ticks or smooth scrolling. |
||||||||||||||
|
|
||||||||||||||
| /** Whether labels should auto adjust on window resize. */ | ||||||||||||||
| public bool $autoAdjustLabels = true; | ||||||||||||||
|
|
||||||||||||||
| /** The distance between labels. */ | ||||||||||||||
| public int $labelDistance = 100; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When is this helpful? Does this affect CSS only?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but it also defines what labels will be shown, depending on space available. |
||||||||||||||
|
|
||||||||||||||
| /** Number of decimals to use with an unstepped slider. */ | ||||||||||||||
| public int $decimalPlaces = 2; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is this helpful vs.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. decimalPlaces 2 Number of decimals to use with an unstepped slider |
||||||||||||||
|
|
||||||||||||||
| /** Page up/down multiplier. Define how many more times the steps to take on page up/down press. */ | ||||||||||||||
| public int $pageMultiplier = 2; | ||||||||||||||
|
|
||||||||||||||
| /** Prevents the lower thumb to crossover the thumb handle. */ | ||||||||||||||
| public bool $preventCrossover = true; | ||||||||||||||
|
|
||||||||||||||
| /** Settings for the slider-class */ | ||||||||||||||
| /** Whether the slider should be ticked or not. */ | ||||||||||||||
| public bool $ticked = false; | ||||||||||||||
|
|
||||||||||||||
| /** Whether the slider should be labeled or not. */ | ||||||||||||||
| public bool $labeled = false; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this controlled by something in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, you are thinking of caption, that's the info "before" the controller, labeled is if the slider should have text at the ticks or not. |
||||||||||||||
|
|
||||||||||||||
| /** Whether the ticks and labels should be at the bottom. */ | ||||||||||||||
| public bool $bottom = false; | ||||||||||||||
|
|
||||||||||||||
| /** @var object */ | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
at least if general View type is needed
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. must be |
||||||||||||||
| private $slider; | ||||||||||||||
|
|
||||||||||||||
| /** @var object */ | ||||||||||||||
| private $owner; | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. owner is stored in the parent API already
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't find this, do you have an example? I just need to know how to find the parent object.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||
|
|
||||||||||||||
| /** @var object */ | ||||||||||||||
| private $firstInput; | ||||||||||||||
|
|
||||||||||||||
| /** @var object */ | ||||||||||||||
| private $secondInput; | ||||||||||||||
|
|
||||||||||||||
| #[\Override] | ||||||||||||||
| protected function init(): void | ||||||||||||||
| { | ||||||||||||||
| parent::init(); | ||||||||||||||
|
|
||||||||||||||
| $this->owner = $this->getOwner(); | ||||||||||||||
|
|
||||||||||||||
| $this->slider = View::addTo($this->owner)->addClass('ui slider'); | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||
|
|
||||||||||||||
| if ($this->end) { | ||||||||||||||
| $this->slider->addClass('range'); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if ($this->ticked) { | ||||||||||||||
| $this->slider->addClass('ticked'); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if ($this->labeled) { | ||||||||||||||
| $this->slider->addClass('labeled'); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if ($this->bottom) { | ||||||||||||||
| $this->slider->addClass('bottom aligned'); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| $sliderSettings = []; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['min' => $this->min]; | ||||||||||||||
|
mvorisek marked this conversation as resolved.
Outdated
|
||||||||||||||
| $sliderSettings = $sliderSettings + ['max' => $this->max]; | ||||||||||||||
| if ($this->start) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['start' => $this->start]; | ||||||||||||||
| } | ||||||||||||||
| if ($this->step) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['step' => $this->step]; | ||||||||||||||
| } | ||||||||||||||
| if ($this->end) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['end' => $this->end]; | ||||||||||||||
| if ($this->minRange) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['minRange' => $this->minRange]; | ||||||||||||||
| } | ||||||||||||||
| if ($this->maxRange) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['maxRange' => $this->maxRange]; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| $sliderSettings = $sliderSettings + ['labelType' => $this->labelType]; | ||||||||||||||
| if ($this->restrictedLabels) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['restrictedLabels' => $this->restrictedLabels]; | ||||||||||||||
| } | ||||||||||||||
| if ($this->showThumbTooltip) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['showThumbTooltip' => $this->showThumbTooltip]; | ||||||||||||||
| if ($this->tooltipConfig) { | ||||||||||||||
| $sliderSettings = $sliderSettings + ['tooltipConfig' => $this->tooltipConfig]; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| $sliderSettings = $sliderSettings + ['showLabelTicks' => $this->showLabelTicks]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['smooth' => $this->smooth]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['autoAdjustLabels' => $this->autoAdjustLabels]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['labelDistance' => $this->labelDistance]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['decimalPlaces' => $this->decimalPlaces]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['pageMultiplier' => $this->pageMultiplier]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['decimalPlaces' => $this->decimalPlaces]; | ||||||||||||||
| $sliderSettings = $sliderSettings + ['preventCrossover' => $this->preventCrossover]; | ||||||||||||||
|
|
||||||||||||||
| /* | ||||||||||||||
| * First input value, always present | ||||||||||||||
| */ | ||||||||||||||
| $this->firstInput = $this->owner->addControl( | ||||||||||||||
| $this->shortName . '_first', | ||||||||||||||
| [ | ||||||||||||||
| Hidden::class | ||||||||||||||
| ] | ||||||||||||||
| )->set($this->start); | ||||||||||||||
|
|
||||||||||||||
| $onChange = [ | ||||||||||||||
| 'onChange' => new JsFunction( | ||||||||||||||
| ['v'], | ||||||||||||||
| [ | ||||||||||||||
| new JsExpression($this->firstInput->js()->find('input')->jsRender().".val($('div#" . $this->slider->getHtmlId() . "').slider('get thumbValue', 'first'))"), | ||||||||||||||
|
mvorisek marked this conversation as resolved.
Outdated
|
||||||||||||||
| ]) | ||||||||||||||
| ]; | ||||||||||||||
|
|
||||||||||||||
| /* | ||||||||||||||
| * Second input value, optional, depending on $this->end | ||||||||||||||
| */ | ||||||||||||||
| if ($this->end) { | ||||||||||||||
| $this->secondInput = $this->owner->addControl( | ||||||||||||||
| $this->shortName . '_second', | ||||||||||||||
| [ | ||||||||||||||
| Hidden::class | ||||||||||||||
| ] | ||||||||||||||
| )->set($this->end); | ||||||||||||||
|
|
||||||||||||||
| $onChange = [ | ||||||||||||||
| 'onChange' => new JsFunction( | ||||||||||||||
| ['v'], | ||||||||||||||
| [ | ||||||||||||||
| new JsExpression($this->firstInput->js()->find('input')->jsRender().".val($('div#" . $this->slider->getHtmlId() . "').slider('get thumbValue', 'first'))"), | ||||||||||||||
| new JsExpression($this->secondInput->js()->find('input')->jsRender().".val($('div#" . $this->slider->getHtmlId() . "').slider('get thumbValue', 'second'))") | ||||||||||||||
| ]) | ||||||||||||||
| ]; | ||||||||||||||
| } | ||||||||||||||
| $sliderSettings = $sliderSettings + $onChange; | ||||||||||||||
|
|
||||||||||||||
| $this->slider->js(true)->slider( | ||||||||||||||
| $sliderSettings, | ||||||||||||||
| ); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| #[\Override] | ||||||||||||||
| protected function recursiveRender(): void | ||||||||||||||
| { | ||||||||||||||
| parent::recursiveRender(); | ||||||||||||||
| } | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll remove it later, now I'm using it to check variables and classes after render. |
||||||||||||||
| } | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enabled/disabled/readonly demo should be added into
demos/form-control/input2.phpand there should be probably a separate demo for Slicer + Behat tests are needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll get to this in time...