Wicket, modify HTML <body> element - java

I want to modify the HTML body tag when I open a Wicket-Bootstrap Modal. What I'm trying to achieve is <body class="modal-open"> instead of <body>
Using Wicket 8 M8 , I have this code:
owsImportDialog = new MyModalBootstrapDialog("owsImportDialog"
, new CompoundPropertyModel<>(new BopOwsTO())) {
#Override
void importOws(AjaxRequestTarget target, IModel<BopOwsTO> owsModel) {
appendCloseDialogJavaScript(target);
BopOwsTO owsTo = owsModel.getObject();
try {
importOwsCapabilities(owsTo);
owsViewDialog.header(Model.of("OWS anzeigen"))
.setModel(Model.of(owsTo.getServiceId()));
owsViewDialog.appendShowDialogJavaScript(target);
}
catch (OwsCapsImportException e) {
String localizedMessage = e.getLocalizedMessage();
importAlert.setModelObject(localizedMessage);
importAlert.appendShowDialogJavaScript(target);
error(localizedMessage);
}
finally {
target.appendJavaScript("document.getElementsByTagName('body')[0]" +
".setAttribute('class', 'modal-open');");
// target.appendJavaScript("document.body.setAttribute('class', 'modal-open');");
// target.prependJavaScript("document.body.setAttribute('class', 'modal-open');");
// target.appendJavaScript("alert('Hallo');");
// owsViewDialog is a child of owsView WebMarkupContainer
target.add(owsView, feedback);
}
}
#Override
void saveOws(AjaxRequestTarget target, IModel<BopOwsTO> owsModel)
{ }
#Override
void cancel(AjaxRequestTarget target)
{ }
};
If the line target.appendJavaScript("alert('Hallo');"); is active I actually see the alert window.
I also tried this code in the page class:
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
PackageResourceReference resourceReference = new PackageResourceReference(
getClass(), "../css/BuiOwsPage.css");
CssReferenceHeaderItem cssRef = CssReferenceHeaderItem.forReference(resourceReference);
response.render(cssRef);
response.render(OnLoadHeaderItem
.forScript("document.body.setAttribute('class', 'modal-open');"));
}
But none of my attempts was succesful.
Update
The answer of #martin-g didn't solve the issue.
I'm quite sure that the problem is caused by the sequence of these statements:
{
appendCloseDialogJavaScript(target);
...
try {
owsViewDialog.appendShowDialogJavaScript(target);
....
}
catch { ... }
finally {
target.add(owsView, feedback);
}
}
When this modal is closed because of appendCloseDialogJavaScript() ,
the class modal-open is erased from the class attribute of the <body> .
Then owsViewDialog opens, but modal-open isn't inserted in class, no matter if I append the snippet jQuery(document.body).addClass('modal-open') or not. The missing modal-open means that the page can't be scrolled.

Since Wicket and Bootstrap are used then jQuery is also available. I would recommend you to use jQuery(document.body).addClass('modal-open').
There must be a reason why jQuery has both addClass() and attr()!

Related

Refresh panel in Wicket with BootstrapDownloadLink

