0

I am trying to add a function to a JSONJavaObject and calling it from a control on an xpage.

so far I have:

json = (JsonJavaObject) JsonParser.fromJson(factory, colJson);                      
String func = "function () { alert('you clicked?'); }";                         
json.put("onClick", new JsonReference(func) );

In the first line I add key-value pairs from a column in a Notes view. In the second line I define the function as a string. In the last line I place the converted string as function in the jsonjava object.

I read about this in the following blog post: http://camerongregor.com/2016/01/19/doublequoteavoidance/

In the next step I bind the function to e.g. a button control as followed:

<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[obj.onClick]]></xp:this.script>
</xp:eventHandler>
</xp:button>

obj is the respresentation of the JSONJava object in SSJS.

But without success. Anyone know how I can call the function in the object?

Patrick Kwinten
  • 1,789
  • 1
  • 13
  • 21

2 Answers2

0

Does obj.onClick already give you a handle to the function returned by the Java class? If it does then you should be able to call it using the call or apply methods that are available in JavaScript:

obj.onClick.call();
obj.onClick.apply();

More details about those two methods can be found here: What is the difference between call and apply?

Community
  • 1
  • 1
Mark Leusink
  • 3,567
  • 12
  • 21
  • it looks obj.onClick does not give me handle to the function. when i try both methods nothing happens (alert function invoked). – Patrick Kwinten Apr 08 '16 at 14:22
  • if I print obj.onClick to the screen (e.g. computed text) then I get displayed com.ibm.commons.util.io.json.JsonReference@3d7b3d7b . So it looks there is a hook to the jsonreference established. not sure how to utilize it – Patrick Kwinten Apr 08 '16 at 14:24
  • You need to serialize the JsonJavaObject to a string before returning it, as described in Cameron's article: return JsonGenerator.toJson(JsonJavaFactory.instance, o, false); – Mark Leusink Apr 08 '16 at 15:20
0

I hope I will make sense here, let me know if anything to clarify.

If you are simply trying to dynamically output the client side script of a button event, then you don't need to use JsonReference at all. You can just use a String.

In my blog article I might not have make it clear why I needed to use JsonReference. I was using it in the process of rendering a custom UIComponent, part of this process required generating a Json object client side. To do this I created the JsonJavaObject as you did and then asked it to be turned into a string with the 'toJson' method. My problem was that when I asked the whole object to become a string, every property of that object that was a String, would begin and end with a double quote. I needed to ensure that the properties which were intended to be functions did not begin and end with "". By using the JsonReference the JsonGenerator became aware of my intention not to include these double quotes.

In your case, it looks as though you are just trying to dynamically determine what happens with onClick. To do this you could simply use a String instead of the JsonReference. The inclusion of the 'function() {}' is unnecessary as this will be generated when the event handler is rendered at the end of the page.

For Example here would be the Json Java Object

JsonJavaObject obj = new JsonJavaObject();
String func = " alert('you clicked?'); ";
obj.put("onClick", func);   
return obj;

And here would be the button:

<xp:button id="button1" value="Alert Me">
    <xp:eventHandler event="onclick" submit="false"
        script="#{javascript: myBean.myObject.get('onClick')}">
    </xp:eventHandler>
</xp:button>

This should give you the end result of seeing 'you clicked?' alert.

You can also inspect how this has all been generated in the script block near the end of the page using 'view Source' or your favourite web browser developer tools:

function view__id1__id2_clientSide_onclick(thisEvent) {
 alert('you clicked?'); 

}

XSP.addOnLoad(function() {
XSP.attachEvent("view:_id1:_id2", "view:_id1:button1", "onclick",     
  view__id1__id2_clientSide_onclick, false, 2);
}); 

Let me know if anything isn't clear, hope it helps!

Cameron Gregor
  • 1,450
  • 7
  • 8