Link to home
Start Free TrialLog in
Avatar of ramesh4046
ramesh4046

asked on

Jquery/javascript to select the simple slider range values

I am relatively new to scripting languages like PHP, javascript. This is what am trying to do. I have a huge CSV file. I am trying to display the CSV file in my web page in a paginated format. I am including a jquery simple slider to select the range values. Once the range values are selected, I need to display only those rows satisfying the given criteria. I am done with most part of the project with help from many online resources.

The working example of my project can be found at,

My work so far

Now, I have to update the web page based on the slider values that I selected. For this reason, I am having the SUBMIT button in my page. Once the submit button is clicked, I need to display the web page with the updated values from CSV file.

This is the code I have so far.

<!DOCTYPE html>
<html>
<!-- Include jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="js/simple-slider.js"></script>
<?php include 'index.php'; ?>
<?php 
&#9;  $totalcolumns = $_SESSION["totalcolumns"];
?>

<!-- Include Simple Slider JavaScript and CSS -->
<link href="css/simple-slider.css" rel="stylesheet" type="text/css" />
<link href="css/simple-slider-volume.css" rel="stylesheet" type="text/css" /> 
<script src="css/simple-slider.js"></script>
<link href="css/simple-slider.css" rel="stylesheet" type="text/css" />

<!-- Activate Simple Slider on your input -->
  <h2>Keyword Scores</h2>
  <?php
 
$i = 1;
while (++$i <= $_SESSION['totalcolumns']) {
    $range = $_SESSION["min-column-$i"] . ',' . $_SESSION["max-column-$i"];?>
&#9;    <br><?php echo "Keyword" ?>
&#9;    <?php echo $i -1 ?>
&#9;&#9;<br><input type="text" data-slider="true" data-slider-range="<?php echo $range ?>" data-slider-step="1">
&#9;&#9;<?php } ?>
&#9;&#9;
 <a href="delete" id="delbtn">delete</a>
 <script>
      $(document).ready(function(){

                $('#delbtn').click(function(){
                         var val = $("[data-slider]").slider("option", "value");
                         return val;

                 });
      });
</script>

 <!--<input type="text" data-slider="true" data-slider-range="1,500" data-slider-step="1"> 

 <form action = "update.php" method="post"><input type="submit" name="submit"value="SUBMIT" ></form>

 
 <script>
    $("[data-slider]")
        .each(function () {
&#9;&#9; 
            var range;
            var input = $(this);
            $("<span>").addClass("output")
                .insertAfter(input);
            range = input.data("slider-range").split(",");
            $("<span>").addClass("range")
                .html(range[0])
                .insertBefore(input);
            $("<span>").addClass("range")
                .html(range[1])
                .insertAfter(input);
        })
        .bind("slider:ready slider:changed", function (event, data) {
            $(this).nextAll(".output:first")
                .html(data.value.toFixed(2));
        });
</script>

Open in new window


My index.php file to display the CSV content and find the min and max for the UI slider is as below.

<!DOCTYPE html>
<?php
require_once "Paginated.php";
require_once "DoubleBarLayout.php";
?>
<html>
<head>
<title>Skyline Query</title>

<!-- Just a little style formatting. Has no bearing on example -->
<style type="text/css">
&#9;body {
&#9;&#9;font-family: Verdana;
&#9;&#9;font-size: 13px;
&#9;}
&#9;
&#9;a {
&#9;&#9;text-decoration: none;
&#9;}
&#9;
&#9;a:hover {
&#9;&#9;text-decoration: underline;
&#9;}
</style>
<!-- End style formatting -->
</head>

<body>
<?php
$names = file('demo.csv');
$page = $_GET['page'];

//constructor takes three parameters
//1. array to be paged
//2. number of results per page (optional parameter. Default is 10)
//3. the current page (optional parameter. Default  is 1)
$pagedResults = new Paginated($names, 20, $page);
$handle = fopen('demo.csv', 'r');
  if (($data = fgetcsv($handle, 1000, ',')) !== FALSE)
    {
    }
&#9; 
echo "<table border='3' bgcolor='#dceba9' style='float:center; margin:50'>";
echo '<tr><th>'.implode('</th><th>', $data).'</th></tr>';
//when $row is false loop terminates
while ( $row = $pagedResults->fetchPagedRow())
{
    echo "<tr><td>";
&#9;//echo '<tr><th>'.implode('</th><th>', $data).'</th></tr>';
    $row1 = str_replace( ',', "</td><td>", $row );
    echo $row1;
    echo "</td></tr>";
}
fclose($handle);
echo "</table>";

//important to set the strategy to be used before a call to fetchPagedNavigation
$pagedResults->setLayout(new DoubleBarLayout());
echo $pagedResults->fetchPagedNavigation();
//$data1 = [];
$total_columns = 0;
$handle1 = fopen('demo.csv', 'r');
while (false !== ($row = fgetcsv($handle1, 1000, ','))) {
    0 === $total_columns and $total_columns = count($row);
    $i = 1;
    while (++$i <= $total_columns) {
&#9;     $data1[$i][] = (int) $row[$i - 1];
&#9; }
}

$i = 0;
while (++$i <= $total_columns) {
    $_SESSION["min-column-$i"] = min($data1[$i]);
    $_SESSION["max-column-$i"] = max($data1[$i]);
}

$_SESSION['totalcolumns'] = $total_columns;
fclose($handle1);
?>

Open in new window


I have no clue on how to proceed with the jquery/javascript or PHP. I am absolutely new to these technologies and any help in the right directions is highly appreciated.

Thanks!
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

I suggest you make a PHP file that returns the values in JSON format.
Then when slider is changed, you wait a second to make sure they mean it, and then ajax the contents in depending on the slider value. That way you o not need a submit and the page will not update, only the data.

I also STRONGLY suggest you change your alert to

window.console && console.log(string)
So the table would be returned as

header("content-type:application/json");

and look like

["aiD":1234,"kw1":1,"kw2":2,"kw3":3},
"aiD":5678,"kw1":4,"kw2":5,"kw3":6},
"aiD":1234,"kw1":2,"kw2":3,"kw3":4},
"aiD":1234,"kw1":6,"kw2":7,"kw3":8},
"aiD":5678,"kw1":10,"kw2":11,"kw3":12},
"aiD":1234,"kw1":2,"kw2":3,"kw3":4},
"aiD":1234,"kw1":6,"kw2":7,"kw3":8},
"aiD":5678,"kw1":10,"kw2":11,"kw3":12},
"aiD":1234,"kw1":2,"kw2":3,"kw3":4},
"aiD":1234,"kw1":6,"kw2":7,"kw3":8},
"aiD":5678,"kw1":10,"kw2":11,"kw3":12},
"aiD":1234,"kw1":2,"kw2":3,"kw3":4},
"aiD":1234,"kw1":6,"kw2":7,"kw3":8},
"aiD":5678,"kw1":10,"kw2":11,"kw3":12},
"aiD":1234,"kw1":2,"kw2":3,"kw3":4},
"aiD":1234,"kw1":6,"kw2":7,"kw3":8},
"aiD":5678,"kw1":10,"kw2":11,"kw3":12},
"aiD":1234,"kw1":2,"kw2":3,"kw3":4},
"aiD":1234,"kw1":6,"kw2":7,"kw3":8}]
Avatar of ramesh4046
ramesh4046