My problem is simple but I have no clue how to solve it. I have a feedbackPanel and I want to show an error message if the BootstrapDownloadLink fails. With a submit I could easily do:
protected void onSubmit(AjaxRequestTarget target) {
...
error("File_not_found"); //Wicket will print this on the feedback panel
target.add(getModalPanel().getFeedbackPanel()); //But i need to refresh it first
}
But the button is inside a panel which I fill with a populateItem and is the only way I know to insert Bootstrap Styles to it. The code of the button:
BootstrapDownloadLink downloadDocument = new BootstrapDownloadLink(IDITEMREPEATER, file) {
#Override
public void onClick() {
File file = (File)getModelObject();
if(file.exists()) {
IResourceStream resourceStream = new FileResourceStream(new org.apache.wicket.util.file.File(file));
getRequestCycle().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(resourceStream, file.getName()));
} else {
error(getString("error_fichero_no_existe"));
/// ???? need to refresh-> getModalPanel().getFeedbackPanel()
}
}
};
downloadDocument.setIconType(GlyphIconType.clouddownload);
downloadDocument.add(new AttributeModifier("title", getString("documentos.descargar")));
downloadDocument.add(new AttributeModifier("class", " btn btn-info negrita btn-xs center-block"));
downloadDocument.setVisible(Boolean.TRUE);
list.add(downloadDocument);
You could create or extend from an AjaxDownloadLink, for example like here.
The main idea is to have an AjaxBehavior that does the download, and you get a public void onClick(AjaxRequestTarget target) in which you can add the FeedbackPanel
downloadBehavior = new AbstractAjaxBehavior()
{
private static final long serialVersionUID = 3472918725573624819L;
#Override
public void onRequest()
{
[...]
ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(
AjaxDownloadLink.this.getModelObject(), name);
handler.setContentDisposition(ContentDisposition.ATTACHMENT);
getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
}
};
And use that behavior in the onclick:
#Override
public void onClick(AjaxRequestTarget aTarget)
{
String url = downloadBehavior.getCallbackUrl().toString();
if (addAntiCache) {
url = url + (url.contains("?") ? "&" : "?");
url = url + "antiCache=" + System.currentTimeMillis();
}
// the timeout is needed to let Wicket release the channel
aTarget.appendJavaScript("setTimeout(\"window.location.href='" + url + "'\", 100);");
}
You can use target.addChildren(getPage(), IFeedback.class). This will add all instances of IFeedback interface in the page to the AjaxRequestTarget.
You can also use FeedbackPanel.class instead of the interface.
Or use getPage().visit(new IVisitor() {...}) to find a specific feedback panel if you don't want to add others which are not related.

how to run java on website and to get values to html

