User input, PHP, Javascript and security - php

I am working on a directions service where users enter the from and to addresses and get the directions table ( that gives turn by turn information ) along with a map showing the route.
Below is the complete source code ( getdirections.php ):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Directions</title>
<style>
* { font-family: Verdana; font-size: 96%; }
label { width: 15em; float: left; }
label.error { display: block; float: none; color: red; vertical-align: top; }
p { clear: both; }
.submit { margin-left: 12em; }
em { font-weight: bold; padding-right: 1em; vertical-align: top; }
</style>
<script src="jquery-1.3.1.js" type="text/javascript">
</script>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false& amp;key=[Your Key Here]"
type="text/javascript">
</script>
</head>
<body onunload="GUnload()">
<div id="container">
<div id="directform">
<form id="direct" action="getdirections.php" method="get">
<p><label for="loc1">From Here:</label>
<input id="loc1" type="text" name="location1" class="required" /></p>
<p><label for="loc2">To Here:</label>
<input id="loc2" type="text" name="location2" class="required" /></p>
<p><input type="submit" value="Search" /></p>
</form>
</div>
<?php
function filterInput ( $input ) {
$replacement = ',';
$input = preg_replace('/(\n|\r)+/', $replacement, $input);
$replacement = " ";
$input = preg_replace('/(\t)+/', $replacement, $input);
$inputarray = explode(' ', $input);
foreach ( $inputarray as $i => $value ) {
$ch = '';
if ( $value[strlen($value)-1] == ',') {
$ch = ',';
$value = substr($value, 0, -1);
}
$value =
preg_replace('/^(\&|\(|\)|\[|\]|\{|\}|\"|\.|\!|\?|\'|\:|\;)+/', "", $value);
$inputarray[$i] =
preg_replace('/(\&|\(|\)|\[|\]|\{|\}|\"|\.|\!|\?|\'|\:|\;)+$/', "", $value);
$inputarray[$i] = $inputarray[$i].$ch;
}
$filteredString = implode(" ", $inputarray);
return $filteredString;
}
?>
</div>
<table class="directions">
<tr>
<td valign="top">
<div id="directions" style="width: 100%"></div>
</td>
</tr>
<tr>
<td valign="top">
<div id="map_canvas" style="width: 250px; height: 400px"></div>
</td>
</tr>
<td valign="top">
<div id="directions_url"></div>
</td>
</table>
<noscript><b>JavaScript must be enabled in order for you to use Google Maps.</b>
However, it seems JavaScript is either disabled or not supported by your browser.
To view Google Maps, enable JavaScript by changing your browser options, and then
try again.
</noscript>
<script type="text/javascript">
// This programming pattern limits the number of global variables
// Thus it does not pollute the global namespace
// for_directions is the only global object here.
for_directions = function(){
// The map is loaded into the div element having id specified by mapid
// private variable
var mapid = "map_canvas";
// The direction listing is loaded into the div element having id specified by directionsid.
// private variable
var directionsid = "directions";
// From here
// private variable
var location1;
// To here
// private variable
var location2;
// The functions ( init and addevent ) are public methods of for_directions object
return {
// Called on loading of this page
// public method
init: function (){
location1 = "<?= filterInput($_GET['location1']) ?>" || 0;
location2 = "<?= filterInput($_GET['location2']) ?>" || 0;
var directions = document.getElementById(directionsid);
directions.innerHTML = "Please check the address and try again";
if ( GBrowserIsCompatible() && location1 != 0 && location2 != 0){
mapAddress(location1, location2);
}
},
// This method is cross browser compliant and is used to add an event listener
// public method
addEvent:function(elm,evType,fn,useCapture){
if(elm.addEventListener){
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;
} else {
elm['on' + evType] = fn;
}
}
};
// Called from init
// private method
function mapAddress ( address1, address2 ){
var geocoder = new GClientGeocoder();
var directions = document.getElementById(directionsid);
var i = 0;
geocoder.getLatLng( address1, function(point1){
if (point1){
geocoder.getLatLng ( address2, function(point2){
if (point2){
getDirections();
} else {
directions.innerHTML = "Please check the address and try again";
}
});
} else {
directions.innerHTML = "Please check the address and try again";
}
});
}
// Called from mapAddress to load the directions and map
// private method
function getDirections( ){
var gmap = new GMap2(document.getElementById(mapid));
var gdir = new GDirections(gmap,document.getElementById(directionsid));
gdir.load("from: " + location1 + " to: " + location2,
{ "locale": "en_US" });
generateURL();
}
function generateURL(){
var url = "http://maps.google.com/maps?saddr=";
url += location1;
url += "&daddr=";
url += location2;
var a = $("<a></a>").attr('href',url);
$(a).text("Google Maps");
$("#directions_url").append(a);
}
}();
// The (); above results in the function being interpreted by the browser just before the page is loaded.
// Make for_directions.init as the listener to load event
// Note that the init method is public that why its accessible outside the object scope
for_directions.addEvent(window, 'load', for_directions.init, false);
</script>
</body>
</html>
If you try out this code on your system name it as getdirections.php. The only thing you would need to change is the google maps api key. You can get the key here.
Once you generate your key put in the key parameter ( reproduced the line below for convenience ):
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false& amp;key=[Your key here]"
type="text/javascript">
As is seen from the code above, I get the input through PHP and do the processing in Javascript. Now, I don't want users to get away with any kind of input ( javscript, dangerous HTML, etc ). I tried using the urlencode function in PHP. However, the encoded user input is not accepted by the javascript code and fails even on good input.
As a workaround to this problem I wrote a filterInput function in PHP that will replace/delete certain characters and thwart any attempt by the user to try and execute Javascript code through input.
This worked well. However, when the user did try give malicious input, say like "+alert("hello")+" with both the beginning and ending quotes included, the filterInput function trimmed the leading and tailing quotes and the resulting string is below:
+alert("hello")+
Now when code below is executed:
location1 = "<?= filterInput($_GET['location1']) ?>" || 0;
PHP substitues the function call with its return value like below:
location1 = "+alert("hello")+" || 0;
Execution of the script halts with the line above with an error ( missing ; before statement )
Note, had I not trimmed the quotes and used $_GET['location1'] directly I would get.
location1 = ""+alert("hello")+"" || 0;
alert("hello") would get executed!!
So, I am in a fix. If I filter input I get a javascript error on certain user input and if I don't filter input I allow users to execute any kind of javascript.
My questions then are:
What is a proper and secure way to handle input on the web?
Is this kind of user input crossing languages ( from PHP to Javascript ) ok?
Apart from the user being able to execute javascript what other kinds of security threats does is this piece of code vulnerable?
Thanks for reading!!
Please help.

