JSON Newbie - permanently saving values to JSON between browser reloads - javascript

I have an AJAX poll based on this tutorial: http://www.w3schools.com/php/php_ajax_poll.asp
However, instead of writing the poll entries from the HTML radio button to an array in a text file (as outlined in the tutorial). I would like to write to a JSON file. At the moment the values from the radio button entry are sent to the JSON, but the file does not retain the value between browser refreshes. I think that this is probably an issue with my syntax or encoding - the server should have the correct permissions to write to the file. Any tips are greatly appreciated.
<?php $vote = $_REQUEST['vote'];
//get content of json
$filename = "poll.json";
$poll = file_get_contents($filename);
$json = json_decode($poll);
//put content in array
$array = explode("||", $content[0]);
$yes = $array[0];
$no = $array[1];
if ($vote == 0) {
$yes = $yes + 1;
}
if ($vote == 1) {
$no = $no + 1;
}
//insert votes to json file
$insertvote = $yes."||".$no;
$fp = fopen($filename,"w");
fputs($fp,$insertvote);
$poll = json_encode($json);
fclose($fp);?>
At the moment the result is either:
{1||}
or
{||1} in the JSON file, I can't figure out how to save the values the way that they were saved to the .txt file version (as outlined here: http://www.w3schools.com/php/php_ajax_poll.asp)
Update
So based on the excellent advice I received I am much closer. I found that "w" was the correct option for the php as "a+" appended data in the JSON rather than updating the existing values.
I now have a JSON file which is updating the values that are added through the html radio buttons.
So the result looks like: [3,4]
AKA 3 votes from option 1 and 4 votes for option 2

Several issues:
You JSON format is not JSON. Values like 0||1 are not JSON, and so json_encode on it will fail. One of the benefits of true JSON is that you don't have to juggle with delimiters like ||.
The $content variable is nowhere initialised.
You encode something as JSON near the end, but don't do anything with it.
You call a variable $json when you intend to store decoded JSON in it. That is really confusing. Don't call such a variable $json.
Here is some alternative code:
$vote = $_REQUEST['vote'];
//get content of json
$filename = "poll.json";
if (!file_exists($filename)) { // First time ever
$poll = [0, 0];
} else {
$poll = json_decode(file_get_contents($filename));
if (!$poll) $poll = [0, 0];
}
// increment counter for vote
$poll[$vote] += 1;
//insert votes to json file
file_put_contents($filename, json_encode($poll));

Your problem is at this line:
$fp = fopen($filename,"w");
According to the manual, mode "w":
places the file pointer at the beginning of the file and truncate the file to zero length
In other words: Each request overrides the whole file with it's contents.
To fix this, use mode "a+".
$fp = fopen($filename,"w");

Probably you change code and this is undefined:
$content[0]
In
$array = explode("||", $content[0]);
Source Is:
<?php
$vote = $_REQUEST['vote'];
//get content of textfile
$filename = "poll_result.txt";
$content = file($filename);
//put content in array
$array = explode("||", $content[0]);
$yes = $array[0];
$no = $array[1];
if ($vote == 0) {
$yes = $yes + 1;
}
if ($vote == 1) {
$no = $no + 1;
}
//insert votes to txt file
$insertvote = $yes."||".$no;
$fp = fopen($filename,"w");
fputs($fp,$insertvote);
fclose($fp);
?>

Related

Saving HTML table to CSV on server from client side

