Skip to content

Commit

Permalink
Slider that displays lower and upper bound (#63)
Browse files Browse the repository at this point in the history
Co-authored-by: fonsp <[email protected]>
  • Loading branch information
jin-park and fonsp authored Nov 5, 2020
1 parent 59705e2 commit 84c37c1
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PlutoUI"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
authors = ["Fons van der Plas <[email protected]>"]
version = "0.6.9"
version = "0.6.10"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
87 changes: 87 additions & 0 deletions assets/rangeslider.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
.middle {
position: relative;
width: 50%;
max-width: 500px;
}

.slider {
position: relative;
z-index: 1;
height: 10px;
margin: 15px 15px;
}

.slider > .track {
position: absolute;
z-index: 1;
left: 0;
right: 0;
top: 0;
bottom: 0;
border-radius: 5px;
border: 1px solid rgb(182, 182, 182);
background-color: rgb(239, 239, 239);
}

.slider > .range {
position: absolute;
z-index: 2;
top: 0;
bottom: 0;
border-radius: 5px;
border: 1px solid rgb(69, 119, 184);
background-color: rgb(20, 121, 251);
}

.slider > .range:hover {
filter: brightness(90%);
}

.slider > .track:hover {
filter: brightness(95%);
}

.slider > .thumb {
position: absolute;
z-index: 3;
width: 15px;
height: 15px;
background-color: rgb(20, 121, 251);
border-radius: 50%;
}

.slider > .thumb.left {
transform: translate(-7.5px, -2.5px);
}

.slider > .thumb.right {
transform: translate(7.5px, -2.5px);
}

#input-left, #input-right {
position: absolute;
pointer-events: none;
-webkit-appearance: none;
z-index: 2;
height: 10px;
width: 100%;
opacity: 0;
}

#input-left::-moz-range-thumb, #input-right::-moz-range-thumb {
pointer-events: all;
width: 20px;
height: 20px;
border-radius: 0;
border: 0 none;
-moz-appearance: none;
}

#input-left::-webkit-slider-thumb, #input-right::-webkit-slider-thumb {
pointer-events: all;
width: 20px;
height: 20px;
border-radius: 0;
border: 0 none;
-webkit-appearance: none;
}
81 changes: 81 additions & 0 deletions assets/rangeslider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const container = currentScript.parentElement
const inputLeft = container.querySelector("#input-left");
const inputRight = container.querySelector("#input-right");
const thumbLeft = container.querySelector(".slider > .thumb.left");
const thumbRight = container.querySelector(".slider > .thumb.right");
const range = container.querySelector(".slider > .range");
const display = container.querySelector("#slider-output")

const min = parseFloat(inputLeft.min);
const max = parseFloat(inputLeft.max);

function setLeftValue() {
inputLeft.value = Math.min(parseFloat(inputLeft.value), parseFloat(inputRight.value));

const percent = ((inputLeft.value - min) / (max - min)) * 100;

thumbLeft.style.left = percent + "%";
range.style.left = percent + "%";

const leftValue = parseFloat(inputLeft.value),
rightValue = parseFloat(inputRight.value);

if (rightValue === leftValue) {
inputRight.hidden = true;
} else {
inputRight.hidden = false;
}

var returnValue = []
var i = leftValue;
while (i <= rightValue) {
returnValue.push(i);
i += parseFloat(inputLeft.step);
}

container.value = returnValue;
container.dispatchEvent(new CustomEvent("input"));
}
setLeftValue();

function setRightValue() {
inputRight.value = Math.max(parseFloat(inputRight.value), parseFloat(inputLeft.value));

const percent = ((inputRight.value - min) / (max - min)) * 100;

thumbRight.style.right = (100 - percent) + "%";
range.style.right = (100 - percent) + "%";

const leftValue = parseFloat(inputLeft.value),
rightValue = parseFloat(inputRight.value);

if(rightValue === leftValue) {
inputLeft.hidden = true;
} else {
inputLeft.hidden = false;
}

var returnValue = []
var i = leftValue;
while (i <= rightValue) {
returnValue.push(i);
i += parseFloat(inputLeft.step);
}

container.value = returnValue;
container.dispatchEvent(new CustomEvent("input"));
}
setRightValue();

inputLeft.addEventListener("input", setLeftValue);
inputRight.addEventListener("input", setRightValue);

function updateDisplay() {
if(display != null) {
display.value = (inputLeft.step == 1) ? `${inputLeft.value}:${inputRight.value}`
: `${inputLeft.value}:${inputLeft.step}:${inputRight.value}`;
}
}
inputLeft.addEventListener("input", updateDisplay)
inputRight.addEventListener("input", updateDisplay)
updateDisplay()
1 change: 1 addition & 0 deletions src/PlutoUI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include("./Builtins.jl")
include("./Clock.jl")
include("./Resource.jl")
include("./Terminal.jl")
include("./RangeSlider.jl")
include("./DisplayTricks.jl")

end
64 changes: 64 additions & 0 deletions src/RangeSlider.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
export RangeSlider

struct RangeSlider
range::AbstractRange
left::Number
right::Number
show_value::Bool
end

RangeSlider(range::AbstractRange; left=first(range), right=last(range), show_value=false) =
left > right ? error("Left value cannot be bigger than right") : RangeSlider(range, left, right, show_value)

"""
A `RangeSlider` is a two thumb slider which returns the range between the two thumbs.
If you set `show_value` to `false`, the slider won't display its value.
By default `show_value` is set to `true`
Use `left` and `right` to set default values for the slider thumbs.
## Examples
`@bind range RangeSlider(1:100)`
`@bind range RangeSlider(1:0.1:100, show_value=false)`
`@bind range RangeSlider(1:0.1:100, left=25, right=75)`
"""

function show(io::IO, ::MIME"text/html", slider::RangeSlider)
js = read(joinpath(PKG_ROOT_DIR, "assets", "rangeslider.js"), String)
css = read(joinpath(PKG_ROOT_DIR, "assets", "rangeslider.css"), String)

result = """
<multi-range-slider>
<div class="middle">
<input type="range" id="input-left" step="$(step(slider.range))"
min="$(first(slider.range))" max="$(last(slider.range))"
value="$(slider.left)">
<input type="range" id="input-right" step="$(step(slider.range))"
min="$(first(slider.range))" max="$(last(slider.range))"
value="$(slider.right)">
<div class="slider">
<div class="track" onmousedown="event.preventDefault()"></div>
<div class="range" onmousedown="event.preventDefault()"></div>
<div class="thumb right"></div>
<div class="thumb left"></div>
</div>
</div>
$(slider.show_value ? """<output id=\"slider-output\"></output>""" : "")
<script>
$(js)
</script>
<style>
$(css)
</style>
</multi-range-slider>
"""

print(io, result)
end

get(slider::RangeSlider) = collect(slider.left:step(slider.range):slider.right)

2 comments on commit 84c37c1

@fonsp
Copy link
Member

@fonsp fonsp commented on 84c37c1 Nov 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/24212

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.10 -m "<description of version>" 84c37c1386960df932aeb4eabc4f41be6dbbacd3
git push origin v0.6.10

Please sign in to comment.