ASKER

Thanks for replying back. I am really new to these technologies and I have no idea. I tried to find some online resources but am not able to find anything. Basically, I need to display the CSV values based on the slider values selected. For example, if my CSV file contains 10 columns, I will have 10 sliders. I will set the values for all the 10 sliders and click on SUBMIT button. Once I click on SUBMIT button, I need to display only those values that are above the slider values. If someone can share me with a sample code or something, it would be really useful. I really appreciate all your help. Thanks !
What is the maximum data you generate? If only a few K then no need to submit anything. All can be done one the client after loading the data once
The maximum data can be like around 1000 - 2000 rows. As this data gets generated dynamically from another program, I am not sure of the exact count of it.
But first time the page loads, all data is presented since the sliders are not yet moved, right?
Thanks again for commenting.

Yeah. First time, by default the entire CSV contents are presented. I have a simple slider based on the number of columns in the CSV file. Now, after the user selects some values in the slider and clicks on SUBMIT button, I need the CSV values to get updated. Or is there a better approach to this problem?
Yes.

Do you want to UPDATE the CSV file itself on the server or just UPDATE the DISPLAY of the CSV?
I want to just update the display of the CSV on the server. I do not need to edit the CSV file.
Sorry that is confusing

You mean, you just want to show the user different views of the CSV right?
yeah exactly. Based on the slider values, the CSV view should be updated dynamically.
You have two sets (page 1 and page2).

Can they become one?
I need to display 20 results in a page. If the results are less than 20, they can become one. If the results are more than 20, they need to be displayed in the paginated format like how am displaying currently.
The initial page will be displayed like this.

User generated image
As we can see the CSV file contains 3 keywords and so we are having 3 sliders. If the CSV file contains 5 keywords we will be having 5 sliders. Also, the sliders minimum and maximum value are set according to the minimum and maximum of that particular column. Suppose if keyword1 has 10 as maximum, the keyword1 slider will have the maximum value of 10. Now, I am allowing the user to select the slider values as below.

