Can I save serialized form data? - php

In my continued effort to understand hash tags and page navigation I'm hitting a road block with resubmitting form data if a user uses the browsers navigation buttons (e.g. back and forward).
My function that uses the form data is below:
if(page == "/visits_results") {
$('#start').val(start);
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
$('#search_results').html(data);
location.href = "#visits_results=" + start;
});
}
This works fine and dandy if the form is still visible, for instance if I use pagination it performs as I would expect.
My issue is when the user clicks the browsers back button (the form has now been removed) and then they click the browsers forward button. The event gets triggered but my serialized form data is now empty. Is there any way to cache the form data so I can continue to call it?
Any thoughts?

Your best bet (I think) would be to store the serialized data in a cookie. When the user returns to the page which he/she has already filled out, retrieve the data from the cookie, unserialize it, and place it back where it belongs.
Cookies are fairly trivial to work with, there is a decent cross-browser implementation for reading/writing cookies on quirksmode:
http://www.quirksmode.org/js/cookies.html
or if you'd prefer to use a plugin:
http://code.google.com/p/cookies/
http://plugins.jquery.com/project/Cookie

You can save data fairly easily using localStorage like http://jsfiddle.net/zDPjm/

Well, sure, you could do something very simple such as:
if ($("#profile_form_id").serialize() != "") serializedFormData = $("#profile_form_id").serialize();
$.post("visits_results.php", serializedFormData, /* Rest of Code */

Related

How to send array to Javascript function from another page?

I have a static site (let's call it settings page), and my Javascript function takes with AJAX data from mysql table and draws table on a HTML document.
It works like a charm - it takes all the data I need and doing it in a proper way.
Here's my function:
function get_people()
{
$.post("/controller/get_people", function(data,status,xhr)
{
if(status=="success")
{
people_data = data;
draw_table();
}
})
}
The thing is, on ANOTHER PAGE I have table with all people and checkboxes next to them.
I'm checking this checkboxes, clicking a button and I want to get into settings page - and my get_people function will select data from mysql only about people checked on previous page.
technically the problem is - how can I pass an array to javascript function from another page? Can I save it on a DOM or something and read it from JS?
Please provide me some ideas : ]
You can use sessionStorage and JSON.parse.
On your first page:
var arrayJSON = JSON.stringify(yourArray);
sessionStorage.setItem("tabledata",arrayJSON);
On your second page:
var tableData = JSON.parse(sessionStorage.getItem("tabledata"));
This will save the data as a string in your browser for the duration of the current session. If you want it to be stored more permanently, you can use localStorage instead of sessionStorage (same syntax) and it will be stored even if the user closes the browser and comes back later.
There's more on sessionStorage and localStorage at the MDN docs

How to restrict my app to a single browser tab?

Frankly, it's just causing too much hassle in in v1.0 to have a functionality which requires three form submissions, with $_SESSION session data holding all of the intermediate stuff - only to have a user start an operation, then open a second tab and perform a second operation which tramples over the session data.
I doubt that this is malicious (but can’t discount it). More likely the user starts an operation, gets interrupted, forgets that they started or can’t find the original tab so starts again (then later finds the original tab and tries to complete the operation a second time).
Since I am coding in PHP I can detect the existence of session data on form submission (how would I do that with JS if the user as much as opens another tab – I guess that I would need Ajax – right?).
So, each time I start an operation I check for a flag in session data and if set I reload to a “I’m sorry, Dave. I’m afraid I can’t do that” page, else I set the flag and continue (remembering to clear it at the end of the operation).
I guess that that would work, but:
1) Is it acceptable to restrict browser apps to a single tab/instance?
2) Should I attempt to allow multiple instances in v2.0 ?
Any other comments, help or advice?
A better design would be to avoid storing user interaction state in the session. Put it in hidden form fields or something so that each client request carries its associated state with it. If you're concerned about the user tampering with it, use an HMAC to prevent that, and possibly encrypt it if it contains things the user shouldn't be able to see.
Only state that should be shared between tabs — like the user's login identity, or something like a shopping cart — should be stored in the session.
At most you can is keep a "last requested page" listing in the session file, with flags to indicate that the user shouldn't be allowed to move off it if it's one of these critical form flags. So if you're on form.php and it's a no-move-off one, then any new page loaded should present an "abort or close window" option.
You cannot prevent a user from opening up another tab/window, but you can prevent them from moving elsewhere in your site in those other windows/tabs.
However, consider that this is a very poor user experience. Imagine if Amazon trapped you in the shopping cart page and never let you on to another page without having to actually buy something. Consider updating your code to allow multiple different windows use the same form.
With every browser supporting tabbed browsing it would be a poor user experience to try to restrict browsing to a single tab (you might as well make a desktop app then).
One way you could solve this is by adding a CSRF token to your forms (as a hidden variable), that would be submitted with the request.
CSRF reference
There are many ways to generate the token, but essentially you:
create the token
store in your $_SESSION
output the form with <input type="hidden" name="{token name}"
value="{token value}" />
Then when the form submits you check $_REQUEST['{token name}'] == $_SESSION[{token name}]`.
If that token is different you know it wasn't the form you originally generated and thus can ignore the request until the real form comes in with the correct token.
One thing: if an attacker can figure out how you generate your CSRF tokens then they can forge requests.
Added the below script after I login(say dashboard.php)
<script>
$(document).ready(function()
{
$("a").attr("target", "");
if(typeof(Storage) !== "undefined")
{
sessionStorage.pagecount = 1;
var randomVal = Math.floor((Math.random() * 10000000) + 1);
window.name = randomVal;
var url = "url to update the value in db(say random_value)";
$.post(url, function (data, url)
{
});
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
Added the below script in Header in rest of my pages - 'random_value' is from db for that user
<script>
$(document).ready(function()
{
$("a").attr("target", "_self");
if(typeof(Storage) !== "undefined")
{
if (sessionStorage.pagecount)
{
if('<?=$random_value?>' == window.name)
{
sessionStorage.pagecount = Number(sessionStorage.pagecount) + 1;
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
}
else
{
var url = "url to remove random_value";
$.post(url, function (data, url)
{
sessionStorage.removeItem('pagecount');
sessionStorage.clear();
window.location = 'logout.php';
});
}
});
</script>
If I were doing this now, I would probably code a single page AngularJs app (although any form of Js will do).
On start-up, look in local storage for a flag. If set, refuse to start, with suitable message, else set the flag & run the app.
Sure, a malicious user could get around it, since it's not a server-side check, but I would just refuse to support such.

How to query database using javascript?

Another question by a newbie. I have a php variable that queries the database for a value. It is stored in the variable $publish and its value will change (in the database) when a user clicks on a hyperlink.
if ($publish == '') {
Link to publish.html
} else {
Link to edit.html
}
What is happening in the background is i am querying a database table for some data that i stored in the $publish variable. If the $publish is empty, it will add a link for publish.html in a popup. The popup will process a form and will add the data to the database and which means that the $publish is no more empty. What i would like to achieve is that as soon as the form is processed in the popup and a data has been added to the database, the link should change to edit.html. This can happen when the page will re-query the database but it should happen without page refresh.
How can it be donw using javascript, jquery or ajax?? Please assist.
Javascript by itself cannot be used to deal with database. That is done using php (Or the server side language of your choice). Ajax is used to send a request to your php script using javascript which will in turn communicate with the db. And it doesn't require a page refresh.
So what you are trying to do can be easily achieved using ajax. Since you mentioned jquery, you can check out the $.ajax or $.post methods in jquery which make the process even more simple.
You need to process the form using ajax. The ajax request is sent to a php script which will make the necessary changes in the database and send the new link (link to edit.html) in the response. Upon getting the response, just replace the current anchor element with the new one ..
for eg..
$.post(url, formdataobject , function (resp) {
$("a.youra").text('edit').attr('href', resp);
});
url - where the php script is located
formdataobject - a javascript object that will have the form data as key value pairs
the third parameter is an anonymous function also known as callback function since it will be invoked only when the response is received from the server. This is because ajax requests are asynchronous.
Inside the callback function, jquery is used to change the text inside the anchor element to edit and the href attribute is changed to value that came in the response.
$.post means we are using the post method. so the parameters can be accessed as elements of $_POST array in php.
After updating the db, you can simply echo out the new link and it will be received in the response.
Also, there are other formats in which you can get the response for eg. xml, json.
I'll try to leave the technical jargon aside and give a more generic response since I think you might be confused with client-side and server-side scripting.
Think of javascript as a language that can only instruct your WEB BROWSER how to act. Javascript executes after the server has already finished processing your web page.
PHP on the other hand runs on your web server and has the ability to communicate with your database. If you want to get information from your database using javascript, you'll need to have javascript ask PHP to query the database through an AJAX call to a PHP script.
For example, you could have javascript call a script like:
http://www.myserver.com/ajax_function.php?do=queryTheDatabase
In summary: Javascript can't connect to the database but it can ask PHP to do so. I hope that helps.
Let me try, you want to change the link in a page from a pop-up that handles a form processing. Try to give your link a container:
<div id="publish_link">Publish</div>
As for the form submission use Ajax to submit data to the server to do an update and get a response back to change the link to edit or something:
$.post("submit.php", { some_field: "some_value"}, function(response) {
if(response.isPublished)
$('#publish_link', window.opener.document).html('Edit');
});
Basically your publish link is contained in a div with an ID publish_link so you change its content later after data processing without reloading the page. In the pop-up where you would do the form processing it is done using jQuery Ajax POST method to submit the data. Your script then accepts that data, update the database and if successful returns a response. jQuery POST function receives that response and there's a check there if isPublished is true, get the pop-up's opener window (your main window) and update the link to Edit. Just an idea, may not be the best out there.
It cannot be made with javascript, jquery or ajax. only server side script can query a database. with ajax request you can get the script output. ajax requests can be sent either with pure javascript or jquery.
Well, i think i understand your quaestion, but you have to get a starting point, try to understand this:
try to understand what are client variables and server variables.
javascript does not comunicate with database.
you can use javascript to retrieve data to a specific "Object variable".
Using ajax methods of jquery you can post that data do other page, that will execute the
proper actions
you can ;)
at first you must create php file to query database and return something like true or flase and then with file url check the function and get answer
function find_published(folder_id) {
var aj_url = "{{server_path}}/ajax/url"
var list;
$.getJSON(aj_url+"?callback=?&",
function(data) {
//here is your data... true false ... do every thing you want
}
);
};
this app for node.js does mysql queries https://github.com/felixge/node-mysql
You need to use AJAX for this, like .post() or .get() or JSON.

Set Session variable using javascript in PHP

Is it possible to set PHP session variables using Javascript?
In JavaScript:
jQuery('#div_session_write').load('session_write.php?session_name=new_value');
In session_write.php file:
<?
session_start();
if (isset($_GET['session_name'])) {$_SESSION['session_name'] = $_GET['session_name'];}
?>
In HTML:
<div id='div_session_write'> </div>
The session is stored server-side so you cannot add values to it from JavaScript. All that you get client-side is the session cookie which contains an id. One possibility would be to send an AJAX request to a server-side script which would set the session variable. Example with jQuery's .post() method:
$.post('/setsessionvariable.php', { name: 'value' });
You should, of course, be cautious about exposing such script.
If you want to allow client-side manipulation of persistent data, then it's best to just use cookies. That's what cookies were designed for.
or by pure js, see also on StackOverflow :
JavaScript post request like a form submit
BUT WHY try to set $_session with js? any JS variable can be modified by a player with
some 3rd party tools (firebug), thus any player can mod the $_session[]! And PHP cant give js any secret codes (or even [rolling] encrypted) to return, it is all visible. Jquery or AJAX can't help, it's all js in the end.
This happens in online game design a lot. (Maybe a bit of Game Theory? forgive me, I have a masters and love to put theory to use :) ) Like in crimegameonline.com, I
initialize a minigame puzzle with PHP, saving the initial board in $_SESSION['foo'].
Then, I use php to [make html that] shows the initial puzzle start. Then, js takes over, watching buttons and modding element xy's as players make moves. I DONT want to play client-server (like WOW) and ask the server 'hey, my player want's to move to xy, what should I do?'. It's a lot of bandwidth, I don't want the server that involved.
And I can just send POSTs each time the player makes an error (or dies). The player can block outgoing POSTs (and alter local JS vars to make it forget the out count) or simply modify outgoing POST data. YES, people will do this, especially if real money is involved.
If the game is small, you could send post updates EACH move (button click), 1-way, with post vars of the last TWO moves. Then, the server sanity checks last and cats new in a $_SESSION['allMoves']. If the game is massive, you could just send a 'halfway' update of all preceeding moves, and see if it matches in the final update's list.
Then, after a js thinks we have a win, add or mod a button to change pages:
document.getElementById('but1').onclick=Function("leave()");
...
function leave() {
var line='crimegameonline-p9b.php';
top.location.href=line;
}
Then the new page's PHP looks at $_SESSION['init'] and plays thru each of the
$_SESSION['allMoves'] to see if it is really a winner. The server (PHP) must decide if it is really a winner, not the client (js).
You can't directly manipulate a session value from Javascript - they only exist on the server.
You could let your Javascript get and set values in the session by using AJAX calls though.
See also
Javascript and session variables
jQuery click event to change php session variable
One simple way to set session variable is by sending request to another PHP file. Here no need to use Jquery or any other library.
Consider I have index.php file where I am creating SESSION variable (say $_SESSION['v']=0) if SESSION is not created otherwise I will load other file.
Code is like this:
session_start();
if(!isset($_SESSION['v']))
{
$_SESSION['v']=0;
}
else
{
header("Location:connect.php");
}
Now in count.html I want to set this session variable to 1.
Content in count.html
function doneHandler(result) {
window.location="setSession.php";
}
In count.html javascript part, send a request to another PHP file (say setSession.php) where i can have access to session variable.
So in setSession.php will write
session_start();
$_SESSION['v']=1;
header('Location:index.php');
Not possible. Because JavaScript is client-side and session is server-side. To do anything related to a PHP session, you have to go to the server.
be careful when doing this, as it is a security risk. attackers could just repeatedly inject data into session variables, which is data stored on the server. this opens you to someone overloading your server with junk session data.
here's an example of code that you wouldn't want to do..
<input type="hidden" value="..." name="putIntoSession">
..
<?php
$_SESSION["somekey"] = $_POST["putIntoSession"]
?>
Now an attacker can just change the value of putIntoSession and submit the form a billion times. Boom!
If you take the approach of creating an AJAX service to do this, you'll want to make sure you enforce security to make sure repeated requests can't be made, that you're truncating the received value, and doing some basic data validation.
I solved this question using Ajax. What I do is make an ajax call to a PHP page where the value that passes will be saved in session.
The example that I am going to show you, what I do is that when you change the value of the number of items to show in a datatable, that value is saved in session.
$('#table-campus').on( 'length.dt', function ( e, settings, len ) {
$.ajax ({
data: {"numElems": len},
url: '../../Utiles/GuardarNumElems.php',
type: 'post'
});
});
And the GuardarNumElems.php is as following:
<?php
session_start();
if(isset ($_POST['numElems'] )){
$numElems = $_POST['numElems'];
$_SESSION['elems_table'] = $numElems;
}else{
$_SESSION['elems_table'] = 25;
}
?>

How can web form content be preserved for the back button

When a web form is submitted and takes the user to another page, it is quite often the case that the user will click the Back button in order to submit the form again (the form is an advanced search in my case.)
How can I reliably preserve the form options selected by the user when they click Back (so they don't have to start from scratch with filling the form in again if they are only changing one of many form elements?)
Do I have to go down the route of storing the form options in session data (cookies or server-side) or is there a way to get the browser to handle this for me?
(Environment is PHP/JavaScript - and the site must work on IE6+ and Firefox2+)
I believe you're at the mercy of the browser. When you hit back, the browser does not make a new request to the server for the content, it uses the cache (in nearly every browser I've seen anyway). So anything server-side is out.
I'm wondering if you could do something very complicated like storing the search result in a cookie during the onunload event of the results page, and then reading the cookie in javascript on the search page and filling in the form - but this is just speculation, I don't know if it would work.
I'd put it in the session.
It's going to be the most reliable and even if they don't go straight "back", it'll still have their search options there.
Putting it in the cookie would also work, but wouldn't be recommended unless it's a very small form.
It's up to the browser, but in most cases you don't have to do anything.
IE, Firefox, etc. will happily remember the contents of the form in the previous page, and show it again when Back is clicked... as long as you don't do anything to stop that working, such as making the page no-cache or building the form entirely from script.
(Putting stuff in the session is likely to confuse browsers with two tabs open on the same form. Be very careful when doing anything like that.)
The problem you have is that the browser will return a cached version of the page, and probably not ask the server for it again, meaning using the session would be irrelevant.
You could however use AJAX to load the details of the previously submitted form on the page's load event.
You would basically have to store it on your server in some way (probably in session variables, as suggested) after the POST. You also have to setup Javascript on the form page to execute on load to issue an AJAX call to get the data from your server (in, say, JSON format) and prefill the form fields with the data.
Example jQuery code:
$( document ).ready( function() {
$.getJSON(
"/getformdata.php",
function( data ) {
$.each( data.items, function(i,item) {
$( '#' + item.eid ).val( item.val );
} );
});
} );
Your /getformdata.php might return data like:
{
'items': [
{
'eid': 'formfield1',
'val': 'John',
},
{
'eid': 'formfield2',
'val': 'Doe',
}
]
}
and it would obviously return an empty array if there were nothing saved yet for the session. The above code is rough and untested, but that should give you the basic idea.
As a side note: current versions of Opera and Firefox will preserve form field content when going Back. Your JS code will overwrite this, but that should be safe.
Another ajaxy options (so it's not good for users without javascript) is to submit the form via javascript and then go the confirmation page (or show the message on the form by replacing the button with a message). That way there is no "back" possible.
Why not store the values into a cookie before submitting? You could also include a timestamp or token to indicate when it was filled out. Then when the page loads, you can determine whether you should fill in the fields with data from the cookie, or just leave them blank because this is a new search.
You could also do everything local by javascript. So you store a cookie with the search value and on pageload you check if the cookie exists. Something like this:
$('#formSubmitButton').click( function() {
var value = $('#searchbox').val();
var days = 1;
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
document.cookie = "searchbox="+value+expires+"; path=/";
});
$(document).ready( function() {
var nameEQ = "searchbox=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) var valueC = c.substring(nameEQ.length,c.length);
}
$('#searchbox').val(valueC);
});
Have not tested this but is should work. You will need jQuery for this.
Cookie functions came from: http://www.quirksmode.org/js/cookies.html
I should say btw that both FireFox and IE have this behaviour by default.

Categories