Skip to content

Commit

Permalink
Bypass full updateOptions, fix eslint, check for two handles
Browse files Browse the repository at this point in the history
  • Loading branch information
lgersen committed Jun 10, 2024
1 parent 4697c18 commit 3406bc1
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 34 deletions.
6 changes: 3 additions & 3 deletions documentation/behaviour-option.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

<div class="view">

<p>noUiSlider offers several ways to handle user interaction. The range can be made draggable, or handles can move to tapped positions. All these effects are optional, and can be enable by adding their keyword to the <code>behaviour</code> option.</p>
<p>noUiSlider offers several ways to handle user interaction. The range can be made draggable, or handles can move to tapped positions. All these effects are optional, and can be enabled by adding their keyword to the <code>behaviour</code> option.</p>

<p>This option accepts a <code>"-"</code> separated list of <code>"drag"</code>, <code>"drag-all"</code>, <code>"tap"</code>, <code>"fixed"</code>, <code>"snap"</code>, <code>"unconstrained"</code> or <code>"none"</code>.</p>
<p>This option accepts a <code>"-"</code> separated list of <code>"drag"</code>, <code>"drag-all"</code>, <code>"tap"</code>, <code>"fixed"</code>, <code>"snap"</code>, <code>"unconstrained"</code>, <code>"invert-connects"</code> or <code>"none"</code>.</p>

<div class="example">
<div id="behaviour"></div>
Expand Down Expand Up @@ -273,7 +273,7 @@
<div class="view">
<p>With this option set, connects invert when handles pass each other.</p>

<p>Requires the <code><a href="#section-unconstrained">unconstrained</a></code> behaviour and the <code>connect</code> option.</p>
<p>Requires the <code><a href="#section-unconstrained">unconstrained</a></code> behaviour and the <code>connect</code> option. This option is only applicable for sliders with two handles.</p>
<div class="example">
<div id="invert-connects"></div>
<span class="example-val" id="invert-connects-values"></span>
Expand Down
2 changes: 1 addition & 1 deletion documentation/behaviour-option/invert-connects-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ invertConnectsSlider.noUiSlider.on('update', function (values) {
return [mins / 60 ^ 0, mins % 60].map(pad).join(':');
};
invertConnectsValues.innerHTML = values.map(minToHHMM).join(' - ');
});
});
2 changes: 1 addition & 1 deletion documentation/behaviour-option/invert-connects.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ noUiSlider.create(invertConnectsSlider, {
'min': 0,
'max': 24*60
}
});
});
2 changes: 1 addition & 1 deletion documentation/more.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

<div class="view">

<p>noUiSlider has an update method that can change the <code>'margin'</code>, <code>'padding'</code>, <code>'limit'</code>, <code>'step'</code>, <code>'range'</code>, <code>'pips'</code>, <code>'tooltips'</code>, <code>'animate'</code> and <code>'snap'</code> options.</p>
<p>noUiSlider has an update method that can change the <code>'margin'</code>, <code>'padding'</code>, <code>'limit'</code>, <code>'step'</code>, <code>'range'</code>, <code>'pips'</code>, <code>'tooltips'</code>, <code>'connect'</code>, <code>'animate'</code> and <code>'snap'</code> options.</p>

<p>All other options require changes to the slider's HTML or event bindings.</p>

Expand Down
71 changes: 43 additions & 28 deletions src/nouislider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,10 @@ function testBehaviour(parsed: ParsedOptions, entry: unknown): void {
testMargin(parsed, parsed.start[1] - parsed.start[0]);
}

if (invertConnects && parsed.handles !== 2) {
throw new Error("noUiSlider: 'invert-connects' behaviour must be used with 2 handles");
}

