Multiple inputs with same name in struts - html

I have a form with a field that may have zero to multiple values for the named field, e.g.,:
<form ...>
<input type="hidden" name="browseId[]" value="3">
<input type="hidden" name="browseId[]" value="4">
<input type="hidden" name="browseId[]" value="8">
<input type="hidden" name="browseId[]" value="10">
<input type="text" name="browseId[]">
...
</form>
I do not seem to be able to get the variable browseId as an array, which is standard operating procedure in HTML, other languages, and I'm stumped. I'm actually first processing the form output in a validation method, using a DynaActionForm:
public static ActionMessages validatePlacement(DynaActionForm form) {
String[] rootBrowseIds = (String []) form.get("browseId");
...
}
Here's the form bean and action definition in struts-config.xml:
<form-bean name="placementForm" type="org.apache.struts.validator.DynaValidatorForm">
<!-- I've tried a few variations -->
<!--<form-property name="browseId" type="java.lang.String"/>-->
<!--<form-property name="browseIds" type="java.lang.String[]"/>-->
<form-property name="browseId" type="java.lang.String[]"/>
...
</form-bean>
...
<action path="/admin/editPlacement"
type="com.rc.mexp.action.admin.placementinventory.EditPlacementAction"
name="placementForm">
<forward name="success" path="/WEB-INF/pages/admin/placement/placementEdit.jsp"/>
<forward name="error" path="/admin/managePlacementInventory.do"/>
</action>
It appears that only the last value, empty in this case, is being received by Struts. WTF?
Any ideas?
Is there a way to change my form-bean definition to include something like this? I'm not allowed to use the < and > characters inside the type:
<form-property name="browseId" type="java.util.Map<java.lang.String[]>"/>
Other stackoverflow Qs that I examined already:
retrieve multiple inputs of the same name from jsp to struts (does not seem relevant)
Multiple inputs with same name through POST in php
Struts 2 - pattern/strategy for multiple objects on the same page

You're accessing the form field incorrectly, you should be using getStrings("browseId") since you're trying to get multiple strings.
Your code won't even compile for me, I'm not sure why you don't get a class cast exception.

Related

Using spring controller to provide list to html and make a drop down menu

I've created a controller to pass a list of pojo objects to the html. This seems to be working as when I refer to the list the IDE finds it. However, when I refer to a field within an element of the list it cannot find it and, instead of returning the value, it returns a literal text.
#GetMapping (value = "/searchforgames.html")
public String getsearchforgames(Model model) throws IOException {
List<Game> games = gamesService.getGames();
model.addAttribute("games", games);
return "searchforgames";
}
html within the searchforgames html
<div class="formformat">
<br><br>
<form>
<label for="name">Name:</label><br>
<select id="name" name="name">
<th:block th:each="game : ${games}">
<option value=${game.firstName}>${game.firstName}</option>
</th:block>
</select><br><br>
<label for="date">Date from:</label><br>
<input type="text" id="date" name="date"><br><br>
<label for="allresults">All entries</label><br>
<input type="checkbox" id="allresults" name="allresults"><br><br>
<input type="submit">
</form>
</div>
The Game class is a simple pojo with firstName, lastName, slName, sfName and date, zero argument constructor, constructor with all variables and getter/setters for each variable.
If anyone can point the error I'm doing I would be very grateful.
Use th:text to display the value for each of the options. Update value to th:value as well.
<option th:value="${game.firstName}" th:text="${game.firstName}"></option>
Using ${...} does no do much on its own, you will have to use something like th: to have thymeleaf to process the code it is referring to.

How to add default values to input fields in Thymeleaf