i know the question may sound easy to most of you but I am stuck with it.
First of all i like to define what i am trying to achieve.
on eclipse i am running a piece of code that sends some data over specific port, and via html and javascript i am getting those that it's sent and print them on screen.
I have an account from one of free hosting websites.
I want to run my code on that website e.g mywebsite.blahblah.com/...
and from html file on my computer i want to access that website, get those values produced by java code and print them on screen.
I have no idea where to start.
the codes are
java and html
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
public class GPSServer extends WebSocketServer {
static int port = 9876;
public GPSServer(int port) throws UnknownHostException {
super(new InetSocketAddress(port));
}
public GPSServer(InetSocketAddress address) {
super(address);
}
public void sendData(String s) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
c.send(s);
}
}
}
#Override
public void onOpen(WebSocket arg0, ClientHandshake arg1) {
System.out.println(arg0.getRemoteSocketAddress().getAddress()
.getHostAddress()
+ " connected to the server!");
}
#Override
public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
System.out.println(arg0 + " disconnected!");
}
#Override
public void onError(WebSocket arg0, Exception arg1) {
arg1.printStackTrace();
if (arg0 != null) {
}
}
#Override
public void onMessage(WebSocket arg0, String arg1) {
System.out.println(arg0 + ": " + arg1);
}
public static Runnable sendData() {
Runnable r = new Runnable() {
#Override
public void run() {
WebSocketImpl.DEBUG = true;
GPSServer server;
try {
server = new GPSServer(GPSServer.port);
server.start();
System.out.println("GPS server started at port: "
+ server.getPort());
double longitude = 39.55;
double latitude = 22.16;
String lng = Double.toString(longitude);
String ltd = Double.toString(latitude);
String all = lng + "-" + ltd;
while (true) {
server.sendData(all);
/*
* server.sendData(Double.toString(longitude));
* System.out.println("longitude sent...");
* server.sendData(Double.toString(latitude));
* System.out.println("latitude sent...");
*/
Thread.sleep(5000);
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
};
return r;
}
public static void main(String[] args) throws UnknownHostException {
Thread thread = new Thread(GPSServer.sendData());
thread.start();
}
}
--
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
function WebSocketTest()
{
var lat;
var lng;
if ("WebSocket" in window)
{
alert("WebSocket is supported by your Browser!");
console.log("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:9876/echo");
ws.onopen = function()
{
ws.send("Message to send");
alert("Message is sent...");
};
ws.onmessage = function (evt) {
var partsArray = evt.data.split('-');
lng=partsArray[0];
lat=partsArray[1];
alert(lat);
alert(lng);
};
ws.onclose = function() {
alert("Connection is closed...");
console.log("Connection is closed...");
};
}
else
{
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
</head>
<body>
<div id="sse">
Run WebSocket
</div>
<div>
<p id="para"> BASIC HTML!</p>
</div>
</body>
</html>
Thanks!
I'm assuming you're very new to all this web development. I haven't studied your code fully but the basic idea is you need a server side scripting language like JSP(of course JSP because you're using Java Code). I hope you know Javascript's basic idea is to use resources on the client's end, or to load data dynamically. So if you're only concerned with displaying some values from server to the client, you can simple make a servlet which will print your data.
Following MVC pattern,
Controller== Make a servlet which will handle the request made by user(i.e. the link which will show data,basically). Set your Model in this controller once you receive a request(you can decide what to do on GET/POST separately too).
Model== Make an abstract representation(class of Java) holding all your data that is to be displayed.
View== Here you'll receive the model. In other words, this will be your HTML. You can use JSP helpers to customize the view, the basic idea is to control HOW DATA WILL BE SHOWN TO THE USER(hence the name View). HTML will be automatically generated at run-time and passed to the user.
Again, I say I'm assuming you're very new to web development. Please let me know if I haven't understood your question well. Enjoy coding.

How to hook into the internal Eclipse browser?

For my eclipse plugin I want to track every URL that is opened with the internal (and if possible also external) Eclipse browser.
So far I use
org.eclipse.swt.browser.Browser;
and
addLocationListener(...)
But I would prefer that it works also for the internal Eclipse browser. How can I achieve that?
One possible solution for the Eclipse Internal Browser would be to create an eclipse plugin that registers an IStartup extension. In your earlyStartup() method you would register an IPartListener on the workbenchPage. Then when the internal browser part is created, you will receive a callback with a reference to the WebBrowserEditor (or WebBrowserView). Since there is no direct API you will have to hack a bit and use reflection to grab the internal SWT Browser instance. Once you have that, you can add your location listener.
Sometimes during early startup there is no active Workbench window yet so you have to loop through all existing workbench windows (usually just one) and each of their workbench pages to add part listeners also.
Here is the snippet of code for the earlyStartup() routine. Note that I have omitted any cleanup of listeners during dispose for windows/pages so that still needs to be done.
//Add this code to an IStartup.earlyStartup() method
final IPartListener partListener = new IPartListener() {
#Override
public void partOpened(IWorkbenchPart part) {
if (part instanceof WebBrowserEditor)
{
WebBrowserEditor editor = (WebBrowserEditor) part;
try {
Field webBrowser = editor.getClass().getDeclaredField("webBrowser");
webBrowser.setAccessible(true);
BrowserViewer viewer = (BrowserViewer)webBrowser.get(editor);
Field browser = viewer.getClass().getDeclaredField("browser");
browser.setAccessible(true);
Browser swtBrowser = (Browser) browser.get(viewer);
swtBrowser.addLocationListener(new LocationListener() {
#Override
public void changed(LocationEvent event) {
System.out.println(event.location);
}
});
} catch (Exception e) {
}
}
else if (part instanceof WebBrowserView)
{
WebBrowserView view = (WebBrowserView) part;
try {
Field webBrowser = editor.getClass().getDeclaredField("viewer");
webBrowser.setAccessible(true);
BrowserViewer viewer = (BrowserViewer)webBrowser.get(view);
Field browser = viewer.getClass().getDeclaredField("browser");
browser.setAccessible(true);
Browser swtBrowser = (Browser) browser.get(viewer);
swtBrowser.addLocationListener(new LocationListener() {
#Override
public void changed(LocationEvent event) {
System.out.println(event.location);
}
});
} catch (Exception e) {
}
}
}
...
};
final IPageListener pageListener = new IPageListener() {
#Override
public void pageOpened(IWorkbenchPage page) {
page.addPartListener(partListener);
}
...
};
final IWindowListener windowListener = new IWindowListener() {
#Override
public void windowOpened(IWorkbenchWindow window) {
window.addPageListener(pageListener);
}
...
};
IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (activeWindow != null)
{
IWorkbenchPage activePage = activeWindow.getActivePage();
if (activePage != null)
{
activePage.addPartListener(partListener);
}
else
{
activeWindow.addPageListener(pageListener);
}
}
else
{
for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows())
{
for (IWorkbenchPage page : window.getPages()) {
page.addPartListener(partListener);
}
window.addPageListener(pageListener);
}
PlatformUI.getWorkbench().addWindowListener(windowListener);
}
One last detail about this code snippet is that it requires a dependency on the org.eclipse.ui.browser plugin to have access to the WebBrowserEditor class.

use deployJava.js to call java methods in javascript

I want to call java methods in javascript and Andrew Thompson suggested to use the deployJava.js library for this. I followed these instructions:
http://docs.oracle.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html
Here is explained how to use the java class in javascript, but I would like to call the java methods from within the javascript. (This is because I want to import a .owl file in java en export the information in json-format to my code written in javascript.)
Does anybody know how to do this with the deployJava library?
This is my code to import the java file:
<noscript>A browser with JavaScript enabled is required for this page to operate properly.</noscript>
<h1>Sending Messages to Other Applets</h1>
<script>
function sendMsgToIncrementCounter() {
receiver.incrementCounter();
}
</script>
<p>Sender Applet</p>
<script>
var attributes = { id:'sender', code:'Sender.class', width:300, height:50} ;
var parameters = {} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>
<br/>
<br/>
<p>Receiver Applet</p>
<script>
var attributes = { id:'receiver', code:'../Receiver.class', width:300, height:50} ;
var parameters = {} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>
and this is are the sender and receiver java files:
import javax.swing.*;
public class Receiver extends JApplet {
private int ctr = 0;
private JLabel ctrLbl = null;
public void init() {
//Execute a job on the event-dispatching thread; creating this applet's GUI.
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
ctrLbl = new JLabel("");
add(ctrLbl);
}
});
} catch (Exception e) {
System.err.println("Could not create applet's GUI");
}
}
public void incrementCounter() {
ctr++;
String text = " Current Value Of Counter: " + (new Integer(ctr)).toString();
ctrLbl.setText(text);
}
}
import javax.swing.*;
import java.awt.event.;
import netscape.javascript.;
public class Sender extends JApplet implements ActionListener {
public void init() {
//Execute a job on the event-dispatching thread; creating this applet's GUI.
try {
final ActionListener al = this;
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JButton btn = new JButton("Click To Increment Counter");
add(btn);
btn.addActionListener(al);
}
});
} catch (Exception e) {
System.err.println("createGUI didn't complete successfully");
}
}
public void actionPerformed(ActionEvent e) {
try {
JSObject window = JSObject.getWindow(this);
window.eval("sendMsgToIncrementCounter()");
} catch (JSException jse) {
jse.printStackTrace();
}
}
}
I just copy-paste this from the example given on this site:
http://docs.oracle.com/javase/tutorial/deployment/applet/iac.html
This example works perfect in my browser, so the way it is done is correct, but I suspect that I don't import the javafiles correct, since this are the errors from je java-console:
load: class Sender.class not found.
java.lang.ClassNotFoundException: Sender.class
at sun.plugin2.applet.Applet2ClassLoader.findClass(Applet2ClassLoader.java:195)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Plugin2ClassLoader.java:249)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Plugin2ClassLoader.java:179)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Plugin2ClassLoader.java:160)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Plugin2ClassLoader.java:690)
at sun.plugin2.applet.Plugin2Manager.createApplet(Plugin2Manager.java:3045)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Plugin2Manager.java:1497)
at java.lang.Thread.run(Thread.java:680)
Exception: java.lang.ClassNotFoundException: Sender.class
Combining your original method, with the new JS snippet, and part of the accepted answer on your last question (tweaked), gives..
<html>
<head>
<script>
// dangerous to have a 0x0 applet! Some security plug-ins regard it
// as suspicious & automatically remove the element. Better to set it
// not visible using styles
var attributes = {
codebase:'../sesame',
code:'applet_test',
width:10,
height:10
};
var parameters = {fontSize:16} ;
var version = '1.6' ;
deployJava.runApplet(attributes, parameters, version);
function test() {
var app = document.applet_test;
alert("Screen Dimension\r\n width:" + app.getScreenWidth()
+ " height:" + app.getScreenHeight());
}
</script>
<body>
<FORM>
<INPUT
type="button"
value="call JAVA"
onClick = "test()">
</FORM>
<script>
deployJava.runApplet(attributes, parameters, version);
</script>
</body>
</html>
But I just wrote that up off the top of my head. Don't trust me, trust a validation service. ;)
I would advise setting up a simple webservice that your javascript code can use. It doesn't need to be very involved, personally I'd use a simple REST layout with JAX-RS (jersey is really nice to work with), especially if you want something simple with JSON support built-in (with the right plugin).
Trying to actually communicate with the applet on the page might be possible, but very browser dependent and IMHO not worth the hassle. If you're working on the web, might as well use a web service.
There was a problem with the directory of the .class files given in the attributes. Here is the correct code:
<p>Sender Applet</p>
<script>
var attributes = { id:'sender', code:'sesame/Sender.class', archive:'sesame/applet_SenderReceiver.jar', width:300, height:50} ;
var parameters = {} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>
<br/>
<br/>
<p>Receiver Applet</p>
<script>
var attributes = { id:'receiver', code:'sesame/Receiver.class', archive:'sesame/applet_SenderReceiver.jar', width:300, height:50} ;
var parameters = {} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>

