1

I am trying to pass a JSON element to a function, but it's not working. Any thoughts? Here is my code:

$(document).ready(function () {
    $.ajax({
        type: "GET",
        url: "/smallbusiness/_assets/js/events.json",
        success: formatJson,
        error: function() {
            alert("Data file failed to load");
        }
    });
});

function formatJson (data) {

        var json = data.events.event;
        var containerList = $('#event-list');
        var containerDescrip = $('#event-descrip');
        var template = '';
        var defaultDescrip = '';

        //Format and display event list 
        $.each(json, function(i, item) {
            template += '<p><a href="javascript:void(0)" onClick="formatDescrip(' + i + ',' + json[i].title + ')">' + this.title + '</a></p>';
        });
        containerList.html(template);
}

function formatDescrip(j, jsonData) {
    alert(j);
    alert(jsonData);
}

I am trying to pass both i and json[i].title to formatDescrip() but it's throwing this error:

Error: missing ) after argument list
Source File: http://localhost/smallbusiness/webinars.html#
Line: 1, Column: 20
Source Code:
formatDescrip(3,How to Leverage Email Marketing)

What am I doing wrong? And what if I wanted to pass the entire json object? How would I go about that? It seems like it should be straightforward, but I keep getting errors.

5
  • 1
    The error is pretty clear. Look at this: formatDescrip(3,How to Leverage Email Marketing). This is not valid JavaScript. It should be formatDescrip(3,'How to Leverage Email Marketing') so you are missing quotation marks. Commented Apr 27, 2011 at 14:20
  • 1
    And please, please, don't use javascript:void(0) the onclick attribute anymore in 2011... My eyes are bleeding. Commented Apr 27, 2011 at 14:22
  • Capsule - can you advise me what I should be doing instead? Commented Apr 27, 2011 at 14:23
  • don't use onclick either... Commented Apr 27, 2011 at 14:27
  • 1
    @ellenchristine if a <a> has no href, then it shouldn't be a <a> anyway, use something else: a button or just a span. That way you don't have to worry about what to put in the href attribute. About the onclick, see the accepted answer or read more about the click event handler: api.jquery.com/click Commented Apr 27, 2011 at 15:26

3 Answers 3

2

You forgot the quotes around the title.

    $.each(json, function(i, item) {
        template += '<p><a href="javascript:void(0)" onClick="formatDescrip(' + i + ',\"' + json[i].title + '\")">' + this.title + '</a></p>';
    });

Instead of setting up the handlers that way, however, why not use jQuery's ".delegate()"?

    $.each(json, function(i, item) {
        template += '<p><a class="dynamic" data-index="' + i + '" href="#">' + this.title + '</a></p>';
    });
    containerList.delegate("a.dynamic", "click", function(ev) {
      formatDescrip($(this).data('index'), $(this).text());
    });

Or something like that; if the list is extended multiple times then the ".delegate()" call should probably be done once, outside the handler.

edit — if the "formatDescrip()" function needs access to the original "event" object (whatever those things are that you use to make the list of <a> tags), you can pass it in to "formatDescrip()" instead of the index, and then modify the other function as necessary:

    containerList.delegate("a.dynamic", "click", function(ev) {
      formatDescrip( json[$(this).data('index')] );
    });

    // ...

function formatDescrip(eventObj) {
    alert(eventObj.title);
    //
    // ... more code here ...
    //
}
Sign up to request clarification or add additional context in comments.

3 Comments

Your solution worked great, thanks! And I learned something new about jQuery today. :)
One more question...what if instead of just passing the title, I wanted to pass the entire object?
Well, that that "json" array you extract from the AJAX response will still be around. The index that (in my sample) gets stashed in the "data-index" attribute of the <a> tags, well, it could be used to find the entry in that table corresponding to the <a>. Does that make sense? So, in "formatDescrip()", you'd just look up json[j] and that should be the original "event" (or whatever they are). You'd have to pass "json" to that function too, however. I'll edit the answer to be more clear.
1

I already explained in my comment what is the problem (missing quotes).

But it is better to not create the HTML this way, but to create "real" elements. It is even easier with jQuery:

var $div = $('<div />');
//Format and display event list 
$.each(json, function(i, item) {
    var title = json[i].title;
    $('<p />').append(
        $("<a />", {
            href: "javascript:void(0)", // you should use a proper URL here
            text: title,
            click: function(e){
                e.preventDefault(); 
                formatDescrip(i, title);
            }
        })
    ).appendTo($div);
});
containerList.empty().append($div.children());

Update: Or maybe even better, use .delegate() as @Pointy suggests.

2 Comments

What if no proper URL makes sense?
@ellenchristine: Then use a <button> and style it however you want it to. A link has a distinct semantic meaning.
0

I think that maybe you have a simple quote as part of the title and that is breaking your code. Try to scape those characters in your string or using double quotes instead simple ones.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.