Wicket: get input from TextField updated by script - java

I render a TextField. It's value is populated by script, not the user. I need to get that value from Java but I get null by doing textField.getInput();
Any ideas how to get that value and use it in Java code?

I had the same problem a few month ago. One problem is, that setting the input value via javascript doesn't fire the "onChange" event which you could easily use to get the value.
The solution I implemented might not be the easiest one, but it's working:
put a form with a hidden ajax submit link around your input
when you fill your input with javascript, use javascript also to do a form submit
html:
<html xmlns:wicket="http://wicket.apache.org">
<body>
<div>
<a href="#" onclick="document.getElementById('input').value = 'test'; document.getElementById('myForm').submit();">fill
input</a>
<form wicket:id="form" id="myForm">
<input type="text" wicket:id="input" id="input">
<a style="visibility: hidden;" wicket:id="submit">submit</a>
</form>
<p> Output:
<wicket:container wicket:id="output"></wicket:container>
</p>
</div>
</body>
</html>
and the corresponding java:
public class HomePage extends WebPage {
private String inputValue;
public HomePage(final PageParameters parameters) {
super(parameters);
final Label output = new Label("output", new PropertyModel<String>(
this, "inputValue"));
output.setOutputMarkupId(true);
add(output);
Form form = new Form("form");
form.add(new AjaxSubmitLink("submit") {
#Override
protected void onAfterSubmit(AjaxRequestTarget target, Form<?> form) {
super.onAfterSubmit(target, form);
target.add(output);
}
});
add(form);
form.add(new TextField<String>("input", new PropertyModel<String>(this,
"inputValue")));
}
}

Explanation:
The TextField gets an AjaxFormSubmitBehaviour with a custom event.
This event can be triggered by javascript. I use jQuery, as it is provided by Wicket anyway.
See the code:
public class Example extends WebPage
{
public Example(PageParameters pp)
{
super(pp);
final Model<String> m = new Model<String>("");
Form<Void> f = new Form<Void> ("form");
TextField<String> textField = new TextField<String>("textField", m, String.class);
textField.setOutputMarkupId( true );
textField.setMarkupId( "myuniqueid" );
textField.add( new AjaxFormSubmitBehavior("customevent")
{
protected void onSubmit(AjaxRequestTarget target)
{
System.out.println("Model value:"+m.getObject());
target.add( this.getComponent() );
}
} );
f.add(textField);
add(f);
}
}
HTML
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="utf-8" />
</head>
<body>
<a href="#" onclick="$('#myuniqueid').val('test'); $('#myuniqueid').trigger('customevent');">fill
input</a>
<form wicket:id="form">
<input wicket:id="textField"></input>
</form>
</body>
</html>

Related

How to map submit button of a JSP to a servlet to?

