简体   繁体   中英

How do I replicate the functionality of this combination of php and jquery/js with *just* jquery/js?

I wrote a function called sliderinitialiser that initiates two jQuery sliders that I have placed onto my page - one for adjusting a Profit and Loss (PnL) value, and one for adjusting Turnover. The jQuery widget I am using is demonstrated here: http://jqueryui.com/slider/#range-vertical .

When the 'handles' of the two sliders are adjusted, they also adjust the values of a couple of associated 'Minimum' and 'Maximum' textboxes. These textboxes also have their onchange events triggered by the slider, so that they send their updated values to two arrays (minValueSTORE and maxValueSTORE) that are used as storage.

The working code that I started off with is shown below. I wish to reproduce this as a more efficient and flexible loop in pure javascript.

Initial Working Code (successful)

    <script>

    //Used to control the numerical/currency filters

    function sliderinitialiser() {

    //Initiates the PnL slider

    $(function() { 

        $( "#slider-range-PnL").slider({
          max:getminandmax('max','PnL'),
          min:getminandmax('min','PnL'),
          orientation: "vertical",
          range: true,
          values: [minValueSTORE['PnL'],maxValueSTORE['PnL']],
          slide: function( event, ui) {


            $( "#amountmin-PnL").val( "£" + ui.values[ 0 ]);
            $( "#amountmax-PnL").val( "£" + ui.values[ 1 ]);

            //alert(ui);

            var minid = "amountmin-PnL";
            var maxid = "amountmax-PnL";

            document.getElementById(minid).onchange();
            document.getElementById(maxid).onchange();
          }
        });

        $( "#amountmin-PnL").val("£" + minValueSTORE['PnL']);
        $( "#amountmax-PnL").val("£" + maxValueSTORE['PnL']);


       //Initiates the Turnover slider

        $( "#slider-range-Turnover").slider({
          max:getminandmax('max','Turnover'),
          min:getminandmax('min','Turnover'),
          orientation: "vertical",
          range: true,
          values: [minValueSTORE['Turnover'],maxValueSTORE['Turnover']],
          slide: function( event, ui) {

            $( "#amountmin-Turnover").val( "£" + ui.values[ 0 ]);
            $( "#amountmax-Turnover").val( "£" + ui.values[ 1 ]);

            //alert(ui);

            var minid = "amountmin-Turnover";
            var maxid = "amountmax-Turnover";

            document.getElementById(minid).onchange();
            document.getElementById(maxid).onchange();
          }
        });

        $( "#amountmin-Turnover").val("£" + minValueSTORE['Turnover']);
        $( "#amountmax-Turnover").val("£" + maxValueSTORE['Turnover']);


  });
  }

  </script>

The code above seems to work correctly. However, there are a number of these filters that I wish to implement and therefore I thought that making use of a loop would be the most efficient means of doing this.

I am more experienced with php than javascript, and I am able to use a php array and loop to replicate the above code, as shown in the code sample below:

Loop Implementation using PHP (successful)

    function sliderinitialiser() {

    $(function() {

    //construct an array to hold the columns with sliders that need to be initialised

    <?php $sliders = ['PnL','Turnover']; 


    for ($sliderindex = 0; $sliderindex < 2; $sliderindex++) { ?>

        //console.log(sliderindex);

        $( "#slider-range-<?php echo $sliders[$sliderindex] ?>").slider({
          max:getminandmax('max','<?php echo  $sliders[$sliderindex] ?>'),
          min:getminandmax('min','<?php  echo  $sliders[$sliderindex] ?>'),
          orientation: "vertical",
          range: true,
          values: [minValueSTORE['<?php echo   $sliders[$sliderindex] ?>'],maxValueSTORE['<?php echo   $sliders[$sliderindex] ?>']],
          slide: function( event, ui) {


            $( "#amountmin-<?php echo   $sliders[$sliderindex] ?>").val( "£" + ui.values[ 0 ]);
            $( "#amountmax-<?php echo   $sliders[$sliderindex] ?>").val( "£" + ui.values[ 1 ]);

            //alert(ui);

            var minid = "amountmin-<?php echo   $sliders[$sliderindex] ?>";
            var maxid = "amountmax-<?php  echo  $sliders[$sliderindex] ?>";

            document.getElementById(minid).onchange();
            document.getElementById(maxid).onchange();
          }
        });

        $( "#amountmin-<?php  echo  $sliders[$sliderindex] ?>").val("£" + minValueSTORE['<?php  echo  $sliders[$sliderindex] ?>']);
        $( "#amountmax-<?php  echo  $sliders[$sliderindex] ?>").val("£" + maxValueSTORE['<?php  echo  $sliders[$sliderindex] ?>']);

<?php    } ?>

  });
  }

