views:

599

answers:

4

Hello,

I hope somebody can help me with this little problem. The problem is that I still get confused with the syntax

The php line echo's a javascript function that takes one parameter, the database value.

It needs to be corrected, to get it to work. extra comma's??escaping?? I never know where exactly.

while($row=mysql_fetch_array($r)){
     echo '<li onclick="fill(\''.$row["value"].'\');">'.$row["value"].'</li>';

}

EDIT BECAUSE I just found out that my syntax is correct. I just needed to include the backslashes. It seems the javascript function is causing problems. In particular the line that hides the list

Does anyone has a solution for this?

function fill(thisValue) {
    $('#inputString').val(thisValue);
   //$('#suggesties').hide();

}

EDIT I finally came up with this: a callback

function fill(thisValue) {

     $('#suggesties').fadeOut('fast',function(){
        $('#inputString').val(thisValue);
    });

    }

thanks, Richard

A: 

Try escaping like this:

while($row=mysql_fetch_array($r)){
 echo '<li onclick="fill(\''.$row["value"].'\');">'.$row["value"].'</li>';

}
andreas
thanks, I did try'd that already. Is not working either
Richard
seems like your $row['value'] contains double quotes or characters that creates invalid javascript. There are numerous occasions where i had to do the same thing.
andreas
+1  A: 

I'd recommend also escape the string for use in javascript. json_encode does the trick. And the html part too, if it's not supposed to contain html:

echo '<li onclick="fill('.htmlentities(json_encode($row["value"])).');">'.htmlspecialchars($row["value"]).'</li>';
Michael Krelin - hacker
`htmlspecialchars` suffices in both cases.
Gumbo
Gumbo,not if string contains quotes. It will error-out at javascripting time.
Michael Krelin - hacker
Gumbo
Yes, Gumbo, it will escape the quote effective at the time of parsing html attribute. Then the parsed code goes to javascript interpreter which errors out on something like `fill("a"b")`.
Michael Krelin - hacker
@hacker: But `htmlentities` doesn’t solve that issue neither.
Gumbo
not `htmlentities` alone, but combined with `json_encode()`.
Michael Krelin - hacker
+1  A: 

You could keep the PHP within PHP Tags. Sometimes it's easier than escaping numerous places:

<?php while($row=mysql_fetch_array($r)) { ?>
  <li onclick="fill('<?php print $row["value"]; ?>');">
    <?php print $row["value"]; ?>
  </li>
<?php } ?>
Jonathan Sampson
+1  A: 
echo '<li onclick="fill(\''.$row["value"].'\');">'.$row["value"].'</li>';

Ouch. You've got a JavaScript string literal, inside an HTML-encoded attribute, inside a PHP string literal. No wonder the escaping is confusing you.

Well, first: you're outputting $row['value'] in the list item's text without escaping. This means trouble (potentially security trouble) when that value contains special characters like <, & and ". This needs to be wrapped in htmlspecialchars().

Next, you're putting something in a JavaScript string literal. That means if the string delimiter character ' or the escaping backslash \ is used in the value, it can break out of the string and inject JavaScript code into the page: again, a potential security issue. addslashes() can be used to escape a string for inclusion in a JS string literal; note you still have to htmlspecialchars() it afterwards because the string literal is itself inside an HTML-encoded attribute.

So we're looking at:

echo "<li onclick=\"fill('".htmlspecialchars(addslashes($row['value']), ENT_QUOTES)."');\">".htmlspecialchars($row['value']).'</li>';

Not very readable, is it? Well, we can improve that:

  1. We can lose the PHP string literal by using PHP itself to interpolate strings (as demonstrated by Jonathan). PHP is a templating language, take advantage of that!

  2. We can define a function with a shorter name than htmlspecialchars, which is a good idea since we need to use that function a lot in a typical template.

  3. We can avoid the JavaScript string literal by having the JavaScript side read the data it needs from the contents of the list item (text(), in jQuery, since that's what you seem to be using), rather than having to wrap it inside an ugly inline event handler.

For example:

<?php
    function h($text) {
        echo(htmlspecialchars($text, ENT_QUOTES));
    }
?>

<ul id="suggesties">
    <?php while ($row= mysql_fetch_array($r)) { ?>
        <li><?php h($row['value']); ?></li>
    <?php } ?>
</ul>

<script type="text/javascript">
    $('#suggesties>li').click(function() {
        $('#inputString').val($(this).text());
        $('#suggesties').hide();
    });
</script>
bobince
thanks, I like the jquery way--Still, I keep having the same problem.--The list hides and the text is not in the textbox.--If I do not hide the list, it works??
Richard
It works for me. Are you sure you got the capitalisation of `id="inputString"` right? (And it is an `id` and not a `name`.) Post complete non-working HTML page?
bobince
@Bobince I actually did not needed solving of my question anymore, see question.But with the security issues pointing out you where very very helpfull.
Richard