I am old to JAVA but very new to the topics of JSPs & Servlets. I am trying to do some jdbc operations by taking the values from JSP into servlet. To do that, I have written a JSP with a drop down list and a submit button.
Jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<div align='left' >
<div align='left' >
<label class="text-white mb-3 lead">Which report do you want to generate?</label>
<select id="reportSelection" data-style="bg-white rounded-pill px-5 py-3 shadow-sm " class="selectpicker w-100" name="reportselection">
<option>Outage</option>
<option>DataQuality</option>
<option>Latency</option>
</select>
</head>
<body>
<p id = "demo"> </p>
<script>
var d = new Date();
document.getElementById("demo").innerHTML = d;
</script>
</body>
</div>
</div>
</body>
<hr class="colorgraph">
<div class="row">
<div class="col-xs-12 col-md-6"><input type="submit" value="Submit" class="btn btn-primary btn-block btn-lg register" tabindex="7"></div>
</div>
</body>
</html>
And this is how my servlet class looks like.
#WebServlet("/getdata.do")
public class DataServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
GetTableColumn gt = new GetTableColumn();
String issue = request.getParameter("reportSelection");
String message;
try {
if ("Latency".equals(issue)) {
message = gt.process("latency");
} else if ("DataQuality".equals(issue)) {
message = gt.process("DataQuality");
System.out.println("Data quality");
} else if ("Outage".equals(issue)) {
message = gt.process("Outage");
}
} catch (SQLException s) {
s.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
I am reading the JSP drop down values in my servlet class and passing a String to method process based on the value received. I looked online to configure the web.xml file as below.
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>DataServlet</servlet-name>
<display-name>DataServlet</display-name>
<description>Begin servlet</description>
<servlet-class>com.servlets.DataServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataServlet</servlet-name>
<url-pattern>/parse</url-pattern>
</servlet-mapping>
I am trying to run the code on IntelliJ and here is how I have configured my tomcar server on IntelliJ.
When I run the code, I see the page is generating the jsp as expected.
What I don't understand is how to configure the submit with onclick so that I click on submit and the java program in the backed triggers. I have written the java code just to read values from a database by taking the input from the method process. This was running fine and I was asked to take the input from JSP and display the result back on a JSP.
When I click on submit button, I don't see any progress in the console output. I guess I didn't map it correctly.
Most of the links online contain JSP & JAVA together which is even more confusing.
Could anyone let me know how can I trigger the program by clicking the submit button
Since you are using #WebServlet, you do not need mapping in web.xml. Just add the following line inside body of your JSP:
<form action="getdata.do" method="post">
Look at your JSP file, pay attention at your head and body tag. I think it's a wrong that you have body inside other body and closing head tag inside body.
Other case that can be more important that to send a form by clicking to submit button you should put it inside tag form, something like this.
<form action = "getdata.do" method = "POST">
First Name: <input type = "text" name = "first_name">
<br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>

Cannot call Play Framework static method from view

I have server and I should make request on button pressed also I have to call this method and when it is works I should parse json but my doesn't see controller method only main method is available
How to call
<input type="submit" onclick="#routes.Login.resp()" value="LOGIN" >
because it is not worrking Cannot resolve symbol
GET /login controllers.Login.main()
My controller:
package controllers;
import play.libs.F;
import play.libs.WS;
import play.mvc.Controller;
import play.mvc.Result;
public class Login extends Controller {
public static Result main() {
return ok(views.html.login.render());
}
public static F.Promise<Result> resp() {
String feedUrl="http://validate.jsontest.com/?json=%7B%22key%22:%22value%22%7D";
final F.Promise<Result> resultPromise = WS.url(feedUrl).get().flatMap(
new F.Function<WS.Response, F.Promise<Result>>() {
public F.Promise<Result> apply(WS.Response response) {
return WS.url(response.asJson().findPath("empty").asText()).get().map(
new F.Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("size" + response.asJson().findPath("count").asInt());
}
}
);
}
}
);
return resultPromise;
}
}
view:
<!--
Author: W3layouts
Author URL: http://w3layouts.com
License: Creative Commons Attribution 3.0 Unported
License URL: http://creativecommons.org/licenses/by/3.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>LOGIN</title>
<meta charset="utf-8">
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/stylelogin.css")">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
<!--webfonts-->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:600italic,400,300,600,700' rel='stylesheet' type='text/css'>
<!--//webfonts-->
</head>
<body>
<!-----start-main---->
<div class="main">
<div class="login-form">
<h1>Member Login</h1>
<div class="head">
<img src="#routes.Assets.at("images/user.png")" alt=""/>
</div>
<form>
<input type="text" class="text" value="USERNAME" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'USERNAME';}" >
<input type="password" value="Password" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Password';}">
<div class="submit">
<input type="submit" onclick="#routes.Login.main()" value="LOGIN" >
</div>
</form>
</div>
<!--//End-login-form-->
<!-----start-copyright---->
<!-----//end-copyright---->
</div>
<!-----//end-main---->
</body>
</html>
I am not sure if I also parse json properly,how to make proper GET,POST requests and parse it
As far as I know with the onclick attribute you always call a function in your JavaScript. If you want to specify an URL you need to put it into your form tag with an action attribute like <form action="#routes.Login.main()">.
The default for the HTML form tag is to send a GET. If you want to send a POST you have to specify it via an additional method="post" like <form action="#routes.Login.main()" method="post">. But then you have to change your routing too: POST /login controllers.Login.main(). If you want to post login data I'd strongly recommend to use POST because with GET your data including the password turns up in the query string of your URL.
Additionally your #routes.Login.main() method just returns the login view return ok(views.html.login.render());. Instead it should evaluate the form data you are sending.