I am programming in Spring and using Thymeleaf as my view, and am trying to create a form where users can update their profile. I have a profile page which lists the user's information (first name, last name, address, etc), and there is a link which says "edit profile". When that link is clicked it takes them to a form where they can edit their profile. The form consists of text fields that they can input, just like your standard registration form.
Everything works fine, but my question is, when that link is clicked, how do I add the user's information to the input fields so that it is already present, and that they only modify what they want to change instead of having to re-enter all the fields.
This should behave just like a standard "edit profile" page.
Here is a segment of my edit_profile.html page:
First Name:
Here is the view controller method that returns edit_profile.html page:
#RequestMapping(value = "/edit", method = RequestMethod.GET)
public String getEditProfilePage(Model model) {
model.addAttribute("currentUser", currentUser);
System.out.println("current user firstname: " + currentUser.getFirstname());
model.addAttribute("user", new User());
return "edit_profile";
}
currentUser.getFirstname() prints out the expected value, but I'm getting blank input values in the form.
Thanks.
Solved the problem by removing th:field altogether and instead using th:value to store the default value, and html name and id for the model's field. So name and id is acting like th:field.
I'm slightly confused, you're adding currentUser and a new'd user object to the model map.
But, if currentUser is the target object, you'd just do:
<input type="text" name="firstname" value="James" th:value="${currentUser.firstname}" />
From the documentation:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
I did not have a form with input elements but only a button that should call a specific Spring Controller method and submit an ID of an animal in a list (so I had a list of anmials already showing on my page). I struggled some time to figure out how to submit this id in the form. Here is my solution:
So I started having a form with just one input field (that I would change to a hidden field in the end). In this case of course the id would be empty after submitting the form.
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
The following did not throw an error but neither did it submit the animalIAlreadyShownOnPage's ID.
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:value="${animalIAlreadyShownOnPage.id}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
In another post user's recommended the "th:attr" attribute, but it didn't work either.
This finally worked - I simply added the name element ("id" is a String attribute in the Animal POJO).
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:value="${animalIAlreadyShownOnPage.id}" name="id" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>

output all members of a form (form.FormController)

Please see the code here
it is an angular form, and the variable form should be of FormController . As you see with the usage of form.$pristine, the variable $pristine exists in form, but why it doesn't output when I just try <pre>form = {{form}}</pre>. I wanted to see all the members (if possible function names, else at least all primitives like $dirty, $valid , etc.) Why it is not outputting in the pre tag and how can I show them? It is mainly for debugging, but curious as well.
<form novalidate name="form" class="simple-form">
Name: <input type="text" ng-model="user.name" /><br />
E-mail: <input type="email" ng-model="user.email" /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
</form>
<pre>pristine = {{form.$pristine}}</pre>
<pre>form = {{form}}</pre>
output
pristine = true
form = {}
An expression like this: {{form}} will convert the form object to a string. Angular uses the build in angular.toJson function to serialize the object. Please have a look at the documentation: angular.toJson. As you can see there all properties with a leading $ are stripped.
How to solve your problem:
You may use the JSON.stringify function to get all properties. Because you can't call this function in an expression you need to provide a helper function in your controller:
$scope.stringify = function(obj){
return JSON.stringify(obj);
}
Now you are able to output your complete form object in the view:
{{stringify(form)}}
The following should also work...
<pre>form = {{form | json}}</pre>

MVC - How to submit two sets of multiple check boxes to controller action?

