Search code examples
javascriptjqueryjquery-eventsmultiple-instancesjquery-knob

jQuery Knob - Return values of multiple knobs on-demand?


[jsFiddle][1]

I need to access the correct (displayed) [knob][2] values on demand with jQuery. I know about the 'change' function, but I need to access the values of multiple knobs at once.

I need to multiply each of these knob's values by specific amounts and then sum the result; Is there a way to get the 'change' function to supply the knob's id or some other identifying attribute so my script can tell their values apart?

This calculate function is what I have so far, I've made it trigger on every knob's 'change' and when a button is clicked:

function calculate() {
    var result = 0;
    $('.dial').each(function (e) {
        result += $(this).val(); //Multiply by 1 to get an int
    });
    $('#result').text((typeof result) + ' ' + result); //Why is this a string in the first place?
} 

With this to set up the knobs:

$('.dial').each(function (e) {
        $(this).knob({
            max: 99,
            width: 120,
            height: 120,
            bgColor: '#85d4b0',
            fgColor: '#0ca961',
            inputColor: '#0ca961',
            thickness: 0.15,
            change: function (v) {
                console.log(v, this.v, this.cv);
                calculate(); //I need it to (re-)calculate every time any knob's value changes
            }
        });
    }

.val() doesn't work because it seems to be lagging behind; the first time it's run it doesn't update the result and the consecutive times it does, but it changes it to that of the previous value.

Any ideas?

Edit: If I could get the id of the knob whose value changed, I could do the following:

var knobs = [{
    id: '',
    val: 0
}];
$('.dial').each(function () {
    $(this).knob({change: function(v, id){
        knobsMod(v, id);
    }});
});
$('.dial').parent().each(function (e) {
        $(this).attr('id', 'knob'+e);
        if (e > (knobs.length - 1)) {
            knobs[e] = $.extend({}, knobs[0]);
        }
        knobs[e].id = $(this).attr('id');
        knobs[e].val = $(this).val()*1;
});
function knobsMod(v, id){
    for (var i = 0; i < knobs.length; i++){
        if (knobs[i].id === id){
            knobs[i].val = v;
            break;
        }
    }
}

And then it could just read the knobs object whenever it recalculates. [1]: http://jsfiddle.net/SoullessWaffle/2mt2U/ [2]: http://anthonyterrien.com/knob/


Solution

  • It turned out I didn't need an id to tell them apart.

    var knobs = [],
        cdata = [
            {name: 'knob0', value: 1},
            {name: 'knob1', value: 2},
            {name: 'knob2', value: 5},
            {name: 'knob3', value: 200},
            {name: 'knob4', value: 400},
            {name: 'knob5', value: 800},
            {name: 'knob6', value: 1000},
            {name: 'knob7', value: 2000},
            {name: 'knob8', value: 3000},
            {name: 'knob9', value: 5000},
            {name: 'knob10', value: 8000},
            {name: 'knob11', value: 10000},
            {name: 'knob12', value: 20000},
            {name: 'knob13', value: 1200},
            {name: 'knob14', value: 8000},
            {name: 'knob15', value: 12000},
            {name: 'knob16', value: 12000},
            {name: 'knob17', value: 12000},
            {name: 'knob18', value: 12000},
            {name: 'knob19', value: 12000},
            {name: 'knob20', value: 16000},
            {name: 'knob21', value: 16000},
            {name: 'knob22', value: 16000},
            {name: 'knob23', value: 18000},
            {name: 'knob24', value: 20000}
        ];
    $(document).ready(function () {
        $('.dial').each(function (e) {
            knobs.push(0);
            $(this).knob({
                max: 99,
                width: 120,
                height: 120,
                bgColor: '#85d4b0',
                fgColor: '#0ca961',
                inputColor: '#0ca961',
                thickness: 0.15,
                change: function (v) {
                    knobs[e] = v; //e can be used as an identifier
                    console.log(calculate());
                }
            });
        });
    });
    
    function calculate() {
        var result = 0;
        for (var i = 0; i < cdata.length; i++){
            result += knobs[i] * cdata[i].value;
        }
        return result;
    }
    

    Here I'm using e as an identifier, which allows me to maintain an array of knob values and thus store every knob's value individually.

    Then the calculate(); function reads the array and multiplies each value by a specific amount (as specified in cdata) and returns the result.