You can try json_encode in php and an eval in javascript.
If the JS is executed on the same machine where the input is done, I wouldn't be too concerned about security. A hacker can hack his own machine, it should be no problem.

Related

Passing 2 or more parameters from a HTML form to a PHP function

So, I have a HTML form and I need to send it's value as a parameter to a php function, but I also need a different value, that's not even inside the HTML.
For example:
<form action="methods.php" method="register">
<input type="text" placeholder="EventID">
<input type="submit" value="Register">
</form>
This form would get the event id and send it as a parameter to register the user into the event. But I need to send the user as a parameter also (function register($user, $eventid)) and I have no idea on how to do so.
I did find some similar things around here, but they were related to POST and GET and I'm not sure they work for me and I could not understand how to use in them in my case, so if anyone could help me out, pleaaaaaase, i'd be really thankful
Its very simple you just need to take care of few things.
1: every input field should have a name.
2: set form method either GET(to send values visible in the url) or POST(to send data without showing in the url)
3: on methods.php receive form data if send via GET then $_GET['input_field_name'] or via POST then $_POST['input_field_name']
Look for the explanation in comments below:
//<![CDATA[
// external.js
var post, doc, bod, htm, C, E, T; // for use on other loads
addEventListener('load', function(){ // load
// used in post function below to create String from Object
function phpEncode(obj){
var r = [];
if(obj instanceof Array){
for(var i=0,l=obj.length; i<l; i++){
r.push(phpEncode(obj[i]));
}
return '%5B'+r.join(',')+'%5D';
}
else if(typeof obj === 'object' && obj){
for(var i in obj){
if(obj.hasOwnProperty(i)){
var v = obj[i], s;
if(typeof v === 'object' && v){
s = encodeURIComponent('"'+i.replace('"', '\\"')+'":')+phpEncode(v);
}
else{
v = typeof v === 'string' ? '"'+v.replace('"', '\"')+'"' : v;
s = encodeURIComponent('"'+i.replace('"', '\\"')+'":'+v);
}
r.push(s);
}
}
return '%7B'+r.join(',')+'%7D';
}
else{
r = typeof obj === 'string' ? '"'+obj.replace('"', '\\"')+'"' : obj;
return ''+r;
}
}
// used in post function below to evaluate (make into code) JSON String that comes back from PHP
function phpAccept(url){
return eval('('+decodeURIComponent(url)+')');
}
// here is an example of a post AJAX function
post = function(send, where, success, context){
var x = new XMLHttpRequest;
var c = context || this;
x.open('POST', where); x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.onreadystatechange = function(){
if(x.readyState === 4 && x.status === 200){
if(success)success.call(c, phpAccept(x.responseText));
}
}
if(typeof send === 'object' && send && !(send instanceof Array)){
var r = [];
for(var p in send){
r.push(encodeURIComponent(p)+'='+phpEncode(send[p]));
}
x.send(r.join('&'));
}
else{
throw new Error('send must be an Object');
}
return x;
}
// yes, you can do this - just remember that non-primitive values are the actual Object through assingment
doc = document; bod = doc.body; htm = doc.documentElement;
// simple way to create an Element by tag
C = function(tag){
return doc.createElement(tag);
}
// simple way to document.getElementById()
E = function(id){
return doc.getElementById(id);
}
T = function(tag){
return doc.getElementsByTagName(tag);
}
var form = E('form'), sub = E('sub'), i1 = E('i1'), i2 = E('i2');
// prevent old school submission
form.addEventListener('submit', function(ev){
ev.preventDefault(); // prevents submission
});
// just for testing remove below
var tS = E('test_out').style;
// remove above
// ajax submisson
sub.addEventListener('click', function(){
/* note that if the Elements are not removed from or added
to the DOM you don't need to get them again Element.value
will probably be different so you'll want to get them
on every click
*/
post({phpProp1:i1.value, phpProp2:i2.value}, 'yourPHPajaxResponsePage.php', function(data){
/* before data comes back yourPHPajaxResponsePage.php may look like this:
<?php
session_start(); // super common - read up on it - not needed here - but won't hurt
if(isset($_POST['phpProp1'], $_POST['phpProp2'])){
// usually you affect MySQL using PHP at this point
// we'll just send them back in this lame example
$res = array('jsProp1' => $_POST['phpProp1'], 'jsProp2' => $_POST['phpProp2']);
// makes results come back as JSON
echo json_encode($res);
}
?>
*/
if(data){ // may want more conditions
E('out').innerHTML = data.jsProp1+'<br />'+data.jsProp2;
}
}, this);
// just for testing - remove below
tS.display = 'block';
E('temp_res').innerHTML = i1.value+'<br />'+i2.value;
// remove above
});
// testing only remove below
var ins = doc.querySelectorAll('input[type=text]');
for(var i=0,l=ins.length; i<l; i++){
ins[i].addEventListener('focus', function(){
tS.display = 'none';
});
}
// remove above
form.addEventListener('keydown', function(ev){
// if user hits enter
if(ev.keyCode === 13)sub.click();
});
}); // end load
//]]>
/* external.css */
html,body{
padding:0; margin:0;
}
.main{
width:980px; margin:0 auto;
}
#form{
width:266px; color:#fff; background:green; padding:10px;
}
#form>div>label{
display:block; float:left; width:57px;
}
#form>div>input{
width:203px;
}
#form>div{
margin-bottom:10px;
}
#form>#sub{
display:block; margin:0 auto;
}
/* remove below - testing only */
#test_out{
display:none;
}
#test_out>div:first-child{
color:red;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<title>AJAX Example</title>
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<div class='main'>
<form id='form'>
<div><label for='i1'>Input 1</label><input id='i1' name='i1' type='text' value='' /></div>
<div><label for='i2'>Input 2</label><input id='i2' name='i2' type='text' value='' /></div>
<input id='sub' type='button' value='submit' />
</form>
<div id='out'></div>
<!-- for testing remove below -->
<div id='test_out'><div>Must have PHPServer code in JavaScript Comments to get real results</div><div id='temp_res'></div></div>
<!-- remove above -->
</div>
</body>
</html>
What do you think?
you can use hidden field or you can use session or cookie for user
<form action="methods.php" method="post">
<input type="hidden" name="txtuser" value="abc">
<input type="text" placeholder="EventID">
<input type="submit" value="Register">
</form>
if you use cookie or session then there is not need to pass it as parameter its a global variable so you can access its value at any page directly, you just need to store value to it and access it any where in your project.

