web-dev-qa-db-fra.com

JQuery Slider, comment effectuer un changement de taille "par étapes"

Est-il possible d'utiliser le curseur JQuery (curseur de la plage/curseur double) pour obtenir des valeurs non linéaires (taille "pas" cohérente)?

Je veux que le curseur horizontal ressemble à ceci:

|----|----|----|----|----|--------|--------|-------------------------|--------------------------|...
0   500  750  1000  1250 1500     2000     2500                      75000                      100000...

Par exemple, je veux avoir le code JQuery suivant:

var values = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
var slider = $("#price-range").slider({
    orientation: 'horizontal',
    range: true,
    min: 0,
    max: 1000000,
    values: [0, 1000000],
    slide: function(event, ui) {
            var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
            var includeRight = event.keyCode != $.ui.keyCode.LEFT;
            slider.slider('option', 'value', findNearest(includeLeft, includeRight, ui.value));
            $("#price-amount").html('$' + ui.values[0] + ' - $' + ui.values[1]);
            return false;
    },
    change: function(event, ui) { 
        getHomeListings();
    }
});
function findNearest(includeLeft, includeRight, value) {
    var nearest = null;
    var diff = null;
    for (var i = 0; i < values.length; i++) {
            if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
                    var newDiff = Math.abs(value - values[i]);
                    if (diff == null || newDiff < diff) {
                            nearest = values[i];
                            diff = newDiff;
                    }
            }
    }
    return nearest;
}

Le code ci-dessus ne fonctionne pas exactement mais la fonctionnalité d'accrochage à la grille ne fonctionne pas.

63
TomHankers

Vous n'êtes pas sûr de vouloir que le curseur soit proportionnel à vos valeurs *, mais si c'est le cas, j'ai fourni une solution à ce problème pour quelqu'un d'autre qui a posé la même question. Vous pouvez trouver ma solution ici . Fondamentalement, je me sers de l'événement slide qui est déclenché lorsque vous déplacez le curseur pour imiter le pas à pas, mais basé sur un tableau personnalisé définissant les étapes. De cette façon, cela ne vous permet que de "passer" à vos valeurs prédéfinies, même si elles ne sont pas réparties de manière uniforme.

* En d'autres termes, si vous souhaitez que votre curseur ressemble à ceci:

|----|----|----|----|----|----|----|
0   10   20  100  1000 2000 10000 20000

ensuite, choisissez l'une des autres solutions ici, mais si vous souhaitez que votre curseur ressemble à ceci (le diagramme n'est pas à l'échelle):

|--|--|-------|-----------|-----------|--------------------|--------------------|
0 10 20     100         1000        2000               10000                20000

Ensuite, la solution que j'ai liée à peut être plus ce que vous recherchez.


Modifier: Ok, cette version du script devrait fonctionner avec deux curseurs:

$(function() {
    var values = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
    var slider = $("#price-range").slider({
        orientation: 'horizontal',
        range: true,
        min: 0,
        max: 1000000,
        values: [0, 1000000],
        slide: function(event, ui) {
            var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
            var includeRight = event.keyCode != $.ui.keyCode.LEFT;
            var value = findNearest(includeLeft, includeRight, ui.value);
            if (ui.value == ui.values[0]) {
                slider.slider('values', 0, value);
            }
            else {
                slider.slider('values', 1, value);
            }
            $("#price-amount").html('$' + slider.slider('values', 0) + ' - $' + slider.slider('values', 1));
            return false;
        },
        change: function(event, ui) { 
            getHomeListings();
        }
    });
    function findNearest(includeLeft, includeRight, value) {
        var nearest = null;
        var diff = null;
        for (var i = 0; i < values.length; i++) {
            if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
                var newDiff = Math.abs(value - values[i]);
                if (diff == null || newDiff < diff) {
                    nearest = values[i];
                    diff = newDiff;
                }
            }
        }
        return nearest;
    }
});

Notez que cela semble un peu drôle à l'extrême gauche, car les sauts sont très rapprochés par rapport à l'extrémité droite, mais vous pouvez voir sa progression comme vous le souhaitez si vous utilisez les flèches du clavier pour déplacer le curseur. La seule façon de contourner ce problème est de changer votre échelle pour ne pas être aussi radicalement exponentielle.


Edit 2:Ok. Si l’espacement est trop exagéré lorsque vous utilisez les valeurs vraies, vous pouvez utiliser un ensemble de valeurs factices pour le curseur, puis rechercher la valeur réelle à laquelle cela correspond lorsque vous devez utiliser la valeur réelle similaire à ce que les autres solutions suggérées ici). Voici le code:

$(function() {
    var trueValues = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
    var values =     [0,   1,   2,    3,    4,    5,    6,    7,    10,     15,     20,     25,     30,     40,     50,     60,     75,     100];
    var slider = $("#price-range").slider({
        orientation: 'horizontal',
        range: true,
        min: 0,
        max: 100,
        values: [0, 100],
        slide: function(event, ui) {
            var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
            var includeRight = event.keyCode != $.ui.keyCode.LEFT;
            var value = findNearest(includeLeft, includeRight, ui.value);
            if (ui.value == ui.values[0]) {
                slider.slider('values', 0, value);
            }
            else {
                slider.slider('values', 1, value);
            }
            $("#price-amount").html('$' + getRealValue(slider.slider('values', 0)) + ' - $' + getRealValue(slider.slider('values', 1)));
            return false;
        },
        change: function(event, ui) { 
            getHomeListings();
        }
    });
    function findNearest(includeLeft, includeRight, value) {
        var nearest = null;
        var diff = null;
        for (var i = 0; i < values.length; i++) {
            if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
                var newDiff = Math.abs(value - values[i]);
                if (diff == null || newDiff < diff) {
                    nearest = values[i];
                    diff = newDiff;
                }
            }
        }
        return nearest;
    }
    function getRealValue(sliderValue) {
        for (var i = 0; i < values.length; i++) {
            if (values[i] >= sliderValue) {
                return trueValues[i];
            }
        }
        return 0;
    }
});

Vous pouvez manipuler les nombres dans le tableau values (qui représente les points d'arrêt du curseur) jusqu'à ce que vous les obteniez espacés comme vous le souhaitez. De cette façon, vous pouvez vous sentir, du point de vue de l'utilisateur, comme si cela glissait proportionnellement aux valeurs, mais sans être aussi exagéré. Évidemment, si vos vraies valeurs sont créées dynamiquement, vous devrez peut-être créer un algorithme pour générer les valeurs de curseur au lieu de les définir de manière statique ...

53
Alconja

HTML:

<body>
   <p>
      Slider Value: <span id="val"></span><br/>
      Nonlinear Value: <span id="nlVal"></span><br/>
   </p>
   <div id="slider"></div>
</body>

JS:

    $(function() {
     var valMap = [0, 25,30,50,55,55,60,100];
     $("#slider").slider({
        // min: 0,
         max: valMap.length - 1,
         slide: function(event, ui) {
           $("#val").text(ui.value);
           $("#nlVal").text(valMap[ui.value]);
         }
     });
    });
13
Bharat Parmar

Une option pour vous est d'utiliser une taille d'étape de un et de référencer un tableau contenant les valeurs sélectionnées. Commencez à 0, allez jusqu'à 20, obtenez un tableau [value_of_slider] pour obtenir votre valeur réelle. Je ne connais pas assez bien les curseurs pour vous dire s'il existe ou non un moyen de lui attribuer un ensemble de valeurs personnalisé.

7
Seburdis

Sur la base de la réponse ci-dessus et de la discussion de @Seburdis, et en utilisant les noms de votre exemple:

var prices_array = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 250, 500, 1000, 1500, 2000, 2500, 5000, 10000];

function imSliding(event,ui)
{
    //update the amount by fetching the value in the value_array at index ui.value
    $('#amount').val('$' + prices_arr[ui.value] + ' - $' + prices_arr[prices_arr.length - 1]); 
}

$('#slider-interval').slider({ min:0, max:values_arr.length - 1, slide: imSliding});
6
karim79

Je pense pouvoir offrir une meilleure solution: L’idée est de conserver un tableau avec mes valeurs réelles en dehors du curseur, puis de définir l’attribut step sur 1 et de laisser le curseur fonctionner avec le index de ce tableau chercher la valeur réelle de mon tableau de données réelles. J'espère que cet exemple aide: http://jsfiddle.net/3B3tt/3/

5
Broshi

Quelqu'un a posté ceci sur le site Web de jQuery. Voir:

http://forum.jquery.com/topic/non-linear-logarithmic-or-exponential-scale-for-slider

et

http://jsbin.com/ezema

C'est exactement ce que vous avez, mais beaucoup plus simple (comme une ligne de code).

4
Nitroware

voici comment j'ai fait le mien. demo here - http://janpatricklara.com/web/extra/jQueryUISliderUnevenSteps.html

avoir un tableau de vos valeurs souhaitées

var amts=[50,100,150,200,225,250,300];

faites en sorte que le curseur incrémente de 0 à la longueur du tableau, avec des pas de 1 ., affiche la valeur à partir de l'index du tableau au lieu d'utiliser la valeur réelle du curseur.

de cette façon, les incréments et les étapes sont répartis uniformément. Après cela, vous pouvez simplement saisir la valeur de l'étiquette ou l'enregistrer dans un fichier var.

$('#amtslider').slider({
    min:0,
    max:amts.length-1,
    step:1,
    value:0,
    change:function(event, ui){
        //alert(amts[$(this).slider("value")]);
        //alert($(this).slider("value"));
        $('#lbl_amt').val(amts[$(this).slider("value")]);
    },
    slide:function(event, ui){
        $('#lbl_amt').val(amts[$(this).slider("value")]);
    }
});
3
jplara