if (unconstrained && (parsed.margin || parsed.limit)) {
throw new Error("noUiSlider: 'unconstrained' behaviour cannot be used with margin or limit");
}
Expand Down Expand Up @@ -1383,7 +1387,7 @@ function scope(target: TargetElement, options: ParsedOptions, originalOptions: O
const scope_HandleNumbers: number[] = [];
let scope_ActiveHandlesCount = 0;
const scope_Events: { [key: string]: EventCallback[] } = {};
let scope_ConnectsInverted: boolean = false;
let scope_ConnectsInverted = false;

// Document Nodes
const scope_Document = target.ownerDocument;
Expand Down Expand Up @@ -2671,23 +2675,27 @@ function scope(target: TargetElement, options: ParsedOptions, originalOptions: O

(scope_Handles[handleNumber].style as CSSStyleDeclarationIE10)[options.transformRule] = translateRule;

if(
options.events.invertConnects &&
// sanity check for at least 2 handles
scope_Locations.length > 1 &&
// sanity check for at least 2 handles (e.g. during setup)
if (options.events.invertConnects && scope_Locations.length > 1) {
// check if handles passed each other, but don't match the ConnectsInverted state
scope_ConnectsInverted !== !scope_Locations.every(
(position: number, index: number, locations: number[]): boolean =>
const handlesAreInOrder = scope_Locations.every(
(position: number, index: number, locations: number[]): boolean =>
index === 0 || position >= locations[index - 1]
)) {
// when invertConnects is set, automatically invert connects when handles pass each other
);

if (scope_ConnectsInverted !== !handlesAreInOrder) {
// invert connects when handles pass each other
invertConnects();

// invertConnects already updates all connect elements
return;
}
}

updateConnect(handleNumber);
updateConnect(handleNumber + 1);
if(scope_ConnectsInverted) {

if (scope_ConnectsInverted) {
// When connects are inverted, we also have to update adjacent connects
updateConnect(handleNumber - 1);
updateConnect(handleNumber + 2);
Expand Down Expand Up @@ -2744,9 +2752,10 @@ function scope(target: TargetElement, options: ParsedOptions, originalOptions: O
}

// Create a copy of locations, so we can sort them for the local scope logic
let locations = scope_Locations.slice();
const locations = scope_Locations.slice();

if (scope_ConnectsInverted) {
locations.sort(function(a, b) {
locations.sort(function (a, b) {
return a - b;
});
}
Expand Down Expand Up @@ -3048,30 +3057,36 @@ function scope(target: TargetElement, options: ParsedOptions, originalOptions: O

// Update connects only if it was set
if (optionsToUpdate.connect) {
// IE supported way of removing children including event handlers
while (scope_ConnectBase.firstChild) {
scope_ConnectBase.removeChild(scope_ConnectBase.firstChild);
}
updateConnectOption();
}
}

// Adding new connects according to the new connect options
for (let i = 0; i <= options.handles; i++) {
scope_Connects[i] = addConnect(scope_ConnectBase, options.connect[i]);
updateConnect(i);
}
function updateConnectOption() {
// IE supported way of removing children including event handlers
while (scope_ConnectBase.firstChild) {
scope_ConnectBase.removeChild(scope_ConnectBase.firstChild);
}

// readding drag events for the new connect elements
// to ignore the other events we have to negate the 'if (!behaviour.fixed)' check
bindSliderEvents({ drag: options.events.drag, fixed: true } as Behaviour);
// Adding new connects according to the new connect options
for (let i = 0; i <= options.handles; i++) {
scope_Connects[i] = addConnect(scope_ConnectBase, options.connect[i]);
updateConnect(i);
}

// re-adding drag events for the new connect elements
// to ignore the other events we have to negate the 'if (!behaviour.fixed)' check
bindSliderEvents({ drag: options.events.drag, fixed: true } as Behaviour);
}

// Invert options for connect handles
function invertConnects() {
scope_ConnectsInverted = !scope_ConnectsInverted;
updateOptions({
testConnect(
options,
// inverse the connect boolean array
connect: options.connect.map((b: boolean) => !b)
}, false); // don't fire the set event
options.connect.map((b: boolean) => !b)
);
updateConnectOption();
}

// Initialization steps
Expand Down

0 comments on commit 3406bc1

Please sign in to comment.