Automatically show usernames whilst still typing into the search box?

Is there a way I can use a HTML form text box to perform an advanced search where I will be able to start typing a username of one of my members and it will list all members close to what I am still typing, something like the facebook search, but only with names (not profile pictures).
So for example, if I had a member list with contents like:
Jamie123
Jackzo
Josh
Dan
When I typed in my box, "J" all of the above apart from "Dan" would show in a drop box.
When I typed in my box, "Ja", "Dan" and "Josh" would not show... and so on?
Is this possible ? If so, How can i do this ?
I would look into using Select2. You can find out more here: http://ivaynberg.github.io/select2/
Yes...lets start by creating your text box:
<input type="text" name="DEMO_NAME" id="DEMO_NAME" alt="Possible Results" onKeyUp="searchSuggest();" autocomplete="off">
You will need a div sto show your results while the user is typing (place it under the textbox via css):
<div id="search_suggest"></div>
On the top of the html page you will have to include (apart from jquery) a .js file which will handle the request:
<script language="JavaScript" type="text/javascript" src="ajax_search.js" charset="utf-8"></script>
aja_search.js code is:
//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("Please update your Browser");
}
}
//Our XmlHttpRequest object to get the auto suggest
var searchReq = getXmlHttpRequestObject();
//Called from keyup on the search textbox.
//Starts the AJAX request.
function searchSuggest() {
if (searchReq.readyState == 4 || searchReq.readyState == 0) {
var str = encodeURI(document.getElementById('DEMO_NAME').value);
searchReq.open("GET", 'search.php?search=' + str, true);
searchReq.onreadystatechange = handleSearchSuggest;
searchReq.send(null);
}
}
//Called when the AJAX response is returned.
function handleSearchSuggest() {
if (searchReq.readyState == 4) {
var ss = document.getElementById('search_suggest')
ss.innerHTML = '';
if(document.getElementById('DEMO_NAME').value.length > 2)
{
var str = searchReq.responseText.split("\n");
for(i=0; i < str.length - 1; i++) {
//Build our element string. This is cleaner using the DOM, but
//IE doesn't support dynamically added attributes.
var suggest = '<div onmouseover="javascript:suggestOver(this);" ';
suggest += 'onmouseout="javascript:suggestOut(this);" ';
suggest += 'onclick="javascript:setSearch(this.innerHTML);" ';
suggest += 'class="suggest_link">' + str[i] + '</div>';
ss.innerHTML += suggest;
}
}
else
{
ss.innerHTML = 'Please insert at least 3 characters';
}
}
}
//Mouse over function
function suggestOver(div_value) {
div_value.className = 'suggest_link_over';
}
//Mouse out function
function suggestOut(div_value) {
div_value.className = 'suggest_link';
}
//Click function
function setSearch(value) {
document.getElementById('DEMO_NAME').value = value;
document.getElementById('search_suggest').innerHTML = '';
}
as you can see from the js above, user must input at least 3 characters in order to fire up the search. I strongly advise you to keep it.
last but not least you need the search.php file which is called by ajax in order to fetch results:
$search = $_GET["search"];
if(!empty($search))
{
$query = mysql_query("SELECT * FROM your_table WHERE username like('%" . simple_protect($search) . "%') ORDER BY username") or die (mysql_error());
while ($row = mysql_fetch_assoc($query))
{ //echo $query;
echo strip_all($row['username'])."\n";
}
}
else
{
echo "No Records available";
}
simple_protect and strip_all are functions of mine, the first one sanitizes the input while the second removes slashes etc. You can use your own.
finally you will need the css that shows results correctl, mine looks like this:
.suggest_link {
background-color: #333333;
padding:2px 4px 4px 2px;
color:#858585; font-family:Verdana; font-size:11px; color:#ffffff;
}
.suggest_link_over {
background-color: #666666;
padding:2px 4px 4px 2px;
color:#858585; font-family:Verdana; font-size:11px; color:#ffffff;
}
#search_suggest {
background-color: #333333;
text-align: left;
z-index:20;
width:240px; height: inherit;
border:hidden;
color:#ffffff; font-family:Verdana; font-size:11px; cursor: pointer;
}
and voila! you have your advanced search...
You have to use javascript for this, i recommend JQuery. You can do this with a built in function in JQuery called ajax, with it you can send a POST request to the server without refreshing the page. And then use php to fetch the data.
I recommend going to youtube and look at some tutorials if you ar new to javascript, look for JQuery tutorials.

