0

ZK Client side trigger click on button

asked 2012-04-17 02:23:53 +0800

charlesfizer gravatar image charlesfizer
21 1

I have the following test page and server POJO for a ZK 6 MVVM project. I am using 04/04/2012 Freshly build. I am attempting to open the FileUpload dialog on a button that is configured to do file upload. In this example I show that using ZK Client side code I can trigger the click event of other list cells and other buttons through the ZK Client side code. However, when attempting to open the File Upload dialog, the same process fails. Does anyone know if what I am trying to accomplish is possible? What event can I trigger on the upload button to popup the filebrowser dialog box and upload files?

The ultimate goal is to allow the upload dialog to trigger from a listcell click. However, listcell and list item don't support the upload syntax like button does. I could put a button in the listcell and style it to look not like a button, but I would prefer to attempt to click the button via code and avoid changing the styles.

Zul page.

<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
<window border="none" apply="org.zkoss.bind.BindComposer"
		viewModel="@id('vm') @init('Test')">
		<listbox>
			<listitem>
				<listcell id="listCell1" label="ListCell1" onClick="@command('sayHello')" />
			</listitem>
			<listitem>
				<listcell id="listCell2" label="Auto Click List Cell 1" xmlns:w="client" w:onClick="this.$f('listCell1', true).doClick_(new zk.Event(this.$f('listCell1', true), 'onClick', null));" />
			</listitem>
			<listitem>
				<listcell id="listCell3" label="Auto Click Button" xmlns:w="client" w:onClick="this.$f('btn', true).doClick_(new zk.Event(this.$f('btn', true), 'onClick', null));" />
			</listitem>
			<listitem>
				<listcell id="listCell4" label="Auto Click Upload Button onClick" xmlns:w="client" w:onClick="this.$f('btnUpload', true).doClick_(new zk.Event(this.$f('btnUpload', true), 'onClick', null));" />
			</listitem>
			<listitem>
				<listcell id="listCell5" label="Auto Click Upload Button onUpload" xmlns:w="client" w:onClick="this.$f('btnUpload', true).doClick_(new zk.Event(this.$f('btnUpload', true), 'onUpload', null));" />
			</listitem>
		</listbox>
		<button id="btn" label="click" onClick="@command('sayHello2')" />
		<button id="btnUpload" label="Upload" upload="true" onUpload="@command('sayHello3')" visible="true" />
</window>
</zk>

MVVM POJO

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;

public class Test {

	@Init
	public void init() {}
	@Command
	public void sayHello() {
		System.out.println("List Cell Hello");
	}
	@Command
	public void sayHello2() {
		System.out.println("Button Hello");
	}
	@Command
	public void sayHello3() {
		System.out.println("Upload Button Hello");
	}
	
}

delete flag offensive retag edit

7 Replies

Sort by ยป oldest newest

answered 2012-04-17 08:02:14 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

Hi,

This can be done by Client Side Programming or execute Javascript from server side, please refer to the sample:

ZKFiddle-Link

TestVM.java
package j1oi61tg$v2;


import java.util.*;

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;
public class TestVM {
public String getMsg () {
return "open upload dialog by client side programming";
}
public String getMsgTwo () {
return "open upload dialog by javascript that executed by server";
}
public String getOverrideClick () {
return "function (evt) {this.$doClick_(evt);jq('$btn').next().find('input').click();}";
}
@Command
public void openUploadDialog () {
System.out.println(" open upload");
Clients.evalJavaScript("jq('$btn').next().find('input').click();");
}

}


index.zul
<zk xmlns:w="client">
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('j1oi61tg$v2.TestVM')">
<label value="@load(vm.msg)">
<attribute w:name="doClick_">
function (evt) {
// call the original doClick_ function
this.$doClick_(evt);
// click the upload button by JQuery
jq('$btn').next().find('input').click();
}
</attribute>
</label>
<div></div>
<label value="@load(vm.msgTwo)" onClick="@command('openUploadDialog')"></label>
<div></div>
<button id="btn" label="Upload" upload="true" />
</window>
</zk>

Click the label 'open upload dialog by client side programming', the upload dialog should opened well,
click the label 'open upload dialog by javascript that executed by server' the browser may block the dialog and confirm whether to allow it.