User generated image
After the user selects the above values, we need to display only those rows which have more than the slider values. For example, let us consider the csv data as below.

AuthorID,kw1,kw2,kw3
1234,5,6,7
5678,4,3,2
9856,5,1,4

Now, we will have 3 sliders for the above example (k1,k2,k3). K1 min will be 4 and max will be 5. For k2, min will be 1 and max will be 6 and for k3 min will be 2 and max will be 7.

Now let us assume the slider values are set as k1 = 5, k2 = 1, k3 = 3 then, we have only the 3rd row which satisifies this slider criteria.

9856,5,1,4

So, I need to display only that value.  If at any time the returned data is more than 20 results, I need to use the pagination and display only 20 results in a page and the remaining in next page and so on.

Please let me know if you need more information.
Yes, Can we load all results and decide afterwards to paginate?

I want to only do ONE server access
yeah. We can load all results and decide afterwards to paginate. That won't be a problem.
Also, one more small thing is that the slider should also get updated accordingly.
Ok - I am ready to code, however I am in CET and off to bed
This weekend I have a seminar but I will see what I can do

Please give me a page with all the data - if possible in the format I gave you earlier
You mean add appropriate number of sliders with the correct values?
yes.  If the user submits the page should get updated accordingly. Also the sliders minimum and maximum value.
Hi, I was trying to use ajax to send the response to server and receive back the page from server. However, I am pretty new to these technologies and so am not getting the output correctly. Is it possible for you to give me some online tutorial or some link which will help me atleast get started? I have the deadline by Monday evening for this demo and am really scared. Can you please help me out? Thanks !
I am on a seminar, so I have limited time these days. I'll see what I can do after breakfast - had I known about tight deadlines, I would have gotten some more experts in on this.

Ajax with jquery is really easy

$.post or $.get("phpfile.php",{"parm1":$("#someformelementID").val()},function(datareturnedfromphp)  { do something with data returned });
So in your case

where you have

masterdata = data.value;


you can do

