I have a wicket Resource link that generates and downloads a pdf file when Clicking on it.
ResourceLink pdfResourceLink = new ResourceLink("dlPdf", new PdfResource() {
private static final long serialVersionUID = 1L;
#Override
public byte[] getPdf() {
//code for generating pdf content
}
#Override
public String getFilename() {
return "file.pdf";
}
});
I want to block the page during the file generation to prevent user from doing any action. Is there a way to execute Javascript when clicking on a Resource Link ?
This is possible with the new AjaxDownload behavior that we are going to introduce in 7.7.0. The JIRA ticket is WICKET-6286 (I'm on my mobile so I might be wrong. Google it !). You can copy the code locally until it is officially released.
See AjaxDownloadPage.java in wicket-examples for demo.
Related
I am trying to create a plug-in, which will show local .html file inside internal browser. Currently i am extending class ViewPart, and writing code into its createPartControl method. Most of people are using this snippet
IWebBrowser browser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser("SOMELABEL");
browser.openURL(url);
Problem is that this snippet opens another view where internal browser is opened, but in my case it needs to be in this view...
I also tried other forms of createBrowser method, e.g.
createBrowser(int style, String browserId, String name, String tooltip);
where i tried to configure flags, but all of these options just open another view or editor. Is there a way do draw HTML inside my view?
I have found the solution. Yes i have tried Browser control before, but i did not created Browser properly (wrong arguments). If anybody else tries to implement ViewPart displaying html pages via SWT, here is the code snippet.
public class CustomView extends ViewPart {
private static final String URL = "file:///d:/playground/d3/project.html";
#Override
public void createPartControl(Composite parent) {
final Browser browser = new Browser(parent, SWT.NONE);
browser.setUrl(URL);
}
#Override
public void setFocus() {
}
}
I have couple of drop downdowns and a download link button. Based on the user selection, i get the file to be downloaded. if the user did not make a selection I show an error on the feedback panel. if the user then makes a selection and clicks on download link it works fine, but the previous feedback message is still visible. How do I clear it.
onclick of the download link, i tried the following, but no use
FeedbackMessages me = Session.get().getFeedbackMessages();
me.clear();
Probably it is
Session.get().cleanupFeedbackMessages()
even it has been changed in Wicket 6.x
I've found this post and I think it is time to share the way for Wicket 6.x and for Wicket 7.x, because Session.get().cleanupFeedbackMessages() was deprecated already.
To do it for Wicket 6.x you have to implement additional filter for the feedback panel. Where to do it, it is your decision to decide.
Create a new FeedbackPanel implementation by extending from the existing FeedBackPanel class
private class MessagesFeedbackPanel extends FeedbackPanel{
private MessageFilter filter = new MessageFilter();
public MessagesFeedbackPanel(String id){
super(id);
setFilter(filter);
}
#Override
protected void onBeforeRender(){
super.onBeforeRender();
// clear old messages
filter.clearMessages();
}
}
Provide a new Filter implementation, by implementing the existing IFeedbackMessageFilter interface
public class MessageFilter implements IFeedbackMessageFilter{
List<FeedbackMessage> messages = new ArrayList<FeedbackMessage>();
public void clearMessages(){
messages.clear();
}
#Override
public boolean accept(FeedbackMessage currentMessage){
for(FeedbackMessage message: messages){
if(message.getMessage().toString().equals(currentMessage.getMessage().toString()))
return false;
}
messages.add(currentMessage);
return true;
}
}
Following code works for me in Wicket 6:
public class MyComponent extends Panel {
...
FeedbackMessages feedback = getFeedbackMessages();
feedback.clear();
We are using 1.4.9 for our current webapp. But we want to upgrade to higher 1.4.x version preferably 1.4.22(latest 1.4). The problem is that the page won't submit if AjaxButton is clicked. This is working in 1.4.9. I put breakpoint on the onSubmit of that button but it is not going there. Any insights on this? Thanks!
Here is the code:
For the button:
public abstract class SXIButton extends AjaxButton {
public SXIButton(String id, Form form) {
super(id, form);
initialize();
add(new SimpleAttributeModifier("validating", "false"));
}
}
In the java:
searchForm.add(new SXIButton("searchButton", searchForm) {
private static final long serialVersionUID = -4366670520053224476L;
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
LOG.info("Searching Users");
target.addComponent(userContainer);
userSearchModel.setUserCurrentUserFilter(getSessionBOUser().getCd());
UserDataProvider udp = new UserDataProvider(userSearchModel,isForSearch);
udp.setSort("cd", true);
userContainer.addOrReplace(getResultPanel(udp));
}
});
add(portlet);
portlet.add(searchForm);
in html
<input type = "submit" wicket:id = "searchButton" wicket:message="value:button.search" />
Without any code it's hard to help you out. I would first check the changelog to see if anything was changed in a later version that might causes you trouble (e.g. this ticket). If you cannot find anything obvious you might want to update first to another version which is not the latest one, to narrow down in which version your code breaks for the first time.
But those are just shots in the dark.
I want to write a simple HTMLUnit test script for Jenkins (former Hudson). INFO: Jenkins uses the YUI Javascript library. The YUI library replaces the form submit with a custom button. The script just creates a new job in Jenkins.
start Jenkins:
java -jar jenkins.war
Current versions of HTMLUnit do not support form.submit any more and require you to use button.click() for form submitting. Unfortunately this does not work for Jenkins (the sample below does not advance the page and create the job but stays on the new job page)
I tried for some hours now to find a solution or workaround but so far I could not get the form submitted. Hopefully somebody has found a solution and let me know.
Here is my sample code:
package example;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlButton;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
public class jenkins3 {
public static void main(String args[]) {
// create a new job in jenkins
// home
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
try {
final HtmlPage page1 = webClient.getPage("http://localhost:8080");
//assertEquals("Dashboard [Jenkins]", page1.getTitleText());
// new job
final HtmlAnchor new_job = page1.getAnchorByText("New Job");
final HtmlPage page2 = new_job.click();
// job name
HtmlTextInput name_field = (HtmlTextInput) page2.getElementById("name");
name_field.type("new job by htmlunit");
// radio button
final HtmlInput radio_freestyle = (HtmlInput) page2.getByXPath("//input[#value='hudson.model.FreeStyleProject']").get(0);
radio_freestyle.click();
Thread.sleep(10000);
// OK button (submit form)
final HtmlForm form = page2.getFormByName("createItem");
//final HtmlSubmitInput button = (HtmlSubmitInput) form.getByXPath("//button").get(0);
final HtmlButton button = (HtmlButton) form.getByXPath("//button").get(0);
final HtmlPage page3 = button.click(); // !!!!! Form submit does not workstacko
//assertEquals("Dashboard [Jenkins]", page3.getTitleText());
}
catch( Exception e ) {
System.out.println( "General exception thrown:" + e.getMessage() );
e.printStackTrace();
}
webClient.closeAllWindows();
}
}
Although this may be completely out of the question in your senerio: i would suggest giving up on HTMLUnit. I've had bug after bug, mainly because of the pages I've been automating tests for aren't always 100% valid html (3rd party piggybacked requests). I finally went looking elsewhere and found PhantomJS (js bindings to the WebKit engine) much better suited.
For me the advantages were evident:
- no need for another app server
- much simpler and faster to script JS than Java
- a "real"-world engine is more realistic than a buggy emulator one
Thats my advice,
Cheers
HTMLUnit doesn't include support for testing javascript actions. You might not want to switch your testing framework at this point, but I would recommend using Selenium for this kind of testing. It runs a mock browser and executes javascript, making it possible to do this sort of thing.
I have found this little trick to work. Navigate to the Jenkins login page using HtmlUnit. Add a Submit button to the login form. Set appropriate attributes to Submit element, including an "onclick" value. Click on this new button and viola! You're logged in.
Note, if you're not concerned about security, you can also do this:
webClient.getPage("https://yourdomain:8443/jenkins/j_acegi_security_check?j_username=yourUsername&j_password=yourPassword");
See below for first method.
Enjoy,
Nick.
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class JenkinsLogin {
final String urlValue = "https://<yourdomain>:8443/jenkins";
private final String userName = "yourUsername";
private final String password = "yourPassword";
protected static final BrowserVersion BROWSER_VERSION_FIREFOX = new BrowserVersion(
"Netscape", "5.0 (Windows)",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0",
(float) 1.2);
private final WebClient webClient = new WebClient(BROWSER_VERSION_FIREFOX);
public static void main(final String[] args) throws Exception {
final JenkinsLogin jenkinsLogin = new JenkinsLogin();
jenkinsLogin.login();
}
private void login() throws Exception {
this.webClient.setThrowExceptionOnScriptError(false);
HtmlPage page = this.webClient.getPage(this.urlValue + "/login");
final HtmlForm form = page.getFormByName("login");
form.getInputByName("j_username").setValueAttribute(this.userName);
form.getInputByName("j_password").setValueAttribute(this.password);
final HtmlElement createdElement = page.createElement("input");
createdElement.setAttribute("type", "submit");
createdElement.setAttribute("name", "submitIt");
createdElement.setAttribute("onclick", "login.submit();");
form.appendChild(createdElement);
final HtmlElement submitButton = form.getInputByName("submitIt");
page = submitButton.click();
final HtmlElement loginField = page.getFirstByXPath("id('login-field')");
if (loginField == null || !loginField.getTextContent().contains(this.userName))
throw new RuntimeException("Unable to log on to Jenkins. ");
System.out.println("Logged in! ");
}
}
Does replacing
final HtmlButton button = (HtmlButton) form.getByXPath("//button").get(0);
final HtmlPage page3 = button.click()
with
form.submit((HtmlButton)last(form.getHtmlElementsByTagName("button")));
work?
I have a larger application that I'm working with but the GWT History documentation has a simple example that demonstrates the problem. The example is copied for convenience:
public class HistoryTest implements EntryPoint, ValueChangeHandler
{
private Label lbl = new Label();
public void onModuleLoad()
{
Hyperlink link0 = new Hyperlink("link to foo", "foo");
Hyperlink link1 = new Hyperlink("link to bar", "bar");
Hyperlink link2 = new Hyperlink("link to baz", "baz");
String initToken = History.getToken();
if (initToken.length() == 0)
{
History.newItem("baz");
}
// Add widgets to the root panel.
VerticalPanel panel = new VerticalPanel();
panel.add(lbl);
panel.add(link0);
panel.add(link1);
panel.add(link2);
RootPanel.get().add(panel);
History.addValueChangeHandler(this); // Add history listener
History.fireCurrentHistoryState();
}
#Override
public void onValueChange(ValueChangeEvent event)
{
lbl.setText("The current history token is: " + event.getValue());
}
}
The problem is that if you refresh the application, the history stack gets blown away. How do you preserve the history so that if the user refreshes the page, the back button is still useful?
I have just tested it with Firefox and Chrome for my application and page refresh does not clear the history. Which browser do you use? Do you have the
<iframe src="javascript:''" id='__gwt_historyFrame' style='position:absolute;width:0;height:0;border:0'></iframe>
in your HTML?
GWT has catered for this problem by providing the History object. By making a call to it's static method History.newItem("your token"), you will be able to pass a token into your query string.
However you need to be aware that any time there is a history change in a gwt application, the onValueChange(ValueChangeEvent event){} event is fired, and in the method you can call the appropriate pages. Below is a list of steps which i use to solve this problem.
Add a click listener to the object that needs too call a new page. In handling the event add a token to the history.(History.newItem("new_token").
Implement the ValueChangeHandler in the class that implements your EntryPoint.
Add onValueChangeHandler(this) listener to the class that implements the EntryPoint. Ensure that the line is add in the onModuleLoad() method (it is important it is added in this method) of the class that implements the EntryPoint(pretty obvious ha!)
Finally implement onValueChange(ValueChangeEvent event){ //call a new page } method.
That's it