diff --git a/common/lib/xmodule/xmodule/gst_module.py b/common/lib/xmodule/xmodule/gst_module.py index 87ce2a8b68..0d6677c2ff 100644 --- a/common/lib/xmodule/xmodule/gst_module.py +++ b/common/lib/xmodule/xmodule/gst_module.py @@ -85,7 +85,7 @@ class GraphicalSliderToolModule(XModule): #substitute sliders slider_div = '
\
' for var in variables: # find $slider var='var' ... $ @@ -151,7 +151,7 @@ class GraphicalSliderToolModule(XModule): """ # root added for interface compatibility with xmltodict.parse self.configuration_json = json.dumps( - xmltodict.parse('' + + xmltodict.parse('' + stringify_children(self.definition['configuration']) + '')) return self.configuration_json diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js index 14594a7b3b..385386eebc 100644 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js +++ b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js @@ -268,7 +268,7 @@ define('Graph', ['logme'], function (logme) { } function addFunction(funcString, color, line, dot, label) { - var newFunctionObject, func, constNames; + var newFunctionObject, func, paramNames; // The main requirement is function string. Without it we can't // create a function, and the series cannot be calculated. @@ -283,19 +283,19 @@ define('Graph', ['logme'], function (logme) { 'dot': false }; - // Get all of the constant names defined by the user in the + // Get all of the parameter names defined by the user in the // XML. - constNames = state.getAllConstantNames(); + paramNames = state.getAllParameterNames(); // The 'x' is always one of the function parameters. - constNames.push('x'); + paramNames.push('x'); // Must make sure that the function body also gets passed to // the Function constructor. - constNames.push(funcString); + paramNames.push(funcString); // Create the function from the function string, and all of the - // available constants + the 'x' variable as it's parameters. + // available parameters AND the 'x' variable as it's parameters. // For this we will use the built-in Function object // constructor. // @@ -303,7 +303,7 @@ define('Graph', ['logme'], function (logme) { // likely the user supplied an invalid JavaScript function body // string. In this case we will not proceed. try { - func = Function.apply(null, constNames); + func = Function.apply(null, paramNames); } catch (err) { // Let's tell the user. He will see a nice red error // message instead of a graph. @@ -363,9 +363,9 @@ define('Graph', ['logme'], function (logme) { } function generateData() { - var c0, functionObj, seriesObj, dataPoints, constValues, x, y; + var c0, functionObj, seriesObj, dataPoints, paramValues, x, y; - constValues = state.getAllConstantValues(); + paramValues = state.getAllParameterValues(); dataSeries = []; @@ -379,16 +379,16 @@ define('Graph', ['logme'], function (logme) { for (x = xrange.start; x <= xrange.end; x += xrange.step) { // Push the 'x' variable to the end of the parameter array. - constValues.push(x); + paramValues.push(x); // We call the user defined function, passing all of the - // available constant values. inside this function they + // available parameter values. Inside this function they // will be accessible by their names. - y = functionObj.func.apply(window, constValues); + y = functionObj.func.apply(window, paramValues); - // Return the constValues array to how it was before we + // Return the paramValues array to how it was before we // added 'x' variable to the end of it. - constValues.pop(); + paramValues.pop(); // Add the generated point to the data points set. dataPoints.push([x, y]); diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js index 0b46eb42bb..4d5d1d12ae 100644 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js +++ b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js @@ -8,26 +8,29 @@ define( // Even though it is not explicitly in this module, we have to specify // 'GeneralMethods' as a dependency. It expands some of the core JS objects // with additional useful methods that are used in other modules. - ['State', 'GeneralMethods', 'Sliders', 'Inputs', 'Graph'], - function (State, GeneralMethods, Sliders, Inputs, Graph) { + ['State', 'GeneralMethods', 'Sliders', 'Inputs', 'Graph', 'logme'], + function (State, GeneralMethods, Sliders, Inputs, Graph, logme) { return GstMain; function GstMain(gstId) { - var config, state; + var config, gstClass, state; // Get the JSON configuration, and parse it, and store as an object. config = JSON.parse($('#' + gstId + '_json').html()).root; + gstClass = config['@class']; + logme('gstClass: ' + gstClass); + // Parse the configuration settings for sliders and text inputs, and // extract all of the defined constants (their names along with their // initial values). - state = State(gstId, config); + state = State(gstId, gstClass, config); // Create the sliders and the text inputs, attaching them to // approriate constants. - Sliders(gstId, config, state); - Inputs(gstId, config, state); + Sliders(gstId, gstClass, state); + Inputs(gstId, gstClass, state); // Configure and display the loop. Attach event for the graph to be // updated on any change of a slider or a text input. diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js index b5d3217a85..0365f40ea5 100644 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js +++ b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js @@ -2,108 +2,60 @@ // define() functions from Require JS available inside the anonymous function. (function (requirejs, require, define) { -define('Inputs', [], function () { +define('Inputs', ['logme'], function (logme) { return Inputs; - function Inputs(gstId, config, state) { - var constNamesUsed; + function Inputs(gstId, gstClass, state) { + var c1, paramName, allParamNames; - // There should not be more than one text input per a constant. This - // just does not make sense. However, nothing really prevents the user - // from specifying more than one text input for the same constant name. - // That's why we have to track which constant names already have - // text inputs for them, and prevent adding further text inputs to - // these constants. - // - // constNamesUsed is an object to which we will add properties having - // the name of the constant to which we are adding a text input to. - // When creating a new text input, we must consult with this object, to - // see if the constant name is not defined as it's property. - constNamesUsed = {}; + allParamNames = state.getAllParameterNames(); - // We will go thorugh all of the inputs, and those that have a valid - // '@var' property will be added to the page as a HTML text input - // element. - if ((typeof config.inputs !== 'undefined') && - (typeof config.inputs.input !== 'undefined')) { - if ($.isArray(config.inputs.input)) { + console.log(allParamNames); - // config.inputs.input is an array. For each element, we will - // add a text input. - for (c1 = 0; c1 < config.inputs.input.length; c1++) { - createInput(config.inputs.input[c1]); + for (c1 = 0; c1 < allParamNames.length; c1 += 1) { + $('#' + gstId).children('.' + gstClass + '_input').each(function (index, value) { + var inputDiv, paramName; + + paramName = allParamNames[c1]; + + inputDiv = $(value); + + if (paramName === inputDiv.data('var')) { + createInput(inputDiv, paramName); } - } else if ($.isPlainObject(config.inputs.input)) { - - // config.inputs.input is an object. Add a text input for it. - createInput(config.inputs.input); - - } + }); } - function createInput(obj) { - var constName, constValue, spanEl, inputEl, readOnly; + return; - // The name of the constant is obj['@var']. If it is not specified, - // we will skip creating a text input for this constant. - if (typeof obj['@var'] !== 'string') { - return; - } - constName = obj['@var']; + function createInput(inputDiv, paramName) { + var paramObj, inputWidth, readOnly; - // We will not add a text input for a constant which already has a - // text input defined for it. - // - // We will add the constant name to the 'constNamesUsed' object in - // the end, when everything went successfully. - if (constNamesUsed.hasOwnProperty(constName)) { - return; + paramObj = state.getParamObj(paramName); + + // We will define the width of the slider to a sensible default. + inputWidth = 400; + + // See if it was specified by the user. + if (isFinite(parseInt(inputDiv.data('el_width'))) === true) { + inputWidth = parseInt(inputDiv.data('el_width')); } - // Multiple sliders and/or inputs can represent the same constant. - // Therefore we will get the most recent const value from the state - // object. If it is undefined, we will skip creating a text input - // for this constant. - constValue = state.getConstValue(constName); - if (constValue === undefined) { - return; + // Set the width of the element. + inputDiv.width(inputWidth); + + inputDiv.css('display', 'inline-block'); + + readOnly = false; + if (inputDiv.attr('data-el_readonly').toLowerCase() === 'true') { + readOnly = true; } - // With the constant name, and the constant value being defined, - // lets get the element on the page into which the text input will - // be inserted. - spanEl = $('#' + gstId + '_input_' + constName); - - // If a corresponding element for this constant does not exist on - // the page, we will not be making a text input. - if (spanEl.length === 0) { - return; - } - - // Create the text input element. - inputEl = $(''); - - // Set the current constant to the text input. It will be visible - // to the user. - inputEl.val(constValue); - - // Before binding a 'change' event, we will check if this text - // input is specified as 'read only'. - // - // By default, this setting is false - the user can change the - // value in the text input. - readonly = false; - if (typeof obj['@readonly'] === 'string') { - if (obj['@readonly'] === 'true') { - readonly = true; - } - } - - if (readonly === true) { + if (readOnly === true) { // In the case of a readonly config option, configure the text // inputit as read-only, and NOT bind an event to it. - inputEl.attr('readonly', 'readonly'); + inputDiv.attr('readonly', 'readonly'); } else { // readonly !== true @@ -111,14 +63,16 @@ define('Inputs', [], function () { // the value of this text input, and presses 'enter' (or clicks // somewhere else on the page), this event will be triggered, and // our callback will be called. - inputEl.bind('change', inputOnChange); + inputDiv.bind('change', inputOnChange); } + inputDiv.val(paramObj.value); + // Lets style the input element nicely. We will use the button() // widget for this since there is no native widget for the text // input. - inputEl.button().css({ + inputDiv.button().css({ 'font': 'inherit', 'color': 'inherit', 'text-align': 'left', @@ -128,19 +82,22 @@ define('Inputs', [], function () { // 'width': '50px' }); - // And finally, publish the text input element to the page. - inputEl.appendTo(spanEl); - - // Don't forget to add the constant to the list of used constants. - // Next time a slider for this constant will not be created. - constNamesUsed[constName] = true; + paramObj.inputDivs.push(inputDiv); return; - // When the user changes the value of this text input, the 'state' - // will be updated, forcing the plot to be redrawn. + // Update the 'state' - i.e. set the value of the parameter this + // input is attached to to a new value. + // + // This will cause the plot to be redrawn each time after the user + // changes the value in the input. Note that he has to either press + // 'Enter', or click somewhere else on the page in order for the + // 'change' event to be tiggered. function inputOnChange(event) { - state.setConstValue(constName, $(this).val()); + var inputDiv; + + inputDiv = $(this); + state.setParameterValue(paramName, inputDiv.val(), inputDiv); } } } diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js index ef3d5bb6d3..f41a43fde7 100644 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js +++ b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js @@ -2,222 +2,70 @@ // define() functions from Require JS available inside the anonymous function. (function (requirejs, require, define) { -define('Sliders', [], function () { +define('Sliders', ['logme'], function (logme) { return Sliders; - function Sliders(gstId, config, state) { - var constNamesUsed; + function Sliders(gstId, gstClass, state) { + var c1, paramName, allParamNames, sliderDiv; - // There should not be more than one slider per a constant. This just - // does not make sense. However, nothing really prevents the user from - // specifying more than one slider for the same constant name. That's - // why we have to track which constant names already have sliders for - // them, and prevent adding further sliders to these constants. - // - // constNamesUsed is an object to which we will add properties having - // the name of the constant to which we are adding a slider to. When - // creating a new slider, we must consult with this object, to see if - // the constant name is not defined as it's property. - constNamesUsed = {}; + allParamNames = state.getAllParameterNames(); - // We will go through all of the sliders. For each one, we will make a - // jQuery UI slider for it, attach "on change" events, and set it's - // state - initial value, max, and min parameters. - if ((typeof config.sliders !== 'undefined') && - (typeof config.sliders.slider !== 'undefined')) { - if ($.isArray(config.sliders.slider)) { + for (c1 = 0; c1 < allParamNames.length; c1 += 1) { + paramName = allParamNames[c1]; - // config.sliders.slider is an array. For each object in the - // array, create a slider. - for (c1 = 0; c1 < config.sliders.slider.length; c1++) { - createSlider(config.sliders.slider[c1]); - } - - } else if ($.isPlainObject(config.sliders.slider)) { - - // config.sliders.slider is an object. Create a slider for it. - createSlider(config.sliders.slider); + logme('Looking for slider with ID: ' + gstId + '_slider_' + paramName); + sliderDiv = $('#' + gstId + '_slider_' + paramName); + if (sliderDiv.length === 1) { + logme('Found one slider DIV with such an ID.'); + createSlider(sliderDiv, paramName); + } else { + logme('Did not find such a slider.'); } } - function createSlider(obj) { - var constName, constValue, rangeBlobs, valueMin, valueMax, spanEl, - sliderEl, sliderWidth; + function createSlider(sliderDiv, paramName) { + var paramObj, sliderWidth; - // The name of the constant is obj['@var']. If it is not specified, - // we will skip creating a slider for this constant. - if (typeof obj['@var'] !== 'string') { - return; - } - constName = obj['@var']; - - // We will not add a slider for a constant which already has a - // slider defined for it. - // - // We will add the constant name to the 'constNamesUsed' object in - // the end, when everything went successfully. - if (constNamesUsed.hasOwnProperty(constName)) { - return; - } - - // Multiple sliders and/or inputs can represent the same constant. - // Therefore we will get the most recent const value from the state - // object. If it is undefined, then something terrible has - // happened! We will skip creating a slider for this constant. - constValue = state.getConstValue(constName); - if (constValue === undefined) { - return; - } - - // The range is a string composed of 3 blobs, separated by commas. - // The first blob is the min value for the slider, the third blob - // is the max value for the slider. - if (typeof obj['@range'] !== 'string') { - - // If the range is not a string, we will set a default range. - // No promise as to the quality of the data points that this - // range will produce. - valueMin = constValue - 10; - valueMax = constValue + 10; - - } else { - - // Separate the range string by commas, and store each blob as - // an element in an array. - rangeBlobs = obj['@range'].split(','); - - // We must have gotten exactly 3 blobs (pieces) from the split. - if (rangeBlobs.length !== 3) { - - // Set some sensible defaults, if the range string was - // split into more or less than 3 pieces. - setDefaultMinMax(); - - } else { - - // Get the first blob from the split string. It is the min - // value. - valueMin = parseFloat(rangeBlobs[0]); - - // Is it a well-formed float number? - if (isNaN(valueMin) === true) { - - // No? Then set a sensible default value. - valueMin = constValue - 10; - - } - - // Get the third blob from the split string. It is the max. - valueMax = parseFloat(rangeBlobs[2]); - - // Is it a well-formed float number? - if (isNaN(valueMax) === true) { - - // No? Then set a sensible default value. - valueMax = constValue + 10; - - } - - // Logically, the min, value, and max should make sense. - // I.e. we will make sure that: - // - // min <= value <= max - // - // If this is not the case, we will set some defaults. - if ((valueMin > valueMax) || - (valueMin > constValue) || - (valueMax < constValue)) { - - // Set some sensible defaults, if min/value/max logic - // is broken. - setDefaultMinMax(); - - } - } - } - - // At this point we have the constant name, the constant value, and - // the min and max values for this slider. Lets get the element on - // the page into which the slider will be inserted. - spanEl = $('#' + gstId + '_slider_' + constName); - - // If a corresponding element for this constant does not exist on - // the page, we will not be making a slider. - if (spanEl.length === 0) { - return; - } - - // Create the slider DIV. - sliderEl = $('
'); + paramObj = state.getParamObj(paramName); // We will define the width of the slider to a sensible default. sliderWidth = 400; - // Then we will see if one is provided in the config for this - // slider. If we find it, and it is a well-formed integer, we will - // use it, instead of the default width. - if (typeof obj['@width'] === 'string') { - if (isNaN(parseInt(obj['@width'], 10)) === false) { - sliderWidth = parseInt(obj['@width'], 10); - } + // See if it was specified by the user. + if (isFinite(parseInt(sliderDiv.data('el_width'))) === true) { + sliderWidth = parseInt(sliderDiv.data('el_width')); } - // Set the defined width to the slider. - // sliderEl.width(sliderWidth); + // Set the width of the element. + sliderDiv.width(sliderWidth); - console.log('[Before]'); - console.log('sliderEl.width: ' + sliderEl.width()); - - sliderEl.width(spanEl.data('el_width')); - - console.log('[After]'); - console.log('sliderEl.width: ' + sliderEl.width()); - - // And make sure that it gets added to the page as an - // 'inline-block' element. This will allow for the insertion of the - // slider into a paragraph, without the browser forcing it out of - // the paragraph onto a new line, separate line. - sliderEl.css('display', 'inline-block'); + sliderDiv.css('display', 'inline-block'); // Create a jQuery UI slider from the slider DIV. We will set // starting parameters, and will also attach a handler to update // the 'state' on the 'change' event. - sliderEl.slider({ - 'min': valueMin, - 'max': valueMax, - 'value': constValue, - 'step': (valueMax - valueMin) / 50.0, + sliderDiv.slider({ + 'min': paramObj.min, + 'max': paramObj.max, + 'value': paramObj.value, + 'step': paramObj.step, // 'change': sliderOnChange, - 'slide': sliderOnChange + 'slide': sliderOnSlide }); - // Append the slider DIV to the element on the page where the user - // wants to see it. - sliderEl.appendTo(spanEl); - - // OK! So we made it this far... - // - // Adding the constant to the list of used constants. Next time a - // slider for this constant will not be created. - constNamesUsed[constName] = true; + paramObj.sliderDiv = sliderDiv; return; - // Update the 'state' - i.e. set the value of the constant this + // Update the 'state' - i.e. set the value of the parameter this // slider is attached to to a new value. // // This will cause the plot to be redrawn each time after the user // drags the slider handle and releases it. - function sliderOnChange(event, ui) { - state.setConstValue(constName, ui.value); - } - - // The sensible defaults for the slider's range. - function setDefaultMinMax() { - valueMin = constValue - 10; - valueMax = constValue + 10; + function sliderOnSlide(event, ui) { + state.setParameterValue(paramName, ui.value, sliderDiv); } } } diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js index c647f96846..ed0ca6ac8b 100644 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js +++ b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js @@ -13,11 +13,22 @@ define('State', ['logme'], function (logme) { return State; // function: State - function State(gstId, config) { - var parameters, allParameterNames, allParameterValues, plotDiv; + function State(gstId, gstClass, config) { + var parameters, allParameterNames, allParameterValues, + plotDiv; + // Initially, there are no parameters to track. So, we will instantiate + // an empty object. + // + // As we parse the JSON config object, we will add parameters as + // named properties (for example + // + // parameters.a = {...}; + // + // for the parameter 'a'. parameters = {}; + // Check that the required object is available. if ( (typeof config.parameters !== 'undefined') && (typeof config.parameters.param !== 'undefined') @@ -28,7 +39,7 @@ define('State', ['logme'], function (logme) { if ($.isArray(config.parameters.param) === true) { (function (c1) { while (c1 < config.parameters.param.length) { - addConstFromInput(config.parameters.param[c1]); + processParameter(config.parameters.param[c1]); c1 += 1; } }(0)); @@ -37,44 +48,53 @@ define('State', ['logme'], function (logme) { // If config.parameters.param is an object, pass this object to the // processor directly. else if ($.isPlainObject(config.inputs.input) === true) { - addConstFromInput(config.parameters.param); + processParameter(config.parameters.param); } } + // Instead of building these arrays every time when some component + // requests them, we will create them in the beginning, and then update + // by element when some parameter's value changes. + // + // Then we can just return the required array, instead of iterating + // over all of the properties of the 'parameters' object, and + // extracting their names/values one by one. + allParameterNames = []; + allParameterValues = []; + + generateHelperArrays(); + + logme(parameters, allParameterNames, allParameterValues); + // The constructor will return an object with methods to operate on // it's private properties. return { 'getParameterValue': getParameterValue, 'setParameterValue': setParameterValue, + 'getParamObj': getParamObj, + 'getAllParameterNames': getAllParameterNames, 'getAllParameterValues': getAllParameterValues, 'bindUpdatePlotEvent': bindUpdatePlotEvent }; - // #################################################################### - // - // To get all parameter names, you would do: - // - // allParamNames = getAllParameterProperties('name'); - // - // To get all parameter values, you would do: - // - // allParamValues = getAllParameterProperties('value'); - // - // #################################################################### - function getAllParameterProperties(propertyName) { - var paramName, allParamProperties; + function getAllParameterNames() { + return allParameterNames; + } - allParamProperties = []; + function getAllParameterValues() { + return allParameterValues; + } - for (paramName in parameters) { - allParamProperties.push(parameters[paramName][propertyName]); + function getParamObj(paramName) { + if (parameters.hasOwnProperty(paramName) === false) { + return; } - return allParamProperties; + return parameters[paramName]; } function bindUpdatePlotEvent(newPlotDiv, callback) { @@ -118,6 +138,8 @@ define('State', ['logme'], function (logme) { // the stored value in the parameter with the new value, and also // update all of the text inputs and the slider that correspond to this // parameter (if any), so that they reflect the new parameter's value. + // Finally, the helper array 'allParameterValues' will also be updated + // to reflect the change. // // If something went wrong (for example the new value is outside the // allowed range), then we will reset the 'element' to display the @@ -125,29 +147,50 @@ define('State', ['logme'], function (logme) { // // #################################################################### function setParameterValue(paramName, paramValue, element) { - var inputDiv; + var paramValueNum, c1; - if (constants.hasOwnProperty(constName) === false) { - // If the name of the constant is not tracked by state, return an - // 'undefined' value. + // If a parameter with the name specified by the 'paramName' + // parameter is not tracked by state, do not do anything. + if (parameters.hasOwnProperty(paramName) === false) { return; } - if (isNaN(parseFloat(constValue)) === true) { - // We are interested only in valid float values. + // Try to convert the passed value to a valid floating-point + // number. + paramValueNum = parseFloat(paramValue); + + if ( + // We are interested only in valid float values. NaN, -INF, + // +INF we will disregard. + (isFinite(paramValueNum) === false) || + + // If the new parameter's value is valid, but lies outised of + // the parameter's allowed range, we will also disregard it. + (paramValueNum < parameters[paramName].min) || + (paramValueNum > parameters[paramName].max) + ) { + // We will also change the element's value back to the current + // parameter's value. + element.val(parameters[paramName].value); + return; } - constants[constName] = parseFloat(constValue); + parameters[paramName].value = paramValueNum; if (plotDiv !== undefined) { plotDiv.trigger('update_plot'); } - inputDiv = $('#' + gstId + '_input_' + constName).children('input'); - if (inputDiv.length !== 0) { - inputDiv.val(constValue); + for (c1 = 0; c1 < parameters[paramName].inputDivs.length; c1 += 1) { + parameters[paramName].inputDivs[c1].val(paramValueNum); } + + if (parameters[paramName].sliderDiv !== null) { + parameters[paramName].sliderDiv.slider('value', paramValueNum); + } + + allParameterValues[parameters[paramName].helperArrayIndex] = paramValueNum; } // End-of: function setParameterValue // #################################################################### @@ -156,7 +199,8 @@ define('State', ['logme'], function (logme) { // ------------------------------- // // - // This function will be run once for each instance of a GST. + // This function will be run once for each instance of a GST when + // parsing the JSON config object. // // 'newParamObj' must be empty from the start for each invocation of // this function, that's why we will declare it locally. @@ -201,6 +245,7 @@ define('State', ['logme'], function (logme) { if ( (processFloat('@min', 'min') === false) || (processFloat('@max', 'max') === false) || + (processFloat('@step', 'step') === false) || (processFloat('@initial', 'value') === false) ) { logme('---> Not adding a parameter named "' + paramName + '".'); @@ -208,7 +253,10 @@ define('State', ['logme'], function (logme) { return; } - constants[constName] = constValue; + newParamObj.inputDivs = []; + newParamObj.sliderDiv = null; + + parameters[paramName] = newParamObj; return; @@ -234,11 +282,29 @@ define('State', ['logme'], function (logme) { } } - newParamObj[newAttrName] = paramValue; + newParamObj[newAttrName] = attrValue; return true; } // End-of: function processFloat } // End-of: function processParameter + + // Populate 'allParameterNames' and 'allParameterValues' with data. + // Link each parameter object with the corresponding helper array via + // an index ('helperArrayIndex'). It will be the same for both of the + // arrays. + function generateHelperArrays() { + var paramName, c1; + + c1 = 0; + for (paramName in parameters) { + allParameterNames.push(paramName); + allParameterValues.push(parameters[paramName].value); + + parameters[paramName].helperArrayIndex = c1; + + c1 += 1; + } + } } // End-of: function State });