JSP Custom Taglib: Nested Evaluation

Say I have my custom taglib:
<%# taglib uri="http://foo.bar/mytaglib" prefix="mytaglib"%>
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<mytaglib:doSomething>
Test
</mytaglib:doSomething>
Inside the taglib class I need to process a template and tell the JSP to re-evaluate its output, so for example if I have this:
public class MyTaglib extends SimpleTagSupport {
#Override public void doTag() throws JspException, IOException {
getJspContext().getOut().println("<c:out value=\"My enclosed tag\"/>");
getJspBody().invoke(null);
}
}
The output I have is:
<c:out value="My enclosed tag"/>
Test
When I actually need to output this:
My enclosed tag
Test
Is this feasible? How?
Thanks.
Tiago, I do not know how to solve your exact problem but you can interpret the JSP code from a file. Just create a RequestDispatcher and include the JSP:
public int doStartTag() throws JspException {
ServletRequest request = pageContext.getRequest();
ServletResponse response = pageContext.getResponse();
RequestDispatcher disp = request.getRequestDispatcher("/test.jsp");
try {
disp.include(request, response);
} catch (ServletException e) {
throw new JspException(e);
} catch (IOException e) {
throw new JspException(e);
}
return super.doStartTag();
}
I tested this code in a Liferay portlet, but I believe it should work in other contexts anyway. If it don't, I would like to know :)
HTH
what you really need to have is this:
<mytaglib:doSomething>
<c:out value="My enclosed tag"/>
Test
</mytaglib:doSomething>
and change your doTag to something like this
#Override public void doTag() throws JspException, IOException {
try {
BodyContent bc = getBodyContent();
String body = bc.getString();
// do something to the body here.
JspWriter out = bc.getEnclosingWriter();
if(body != null) {
out.print(buff.toString());
}
} catch(IOException ioe) {
throw new JspException("Error: "+ioe.getMessage());
}
}
make sure the jsp body content is set to jsp in the tld:
<bodycontent>JSP</bodycontent>
Why do you write a JSTL tag inside your doTag method?
The println is directly going into the compiled JSP (read: servlet) When this gets rendered in the browser it will be printed as it is since teh browser doesn't understand JSTL tags.
public class MyTaglib extends SimpleTagSupport {
#Override public void doTag() throws JspException, IOException {
getJspContext().getOut().println("My enclosed tag");
getJspBody().invoke(null);
}
}
You can optionally add HTML tags to the string.

Categories