How to send form object to Java in JavaFX WebView

I was able to send a simple String from javascript/local html in Webview to Java.
How do I send the whole form object to Java ?
public class JFXTest1 extends Application {
WebView webview = new WebView();
webview.getEngine().load(JFXTest1.class.getResource("local1.html").toExternalForm());
JSObject jsobj = (JSObject) webview.getEngine().executeScript("window");
Local1JSBridge bridge = new Local1JSBridge();
bridge.setWindow(jsobj);
jsobj.setMember("java", bridge);
And my bridge.
public class Local1JSBridge {
public void printFormData(String data1){
System.out.println( data1);
}
}
The javascript part that calls the method in the Java class.
<html>
<head></head>
<body>
hi :)
<form id="form1" name="form1">
<input type="text" id="text1">text value</input>
</form>
<button onclick="java.printFormData(document.getElementById('text1').value);">Submit</button>
<br/>
<button onclick="java.exit()">Exit</button>
</body>
I can't find a way to actually get the form data without executing Javascript back in the HTML document, but the following seems to basically work:
public void printFormData(Object form) {
System.out.println(form.getClass() + " " + form);
if (form instanceof Element) {
NodeList inputs = ((Element)form).getElementsByTagName("input");
for (int i = 0 ; i < inputs.getLength(); i++) {
Node input = inputs.item(i);
Element inputEl = (Element)input ;
String id = inputEl.getAttribute("id");
String value = (String) engine.executeScript(id+".value");
System.out.printf("%s : %s %n", id, value);
}
}
}
and then in the HTML:
<html>
<head></head>
<body>
hi :)
<form id="form1" name="form1">
<input type="text" id="text1">text value</input>
</form>
<button onclick="java.printFormData(document.getElementById('form1'));">Submit</button>
<br/>
<button onclick="java.exit()">Exit</button>
</body>
</html>

Receiving jQuery body changes in Wicket

