Reputation: 711
I've used a code from this answer to style HTML5 input in my GRAV CMS website.
The rendered part of HTML markup:
<div class="form-data" data-grav-field="range" data-grav-disabled="" data-grav-default="40">
<div class="form-input-wrapper ">
<input name="data[space]" value="40" type="range" style="display: inline-block;vertical-align: middle;" oninput="space_output.value = space.value" min="40" max="350" step="10" class="form-input " id="space" required="required">
<output name="data[space]" id="space_output" style="display: inline-block;vertical-align: baseline;padding: 0 0.5em 5px 0.5em;"> 40 </output>
</div>
</div>
The JS code is taken from the answer above and placed in at the beginning of my custom.js
file:
document.getElementById("space").oninput = function() {
var value = (this.value-this.min)/(this.max-this.min)*100
this.style.background = 'linear-gradient(to right, #eec170 0%, #eea624 ' + value + '%, #839788 ' + value + '%, #a6d86c 100%)'
};
So, this part works without any flaws.
The problem:
With JS code the behaviour of input is incorrect, once the page is loaded background color is not reflecting the ball position of the default position 40
, because it's not the center.
Once the slider position is changed, the background colors are changed depending on the slider position.
That's the lesser problem, but the major problem is that the <output>
field no longer displays the new values. It's has been stuck to 40
.
How could it be fixed?
Upvotes: 1
Views: 77
Reputation: 8538
Try this example. I have added one more (hidden) input for calculate range and wrapped it with a form tag to get the value from the output. I also added styles and refactored the gradient calculation to javascript.
document.addEventListener('DOMContentLoaded', function() {
const slider = document.getElementById('range');
// Calculate gradient persent (0% - 100%)
const calcGradientPersent = value => (100 * value) / 360;
// Default value when load page
const initValue = slider.value;
let persent = calcGradientPersent(initValue);
// Set default inline style
slider.style.background = `linear-gradient(to right, #eec170 0%, #eea624 ${persent}%, #839788 ${persent}%, #a6d86c 100%)`;
// Input Range handler
slider.addEventListener('input', event => {
// Get value from input
const value = event.target.value;
persent = calcGradientPersent(value);
// Update inline style
slider.style.background = `linear-gradient(to right, #eec170 0%, #eea624 ${persent}%, #839788 ${persent}%, #a6d86c 100%)`;
});
});
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
input[type='range'] {
appearance: none;
border-radius: 1rem;
}
input[type='range']:focus {
outline: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 100%;
height: 0.4rem;
cursor: pointer;
border-radius: 1rem;
border: 1px solid #eea624;
}
input[type='range']::-webkit-slider-thumb {
height: 1rem;
aspect-ratio: 1;
border-radius: 50%;
border: 2px solid gray;
background: #d8d7f3;
cursor: pointer;
appearance: none;
margin-top: -0.35rem;
}
<div class="form-data" data-grav-field="range" data-grav-disabled="" data-grav-default="40">
<form oninput="result.value=parseInt(range.value)+parseInt(step.value)" class="form-input-wrapper">
<input name="range" value="40" type="range" style="display: inline-block; vertical-align: middle" min="0" max="350" step="10" class="form-input" id="range" required="required" />
<input type="number" id="step" value="0" hidden />
<output name="result" id="space_output" for="range step" style="display: inline-block; vertical-align: baseline; padding: 0 0.5em 5px 0.5em">
40
</output>
</form>
</div>
Upvotes: 1