I'm currently trying to call a JS script in order to export chart from primefaces chart component.
The problem is that the base64str variable seem to be null, and the responsible script for filling this value is not called for some reason :
xhtml code :
<p:chart id="chart" type="line" widgetVar="chart" model="#{cont.lineModel}" style="height:550px;width:1800px">
<p:ajax event="itemSelect" listener="#{cont.itemSelect}" update="growl" />
</p:chart>
<p:commandButton id="exp" value="Export" icon="ui-icon-extlink"
onclick="exportChart();" actionListener="#{cont.submittedBase64Str}"
/>
<h:inputHidden id="b64" value="#{cont.base64Str}" />
<script type="text/javascript">
function exportChart() {
img = chart.exportAsImage();
document.getElementById('hform:b64').value = img.src;
}
</script>
Controller :
public void submittedBase64Str(ActionEvent event){
// You probably want to have a more comprehensive check here.
// In this example I only use a simple check
if(base64Str.split(",").length > 1){
String encoded = base64Str.split(",")[1];
byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(encoded);
// Write to a .png file
try {
RenderedImage renderedImage = ImageIO.read(new ByteArrayInputStream(decoded));
ImageIO.write(renderedImage, "png", new File("D:\\out.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks
Change your onclick attribute to onstart.
<p:commandButton id="exp" value="Export" icon="ui-icon-extlink"
onstart="exportChart();" actionListener="#{cont.submittedBase64Str}" />
That should call the JS function.
EDIT
Also, you need to define img and chart in your function.
chart object is the PrimeFaces JS widget. You define widgetVar:
<p:chart ... widgetVar="chart"
And then you can get the chart object in your JS code like this:
PF('chart')
You need to use the PF function to get widgets since PrimeFaces 4.0.
As a side note, it's better to make your img variable local instead of global:
var img = chart.exportAsImage();
Now img is defined only in the scope of the function.
Related
I have a jsff page containing af:InlineFrame.
The source of this InlineFrame is HTML file say Frame.html
This html file has a javascript function called inlineframeFunction()
I have a button added in the jsff page.
My usecase is to invoke the function inlineframeFunction on click of the button which i am not able achieve.
var doc = inlineFrame.contentDocument?
inlineFrame.contentDocument: inlineFrame.contentWindow.document;
doc.frameFunction();
Frame.html
<script type="javascript">
function inlineframeFunction(){
alert('Inline Frame Function ');
}
</script>
JSFF Page
<af:panelGroupLayout id="pgl1" layout="vertical">
<af:resource type="javascript">
function inlineFrameRegionPageFunction() {
alert('Region Page Function');
var inlineFrame = document.getElementById('r1:0:if2');
var doc = inlineFrame.contentDocument? inlineFrame.contentDocument: inlineFrame.contentWindow.document;
doc.frameFunction();
}
</af:resource>
</af:panelGroupLayout>
<af:panelGroupLayout id="pgl2" layout="vertical">
<af:panelBox text="Inline Frame Region" id="pb2"
inlineStyle="background-color:Lime; border-color:Lime;">
<f:facet name="toolbar"/>
<af:inlineFrame id="if2" source="/Frame.html" shortDesc="InlineFrame"
inlineStyle="background-color:Gray;"/>
<af:commandButton text="Inline Region Button" id="rb2"
actionListener="#{pageFlowScope.RegionBean.onClickInlineFrameRgnButton}"/>
</af:panelBox>
</af:panelGroupLayout>
I used the following and it worked!
function inlineFrameRegionPageFunction() {
var frameComp =$('[id*="InlineFrame"]', document)[0].id;
document.getElementById(frameComp).contentWindow.frameFunction();
}
</af:resource>
To execute a javascript from a managed bean in adf you can use the following function (https://cedricleruth.com/how-to-execute-client-javascript-in-an-adf-java-bean-action/) :
/*** In YOURJSF.jsf button, or other component that need to execute a javascript on action, add : ****/
<af:commandButton text="ClickMe" id="cb1" actionListener="#{YOURSCOPE.YOURJAVABEAN.clickToExecuteJavascriptAction}"/>
/*** In YOURJAVABEAN.java class add : ***/
public void clickToExecuteJavascriptAction(ActionEvent actionEvent) {
this.executeClientJavascript("console.log('You just clicked : " + actionEvent.getSource() + " ')");
//Note: if you use a java string value in this function you should escape it to avoid breaking the javascript.
//Like this : stringValue.replaceAll("[^\\p{L}\\p{Z}]", " ")
}
//You should put this function in a util java class if you want to use it in multiple bean
public static void executeClientJavascript(String script) {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExtendedRenderKitService service = Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
service.addScript(facesContext, script);
}
Then in your case, refer to this question to call your iframe js function using javascript inside your action listener (Calling javascript function in iframe)
document.getElementById("if2").contentWindow.inlineframeFunction();
I am integrating jquery and zk project.
My goal is to pass value from js/jquery side to java side but in vain.
Here is the code I reference: use zAu to send data from client to server
However, there exists the error:
java.lang.ClassCastException: org.zkoss.zk.ui.event.MouseEvent cannot be cast to org.zkoss.zk.ui.event.ForwardEvent
I have seen some other person saying that we must cast the mouseevent to forwardevent in order to get a NOT NULL getData() value.
At my java side:
public class TryHttpLenovo extends SelectorComposer<Component> {
#Listen("onClick=#btnHttp")
public void serverReceive(Event e) {
ForwardEvent forwardE = (ForwardEvent) e;
System.out.println("forwardE.getData()"+forwardE.getData());
}
}
In my http.zul:
<window apply="foo.TryHttpLenovo" xmlns:w="client">
<button id="btnHttp" w:onClick="sentToServer();">http send</button>
</window>
In my testhttp.js:
function sentToServer(){
var wgt=zk.Widget.$('btnHttp');
zAu.send(new zk.Event(wgt, "serverReceive", {foo: 'my data'}, {toServer:true}));
}
After several trial-and-error, I finally solve this!!!!
The solution is to extend GenericForwardComposer.
I also adjust some other things, but the only important change is to extend GenericForwardComposer instead of SelectorComposer.
The #Listen annotation is not needed in my solution.
in .java
public class TryHttpV2 extends GenericForwardComposer {
public void onUser2$info(Event event) {
ForwardEvent forwardE = (ForwardEvent) event;
System.out.println("forwardE.getOrigin().getData(): " + forwardE.getOrigin().getData());
}
}
in .js
function sendToServer(){
payload = "using generic composer";
zAu.send(new zk.Event(zk.Widget.$(this), 'onUser2', payload));
}
in .zul
<?page title="try using generic composer" contentType="text/html;charset=UTF-8"?>
<?script src="/js/tryhttp_v2.js" ?>
<zk xmlns="http://www.zkoss.org/2005/zul">
<window id="info" apply="foo.TryHttpV2" xmlns:w="client">
<button id="btnExec" w:onClick="sendToServer();" label="to be tested button" />
</window>
</zk>
Good day!
I need a help on activating my javascript function via on-load on code behind.
Here is my code:
string script = #"var applyCss = function () {
var css = '#CalendarPanel1-month-day-20170607, #CalendarPanel1-month-day-20170614 {background-color: #D0D3D4;}';
Ext.net.ResourceMgr.registerCssClass('someCssClassId', css);
}; ";
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "css", script, true);
By the way, my code above works in front-end via button click.
But my desired result is, I want my javascript function to work on page load without needing to click the button. I put my javascript function in code-behind because I will put dynamic dates in the css variables. The code above still has static variables. (CalendarPanel1-month-day-20170607)
Will gladly appreaciate any response / solution. Big thanks!
You could use an immediately invoked function to do the trick. Basically you don't give a name to your javascript function and you invoke it right after it's defined.
For example:
var script = #"(function () {alert('Hello');})(); ";
ScriptManager.RegisterStartupScript(this, typeof(Page), "123", script, true);
You need to wrap the function with its body between parenthesis then another set of parenthesis to invoke the function.
You can also pass parameters to your function (which I'm assuming it's what you want to do):
var myAlertText = "Hello Hello";
var script = #"(function (myText) {alert(myText);})('" + myAlertText + "');" ;
If I were you though I would defined the function in client code and just invoke it from code behind with the right parameters.
An alternative and fancier way to call javascript code from code behind would be using X.Call(). Check out this example:
<%# Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
string script = #"var myJSSideVar = 'my var value';
var applyCss = function (paramOne, paramTwo) {
var css = '#CalendarPanel1-month-day-20170607, #CalendarPanel1-month-day-20170614 {background-color: #D0D3D4;}';
Ext.net.ResourceMgr.registerCssClass('someCssClassId', css);
Ext.Msg.alert('applyCss called.', 'I\'ve been run with parameters: (' + paramOne + ', ' + paramTwo + ').');
};";
var hi = "hello";
X.AddScript(script);
X.Call("applyCss", new object[] { hi, new JRawValue("myJSSideVar") });
}
}
</script>
<html>
<head runat="server">
<title></title>
</head>
<body>
<form runat="server" id="form1">
<div>
<ext:ResourceManager runat="server" />
</div>
</form>
</body>
</html>
Notice the second parameter sent to the script call is sent "raw", i.e., it calls: applyCss("hello", myJSSideVar)
If you need to pass but one single parameter you don't need to pass an array, e.g. X.Call("applyCss", hi);
I am very new to javascript but unfortunately it is what I have to use for a thermometer chart that I'm using. I need to get the value of an ASP label text and then store that into a javascript variable which will be used to set the chart value.
For some reason it is not storing the value at all and the chart obviously doesn't have the value needed. Again I am extremely new to javascript so please be nice. :) Here is what I have so far.
Here is part of the ASPX page:
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script>
window.onload = function () {
// Create the Thermometer chart. The arguments are: the canvas ID, the minimum,
// the maximum and the indicated value.
var grossSales = $('#<%= MtdLBL.ClientID %>').next().text;
var thermometer = new RGraph.Thermometer('salesThermometer', 0, 180000, parseInt(grossSales.valueOf))
// Configure the thermometer chart to look as you want.
.Set('chart.gutter.left', 45)
.Set('chart.gutter.right', 45)
.Set('chart.colors', ['rgba(255,0,0,1)'])
.Set('chart.units.pre', '$')
// Now call the .Draw() method to draw the chart.
.Draw();
}
</script>
<link href="Charts/RGraph/demos/demos.css" rel="stylesheet" type="text/css" />
<script src="Charts/RGraph/libraries/RGraph.common.core.js" type="text/javascript"></script>
<script src="Charts/RGraph/libraries/RGraph.thermometer.js" type="text/javascript"></script>
</asp:Content>
And this is from the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["TeamID"] == null || Session["TeamID"] == "")
{
Response.Redirect("~/Default.aspx");
}
else
{
//Populate department average
double deptAvg = achievementData.DeptAverage();
DeptAvgValueLBL.Text = deptAvg.ToString("P0");
//Get sales data
Sales getSalesData = new Sales();
MtdLBL.Text = getSalesData.GrossSalesByTeam(Session["TeamID"].ToString());
}
}
var grossSales = $('#<%= MtdLBL.ClientID %>').text();
Note parentheses; text is a function, not a simple value. The next() is out of place unless you want the following control, which doesn't seem right.
Remove the valueOf() call in the thermometer variable definition line. valueOf is used to return a primitive boolean. I'm assuming you're trying to use the grossSales number for something other than a boolean flag.
See http://www.w3schools.com/jsref/jsref_valueof_boolean.asp
Also, as #catfood said, you don't need the .next()
I’m having trouble getting JSON results working with Struts 2.2.1.1.
Does anyone have a simple working example that returns a JSON result to a JSP using Struts 2.2.1.1 and is ready to run in Eclipse as a dynamic web project?
Please include the struts.xml, action class and JSP code. Also, note dependencies. Thank you.
Here’s how to create a simple JSON example using the Struts 2 jQuery plugin.
Go to Struts2 jQuery Plugin Showcase
Navigate to Ajax Forms > Buttonset / Checkboxes
Review the code for Buttonset that was populated from AJAX JSON Result. This is code I selected to create a simple example.
Create dynamic web project in Eclipse
Create a Java package and name it test.
Download the Struts 2 jQuery plugin showcase source (struts2-jquery-showcase-x.x.x-sources.jar) and extract the JAR file.
Import Echo.java, JsonSample.java, and ListValue.java into the test package and move the code into the package with quick fix.
Change the class annotation in Echo.java and JsonSample.java to #ParentPackage(value = "test")
In addition to the standard Struts 2 libraries, ensure that the struts2-json-plugin-x.x.x.jar, struts2-jquery-plugin-x.x.x.jar, and struts2-convention-plugin-x.x.x.jar files are in your classpath.
Create a struts.xml file and add the following XML:
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.convention.action.packages" value="test" />
<package name="test" extends="json-default” namespace="/">
</package>
</struts>
Create an index.jsp file and insert the following code:
<s:form id="form2" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample" />
<sj:checkboxlist href="%{remoteurl}" id=“remoteCheckboxlist” name="echo" list="languageList" label="Language" />
<sj:submit targets="formResult" value="AJAX Submit" indicator=“indicator” button="true"/>
</s:form>
Run the example.
Must see : struts2-x.x.x-all.zip /apps/struts2-showcase-2.2.1.war
Struts 2 and JSON example
Struts 2 autocompleter + JSON example
It is very simple to get Json work with struts2.
For this,
you need to add struts-json plugin*(jsonplugin-0.32.jar)* to classpath.
Your struts.xml file should extends json-default
<package name="base" namespace="/" extends="json-default">
Your action result be like this.
<result type="json"><param name="root">jsonData</param></result>
Inside action class, declare json as
private LinkedHashMap<K, V> jsonData new LinkedHashMap<k, V>();
and then add the result list to json like
jsonData.put("result", anyList or object);
Thats all we have to do. Then we can access the result using javascript.
Try this, will help you in Struts 2.0.14 with jsonplugin-0.32.jar.
struts.xml:
<struts>
<package name="example" extends="json-default">
<action name="HelloWorld" class="example.HelloWorld" >
<result type="json" />
</action>
<action name="HelloWorld1" class="example.HelloWorld" >
<result name="success" >example/HelloWorld.jsp</result>
</action>
</package>
</struts>
action class Helloworld.java:
package prabhakar;
import glb.DB;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Prabhakar
*/
public class HelloWorld {
private List<StateMaster> stateList= new ArrayList<StateMaster>();
private List<RegnMaster> regnList= new ArrayList<StateMaster>();
private Integer stateId;
public Integer getStateId()
{
return this.stateId;
}
public void setStateId(Integer stateId)
{
this.stateId=stateId;
}
public List<StateMaster> getStateList() {
return stateList;
}
public void setStateList(List<StateMaster> stateList) {
this.stateList = stateList;
}
public void setRegnList(List<RegnMaster> regnList) {
this.regnList = regnList;
}
public List<RegnMaster> getRegnList() {
return regnList;
}
public String execute() throws Exception {
stateList=DB.getStateData()//
if(stateId !=null)
{
regnList=DB.getRegnByStateId(stateId);
}
//setMessage(getText(MESSAGE));
return "success";
}
/**
* Provide default valuie for Message property.
*/
}
You can directly call HelloWorld.action to view the JSON data or else you can bind the JSON data to a form element below.
JSP page HelloWorld.jsp:
/*
Prabhakar
*/
<%# page contentType="text/html; charset=UTF-8" %>
<%# taglib prefix="s" uri="/struts-tags" %>
<script>
<%#include file="../js/jquery-1.7.1.min.js"%>
</script>
<html>
<!-- JavaScript Plugins -->
<script>
function getLoad(){
var stateId = $('#state').val();
$.getJSON('HelloWorld.action', {'stateId': stateId},
function(data) {
var divisionList = (data.regnList);
var options = $("#regn");
options.find('option')
.remove()
.end();
options.append($("<option />").val("-1").text("--Select--"));
$.each(divisionList, function() {
options.append($("<option />").val(this.regnId).text(this.regnName));
});
}
);}
</script>
<!-- jQuery-UI Dependent Scripts -->
<body>
State List <s:select name="stateId" list="stateList" id="state" listKey="stateId" onchange="getLoad()" listValue="stateName" headerKey="0" headerValue="--select--" />
Regn List <s:select name="regnId" list="regnList" listKey="regnId" id="regn" listValue="regnName" headerKey="0" headerValue="--select--" />
</body>
</html>
Happy coding :)