I'm trying to read a .dat file (it's a CSV with delimiter';') and convert it into a table and is done in PHP and is as follows:
<table id='sol'>
<?php
echo "<html><body>";
$f = fopen("/var/www/html/uploads/data_old.dat", "r");
$var = 0;
/* Writes the CSV to table in the page*/
while (($line = fgetcsv($f, 0, ';')) !== false) {
echo "<tr>";
foreach ($line as $cell) {
if ($var < 36) {
echo "<th>" . htmlspecialchars($cell) . "</th>";
$var = $var + 1;
}
else {
echo "<td><div contenteditable>" . htmlspecialchars($cell) . "</div></td>";
}
}
echo "</tr>";
}
fclose($f);
echo "</body></html>";
?>
</table>
Now after editing the values in the table, I need to save this table on the server. Currently, I can download the table in .dat using a script written in JS as below:
// Quick and simple export target #table_id into a csv
function download_table_as_csv(table_id, separator = ';') {
// Select rows from table_id
var rows = document.querySelectorAll('table#' + table_id + ' tr');
// Construct csv
var csv = [];
for (var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll('td, th');
for (var j = 0; j < cols.length; j++) {
// Clean innertext to remove multiple spaces and jumpline (break csv)
var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
// Escape double-quote with double-double-quote
data = data.replace(/"/g, '""');
// Push escaped string
row.push('"' + data + '"');
}
csv.push(row.join(separator));
}
var csv_string = csv.join('\n');
// Download it
var filename = 'data_new' + '.dat';
var link = document.createElement('a');
link.style.display = 'none';
link.setAttribute('target', '_blank');
link.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string));
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
I'm fairly new to this and any help is highly appreciated.
I might not understand the question here, but I think its something like "I get a csv file from a user - how to display file's fields as an HTML table, and then setup a download link for newly editted file"
If that sounds correct, this is probably what you want.
You are correctly displaying the CSV as an HTML table (as far as I can tell).
if htmlspecialchars(..) changes the characters emitted from data_old.dat then we start writing a new CVS file where we'll place the changes emitted by htmlspacechars(..) - and you write in the delimiter yourself by adding ; (as you noted).
$f_ = fopen("/var/www/html/uploads/data_new.dat", "w");
And which ever file we wish the user to download, just place it inside an <a href='...'> tag.
<?php echo "<a href='uploads/data_new.data'>download</a>" ?>
Furthermore (Getting user edits):
While the example above tells us how to setup the backend for the user downloading the file, - it doesn't outline a way for the user to commit edits, and the backend to know about it.
To do allow the server to know about user edits, as mentioned in the comments AJAX is the way to go for php.
AJAX is Javascript sending XML (body) notation to the backend as an http request. The way it works is described in the image below.
AJAX is accessed by javascript in the browser (hey the where the user is!)
var xhttp = new XMLHttpRequest(); // setup object
// hook function
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// this is ran after we get an OK from the server.
// after they've committed a change
}
};
// setup request
xhttp.open("GET", "link/to/your/website", true)
xhttp.send(); // send it
AJAX playground
So far this is pretty vague outlining of what it is, now lets see how we can use it.
So the idea being that when a user changes a field in the table, we run some javascript to send an AJAX request. Specifying what they changed.
The server gets the request, updates the changes on the backend, and then sends OK back to the client.
Hope this helps.

How to call data in PHP as well as in Javascript file?

I am trying to make an application in which I use the simple while loop in PHP file to show the record. the code in product.php is here: How to use this in javascript. I need to call the in the java file in the same way.
$sql2 = "SELECT * FROM product";
$result2 = $DBcon->query($sql2);
if ($result2->num_rows > 0) {
// output data of each row
while($row2 = $result2->fetch_assoc()) {
$pname = $row2["product_name"];
$timg = $row2["thumb_img"];
$pimg = $row2["product_img"];
if(!empty($timg)){
echo '<img src="adminpanel/upload/product/'.$timg.'" alt="'.$pname.'" title="'.$pname.'">';
}else{
echo '<img src="adminpanel/upload/product/'.$pimg.'" alt="'.$pname.'" title="'.$pname.'">';
}
}
}
If you need to call something in javascript from php in the same file you could do something like this
var h=<?php $h ?>;

Image corrupted when using Cropit and form submit

I was introduced to Cropit recently and find it really easy to use but I am stuck at one area. I am trying to use Cropit and form submit. I am following the demo provided by Cropit.
Javascript:
$('form').submit(function() {
// Move cropped image data to hidden input
var imageData = $('.image-editor').cropit('export');
$('.hidden-image-data').val(imageData);
// Print HTTP request params
var formValue = $(this).serialize();
$('#result-data').text(formValue);
// Prevent the form from actually submitting
return false;
});
PHP:
$encoded = $base64_string;
$decoded = urldecode($encoded);
$image_name = explode(';', $decoded);
$image_name = explode(':', $image_name[0]);
$image = array_pop($image_name);
$ext = explode('/', $image);
//decode the url, because we want to use decoded characters to use explode
$decoded = urldecode($encoded);
//explode at ',' - the last part should be the encoded image now
$exp = explode(',', $decoded);
//we just get the last element with array_pop
$base64 = array_pop($exp);
//decode the image and finally save it
$data = base64_decode($base64);
$str = random_string('alnum', 8);
$file = $str.'.'.$ext[1];
$data = $upload;
file_put_contents('assets/image_test/cropped/'.$file, $data);
It is able to output the file into my folder but the picture is just a blank screen with the dimension I set.
I have try to search the web but I couldn't find any solution to my problem.
Hope to get help from anyone who have encounter or know a solution.