The above code appears to work as required.

Now, as I understand it, it is not considered good practice to use php to generate javascript code. Therefore I would like to replicate the functionality of the code above, but do so entirely in javascript/jquery.

I attempted to do with the following code, but this did not work properly. I could not adjust the handle on the slider, and Chrome Developer Tools indicated the following error:

    Uncaught TypeError: Cannot read property 'onchange' of null

Loop Implementation using pure JavaScript (unsuccessful)

Here is the code I used:

    function sliderinitialiser() {

    var sliderindex = 0;

    $(function() {

    //construct an array to hold the columns with sliders that need to be initialised

    var sliders = ['PnL','Turnover'];
    var sliderindex = 0;

    for (sliderindex = 0; sliderindex < sliders.length; sliderindex++) {

        //first console log
        console.log(sliderindex);

        $( "#slider-range-" + sliders[sliderindex] ).slider({
          max:getminandmax('max',sliders[sliderindex]),
          min:getminandmax('min',sliders[sliderindex]),
          orientation: "vertical",
          range: true,
          values: [minValueSTORE[sliders[sliderindex]],maxValueSTORE[sliders[sliderindex]]],
          slide: function( event, ui) {

            //second console log
            console.log(sliderindex);                

            $( "#amountmin-" + sliders[sliderindex] ).val( "£" + ui.values[ 0 ]);
            $( "#amountmax-" + sliders[sliderindex] ).val( "£" + ui.values[ 1 ]);

            //alert(ui);

            var minid = "amountmin-" + sliders[sliderindex];
            var maxid = "amountmax-" + sliders[sliderindex];

            document.getElementById(minid).onchange();
            document.getElementById(maxid).onchange();
          }
        });

        $( "#amountmin-" + sliders[sliderindex] ).val("£" + minValueSTORE[sliders[sliderindex]]);
        $( "#amountmax-" + sliders[sliderindex] ).val("£" + maxValueSTORE[sliders[sliderindex]]);

    }



  });


  }

Debugging Results

Regarding debugging, I have placed console.log lines in the code, as you can see.

When sliderinitialiser is called for the first time (on initial page load), the output of the first console.log is 0, then 1. This is as expected.

However, as soon as I attempt to move the handles of the slider, the second console.log outputs 2 continuously.

I have tried declaring sliderindex 'manually' within the slide callback function (ie adding in the line 'var sliderindex=1'), and if I do this, then one of the sliders has functionality.

This is my first question on stackoverflow. I have been working at this and researching it for a long time today and have not found a solution thus far.

@William Gordon

You want to look into Variable scope and hoisting for javascript as it can get confusing if you are not familiar with it.

One of the hoisting problems I see in your code is redeclaring sliderindex inside anonymous function.

Additionally you may want to use the .on('event', function(){}) instead of .onchange . Since you are using jQuery selectors in this code block its recommended that you stick with using same selector method throughout the remained of your code use $() instead of javascript's document.getElementByID .

Try making those changes to the code to see if that resolved it. Please provide debug information for additional help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM