For couple of days, I am trying to see as why my action is not getting invoked in this particular form.
My Form is something like below and I have struts URL tags which I am using along with Bootstrap framework:
<s:form action="RegisterUser" cssClass="form-horizontal" id="id-register-form" method="post">
Couple of Struts 2 UI tags
</s:form>
My Register user action is very simple with just an execute method in it which returns string "success":
public class RegisterUser extends ActionSupport {
public RegisterUser() {
}
#Override
public String execute() throws Exception {
System.out.println("Inside execute method test 1!");
return "success";
}
}
My struts.xml for the above looks something like below:
<action name="RegisterUser" class="Mypackage.RegisterUser" method="execute">
<result name="success">/WEB-INF/views/usermanagement/register-success.jsp</result>
<result name="error">/WEB-INF/views/usermanagement/register-error.jsp</result>
</action>
But whenever I click the submit button of the form,form submission is never triggered. I have client side validation with jquery with jquery validate library and then doing server side with struts validation framework,but I believe issue is not related to validation but more on action mapping side or something related to submit button.Below is my submit button,
<s:submit type="button" cssClass="btn btn-primary" value="Create Account" cssStyle="float:left;">Create Account</s:submit>
Appreciate if someone can take a look and give me some insights. I am on Glassfish v4 and using Netbeans IDE and my Struts 2 is 2.3.15.3 on win 8.1
Here is my JS code for client side validation with jQuery:
$(document).ready(function() {
// validate the comment form when it is submitted
$("#id-register-form").validate({
errorPlacement: function(error, element) {
if (element.attr("name") == "Email") {
error.appendTo('#error-Email');
}
else if (element.attr("name") == "Password") {
error.appendTo('#error-Password');
}
else if (element.attr("name") == "ConfirmPassword") {
error.appendTo('#error-ConfirmPassword');
}
else if (element.attr("name") == "AgreetoPolicy") {
error.appendTo('#error-Agree');
}
},
rules: {
Email: {
required: true,
email: true
},
Password: {
required: true,
minlength: 5
},
ConfirmPassword: {
required: true,
minlength: 8,
equalTo: "#Password"
},
AgreetoPolicy: "required"
},
messages: {
Email: "<small>Please enter a valid email address</small>",
Password: {
required: "<small>Please provide a password</small>",
minlength: "<small>Your password must be at least 8 characters long</small>"
},
ConfirmPassword: {
required: "<small>Please provide a password</small>",
minlength: "<small>Your password must be at least 5 characters long</small>",
equalTo: "<small>Please enter the same password as above</small>"
},
AgreetoPolicy: "<strong><small>Please accept our policy</small></strong>"
}
});
});
Try to change this code where messages
Email: {
required: "<small>Please enter a valid email address</small>",
email: "Email addresses are of the form user#host."
}
Yup issue is resolved now.It was my broken Jquery validation code that was responsible for not submitting the form...Thanks Roman and Andrea for your help and assistance.Appreciate it.
Related
I am trying to make a simple web app, that will have 3 forms for data input, Submit button and Results form.
Requirements: When I enter a data in forms and push Submit button, these parameters should go to a controller and after that React should also parse data from json response that comes from the controller and show parsed data in the Results form.
I have the Spring Controller that takes 3 parameters and return json file as a response.
But I am new with React. I've tried to use different approaches, but stuck with what way exactly I need to do it in this case. So need a help to create a simple React part.
Controller part:
#GetMapping("/current/city")
public JSONObject getCurrentPollutionDataByCityStateCountry(
#RequestParam(value = "city") String city,
#RequestParam(value = "state") String state,
#RequestParam(value = "country") String country
) {
try {
return pollutionService.getCurrentPollutionDataByCityStateCountry(city, state, country);
} catch (Exception e) {
e.printStackTrace();
}
return new JSONObject();
}
Response example:
{"date":"Tue Dec 06 22:13:32 CET 2022","no2":"48.67","pm10":"9.51","pm2_5":"5.85"}
UPDATE
Here is my App.js part:
import React, {Component} from 'react'
import './App.css'
import axios from 'axios'
class App extends Component {
constructor(props) {
super(props);
this.state = {
city: 'New York',
province: 'New York',
country: 'US',
responseData: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(event) {
axios.get('http://localhost:8080/pollution/current/city?' +
'city=' + this.state.city +
'&state='+ this.state.province +
'&country=' + this.state.country)
//not sure about setState here and what is going after that
.then(response => this.setState({responseData: response.data.date}))
//need to take all fields from response
//just alert message with returned response for now
alert('Response: ' + this.state.responseData);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
City:
<input name="city" type="text" value={this.state.city} onChange={this.handleInputChange}/>
</label>
<br/>
<label>
State:
<input name="state" type="text" value={this.state.province} onChange={this.handleInputChange}/>
</label>
<br/>
<label>
Country:
<input name="country" type="text" value={this.state.country} onChange={this.handleInputChange} />
</label>
<br/>
<input type="submit" value="Submit"/>
</form>
);
}
}
export default App
But I am not sure about my approach in general and particularly about parts where I left comments in App.js.
To be more precise with questions:
Should this approach work for my case or I need to implement some different logic?
If yes, how I can get all fields from response? I mean not only the first one (date) but no2, pm10, pm2_5 also. For now this logic can return only a first value from json.
How I can set these fields to show them in pop-up window (alert) or if question 2 will be solved, this thing also will be good in current form?
The only problem I think you need to solve is to set the data not data.date
use this:
this.setState({responseData: response.data}))
then access your data fields using
responseData.date
you can replace date with any other field.
do the same for alerts.
your code is working fine, furthermore, you can learn to use functional component instead of class, its much easier.
I have the form
<aui:form action="<%= editURL %>" method="POST" name="fm">
<aui:fieldset>
<aui:input name="name" />
<aui:input name="url" />
<aui:input name="address" />
</aui:fieldset>
<aui:button-row>
<aui:button type="submit" />
<aui:button name="cancel" value="Cancel"/>
</aui:button-row>
</aui:form>
and this piece of javascript code which is inserting into database twice I don't know why.
<aui:script use="aui-base,aui-form-validator,aui-io-request">
AUI().use('aui-base','aui-form-validator',function(A){
var rules = {
<portlet:namespace/>name: {
required: true
},
<portlet:namespace/>url: {
url: true
},
<portlet:namespace/>address: {
required: true
},
};
var fieldStrings = {
<portlet:namespace/>name: {
required: 'The Name field is required.'
},
<portlet:namespace/>address: {
required: 'The Address field is required.'
},
};
alert("validator");
new A.FormValidator({
boundingBox: '#<portlet:namespace/>fm',
fieldStrings: fieldStrings,
rules: rules,
showAllMessages:true,
on: {
validateField: function(event) {
},
validField: function(event) {
},
errorField: function(event) {
},
submitError: function(event) {
alert("submitError");
event.preventDefault(); //prevent form submit
},
submit: function(event) {
alert("Submit");
var A = AUI();
var url = '<%=editURL.toString()%>';
A.io.request(
url,
{
method: 'POST',
form: {id: '<portlet:namespace/>fm'},
on: {
success: function() {
alert("inside success");// not getting this alert.
Liferay.Util.getOpener().refreshPortlet();
Liferay.Util.getOpener().closePopup('popupId');
}
}
}
);
}
}
});
});
</aui:script>
However if I add the following piece of code, which is redundant because it is already present inside the submit block of above code and is not triggered any way because I do not have any save button in the form, then the value is inserted only once.
<aui:script use="aui-base,aui-io-request">
A.one('#<portlet:namespace/>save').on('click', function(event) {
var A = AUI();
var url = '<%=editURL.toString()%>';
A.io.request(
url,
{
method: 'POST',
form: {id: '<portlet:namespace/>fm'},
on: {
success: function() {
Liferay.Util.getOpener().refreshPortlet();
Liferay.Util.getOpener().closePopup('popupId');
}
}
}
);
});
</aui:script>
This code generates Uncaught TypeError: Cannot read property 'on' of null which I think is because there is no save button in the form. But adding this code, the value is inserted into database just once which is what I want but the logic is flawed. How can I get the results I want by just by using the first piece of code?
The insertion was happening twice. Once from the default form submit and other from the A.io.request. Adding this piece of code
<aui:script use="aui-base,aui-io-request">
A.one('#<portlet:namespace/>save').on('click', function(event) {
var A = AUI();
var url = '<%=editURL.toString()%>';
A.io.request(
url,
{
method: 'POST',
form: {id: '<portlet:namespace/>fm'},
on: {
success: function() {
Liferay.Util.getOpener().refreshPortlet();
Liferay.Util.getOpener().closePopup('popupId');
}
}
}
);
});
</aui:script>
resulted in the insertion only once. This code has obviously no relevance because there is no save button in the form. Hence there was Uncaught TypeError: Cannot read property 'on' of null which masked the flaw and prevented the form from being submitted twice.
Removing the above piece of code and preventing the default submit (by adding onSubmit="event.preventDefault(); in the form tag) resolves the issue.
I have a web jsp web application. In one page I need two dropdownlist. When I will select a value from dd1 then second dropdown will be fill according this value. How I can call java function from dropdown 1 change event in javascript or jQuery?
I got example but that is calling jsp page but I need to java method and send parameter what i got from dropdown1
This is my dropdown dd1. So if I select tom I have to related information of tom in dd2.
<td>
<select id="dd1">
<option value="1">john</option>
<option value="2">Tom</option>
</select>
</td>
</tr>
<tr>
<th> Projects </th>
<td>
<select id="dd2">
<option value="1">pp1</option>
<option value="2">pp2</option>
</select>
</td>
I have following code
$(function () {
var ddVal = '';
var dropdown = document.getElementById("dd1")
$(dropdown).focus(function () {
ddVal = $(this).val();
}).blur(function () {
if (ddVal == $(this).val()) {
$(this).change();
}
}).change (function () {
});
For change event of dd1. But I don't know how to call java method from jQuery.
In my application I have a java class where there is a method which return list that I need to load in dd2 dropdown.
Can anyone help me regarding this issue?
You should do such things with AJAX.
JavaScript sends the request, your controller utilizes the Java part to carry out what's needed and then passes back a JSON response, based on which your JavaScript manipulates the page.
EDIT:
For example, the script can issue the following request:
$.ajax({
"type": "POST",
"url": "/ajaxAPI/updatedropdown/",
"data": {
"selected": selectedMenuItemId
},
"success": function (data) {
var menuItems = data.menuItems;
dropDownToChange.updateChoices(menuItems);
}
});
Your controller for such a request might look like:
public class DropDownListController implements Controller {
#Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
MenuItem selected = extractSelectionFromRequest(request);
List<MenuItem> choices = dropDownListService.getMenuFor(selected);
ModelAndView mav = new ModelAndView("dropDownListAjax.jsp");
mav.addObject("menu", choices);
}
// WARNING! Some error checks are missing!
private MenuItem extractSelectionFromRequeset(HttpServletRequest request) {
validateRequest(request);
return dropDownListService.getMenuItemById(request.getAttribute("selected"));
}
// ...
}
And for the view you could have something like:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
{
"menuItems": [
<c:forEach items="${menu}" var="menuItem">
{
"url": <c:out value="${menuItem['url']}"/>,
"caption": <c:out value="${menuItem['caption']}"/>
},
</c:forEach>
]
}
The client side JavaScript will then receive a response like:
{
"menuItems": [
{
"url": "http://www.example.com/"
"caption": "Home"
},
{
"url": "http://www.example.com/news/list/"
"caption": "News"
},
{
"url": "http://www.example.com/forum/topics/"
"caption": "Forum"
},
]
}
Please note that the above example might not be 100% correct as there have been a while since I last used JSP (and I'm more comfortable with FreeMarker anyways).
Basically, you invoke part of your web infrastructure that, rather than responding with HTML code, passes back JavaScript Objects based on the results of the requested operation.
Since jQuery is in the client side and JSP is on the server side, you don't have the option of directly calling the remote method. The standard way to do this in the world of the Web is AJAX.
Im looking for a little help on getting my JQuery/Ajax call to return a List from a Struts action and populate a DIV with the list elements using s:iterator.
I have the following JQuery
function lookupCustomerJs() {
alert("lets start");
$.ajax({
type: "POST",
url: "lookupCustomerAjax",
data: $('#lookupCustomer').serialize(),
success:function(response) {
alert("do stuff");
$('div#custList').replaceWith($(response).find("div#custList"));
},
failure:function(response) {
alert('Ajax call failed');
},
error:function(response) {
alert(exception);
}
});
}
I have a DIV within my page which I then want to iterate the list through
<div id="custList">
<s:iterator status="stat" value="customerList" var="customer">
<s:param name="custFName" value="%{customer.firstname}" />
</s:iterator>
</div>
And my Action method which IS called, because when I debug, the debugger goes through the code.
private List<Customer> customerList;
public String lookupCustomerAjax() {
dummyData();
return SUCCESS;
}
This successully calls my Action method, but all I get is the "lets start" alert, then nothing else, no errors, nothing!
So I'm guessing it's just the jQuery/Ajax success:function(response) { not fireing correctly, but can't see why.
It is probably the "lookupCustomerAjax" is an invalid url or file name. You should try adding the extension.
Also, for troubleshooting, you should console.log(response) in your succession to see that you are actually get the result.
I have a JSf form, I am tryin' to use jQuery Ui dialog plugin to submit the form.
here's the code snippet.
function confirmSubmit() {
$('#dialog').dialog('open');
return false;
}
$('#dialog').dialog({
autoOpen : false,
width : 400,
modal : true,
resizable : false,
buttons : {
"Submit Form" : function() {
document.myForm.submit();
},
"Cancel" : function() {
$(this).dialog("close");
}
}
});
<h:form id="myForm">
<h:commandLink action="#{Bean.search}" type="submit" onclick="return confirmSubmit()" id="search" styleClass="buttonSearch">
</h:commandLink>
The "document.myForm.submit();" part in the dialog box isn't working i.e., no calls goes to the server and in the server console I see the error:
11:45:32,738 SEVERE [lifecycle]
JSF1054: (Phase ID: RENDER_RESPONSE 6,
View ID: /PRT01/IMCM0101.jsp)
Exception thrown during phase
execution:
javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl#ec333b]
The dialog box is appearing correctly but once i press the submit button "document.myForm.submit();" code is executed and the form is NOT submitted instead the above described error comes on the server console.
as you return false; it won't submit actually.
To make dialog working
$(document).ready(function() {
var $dialog = $('<div></div>')
.html('This dialog will show every time!')
.dialog({
autoOpen : false,
width : 400,
modal : true,
resizable : false,
buttons : {
"Submit Form" : function() {
document.myForm.submit();
},
"Cancel" : function() {
$(this).dialog("close");
}
}
});
});
and then just call
function confirmSubmit() {
$dialog.dialog('open');
return false;
}
It's done, some JSF parameters were missing. which jsf adds during form submissiom, I added them using jQuery:
$("a[id$='search']").click(function() {
var input = $("<input>").attr("type", "hidden").attr("name", "myForm:search").val("myForm:search");
$('#myForm').append($(input));
$("p#dialog-email").html(titleVar);
$('#dialog').dialog('open');
});