2

HTML & PHP:

<select id="package">
    <?php $package_size_array = array('size_a' => 70, 'size_b' => 90, 'size_c' => 130); ?>
    <option value="size" id="<?php echo json_encode($package_size_array, JSON_PRETTY_PRINT); ?>">Size</option>
    <!--Some more <option>s here...-->
</select>

JavaScript:

$(document).ready(function() {  
    $('select#package').change(function() {
        var id = $(this).children(':selected').attr('id');
        alert(JSON.parse(id)); /* Line 217. in functions.js file */
    });
});

Problem: Chrome and probably other browsers' console prints:

Uncaught SyntaxError: Unexpected end of input functions.js:217
(anonymous function) functions.js:217
jQuery.event.dispatch jquery.js:4371
elemData.handle
12
  • 2
    Why would you need to JSON.parse() the id? Commented Jun 3, 2014 at 13:17
  • What are you actually trying to accomplish with this code? id is just a string, it's not a JSON object. Commented Jun 3, 2014 at 13:18
  • Because the <option> id contains JSON encoded php array. I want get back my PHP array through JavaScript and JSON unserializing. Commented Jun 3, 2014 at 13:19
  • 1
    @David: "JavaScript Object Notation Object"? JSON is never an "Object", rather an string. (Nitpicking, I know) Commented Jun 3, 2014 at 13:19
  • 2
    The syntax error is because he's using double quotes in id="JSON" and the JSON also contains double quotes, so his quotes are all messed up. Commented Jun 3, 2014 at 13:23

1 Answer 1

7

Unless the data you are converting to JSON consists solely of a Boolean or a Number, the resulting JSON is going to contain " characters.

You are using " characters to delimit your ID attribute value, so the first one in the data is going to end the attribute prematurely.

This would be much more obvious if you examined the data you were sending to the browser (with view > source) instead of just looking at the PHP.

You need to convert the text representation of the JSON to an HTML representation of it.

id="<?php echo htmlspecialchars(json_encode($package_size_array)); ?>"

You should also remove JSON_PRETTY_PRINT, it is useful for debugging but inefficient in practice and new lines aren't a good fit for attribute values.


That said, using JSON for an ID value is a terrible idea. If you want to store arbitrary data on an element, use a data-* attribute (you'll still need to convert the text to HTML though!)

Sign up to request clarification or add additional context in comments.

3 Comments

A nice thing about storing JSON in a data-* attribute is that jQuery will automatically decode it for you.
Take out JSON_PRETTY_PRINT, I think that makes things even worse.
in chrome running document.getElementById('package').options[0].id in console on the provided php file gives the expected json in its full glory. So doesnt necessarily break things, altho i share your concern for multiline html attributes

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.