0

I have a jQuery library that wants you to pass it a JavaScript object as an option. For example, this works:

//Hardcoded JavaScript object
var myData = { "A" : "1", "B" : "2", "C" : "3" };

//Call to jQuery with object as an option
$("#mySelectorId").myJqueryFunction({values: myData});

I need the myData object to not be hardwired like that.

I can easy get the "A to 1, B to 2, C to 3" structure in my Java code, put it in a Map (or some other object), and add it to the request via request.setAttribute("myData", myMap);. I am just not sure how to convert the Map (etc) into the needed JavaScript object. Here is what I have tried.

//Java
Map<String, String> myMap = new TreeMap<String, String>();
map.put("A", "1");
map.put("B", "2");
map.put("C", "3");
request.setAttribute("myMap", myMap);

//JSP
<c:set var="myData" value="{" />
<c:forEach var="mapEntry" items="${myMap}" varStatus="counter">
    <c:set var="myData" value="${myData}'${mapEntry.key}' : '${mapEntry.value}'" />
    <c:if test="${counter.count < fn:length(myMap)}">
        <c:set var="myData" value="${myData}, " />
    </c:if>
</c:forEach>
<c:set var="myData" value="${myData}}" />

<script>
    var myData = '${myData}';
    $("#mySelectorId").myJqueryFunction({values: myData});
</script>

This works until the myJqueryFunction reaches a point where it tries to do something like this:

var i = values[code];

Essentially, it is trying to reference a particular variable on the object (e.g. trying to get the value of "B", which is 2). Note that code is a function parameter that holds the A/B/C value.

I have tried messing around with including or not including the quotes around ${mapEntry.key} and things like that, but nothing seems to work.

Does anyone know how to get this working?

Snowy Coder Girl
  • 5,408
  • 10
  • 41
  • 72

4 Answers4

0

To add more properties (including by variable) in JavaScript, you can use this syntax

var myData = {}; // Initial object
myData["A"] = "1";
myData["B"] = "2";
myData["C"] = "3";

Then myData is { "A" : "1", "B" : "2", "C" : "3" }.

Paul S.
  • 64,864
  • 9
  • 122
  • 138
0

It's been a while since I've done JSP, but you're overriding your myData var in every iteration of your JSP forEach call, instead of concatenating to it. Second, your call to 'myJqueryFunction' is syntactically incorrect, instead of values: myData you probably want to use {values: myData}.

Third, you probably don't want to manually assemble a javascript object via JSP, there should be decent libraries out there that will do it for you.

cthulhu
  • 3,142
  • 2
  • 23
  • 32
  • On point 1, notice that `${myData}` is always in the setter value, so it is concatenating. I have done a `` and all is well. On point 2, just a typo (this isn't my real code). I will fix my question text. On point 3, our company probably wouldn't allow any additional libraries, unless you know a well established one. – Snowy Coder Girl Nov 07 '12 at 15:43
0

One solution is to use AJAX/JSON.

In a NEW controller (lets have it map to /MyControllerUrl), use a List and fill it with objects that have both the letter and the number of our objects (lets call this new object MyClass).

List<MyClass> myList = new ArrayList<MyClass>();
myList.add(new MyClass("A", "1"));
myList.add(new MyClass("B", "2"));
myList.add(new MyClass("C", "3"));
request.setAttribute("myList", myList);

The above is all that is in the new controller. And the returned JSP has only the following.

<c:out value="[" />

<c:forEach var="listItem" items="${myList}" varStatus="counter">
    {"letter": "${listItem.letter}", "number": "${listItem.number}"}<c:if test="${counter.count < fn:length(myList)}">,</c:if>
</c:forEach>

<c:out value="]" />

Finally, in the original JSP, have the following.

<script>
    var myJsList= { };
    $.ajax({
        url: '${pageContext.request.contextPath}/MyControllerUrl',
        dataType: 'json',
        async: false,
        success: function(objectInfo) {
            $.each(objectInfo, function(key, object) {
                myJsList[object.code] = object.label;
            });
        }
    });
</script>

Note that I used .ajax instead of .getJSON so that I could set async: false so that the variable would be immediately ready for reference.

I don't love this option, as it requires 2 calls instead of 1. So I'll wait and see if there are any other ideas suggested.

Snowy Coder Girl
  • 5,408
  • 10
  • 41
  • 72
0

If you're getting myData as a string, and you can't remove the quotes around '${myData}' (which seems odd that you couldn't, BTW), then try this:

Change first line of JSP to this:

<c:set var="myData" value="var objMyData = {" />

And change your script to:

<script>
    var myData = '${myData}';
    eval(myData);
    $("#mySelectorId").myJqueryFunction({values: objMyData});
</script>
Wesley Petrowski
  • 1,131
  • 7
  • 11