I got a question here regarding Wicket and jQuery. I got a WebPage which is rendered and shown by Wicket. Within this page I got one "draggable" and one "droppable" component, in which the user should be able to move components. This is realized via jQuery. Additionally I got a "Save" button at the end of the WebPage, which should save the new values (if there are any), which means: the newly dropped items. But if I click on "Save" I don't see the newly dropped objects within Wicket, I still just see the objects which have been in the "droppable" area from the beginning on. Here some Code snippets:
HTML:
<div class="container">
<div id="user">
<h1 class="ui-widget-header">Benutzer</h1>
<div class="ui-widget-content" id="userList">
<input type="text" placeholder="Benutzername" id="userNameSearch" />
<ul class="list-group">
<li class="list-group-item" wicket:id="userList"><span
wicket:id="user" id="user"></span><span style="visibility: hidden;" wicket:id="userId" id="userId"></span></li>
</ul>
</div>
</div>
<div id="project">
<h1 class="ui-widget-header">Benutzer im Projekt</h1>
<div class="ui-widget-content" id="project">
<ul class="list-group">
<li class="placeholder list-group-item"><span>Benutzer
in dieses Feld ziehen.</span></li>
<li class="list-group-item" wicket:id="usersInProjectList"><span
wicket:id="userInProject"></span><span style="visibility: hidden;" wicket:id="userInProjectId"></span></li>
</ul>
</div>
</div>
<button id="save" wicket:id="save">Speichern</button>
</div>
<script>
$(function() {
$("#userList li").draggable({
appendTo : "body",
helper : "clone"
});
$("#project ul")
.droppable(
{
activeClass : "ui-state-default",
hoverClass : "ui-state-hover",
accept : ":not(.ui-sortable-helper)",
drop : function(event, ui) {
$(this).find(".placeholder").remove();
var userName = ui.draggable.find("#user").text();
var userId = ui.draggable.find("#userId").text();
$("<li class=\"list-group-item new-project-member\" wicket:id=\"usersInProjectList\"><span wicket:id=\"userInProject\">"+userName+"</span><span style=\"visibility:hidden;\" wicket:id=\"userInProjectId\">"+userId+"</span></li>")
.appendTo(this);
$(ui.draggable).remove();
}
}).sortable({
items : "li:not(.placeholder)",
sort : function() {
// gets added unintentionally by droppable interacting with sortable
// using connectWithSortable fixes this, but doesn't allow you to customize active/hoverClass options
$(this).removeClass("ui-state-default");
}
});
$('#userNameSearch')
.keyup(
function() {
var valThis = $(this).val().toLowerCase();
if (valThis == "") {
$('#userList li').show();
} else {
$('#userList li')
.each(
function() {
var text = $(this)
.text()
.toLowerCase();
(text.indexOf(valThis) >= 0) ? $(
this).show()
: $(this)
.hide();
});
}
;
});
});
</script>
Java Code (Wicket):
ListView userListView = new ListView("userList", finalUserList) {
protected void populateItem(ListItem item) {
User user = (User) item.getModelObject();
item.add(new Label("user", user.getLastname()+", "+user.getFirstname()));
item.add(new Label("userId", user.getId()));
}
};
ListView usersInProjectListView = new ListView("usersInProjectList", usersInProjectList) {
protected void populateItem(ListItem item) {
User user = (User) item.getModelObject();
item.add(new Label("userInProject", user.getLastname()+", "+user.getFirstname()));
item.add(new Label("userInProjectId", user.getId()));
}
};
usersInProjectListView.setOutputMarkupId(true);
add(new AjaxLink<Void>("save")
{
#Override
public void onClick(AjaxRequestTarget target)
{
System.out.println(target.getPage().get("usersInProjectList"));
//window.close(target);
}
});
add(userListView);
add(usersInProjectListView);
You could somehow get the changes from the client to the server, for example using Ajax. You can fire a callback function that can be added via AbstractAjaxBehaviour (see detail here), or maybe switch to wicket-dnd

Apache Wicket : Onclick of a form button, I need to call a small javascript function

Onclick of a form button, I need to call a small javascript function. This javascript function should validate some fields in the same form and then call the onSubmit() of the form which is in java.
Main Idea is that let validate happen in client side and not in java.
Complete idea :
I have help.html file as shown below :
<form wicket:id="form">
<input type="text" wicket:id="one"/>
<input type="text" wicket:id="two"/>
<input type="submit" wicket:id="save"/>
</form>
In help.java, I created a WebMarkupContainer and added this form with this submit button :
container.add(new Button("save") {
#Override
public void onSubmit() {
//saved
}
});
On click of the button in html, it calls onSubmit() and here we can do a validation on the text box values.
But I need to do all the validations in the HTML page itself.
OnClick of the Button Save, it should call a javascript funciton as shown below :
<form wicket:id="form">
<input type="text" wicket:id="one"/>
<input type="text" wicket:id="two"/>
<input type="submit" wicket:id="save" onclick="validateRange()"/>
</form>
JavaScript :
function validateRange(){
//logic
//Submit the form
}
Can this be done?
You need an AjaxSubmitLink or something like this. The you need to create a new IAjaxCallListener
public class MyAjaxCallListener implements IAjaxCallListener{
#Override
public CharSequence getBeforeHandler(Component component) {
return YOUR_JAVA_SCRIPT;
}
#Override
public CharSequence getBeforeSendHandler(Component component) {
return YOUR_JAVA_SCRIPT;
}
// ... not needed overrides can return null
}
Then in your AjaxSubmitLink you can add this AjaxCallListener
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
super.updateAjaxAttributes(attributes);
attributes.getAjaxCallListeners().add(new MyAjaxCallListener());
}
Here you have an example Try if yourself
HTML:
<form id="form" action="#">
<input id="text" type="text"/>
<input type="button" onclick="validate()" value="TEST"/>
</form>
JS:
function validate() {
var value = document.getElementById("text").value;
if (value == "") {
alert("you have to write something");
return false;
}
else
document.getElementById("form").submit();
}

Categories