Regards,
Ben

link publish delete flag offensive edit

answered 2012-04-18 20:47:44 +0800

charlesfizer gravatar image charlesfizer
21 1

Thank you so much for your reply Ben. The solution you showed worked perfectly!

Do you know where I can read documentation about the html that comprises each widget so I could use that next time to figure out with the JQuery javascript which object to perform click or other operations if needed? I could not seem to find the correct documentation page.

link publish delete flag offensive edit

answered 2012-04-19 03:45:23 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

Hi,

For the client side API, you may refer to Latest jsdoc.

For Component usage, please refer to ZK Component Reference.

For the dom structure, please refer to ZK Style Guide, or you may right click on the component and select 'Inspect Element' in Chrome or in Firefox with Firebug.

For source code, please refer to git browse or svn browse.

Regards,
Ben

link publish delete flag offensive edit

answered 2012-04-23 22:32:03 +0800

charlesfizer gravatar image charlesfizer
21 1

Hi Ben,

Thank you so much for all your assistance.

I am still running into one issue, which hopefully you could help me out with. The previous test I did was with Firefox, however, we need to support IE 8 as well, which causes problems for the code sample. The issue is with IE8 which provides "additional security" which prevents the form from being submit for a file upload if the file upload button was clicked programmatically through javascript.

I followed some sample code from someone on a stackoverflow forum post, which used jquery to set the change event for the input element to run some javascript which got around the issue. I tested and got this code to work, but when trying to apply the same principal within my ZK application it fails to work. The post was: http://stackoverflow.com/questions/5845643/open-file-input-dialog-and-upload-onchange-possible-in-ie

Do you know of a way to get around this problem in IE8 with ZK? Debugging my javascript, i found that the change event on the inner input tag for the file upload button is assigned a certain zk client function. I cannot seem to override this to a separate change event to test the sample. I don't know if that would even work or if it would break some other dependency the input tag has on that function.

Any suggestions would be very much appreciated!

link publish delete flag offensive edit

answered 2012-04-24 03:10:24 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

Hi,

You may try put the changed event to evt.domEvent, if it still not work, I suggest give the change-style way a try.
Please refer to the sample:

ZKFiddle-Link

TestVM.java
package j1oi61tg$v3;


import java.util.*;

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;
public class TestVM {
public String getMsg () {
return "open upload dialog by client side programming";
}
public String getMsgTwo () {
return "open upload dialog by javascript that executed by server";
}
public String getOverrideClick () {
return "function (evt) {this.$doClick_(evt);jq('$btn').next().find('input').click();}";
}
@Command
public void openUploadDialog () {
System.out.println(" open upload");
Clients.evalJavaScript("jq('$btn').next().find('input').click();");
}

}


index.zul
<zk xmlns:w="client">
<style>
.z-button *,
.z-upload * {
background: transparent !important;
margin: 0 !important;
border: 0 !important;
cursor: default !important;
}
.z-button-cm {
display: none;
}
</style>
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('j1oi61tg$v3.TestVM')">
<label value="@load(vm.msg)">
<attribute w:name="doClick_">
function (evt) {
// call the original doClick_ function
this.$doClick_(evt);
//---- update domTarget and domEvent as need ----//
// evt.domEvent = THE_NEW_EVENT; //
// evt.domTarget = THE_NEW_TARGET; //
//---- ------------------------------------- ----//
// click the upload button by JQuery
jq('$btn').next().find('input').click();
}
</attribute>
</label>
<div></div>
<label value="@load(vm.msgTwo)" onClick="@command('openUploadDialog')"></label>
<div></div>
<div style="position: relative; cursor: default;" height="30px"
onMouseOver="uploadDiv.setParent(self);">
<label value="open upload by real click on it" />
</div>
<div style="position: relative; cursor: default;" height="30px"
onMouseOver="uploadDiv.setParent(self);">
<label value="also open upload by real click on it" />
</div>
<div style="position: relative; cursor: default;" height="30px"
onMouseOver="uploadDiv.setParent(self);">
<label value="still open upload by real click on it" />
</div>
<div id="uploadDiv" style="position: absolute; left: 0px; top: 0px; z-index: 100;">
<button id="btn" label="Upload" upload="true"
width="200px" height="15px">
<attribute name="onUpload"><![CDATA[
import org.zkoss.util.media.Media;
Media[] media = event.getMedias();
if (media != null) { // show the infprmation of updated media
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < media.length; i++) {
sb.append(media[i].getName() + ", "+media[i].getByteData().length +" bytes\n");
}
result.setValue(sb.toString());
}
]]></attribute>
</button>
</div>
result: <label id="result" />
</window>
</zk>