Use file_get_contents() and implode() to pass array to javascript not working

I am developing a simple image gallery which shows images and related caption.
All images are inside a directory and caption in another (as single files). A php script lists all files in both directories and pass arrays to a javascript wich change image and caption when the user press a button.
[...]
for($x = 2; $x < $lenght; $x++) {
$filesi[$x] = $imgdirectory."/".$lsi[$x];
}
for($x = 2; $x < $lenght; $x++) {
$filename = $capdirectory."/".$lsc[$x];
$filesc[$x] = file_get_contents($filename);
}
//Create array for JS
$captions = '["' . implode('", "', $filesc). '"]';
$images = '["' . implode('", "', $filesi). '"]';
?>
<script>
var captions = <?php echo $captions; ?>;
var images = <?php echo $images; ?>;
[...]
Images work properly and I can also print caption's file name instead of caption
i.e.
$filesc[$x] = $filename;
but when I use "file_get_contents()" to read file the gallery stops working.
If I echo $captions and manually set $captions with the very same output
e.g.
$captions='["first caption","second caption", "..."]';
the gallery works properly, so the array should be properly formatted...
Thank you in advance
SOLUTION
I was creating an array with two empty elements (0,1) in order to avoid ./ and ../ in file list, so I have added a +2 to the lsi index.
for($x = 0; $x < $lenght-2; $x++) {
$filesi[$x] = $imgdirectory."/".$lsi[$x+2];
}
In addition I have used json_encode, as suggested, instead of manual json encodig. The output seems to be the same but now the gallery works!
var images = <?php echo json_encode($filesi); ?>;
In JS you have to escape new lines in strings like this:
var multilineString = "this is\
just an example";
Maybe try to use trim() and str_replace() if you don't want to make it easier with json_encode().
UPDATE
Then I was wrong. Did you know that you can push items to arrays with just $array[] = 'item';?

Struggling to create a php array to fetch photos from directory that can be used as an array in JavaScript

Basically I am trying to create a photo slideshow that will display specific photos depending on the userid. These photos will be stored in the directory of my web server space. Currently I have a html (not changed into php) file with basic html layout, css style sheet and an external js file that has my code that makes the photos fade in and out. I have added php at the bottom of my html. This is what I have:
$user_id = $_GET['userid'];
print "<h1> Hi, $user_id </h1>";
function returnimages($dirname = "Photos/1") { //will replace 1 with userid once something starts working
$pattern="(\.jpg$)|(\.png$)|(\.jpeg$)|(\.gif$)"; //valid image extensions
$files = array();
$curimage=0;
if($handle = opendir($dirname)) {
while(false !== ($file = readdir($handle))){
if(eregi($pattern, $file)){ //if this file is a valid image
//Output it as a JavaScript array element
echo 'galleryarray['.$curimage.']="'.$file .'";';
$curimage++;
}
}
closedir($handle);
}
return($files);
}
echo 'var galleryarray=new Array();'; //Define array in JavaScript
returnimages() //Output the array elements containing the image file names
?>
and in my javscript, the code I had before for the array of photos:
// List of images for user one
var userphoto = new Array();
userphoto[0] = "Photos/1/1.jpg";
userphoto[1] = "Photos/1/2.jpg";
userphoto[2] = "Photos/1/1.jpg";
userphoto[3] = "Photos/1/1.jpg";
userphoto[4] = "Photos/1/1.jpg";
which I have now commented out and replaced it with this:
var userphoto = <? echo json_encode($galleryarray); ?>;
I am hoping to be able to change the src of photodisplay with the new array:
photodisplay[x].attr("src", userphoto[x]);
Sorry if my problem is not clear at all. I am very confused myself. :( hopefully someone can help!
$user_id = (int) $_GET['userid'];
print "<h1> Hi, $user_id </h1>";
function returnimages($dirname = "Photos/1") {
$dirname = str_replace('..', '.', $dirname); //only remove this if you know why it's here
$pattern = "*{.jpg,.png,.jpeg,.gif}"; //valid image extensions
return glob($dirname . DIRECTORY_SEPARATOR . $pattern, GLOB_BRACE);
}
echo "var galleryarray = ".json_encode(returnimages()).";\n";
?>
Also, you should use <?= json_encode($ret) ?> because the PHP short tag (<?) is deprecated, but <?= is not, and is the equivalent of <?php echo.

Categories

Resources