I'm using 3 noUISliders. I want to combine the outputs of the 3 sliders to create an html output. Specifically, I want to use the combination to select an image file (ie. img135.jpg) where 1 is the output from the first slider, 3 is from the second and 5 is from the third. I have 27 images - I want to be able to select one based on the combined output of the 3 sliders ( 111.jpg, 211.jpg, 311.jpg, etc. through 555.jpg).
I have three sliders providing output:
var slider1 = document.getElementById('slider1');
noUiSlider.create(slider1, {
start: 1,
connect: 'lower',
orientation: 'horizontal',
range: {
'min': 1,
'max': 5
},
snap: true,
format: wNumb({
decimals: 0
})
});
var sliderOutput1 = document.getElementById('value-slider1');
slider1.noUiSlider.on('update', function(values, handle) {
sliderOutput1.innerHTML = values[handle];
});
var sliderOutput2 = document.getElementById('value-slider2');
slider2.noUiSlider.on('update', function(values, handle) {
sliderOutput2.innerHTML = values[handle];
});
var sliderOutput3 = document.getElementById('value-slider3');
slider3.noUiSlider.on('update', function(values, handle) {
sliderOutput3.innerHTML = values[handle];
});
var image_path = 'img' + sliderOutput1.val() + sliderOutput2.val() + sliderOutput3.val() + '.jpg';
("#img").html(image_path);
<div id="slider1"></div>
<div id="slider2"></div>
<div id="slider3"></div>
<span id="value-slider1"> </span>
<span id="value-slider2"> </span>
<span id="value-slider3"> </span>
<div id="img"></div>
The sliders are all in and outputting values. I need advice on how to take the next step.
I'm pretty new at jscript, so any help or advice that you could provide would be great appreciated.
Ken
You can make it a lot fancier, but a simple pattern like the following should be fine:
function updatePicture() {
var image_path = 'img' + sliderOutput1.val() + sliderOutput2.val() + sliderOutput3.val() + '.jpg';
// I assume the missing $ was a typo
$("#img").html(image_path);
}
slider1.noUiSlider.on('update', function(values, handle) {
sliderOutput1.innerHTML = values[handle];
updatePicture();
});
var sliderOutput2 = document.getElementById('value-slider2');
slider2.noUiSlider.on('update', function(values, handle) {
sliderOutput2.innerHTML = values[handle];
updatePicture();
});
var sliderOutput3 = document.getElementById('value-slider3');
slider3.noUiSlider.on('update', function(values, handle) {
sliderOutput3.innerHTML = values[handle];
updatePicture();
});
Basically you get an event when any of the sliders change, you then proceed to update its output text (which you've done yourself), and the last step is to trigger the image refresh function which combines the three outputs into a usable path.
Interesting slider library by the way, I've never seen it before!
Related
I'm working on an e-commerce project that has a price range slider with two handles (min & max price filters). I decided to use NoUiSlider as it comes recommended. Although the plugin has no dependencies, I am also using jQuery 3.2.1, if it all relevant.
How can I make the values "stick" to their respective handlers? The effect I'm looking for is exactly like the slider on this webpage. I scanned through the docs but haven't been able to find anything, the closest thing I could find which I think might be related is this events page.
var handlesSlider = document.getElementById('slider-handles');
var minPrice = document.getElementById('min-price');
var maxPrice = document.getElementById('max-price');
var inputs = [minPrice, maxPrice];
noUiSlider.create(handlesSlider, {
start: [ 0, 100 ],
connect: [false, true, false],
step: 5,
range: {
'min': [ 0 ],
'max': [ 100 ]
},
format: wNumb({
decimals: 0,
thousand: '.',
prefix: '£',
}),
});
handlesSlider.noUiSlider.on('update', function( values, handle ) {
inputs[handle].innerHTML = values[handle];
});
My min-price and max-price are span elements, although I can change them if required.
I had a similar problem.
In my case, I wanted to use input boxes (instead of tooltips) to display slider values. This looks similar to your initial implementation using inputs. :)
So I solved it like this:
Create two or more input boxes in HTML (supplemented with proper ids for javascript)
<div id="exampleSlider"></div>
<div>
<input id="firstInput">
<input id="secondInput">
</div>
On Javascript:
Create a slider (I attached an example here):
var slider = document.getElementById('exampleSlider');
noUiSlider.create(slider, {
// This is an example. Customize this slider to your liking.
start: [300, 500],
range: {
'min': [0],
'max': [1000]
},
format: wNumb({
thousand: ',',
decimals: 0,
to: function (value) {
return value + ',-';
},
from: function (value) {
return Number(value.replace(',-', ''));
}
}),
});
Code for handling inputs from the slider
var firstInput = document.getElementById('firstInput');
var secondInput = document.getElementById('secondInput');
// add additional variables if you have more than two handles...
slider.noUiSlider.on('update', function (values) {
var handleValue = slider.noUiSlider.get();
firstInput.value = handleValue[0]
secondInput.value = handleValue[1]
// add additional inputs if you have more than two handles...
});
You can refer to my example code on JSfiddle
I'm displaying a donut chart using Highcharts and in the middle I've currently got the title; 'Transactions' but below that, but still in the middle, I'm trying to show the total number of the series values which should be €8,173.99.
I thought the following code would work:
events: {
load: function(event) {
var total = 0; // get total of data
for (var i = 0, len = this.series[0].yData.length; i < len; i++) {
total += this.series[0].this.y[i];
}
var text = this.renderer.text(
'Total: ' + total,
this.plotLeft,
this.plotTop - 20
).attr({
zIndex: 5
}).add()
}
},
I see no errors but then again the total is not being displayed. What am I doing wrong?
You can see the JSFiddle here http://jsfiddle.net/tobitobetoby/1fqvzpdn/3/
The events object should be placed inside chart object. As for the adding 'Total' info, I personally think that the better idea is to just set title on load event using Chart.setTitle() function. Take a look at the below example.
API Reference:
http://api.highcharts.com/highcharts/Chart.setTitle
Example:
http://jsfiddle.net/yt5pj3yf/
I am trying to build a ui slider similar to the one on this site: http://www.solarcity.com/
I want to be able to show the monthly value and then a yearly value next to it. ( I would assume multiplying the value of the monthly by 12 of course)
Once upon a time I had my slider working properly until I tried to multiply the monthly value by 12.
What did I do wrong?
(Sorry I am totally new to JavaScript)
Here is my Jsfiddle: http://jsfiddle.net/7qDyq/1/
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<span class="slider-output" id="monthly_bill">0</span>/month or <span class="slider-output" id="yearly_bill">0</span>/year
<div id="bill_slider">
</div>
$(document).ready(function(){
function update() {
var bill_slider = $('#bill_slider').slider('value');
var yearly_bill = (monthly_bill * 12 )
$("#monthly_bill").text(tasks_time);
$("#monthly_bill").text(tasks_done);
}
$("#bill_slider").slider({
value: 1,
min: 0,
max: 450,
step: 5,
slide: function() {
update();
}
});
});
Eventually after I figure this out I am also wondering how to change the color of the slider and words after the slider hits a certain point. (If then statement?) Not sure how to implement...
Any help on this is greatly appreciated. Thanks!
Most of the issues in your original jsFiddle traced back to bad JS var names; here is how you would achieve the desired effect:
function update() {
var bill_slider = $('#bill_slider').slider('value');
var yearly_bill = (bill_slider * 12)
$("#monthly_bill").text(bill_slider);
$("#yearly_bill").text(yearly_bill);
}
$("#bill_slider").slider({
value: 1,
min: 0,
max: 450,
step: 5,
slide: function () {
update();
}
});
Working jsFiddle, forked from yours: http://jsfiddle.net/6Bprf/5/
If you update your question with a description & example of the color-coding you want to do, we can include that in our answers.
I have a button that when clicked creates a slider.
HTML:
<a id="slider"class = "button small">Create Slider</a>
JS:
$('#slider').click(function(eventClick, posX, posY){
var htmlData='<div id="sldr'+$.count+'" class="draggable"' + 'data-page="' + $.page + '" ';
htmlData += 'style="height:25px; width:360px"><input id="movingslider'+$.count+'" class="sldr" type="text" data-slider="true" data-slider-range="10,1000"><span class="output"></span></div>';
var temp = $.count
$('.demo').append(htmlData);
$('#movingslider'+temp).simpleSlider();
$('#movingslider'+temp).bind("slider:ready slider:changed", function (event, data) {
$(this).nextAll(".output:first").html((data.value.toFixed(3)));
});
$('#sldr'+temp).draggable({
containment: "#workspace",
scroll: false,
cancel: false,
}
})
$('a.delete').on('click',function(e){
e.preventDefault();
btnID = $(this).closest('.draggable')[0].id;
//alert('Now deleting "'+objID+'"');
$('#'+btnID+'').remove();
});
$.count++;
});
I'm having some problem with the values of the newly created slider. I've indicated that the ranges should be from 10-1000 but when I started scrolling the slider, it shows the default range, 0-1. How could I change the range printed?
Within the configuration of the slider you can specify the range and steps:
data-slider-range:
The range representing the start and end of the slider. Eg. data-slider-range="10,1000"
data-slider-step:
The interval to move when dragging the slider. Eg. data-slider-step="100"
then you can access the value of the slider as:
$("#movingslider").bind("slider:changed", function (event, data) {
// The currently selected value of the slider
alert(data.value);
// The value as a ratio of the slider (between 0 and 1)
alert(data.ratio);
});
I have a problem want to share with you.
So here it is. Imagine I have a very large image and it take a heavy loading when I open my page. Is it possible if I want to have the effect like cut the image to many smaller pieces and merge them one by one while the image is loading(just javascript, jquery, css and html code).
html:
<div>
<div style="float:left; width: 200px; height: 200px;">
<img id="imgHeavy" src="http://i.stack.imgur.com/kLQe4.png" width="200"/>
</div>
<div id="frameMerge" style="float:left; width: 200px; height:200px; background: #ddd;">
</div>
</div>
So now I want to set the background of my element(#frameMerge) is every single pieces of the image(#imgHeavy) that have been cut when the page is opened.
Please take a look at 2 pictures!
My img:
My div element:
Any idea would be appreciated!
You can use the functionality of multiple background images provided by css3, but it won't be faster in the end as the data being loaded with multiple pictures is even bigger (header-information of every single file) than with just one. The only difference would be, that you see parts of the image before the rest is loaded. But you can have the same effect if your image is a jpg. So you can use a progressive jpg that will show parts of your image while the rest is still loading.
You can do it with CSS3 and jquery.
Here is an example for you :
jsfiddle.net/elclanrs/4nsJE/
;(function( $, window ) {
var _defaults = {
x : 2, // number of tiles in x axis
y : 2, // number of tiles in y axis
random : true, // animate tiles in random order
speed : 2000 // time to clear all times
};
/**
* range Get an array of numbers within a range
* #param min {number} Lowest number in array
* #param max {number} Highest number in array
* #param rand {bool} Shuffle array
* #return {array}
*/
function range( min, max, rand ) {
var arr = ( new Array( ++max - min ) )
.join('.').split('.')
.map(function( v,i ){ return min + i })
return rand
? arr.map(function( v ) { return [ Math.random(), v ] })
.sort().map(function( v ) { return v[ 1 ] })
: arr
}
// Prevent css3 transitions on load
$('body').addClass('css3-preload')
$( window ).load(function(){ $('body').removeClass('css3-preload') })
$.fn.sliced = function( options ) {
var o = $.extend( {}, _defaults, options );
return this.each(function() {
var $container = $(this);
/*---------------------------------
* Make the tiles:
---------------------------------*/
var width = $container.width(),
height = $container.height(),
$img = $container.find('img'),
n_tiles = o.x * o.y,
tiles = [], $tiles;
for ( var i = 0; i < n_tiles; i++ ) {
tiles.push('<div class="tile"/>');
}
$tiles = $( tiles.join('') );
// Hide original image and insert tiles in DOM
$img.hide().after( $tiles );
// Set background
$tiles.css({
width: width / o.x,
height: height / o.y,
backgroundImage: 'url('+ $img.attr('src') +')'
});
// Adjust position
$tiles.each(function() {
var pos = $(this).position();
$(this).css( 'backgroundPosition', -pos.left +'px '+ -pos.top +'px' );
});
/*---------------------------------
* Animate the tiles:
---------------------------------*/
var tilesArr = range( 0, n_tiles, o.random ),
tileSpeed = o.speed / n_tiles; // time to clear a single tile
// Public method
$container.on( 'animate', function() {
tilesArr.forEach(function( tile, i ) {
setTimeout(function(){
$tiles.eq( tile ).toggleClass( 'tile-animated' );
}, i * tileSpeed );
});
});
});
};
}( jQuery, window ));
$('.sliced').sliced({ x: 6, y: 4, speed: 1000 });
$('button').click(function() {
$('.sliced').trigger('animate');
});
Of course you can just put an onload event on every segment (must be on <img> though) that makes it fade in. However, actually splitting the image into segments cannot be done on client side. You will need to either manually split the image beforehand or rely on server side scripting (e.g. php) to do this.
Also, do note that doing this will create quite a lot of overhead depending on the amount of segments you use, since every segment will need to make a new request to the server including downloading the file headers for every image.