Editing css with php or JQuery

Is there a way that I can change a css style sheet's data from a html form and php and/or JQuery. So if I have the following
widths.css
#main #section1 {
width: 25%;
}
#main #section2 {
width: 50%;
}
#main #section3 {
width: 25%;
}
So I want to have 3 text boxes S1, S2 and S3 and then a user can place values into each text box. It will check they add up to 100% or less and then it will write them to the css in place of 25%, 50% and 25%. How would I achieve this using php and/or JQuery.
Thanks
well there is a dirty but solution to this. use php to write javascript to the the html possibly after ending of body tag.
so the code goes like this
..
...
</body>
<?php echo <<< code
<script type="text/javascript">
document.getElementById("section1").style.width="$_POST['s1']";
// and then for each section u can do this
code;
?>
you will have to set the CSS dynamically on the page it self. Once the user entered the data, you can use little bit of AJAX to change the styles. So something like below would be your PHP and styles on the page. if you want this to be a permenant change make sure to put the settings in a DB against the user's profile. This can be added to your AJAX script as well.
<style type="text/css">
#main #section1 {
width: <?php echo $s1; ?>%;
}
#main #section2 {
width: <?php echo $s2; ?>%;
}
#main #section3 {
width: <?php echo $s3; ?>%;
}
</style>
HTH
You can use the jQuery addClass() to add a specific CSS class with the style you require.
To use PHP, you could use CSS internally on the page:
<style type="text/css">
<?php echo "width: 100px;" //for example ?>
</style>
But I wouldn't necessarily recommend that.
something basic but which should work
$(".validate").click(function(){
//I've assumed your text inputs were children of an element with id section$i
var w1 = Number($("#section1 input").val());
var w2 = Number($("#section2 input").val());
var w3 = Number($("#section3 input").val());
if(w1+w2+w3 == 100){
//here you change css rules for #section$i elements
$("#section1").css("width",w1+"%")
$("#section2").css("width",w2+"%")
$("#section3").css("width",w3+"%")
}
else{
alert("sum of values must equals 100%")
}
});
assuming that you have a clickable area with class validate
You can use this script i just made for you:
var merge = function(objectCollections){
var array = new Array();
foreach(objectCollections,function(objectCollection){
foreach(objectCollection,function(object){
array.push(object);
});
});
return array;
}
var foreach = function(object,loop){
for (var key in object) {
if (object.hasOwnProperty(key)) {
loop(object[key],key);
}
}
}
var changeCSS =function(value){
var links = document.getElementsByTagName('link');
var styles = document.getElementsByTagName('style');
var sheets = merge([links,styles]);
var rules = value.split(/[(\ *{)(\})]/g);
for(var i in sheets){
if(typeof sheets[i] == 'object'){
var sheet = sheets[i].sheet ? sheets[i].sheet : sheets[i].styleSheet;
for(var j in sheet.cssRules){
if(typeof sheet.cssRules[j].selectorText != 'undefined'){
if(sheet.cssRules[j].selectorText == rules[0]){
sheet.cssRules[j].cssText = value;
console.debug(sheet.cssRules[j].cssText);
}
}
}
}
}
}
usage example:
changeCSS('#main #section1 {width: 25%;}');
this will change the css (not set a style on a tag or something)