I have two sets of checkboxes in a form that are both almost identical to this:
<input type="checkbox" value="1" name="Test Course"
checked="checked" />Test Course
<input type="checkbox" value="2" name="Test Course 2" />Test Course 2
<input type="checkbox" value="3" name="Test Course 3" />Test Course 3
The form is generated through Razor. Here's the code:
#using (Html.BeginForm("Save", "Material",
new { id = Model.Material.FirstOrDefault().ID },
FormMethod.Get, new { id = "associationForm" })
{
<h3>#Model.Material.FirstOrDefault().Title</h3>
Html.RenderPartial("Association/_Course", Model);
Html.RenderPartial("Association/_Track", Model);
<br />
<input type="submit" value="Save" />
}
The checkboxes are rendered through the two partial views you see in the form.
Right now, the only data being submitted successfully is new { id = Model.Material.FirstOrDefault().ID } in the 2nd line of parameters in the #using() {} statement.
I need to submit both sets of checkboxes as collections so I may iterate through them and perform some database operations. I've never done anything like this before and the only thing stopping me are these check boxes.
How can I submit those values as two separate collections?
To do this, you have to render a collection. I will assume you have two collections in your model, one called Courses, and one called Tracks.
#for(int i = 0; i < collection.Count(); i++ {
// Boolean property indicating value is selected on your Courses view model submodel
Html.CheckBoxFor(model => model.Courses[i].CourseSelected);
Html.Raw(Model.Courses[i].CourseName);
}
Then do the same for your Tracks.
EDIT;
Assuming you have a ViewModel with a List<Course> where Course looks like this:
public class Course {
public bool CourseSelected {get;set;}
public string CourseName {get;set;}
}
You will have to lookup the course based on the index of the checkbox collection. Thus, if Course[0] is set, you need to get the first course based on position. You could also look it up by name, but you will have to include a hidden field to allow it to be posted back to the form containing the name. Otherwise, you will CourseName is going to be null and you will just nave the array with the Booleans bound.
Ok, I think you need the name attribute of the inputs in the same group be the same plus square brackets like "checkgroup1[]"
<input type=checkbox name=checkgroup1[] value=1>
<input type=checkbox name=checkgroup1[] value=2>
if you define in your view two sets of check boxes, with different names, for example:
<input type=checkbox name=checkgroup1[] value="x">
.
.
.
<input type=checkbox name=checkgroup2[] value="y">
.
.
.
you can declare your post method on the controller like this:
[HttpPost]
public ActionResult YourAction(YourModel model, string[] checkgroup1, params string[] checkgroup2)
{
...
}

Conditional Formatting in Html?

I am writing a website and I am currently working on the sign up page. I have a drop down box and I want to have that drop down box open different sign up information for each one. For example: If they picked prime user it would change the sign up information they needed from just username and password to username, password, credit card number, and telephone number . OR if they picked partial user from the drop down list it would ask for username password and telephone. Any clue how to do this in HTML or any other computer language?
Assuming html like this:
Type:<br>
one <input type="radio" name="type" id="type-1" value="1" /><br>
two <input type="radio" name="type" id="type-2" value="2" />
<hr>
<form action="." METHOD="POST">
<input class="second" type="text" name="name" id="name" value="name" />
<input class="second" type="text" name="email" id="email" value="email" />
<input class="second" type="text" name="credit-card" id="credit-card" value="credit card" />
</form>
And css like this: (to hide all the form fields except for type choice)
.second{
display:none
}
You can use jQuery javascript library to show/hide the required form fields dynamically like this:
// when type radio button is pressed
$('#type-1,#type-2').change(function(){
// hide all form fields
$('.second').hide()
// if type is 1
if($('#type-1:checked').length){
// show name and email fields
$('#name,#email').show()
// else if type is 2
}else if($('#type-2:checked').length){
// show name, email and credit-card fields
$('#name,#email,#credit-card').show()
}
})
This is demonstrated here: http://jsfiddle.net/rBvLA/
The result must be processed by server side script using any language you choose.
You might want to look into any of the many fine server side tools available, such as asp.net, php, etc... you could also use javascript.
For instance, using JavaScript, you could have an event fire when they change the drop down and in the code for that event handler, you could modify the DOM in such a way as to display the appropriate form elements for each selection.
another jQuery solution:
Live Demo
$('#reg_type input[type=radio]').change(function() {
var type = $(this).attr('class');
$('#reg_fields div').each(function() {
if ($(this).hasClass(type)) {
$(this).show().removeAttr('disabled');
} else {
$(this).hide().attr('disabled','disabled');
}
});
});