var parms = [];  
$(".output").each(function() {
  parms.push($(this).text();
}
 $.get("phpfile.php",{"parms":parms.join(";")},function(datareturnedfromphp)  { do something with data returned });

which will send 3.00;5.00;7.00 to your server
Here is what I could do before I had to go.

Please study what I did to see if you can use it.

Note the order of tags that are only supposed to exist once
doctype - html - head - body

I moved the script to the head and moved the button click event registration to inside the $(function {...})

which is executed on page load

Also note I added a tbody and removed the duplicate table header

You MAY want to move the sliders above the table since the page moves when you slide

If you slide to 1, 2, 3 on the sliders you will see the top row only - hope that is what you needed

This is homework so I hope you can do the rest yourself. I strongly suggest you send the data in a JSON string rather that in a table. The code I provided also gives you an idea how to do the pagination since you can toggle or create a new table from 1-20 and from 20 onwards

<!DOCTYPE html>
<html>
<head>
<title>Skyline Query</title>

<!-- Just a little style formatting. Has no bearing on example -->
<style type="text/css">
	body {
		font-family: Verdana;
		font-size: 13px;
	}
	
	a {
		text-decoration: none;
	}
	
	a:hover {
		text-decoration: underline;
	}
</style>
<!-- End style formatting -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<!-- Include Simple Slider JavaScript and CSS -->
<script src="js/simple-slider.js"></script>
<link href="css/simple-slider.css" rel="stylesheet" type="text/css" />
<link href="css/simple-slider-volume.css" rel="stylesheet" type="text/css" /> 
<link href="css/simple-slider.css" rel="stylesheet" type="text/css" />

<!-- Activate Simple Slider on your input -->


<script>
var masterData=[];  

function loadXMLDoc() {
  $.post("update.php",{ "value" : masterdata.join(";") },function(data){
    alert(data);
  }); 
}

$(function() {

    $("button").on('click',function(){ loadXMLDoc(); });
    $("[data-slider]")
       .each(function (index) {
           var range;
            var input = $(this);

            $("<span>").addClass("output").attr("id","output"+index)
                .insertAfter(input);
            range = input.data("slider-range").split(",");
            $("<span>").addClass("range")
                .html(range[0])
                .insertBefore(input);
            $("<span>").addClass("range")
                .html(range[1])
                .insertAfter(input);
        })
        .on("slider:ready slider:changed", function (event, data) {
            var $output =$(this).nextAll(".output:first");
            $output.html(data.value.toFixed(2));
            masterData[$output.attr("id").replace(/output/,"")] = data.value;
            window.console && console.log(masterData);
            $("#kwBody > tr").each(function() {
               var $cells = $(this).children("td");
               $(this).toggle(masterData[0]==$cells.eq(1).text() &&
                   masterData[1]==$cells.eq(2).text() &&
                   masterData[2]==$cells.eq(3).text());  
            });
        });
});
        
</script>

</head>

<body>
<table id="kwTable" border='3' bgcolor='#dceba9' style='float:center; margin:50'>
    <tr><th>Author ID</th><th>Keyword1</th><th>Keyword2</th><th>Keyword3</th></tr>
    <tbody id="kwBody">
    <tr><td>1234</td><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>5678</td><td>4</td><td>5</td><td>6</td></tr>
<tr><td>1234</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1234</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>5678</td><td>10</td><td>11</td><td>12</td></tr>
<tr><td>1234</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1234</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>5678</td><td>10</td><td>11</td><td>12</td></tr>
<tr><td>1234</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1234</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>5678</td><td>10</td><td>11</td><td>12</td></tr>
<tr><td>1234</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1234</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>5678</td><td>10</td><td>11</td><td>12</td></tr>
<tr><td>1234</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1234</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>5678</td><td>10</td><td>11</td><td>12</td></tr>
<tr><td>1234</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1234</td><td>6</td><td>7</td><td>8</td></tr>
</tbody>
</table>

<i>Page 1</i> | <a href="?page=2">2</a> <a href="?page=2">next &gt;</a>

  <h2>Keyword Scores</h2>
  	    <br>Keyword	    1		<br><input type="text" data-slider="true" data-slider-range="0,10" data-slider-step="1">
			    <br>Keyword	    2		<br><input type="text" data-slider="true" data-slider-range="0,11" data-slider-step="1">
			    <br>Keyword	    3		<br><input type="text" data-slider="true" data-slider-range="0,12" data-slider-step="1">
				
		<button type="button" >Update</button>
</body>
</html>

Open in new window

Thanks for your explanation. In the sample code you had provided, you are assuming the data is static and hard-coding the values. However, that won't be the case. I will be getting a CSV file which I have to display in a paginated format. There is no chance I know the CSV data beforehand. Also, I have to provide the exact number of sliders as the number of columns in the CSV. This part of the work is already done and now I have difficulty in just displaying the CSV data based on the slider values. Once the sliders are updated, I need to display only the rows satisfying the criteria of the UI sliders (This is important).

So, after the javascript for sliders, I am trying to send the user selected values in the sliders to the next PHP page using ajax. I thought I can use another PHP page to update the display of the CSV. This is the part where am really stuck and not able to proceed further. Also, I tried using the code you had provided for masterdata. I modified the code as below.

<!DOCTYPE html>
<html>
<div id = "myDiv"> 
<!-- Include jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="js/simple-slider.js"></script>
<?php include 'index.php'; ?>
<?php 
	  $totalcolumns = $_SESSION["totalcolumns"];
?>

<!-- Include Simple Slider JavaScript and CSS -->
<link href="css/simple-slider.css" rel="stylesheet" type="text/css" />
<link href="css/simple-slider-volume.css" rel="stylesheet" type="text/css" /> 
<script src="css/simple-slider.js"></script>
<link href="css/simple-slider.css" rel="stylesheet" type="text/css" />

<!-- Activate Simple Slider on your input -->
  <h2>Keyword Scores</h2>
  <?php
 
$i = 1;
while (++$i <= $_SESSION['totalcolumns']) {
    $range = $_SESSION["min-column-$i"] . ',' . $_SESSION["max-column-$i"];?>
	    <br><?php echo "Keyword" ?>
	    <?php echo $i -1 ?>
		<br><input type="text" data-slider="true" data-slider-range="<?php echo $range ?>" data-slider-step="1">
		<?php } ?>
		
		<button type="button" >Update</button>
           		


<script>

    
	alert ("Am I coming here");	
    $("[data-slider]")
	    
       .each(function () {
           var range;
            var input = $(this);
            $("<span>").addClass("output")
                .insertAfter(input);
            range = input.data("slider-range").split(",");
            $("<span>").addClass("range")
                .html(range[0])
                .insertBefore(input);
            $("<span>").addClass("range")
                .html(range[1])
                .insertAfter(input);
        })
        .bind("slider:ready slider:changed", function (event, data) {
            $(this).nextAll(".output:first")
                .html(data.value.toFixed(2));
				});
		$(".output")
		.each(function() {
		var parms = [];
		parms.push($(this).text());
		});
		
		
</script>

<script>

function loadXMLDoc()
		{
		$.ajax({
                    type: "POST",
                    url: "update.php",
                    data: { value : $(parms).serializeArray() },
                    success: function(data)
                    {
                        console.log (data);
                    }
                });	
              	
}
$("button").on('click',function(){ loadXMLDoc(); });
</script>
</div>
</html>

Open in new window


However, I still do not see the data being passed to the next PHP page. Can you please help me out in this part?
Thé code i gave you shows data depending on slider setting. It is simple to Chang to any number if sliders if you change to a loop where I have eq(1) 2 and 3

I'll look at what you posted later
Thanks again for commenting out. But when I run your code, once after setting the sliders I am not able to see any data at all.
Not sure what you mean.

Set the sliders to 1,2,3
then to 7,8,9
then 10,11,12

User generated image
oh ok..I am looking for something similar only. I have now updated the code to send data from javascript to another PHP script using ajax. I thought once the user clicks on Update button, the PHP script will give the new page with the updated display of CSV file. Do you think it is a good idea?
No need if you do what I suggest
Thanks again! As per your code we are setting all the values in a static manner. I will not know any of these data before hand and I need to do everything dynamically. Is that possible with the code that you had given me?
Also, I need to display all the rows that satisfy the UI slider range. For example, if I set the sliders to 6,7,8 I need to display all the rows satisfying the above range criteria.

If my CSV data is as below,

1234, 6, 7, 8
5678, 6, 5, 4
8765, 8, 9, 10

For the sliders 6,7,8, I need to display,

1234, 6, 7, 8
8765, 8, 9, 10

If I set the sliders to 8,9,4, I need to display,

8765, 8, 9, 10 and so on.

All these need to be done dynamically. And, this is not a homework as am doing this work as part of helping out a fellow research student in the lab. Please let me know if you need more information.
Also, I do not know any of these technologies till a week ago. I started coding in these technologies just a week back. So I would really appreciate if you can help me out. Thanks again for the support you are giving me!!
I am attaching the work that I have done so far. Please let me know if you need more information. Also, these are some of the links to my questions in SO.
Question1
Question2
Thanks!
work.zip
I cannot look until tomorrow 12 hours from now - my code will show records that have 1 AND 2 AND 3 values in the slider. Change it to a loop over master values and change the and to or and ANY value static or not will show
Yeah, sure. I will try that.
Please change this code

$(this).toggle(masterData[0]==$cells.eq(1).text() &&
                   masterData[1]==$cells.eq(2).text() &&
                   masterData[2]==$cells.eq(3).text());  
           
To
var found=false,showRow=false,currentCell;
for (var i=0;i<masterData.length;i++) {
  currentCell=$cells.eq(i+1);
  found = masterData[i]==currentCell.text();
  currentCell.toggleClass("found",found); add or remove class to highlight 
  if (found) {
    showRow=true; // no else
  }
}
$(this).toggle(showRow); // show if any cell found

Open in new window

Thanks again for commenting out. As per the code if I select 7,9,8 in the sliders I am getting the rows with (6,7,8). However, I need to display the rows based on all the slider criteria. For example,

slider1 is set to 7.
slider2 is set to 8.
slider3 is set to 9.

I need to display the rows which satisfy all the 3 slider criterias. (i.e.) The displayed rows should have keyword 1 > = 7 and keyword 2 > =8  and keyword 3 >= 9. So the perfect rows to display would be,

7,8,9
8,8,10

However, the rows 7,6,10 or 6,9,10 should not be displayed as they do not satisfy the criteria. Please let me know if you need more information. Thanks once again!
Sigh...


var found=false,count=0,currentCell;
for (var i=0;i<masterData.length;i++) {
  currentCell=$cells.eq(i+1);
  found = parseInt(currentCell.text(),10) >=masterData[i];
  currentCell.toggleClass("found",found); // add or remove class to highlight 
  count+=found;
}
$(this).toggle(count==masterData.length); // show if all cells >

Open in new window

I am sorry if I had not communicated properly. Is it doable? Please let me know if you need more information.
ASKER CERTIFIED SOLUTION
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks a lot again. I was looking for something like this only. Now, how can I make it dynamic to read from CSV and then update accordingly rather than hard-coding the values in the program? Also, how can I make the pagination dynamic based on the total values?
The script can handle any table now as long as the id of the tbody is kept/known. So just put the script in the PHP page that generates the table dynamically
wow, that's perfect. This is what I was looking for. Can I make the page dynamically update the page numbers too?

The Demo

If we see in the above link, if I update the sliders the page numbers are still present. Is that possible?

I highly appreciate your help.