keyboard navigation for ajax drop down

I am using the following code for Ajax dropdown suggest(some what similar to google suggest). It is working good.
[source]: http://www.dynamicajax.com/ of this code
code in html
<html lang="en-US">
<head>
<style type="text/css" media="screen">
body {
font: 11px arial;
}
.suggest_link {
background-color: #FFFFFF;
padding: 2px 6px 2px 6px;
}
.suggest_link_over {
background-color: #3366CC;
padding: 2px 6px 2px 6px;
}
#search_suggest {
position: absolute;
background-color: #FFFFFF;
text-align: left;
border: 1px solid #000000;
}
</style>
<script language="JavaScript" type="text/javascript" src="ajax_search.js"></script>
</head>
<body>
<h3>Simple AJAX Search Suggest</h3>
<form id="frmSearch">
<input type="text" id="txtSearch" name="txtSearch" alt="Search Criteria" onkeyup="searchSuggest(this.value);" autocomplete="off" />
<!-- <input type="submit" id="cmdSearch" name="cmdSearch" value="Search" alt="Run Search" /><br />-->
<div id="search_suggest">
</div>
</form>
</body>
</html>
code in javascript
//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
} else if(window.ActiveXObject) {
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("It's about time to upgrade your browser. don't you think so?");
}
}
//Our XmlHttpRequest object to get the auto suggest
var searchReq = getXmlHttpRequestObject();
//Called from keyup on the search textbox.
//Starts the AJAX request.
function searchSuggest() {
if (searchReq.readyState == 4 || searchReq.readyState == 0) {
var str = escape(document.getElementById('txtSearch').value);
searchReq.open("GET", 'searchSuggest.php?search=' + str, true);
searchReq.onreadystatechange = handleSearchSuggest;
searchReq.send(null);
}
}
//Called when the AJAX response is returned.
function handleSearchSuggest() {
if (searchReq.readyState == 4) {
var ss = document.getElementById('search_suggest')
ss.innerHTML = '';
var str = searchReq.responseText.split("\n");
for(i=0; i < str.length - 1; i++) {
//Build our element string. This is cleaner using the DOM, but
//IE doesn't support dynamically added attributes.
var suggest = '<div onmouseover="javascript:suggestOver(this);" ';
suggest += 'onmouseout="javascript:suggestOut(this);" ';
suggest += 'onclick="javascript:setSearch(this.innerHTML);" ';
suggest += 'class="suggest_link">' + str[i] + '</div>';
ss.innerHTML += suggest;
}
}
}
//Mouse over function
function suggestOver(div_value) {
div_value.className = 'suggest_link_over';
}
//Mouse out function
function suggestOut(div_value) {
div_value.className = 'suggest_link';
}
//Click function
function setSearch(value) {
document.getElementById('txtSearch').value = value;
document.getElementById('search_suggest').innerHTML = '';
}
Now i wanted to know if i can navigate in the dropdown list with the help of keys. i.e
open a drop-down list by using the Down Arrow key. After opening a drop-down list, the user can navigate between drop-down items with the Up Arrow, Down Arrow, Home, End, Page Up, Page Down keys and then select an item with the Enter key. To close the list without changing the value, the user can press the Esc key.
Its nice to have, to have all the above mentioned features. - only if it is feasible.
But naviagting with Up arrow, Down Arrow are required. - Need help for these 2
Thanks in advance!
Do you mean autocomplete options appearing under your text input? In that case you want to set an option for keypress, and if it is a down arrow you do the same thing you currently do with "mouse_out" for the $(this) element, and "mouse_over" for the one below it. For up arrow, same thing with the one above it.
First you are going to need id's on each div, and make them sequential. Then you add functions for keypresses
for(i=0; i < str.length - 1; i++) {
//Build our element string. This is cleaner using the DOM, but
//IE doesn't support dynamically added attributes.
var suggest = '<div onmouseover="javascript:suggestOver(this);" ';
suggest += 'onmouseout="javascript:suggestOut(this);" ';
suggest += 'onclick="javascript:setSearch(this.innerHTML);" ';
suggest += 'onkeypress="javascript:keyPressFunc(k,this);' //THIS IS NEW
suggest += 'id="item"+i'; //THIS IS THE NEW LINE TO ADD
suggest += 'class="suggest_link">' + str[i] + '</div>';
ss.innerHTML += s
}
function keyPressFunc(k, comesFrom)
{
keyIn = k.keyCode;
suggestOut(this);
getsFocusId = "item" + 39-keyIn //38 is up arrow, 40 is down
suggestOver(document.getElementById(getFocusId));
}
I might have messed up the arguments for the incoming key and the reporting element, but thats the idea. The broad strokes are sound even if some details are missing:
1) add unique (and sequential) id's to each of these divs
2) add an event for keypress, use .keyCode to get value, up arrow is 40 down is 38, enter is 13 esc is 27. page up, pagedown, end, home are 33-36
3) For each of these you must do what you currently do for suggestOut for the div that takes the keypress, and what you currently do for suggestOver for another
I haven't done anything like this in vanilla javascript in quite some time so thats why im fuzzy. I think you'd really benefit from jQuery here, I know I would.
PS - get jQuery. Then you can set up these events really easy with stuff like
$(".suggest_link").keypress(function(k) {.....

Get variable from PHP to JavaScript [duplicate]

This question already has answers here:
How do I pass variables and data from PHP to JavaScript?
(19 answers)
Closed 8 years ago.
I want to use a PHP variable in JavaScript. How is it possible?
You can print the PHP variable into your javascript while your page is created.
<script type="text/javascript">
var MyJSStringVar = "<?php Print($MyPHPStringVar); ?>";
var MyJSNumVar = <?php Print($MyPHPNumVar); ?>;
</script>
Of course this is for simple variables and not objects.
You can pass PHP Variables to your JavaScript by generating it with PHP:
<?php
$someVar = 1;
?>
<script type="text/javascript">
var javaScriptVar = "<?php echo $someVar; ?>";
</script>
It depends on what type of PHP variable you want to use in Javascript. For example, entire PHP objects with class methods cannot be used in Javascript. You can, however, use the built-in PHP JSON (JavaScript Object Notation) functions to convert simple PHP variables into JSON representations. For more information, please read the following links:
PHP JSON Manual
PHP json_encode function
PHP json_decode function
You can generate the JSON representation of your PHP variable and then print it into your Javascript code when the page loads. For example:
<script type="text/javascript">
var foo = <?php echo json_encode($bar); ?>;
</script>
I think the easiest route is to include the jQuery javascript library in your webpages, then use JSON as format to pass data between the two.
In your HTML pages, you can request data from the PHP scripts like this:
$.getJSON('http://foo/bar.php', {'num1': 12, 'num2': 27}, function(e) {
alert('Result from PHP: ' + e.result);
});
In bar.php you can do this:
$num1 = $_GET['num1'];
$num2 = $_GET['num2'];
echo json_encode(array("result" => $num1 * $num2));
This is what's usually called AJAX, and it is useful to give web pages a more
dynamic and desktop-like feel (you don't have to refresh the entire page to communicate
with PHP).
Other techniques are simpler. As others have suggested, you can simply generate the
variable data from your PHP script:
$foo = 123;
echo "<script type=\"text/javascript\">\n";
echo "var foo = ${foo};\n";
echo "alert('value is:' + foo);\n";
echo "</script>\n";
Most web pages nowadays use a combination of the two.
<?php
$j=1;
?>
<script>
var i = "<?php echo $j; ?>";
//Do something
</script>
<?php
echo $j;
?>
This is the easiest way of passing a php variable to javascript without Ajax.
You can also use something like this:
var i = "<?php echo json_encode($j); ?>";
This said to be safer or more secure. i think
Update: I completely rewrote this answer. The old code is still there, at the bottom, but I don't recommend it.
There are two main ways you can get access GET variables:
Via PHP's $_GET array (associative array).
Via JavaScript's location object.
With PHP, you can just make a "template", which goes something like this:
<script type="text/javascript">
var $_GET = JSON.parse("<?php echo json_encode($_GET); ?>");
</script>
However, I think the mixture of languages here is sloppy, and should be avoided where possible. I can't really think of any good reasons to mix data between PHP and JavaScript anyway.
It really boils down to this:
If the data can be obtained via JavaScript, use JavaScript.
If the data can't be obtained via JavaScript, use AJAX.
If you otherwise need to communicate with the server, use AJAX.
Since we're talking about $_GET here (or at least I assumed we were when I wrote the original answer), you should get it via JavaScript.
In the original answer, I had two methods for getting the query string, but it was too messy and error-prone. Those are now at the bottom of this answer.
Anyways, I designed a nice little "class" for getting the query string (actually an object constructor, see the relevant section from MDN's OOP article):
function QuerystringTable(_url){
// private
var url = _url,
table = {};
function buildTable(){
getQuerystring().split('&').filter(validatePair).map(parsePair);
}
function parsePair(pair){
var splitPair = pair.split('='),
key = decodeURIComponent(splitPair[0]),
value = decodeURIComponent(splitPair[1]);
table[key] = value;
}
function validatePair(pair){
var splitPair = pair.split('=');
return !!splitPair[0] && !!splitPair[1];
}
function validateUrl(){
if(typeof url !== "string"){
throw "QuerystringTable() :: <string url>: expected string, got " + typeof url;
}
if(url == ""){
throw "QuerystringTable() :: Empty string given for argument <string url>";
}
}
// public
function getKeys(){
return Object.keys(table);
}
function getQuerystring(){
var string;
validateUrl();
string = url.split('?')[1];
if(!string){
string = url;
}
return string;
}
function getValue(key){
var match = table[key] || null;
if(!match){
return "undefined";
}
return match;
}
buildTable();
this.getKeys = getKeys;
this.getQuerystring = getQuerystring;
this.getValue = getValue;
}
JSFiddle demo
function main(){
var imaginaryUrl = "http://example.com/webapp/?search=how%20to%20use%20Google&the_answer=42",
qs = new QuerystringTable(imaginaryUrl);
urlbox.innerHTML = "url: " + imaginaryUrl;
logButton(
"qs.getKeys()",
qs.getKeys()
.map(arrowify)
.join("\n")
);
logButton(
'qs.getValue("search")',
qs.getValue("search")
.arrowify()
);
logButton(
'qs.getValue("the_answer")',
qs.getValue("the_answer")
.arrowify()
);
logButton(
"qs.getQuerystring()",
qs.getQuerystring()
.arrowify()
);
}
function arrowify(str){
return " -> " + str;
}
String.prototype.arrowify = function(){
return arrowify(this);
}
function log(msg){
txt.value += msg + '\n';
txt.scrollTop = txt.scrollHeight;
}
function logButton(name, output){
var el = document.createElement("button");
el.innerHTML = name;
el.onclick = function(){
log(name);
log(output);
log("- - - -");
}
buttonContainer.appendChild(el);
}
function QuerystringTable(_url){
// private
var url = _url,
table = {};
function buildTable(){
getQuerystring().split('&').filter(validatePair).map(parsePair);
}
function parsePair(pair){
var splitPair = pair.split('='),
key = decodeURIComponent(splitPair[0]),
value = decodeURIComponent(splitPair[1]);
table[key] = value;
}
function validatePair(pair){
var splitPair = pair.split('=');
return !!splitPair[0] && !!splitPair[1];
}
function validateUrl(){
if(typeof url !== "string"){
throw "QuerystringTable() :: <string url>: expected string, got " + typeof url;
}
if(url == ""){
throw "QuerystringTable() :: Empty string given for argument <string url>";
}
}
// public
function getKeys(){
return Object.keys(table);
}
function getQuerystring(){
var string;
validateUrl();
string = url.split('?')[1];
if(!string){
string = url;
}
return string;
}
function getValue(key){
var match = table[key] || null;
if(!match){
return "undefined";
}
return match;
}
buildTable();
this.getKeys = getKeys;
this.getQuerystring = getQuerystring;
this.getValue = getValue;
}
main();
#urlbox{
width: 100%;
padding: 5px;
margin: 10px auto;
font: 12px monospace;
background: #fff;
color: #000;
}
#txt{
width: 100%;
height: 200px;
padding: 5px;
margin: 10px auto;
resize: none;
border: none;
background: #fff;
color: #000;
displaY:block;
}
button{
padding: 5px;
margin: 10px;
width: 200px;
background: #eee;
color: #000;
border:1px solid #ccc;
display: block;
}
button:hover{
background: #fff;
cursor: pointer;
}
<p id="urlbox"></p>
<textarea id="txt" disabled="true"></textarea>
<div id="buttonContainer"></div>
It's much more robust, doesn't rely on regex, combines the best parts of both the previous approaches, and will validate your input. You can give it query strings other than the one from the url, and it will fail loudly if you give bad input. Moreover, like a good object/module, it doesn't know or care about anything outside of the class definition, so it can be used with anything.
The constructor automatically populates its internal table and decodes each string such that ...?foo%3F=bar%20baz&ampersand=this%20thing%3A%20%26, for example, will internally become:
{
"foo?" : "bar baz",
"ampersand" : "this thing: &"
}
All the work is done for you at instantiation.
Here's how to use it:
var qst = new QuerystringTable(location.href);
qst.getKeys() // returns an array of keys
qst.getValue("foo") // returns the value of foo, or "undefined" if none.
qst.getQuerystring() // returns the querystring
That's much better. And leaving the url part up to the programmer both allows this to be used in non-browser environments (tested in both node.js and a browser), and allows for a scenario where you might want to compare two different query strings.
var qs1 = new QuerystringTable(/* url #1 */),
qs2 = new QuerystringTable(/* url #2 */);
if (qs1.getValue("vid") !== qs2.getValue("vid")){
// Do something
}
As I said above, there were two messy methods that are referenced by this answer. I'm keeping them here so readers don't have to hunt through revision history to find them. Here they are:
1) Direct parse by function. This just grabs the url and parses it directly with RegEx
$_GET=function(key,def){
try{
return RegExp('[?&;]'+key+'=([^?&#;]*)').exec(location.href)[1]
}catch(e){
return def||''
}
}
Easy peasy, if the query string is ?ducksays=quack&bearsays=growl, then $_GET('ducksays') should return quack and $_GET('bearsays') should return growl
Now you probably instantly notice that the syntax is different as a result of being a function. Instead of $_GET[key], it is $_GET(key). Well, I thought of that :)
Here comes the second method:
2) Object Build by Loop
onload=function(){
$_GET={}//the lack of 'var' makes this global
str=location.search.split('&')//not '?', this will be dealt with later
for(i in str){
REG=RegExp('([^?&#;]*)=([^?&#;]*)').exec(str[i])
$_GET[REG[1]]=REG[2]
}
}
Behold! $_GET is now an object containing an index of every object in the url, so now this is possible:
$_GET['ducksays']//returns 'quack'
AND this is possible
for(i in $_GET){
document.write(i+': '+$_GET[i]+'<hr>')
}
This is definitely not possible with the function.
Again, I don't recommend this old code. It's badly written.

Categories