Regards,
Ben

link publish delete flag offensive edit

answered 2012-07-17 15:10:50 +0800

RichardL gravatar image RichardL
768 4

Hi Ben,
I'm using ZK 6.0.1. Similar to your example (but in java only, not in ZUML), I have a div with this onClick listener :

div.addEventListener("onClick", new EventListener() {

			public void onEvent(Event e) throws Exception {
				Clients.evalJavaScript("jq('$upBtn').next().find('input').click();");
			}
		});

The upload button looks like this:

public class AddImageBtn extends Button {

    public AddImageBtn(int noOfUploads) {
        this.setId("upBtn");
        this.setUpload("true");
        this.addEventListener("onUpload", new EventListener() {

			public void onEvent(Event event) throws Exception {
                ....

When I click the div, I get the upload file dialog, but when I choose an file to upload I get the error:

The server is temporarily out of service.

I read this thread, which mentions it might be a Glassfish problem, but I'm on Eclipse:
http://www.zkoss.org/forum/listComment/19455-FileUpload-issue?lang=en

And here's another related link: http://www.zkoss.org/forum/listComment/18990-The-server-is-temporarily-out-of-service-while-Image-upload?lang=en

Please note that it works fine if I just click the upload button directly instead of invoking it through the Clients.evalJavaScript method.

Do you know why this could be?

link publish delete flag offensive edit

answered 2012-07-18 04:51:22 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

Hi Richard,

Please refer to this sample: Trigger button click by click div in JAVA code

The 'trigger button click by javascript' will perform various result on different browser, for example, when I click the 'uploadDiv' in the sample above, chrome will do nothing, firefox will ask me do set some option to allow it.

But if I click the 'backgroundDiv' it works fine since actually I click on a invisible button that overlapped the backgroundDiv directly, this is the recommended way to go.

Regards,
Ben

link publish delete flag offensive edit

answered 2012-07-18 13:38:35 +0800

RichardL gravatar image RichardL
768 4

updated 2012-07-18 14:59:17 +0800

Thanks, Ben. Your posts are always very thorough - much appreciated. I tested your code in a separate project and it works fine. In my project, when I get the "The server is temporarily out of service." error messagebox, I noticed in firebug I'm getting the following error:

NetworkError: 404 Not Found - http://localhost:8080/Blhog/zkau/upload?uuid=wL1Qu6&dtid=z_fnm&sid=0&maxsize=undefined

link publish delete flag offensive edit

answered 2012-07-21 15:05:08 +0800

RichardL gravatar image RichardL
768 4

Hi again Ben,
I found the source of the error. It is because I am using UrlRewriteFilter for friendly urls. If I take the following out of my web.xml, the upload button works as expected.

<filter>
		<filter-name>UrlRewriteFilter</filter-name>
		<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
	</filter>
 	<filter-mapping>
 		<filter-name>UrlRewriteFilter</filter-name>
 		<url-pattern>/*</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
 	</filter-mapping>

I think this is not related to the current thread so I'll start a new one: http://www.zkoss.org/forum/listComment/20136

Thanks.

link publish delete flag offensive edit

answered 2019-03-15 08:09:42 +0800

takach gravatar image takach
30 2

I have found a working solution (at least for my case, not for upload) here: http://forum.zkoss.org/question/57948/how-to-trigger-the-click-event-of-zk-button/

<n:button onclick="zk.Widget.$('$btn').fire('onClick');">HTML button</n:button>
<button id="btn" label="ZK button" />
link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-04-17 02:23:53 +0800

Seen: 1,281 times

Last updated: Mar 15 '19

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More