views:

4018

answers:

4

I want to populate form fields with values from a database immediately after the user enters a value in the #sid field. Here is my jQuery/HTML example:

<script src="jquery-1.3.1.min.js"></script>
<script type="text/JavaScript">
$(document).ready(function()
{
  $('#sid').bind("change", function(){
    $.getJSON("test.php?sid=" + $("#sid").val(), 
    function(data)
    {
      $.each(data.items, 
      function(i, item)
      {
        if (item.field == "saffil")
        {
              $("#saffil").val(item.value);
        }
        else if (item.field == "sfirst")
        {
              $("#sfirst").val(item.value);
        }
      });
      });
   });
});
</script>

Here is my processing script (test.php which gets called by the .getJSON method)

<?
require_once("db_pers.inc");

$ssql = "SELECT * FROM contacts_mview WHERE sempid = '".$_GET['sid']."'";

$rres = pg_query($hdb, $ssql);
pg_close($hdb);

$ares = pg_fetch_assoc($rres);

$json = array(array('field' => 'saffil',
      'value' => $ares['saffil']),
       array('field' => 'sfirst',
      'value' => $ares['sfirst']));

echo json_encode($json);
?>

According to firebug the GET param is passed just fine to test.php and the JSON object comes back just fine:

[{"field":"saffil","value":"Admin"},{"field":"sfirst","value":"Nicholas"}]

however nothing happens on the page and I get the following error message back:

G is undefined
init()()jquery-1....1.min.js (line 12)
(?)()()test.html (line 15)
I()jquery-1....1.min.js (line 19)
F()()jquery-1....1.min.js (line 19)
[Break on this error] (function(){var l=this,g,y=l.jQuery,p=l.....each(function(){o.dequeue(this,E)})}});

This is my first stab at ajax with jQuery so any input would be much appreciated!

Thanks,

  • Nicholas
+5  A: 

Nice little injection attack waiting to happen there ;)

Try changing

$.each(data.items,

to:

$.each(data,

Edit: to answer your comment, I like to name my fields the same as the data key:

<input type="text" name="saffil" value="" />
<input type="text" name="sfirst" value="" />

var data = {saffil:'foo', sfirst:'bar'};
$.each(data, function(key, value) {
   $('[name='+key+']').val(value)
})
Crescent Fresh
Injection attack = a result of not sanitizing input, yes? (Didn't bother to include that in this example) -- You are correct, that minor change fixed my problem! Thank you!
Nicholas Kreidberg
This brings me to another question though... is there a better way of doing this? At least populating the fields more dynamically so I don't have to spell each one out but rather just "walk" the JSON object to figure out what fields to populate and with what values?
Nicholas Kreidberg
Awesome, thanks for the edit -- I just noticed it and that is exactly what I was looking for.
Nicholas Kreidberg
A: 

Not sure, but I do see a huge Sql Injection hole.

Arron
Of course I am not sanitizing inputs for this example ;)
Nicholas Kreidberg
(that is what you were referring to, using the $_GET value directly in the SQL query, correct?)
Nicholas Kreidberg
+1  A: 

I agree with the previous repliers. That script is an SQL injection waiting to happen. You should probably use something like PDO with prepared statements or at least something like pg_escape_string.

Lior Cohen
All sanitizing was removed from the code in the example just to improve readability and avoid confusing anyone as to where the problem was. Thank you for pointing this out though :)
Nicholas Kreidberg
A: 

I don't believe the answers here are correct.

The problem here is that the PHP (and Perl) libraries encode the JSON that you provide them, and nothing else.

Thus, if you give the encoding function an array, it will output:

[ element1, element2, element3]

This is the correct encoding for an array, but it is not a correct JSON response. A correct JSON response must be an object as outlined at http://json.org/.

Thus, you need to make a wrapper object, around your array and then encode and respond with that.

<?php
$json = array('items' =>
              array(
                    array('field' =>  'saffil',
                          'value' =>      $ares['saffil']),
                    array('field' =>      'sfirst',
                          'value' =>      $ares['sfirst'])
              )
        );

echo json_encode($json);
?>
Dancrumb
A valid JSON string can be any of the states outlined at json.org, including "[]", "true", "false", "null", "52", etc. It doesn't have to be wrapped in object literal braces.
Crescent Fresh
Perhaps, but a valid JSON *object* must be wrapped with braces
Dancrumb