Voici ma solution simple pour un double curseur personnalisé (vous pouvez le modifier en un seul curseur si l'idée est claire) Mon curseur s'appelle "slider-euro", le texte -la zone est nommée montant-euro comme vous pouvez le voir dans le code . L'idée est d'avoir un curseur de 0 à 100 et un tableau ("valeurs réelles") avec 101 places. La valeur du curseur est comprise comme la place dans ce tableau. La seule chose à faire est que vous devez référencer le tableau lorsque vous obtenez les valeurs du curseur . Voici mon exemple:

    $(function() {
    var realvalues = [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000, 105000, 110000, 115000, 120000, 125000, 130000, 135000, 140000, 145000, 150000, 155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000, 205000, 210000, 215000, 220000, 225000, 230000, 235000, 240000, 245000, 250000, 255000, 260000, 265000, 270000, 275000, 280000, 285000, 290000, 295000, 300000, 310000, 320000, 330000, 340000, 350000, 360000, 370000, 380000, 390000, 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000, 800000, 850000, 900000, 1000000, 1500000, 2000000];

    $( "#slider-euro" ).slider({
    range: true,
    min: 0,
    max: 100,
    step: 1,
    values: [ 25, 50 ],
    slide: function( event, ui ) {
    $( "#amount-euro" ).val( realvalues[ui.values[ 0 ]] + " € - " + realvalues[ui.values[ 1 ]] + " €");
    }
    });
    $( "#amount-euro" ).val( realvalues[$( "#slider-euro" ).slider( "values", 0 )] + " € - " + realvalues[$( "#slider-euro" ).slider( "values", 1 )]+" €" );
    });
2
omega

si les valeurs min et max sont identiques, la valeur du curseur ne change pas

changer cette partie

        if (ui.value == ui.values[0]) {
            slider.slider('values', 0, value);
        }
        else {
            slider.slider('values', 1, value);
        }

dans

        if ( ui.values[0] == ui.values[1] ) {
            slider.slider('values', 0, value);
            slider.slider('values', 1, value);
        }else{
            if (ui.value == ui.values[0]) {
                slider.slider('values', 0, value);
            }else {
                slider.slider('values', 1, value);
            }
        }
1
flex

Je devais faire quelque chose de similaire et même s'il s'agissait d'une réponse tardive, quelqu'un d'autre pourrait arriver à ce fil tout comme moi et trouver ma solution utile. Voici la solution que j'ai créée:

http://jsfiddle.net/YDWdu/

So apparently, postings containing links to jsfiddle "must be accompanied by code".
OK - here ya go, stackoverflow... Some lovely "code" for you.
1
Cesar

En complément du jsfiddle de @ Broshi ci-dessus, voici le code d'un curseur personnalisé avec plage désactivée:

jQuery:

var myData = [1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900,1000,2000,3000,4000,5000,10000,20000,30000,50000,100000,200000,500000,1000000,20000000,30000000];
slider_config = {
        range: false,
        min: 0,
        max: myData.length - 1,
        step: 1,
        slide: function( event, ui ) {
            // Set the real value into the inputs
            console.log(ui);
            $('#value').val( myData[ ui.value ] );
        },
        create: function() {
            $(this).slider('value',0);
        }
    };

$("#slider").slider(slider_config);

HTML:

<input id="value" />
<div id="slider"></div>
0
Eamorr

Il suffit de changer les valeurs.

$( "#price-range" ).slider({
        range: true,
        min: 1000,
        max: 300000000,
        /*step:1,*/
        values: [ 1000, 300000000 ],
        slide: function( event, ui ) {
            if(ui.values[0]<=100000 && ui.values[1]<=100000){
                $("#price-range").slider({step:10000});
            }else if(ui.values[0]<=300000 && ui.values[1]<=300000){
                $("#price-range").slider({step:25000});
            }else if(ui.values[0]<=1000000 && ui.values[1]<=1000000){
                $("#price-range").slider({step:50000});
            }else if(ui.values[0]<=2000000 && ui.values[1]<=2000000){
                $("#price-range").slider({step:100000});
            }else if(ui.values[0]<=5000000 && ui.values[1]<=5000000){
                $("#price-range").slider({step:250000});
            }else if(ui.values[0]<=10000000 && ui.values[1]<=10000000){
                $("#price-range").slider({step:500000});
            }else if(ui.values[0]<=20000000 && ui.values[1]<=20000000){
                $("#price-range").slider({step:1000000});
            }else if(ui.values[0]<=50000000 && ui.values[1]<=50000000){
                $("#price-range").slider({step:5000000});
            }else if(ui.values[0]<=50000000 && ui.values[1]<=50000000){
                $("#price-range").slider({step:10000000});
            }else if(ui.values[0]<=200000000 && ui.values[1]<=200000000){
                $("#price-range").slider({step:25000000});
            }else{
                $("#price-range").slider({step:100000000});
            }

            $("#mins").val( ui.values[0] );
            $("#maxs").val( ui.values[1] );

        }
    });
0
CJ Madolara