Submitting objects and lists struts1 - struts2

I have a class MyClass as below
public class MyClass {
private int fieldOne; //with getter, setter
private String fieldTwo; //with getter, setter
}
I have following two fields in my form bean
private MyClass myObject; //with getter, setter
private ArraList<MyClass>myList; //with getter, setter
Using struts1 I want to submit object and list of objects from web-page form.
In struts2 we can get object and list in action as below (considering fields are not in action class instead of form bean). When following fields are submitted, struts2 initiates myObject and myList for me with submitted values. (Parameters Interceptor is the magician behind the scene in struts2.)
<!-- Object -->
<input type="text" name="myObject.fieldOne" value="1" />
<input type="text" name="myObject.fieldTwo" value="Two" />
...
<!-- List -->
<input type="text" name="myList[0].fieldOne" value="1" />
<input type="text" name="myList[0].fieldTwo" value="Two" />
<input type="text" name="myList[1].fieldOne" value="10" />
<input type="text" name="myList[1].fieldTwo" value="Twenty" />
Is there any way to perform such magic in struts1?

AFAIR, the same would work in Struts1, provided the list in your form bean contains a list which already has the right size. I.e. if the last input text has the name myList[7].fieldOne, the list should be of size 8 at least, and thus be prepopulated with 8 MyClass instances. STruts will only do formBean.getMyList().get(7).setFieldOne(10).
See http://struts.apache.org/development/1.x/struts-taglib/indexedprops.html for more details.

Related

Can't prepopulate a form with html tags

I want to show a prepopulated form in jsp.
TestAction.java
import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport {
private String firstName;
private String lastName;
public String execute(){
setFirstName("John");
setLastName("Doe");
return SUCCESS;
}
/** Getters & Setters **/
}
When I use html tags, it fails to do so,
Test.jsp
<!DOCTYPE html>
<html>
<head></head>
<body>
<form>
First Name <input type="text" name="firstName" > <br/>
Last Name <input type="text" name="lastName">
</form>
</body>
</html>
when instead I use struts2 tags, It works fine.
<s:form>
<s:textfield name="firstName"></s:textfield>
<s:textfield name="lastName"></s:textfield>
</s:form>
Can this be achieved using non struts2 tags ?
You can use JSP EL
<form>
First Name <input type="text" name="firstName" value="${fn:escapeXml(firstName)}"><br/>
Last Name <input type="text" name="lastName" value="${fn:escapeXml(lastName)}">
</form>
The values are strings, so better to escape them for safety.
If this jsp returned as a result of the action the variables along with standard scopes also searched the value stack. The action properties should be available from the value stack.

Bind list with missing items, preserve gaps

How can I post a model list with gaps from a MVC webpage, and have it preserve those gaps when accessing it in server code?
For example, I want to post this:
<input type="hidden" name="ImageUrl.Index" value="0" />
<input type="url" name="ImageUrl[0]" value="example0.png" />
<!---->
<input type="hidden" name="ImageUrl.Index" value="2" />
<input type="url" name="ImageUrl[2]" value="example2.png" />
And receive this in the controller:
public ActionResult Save(Gallery model)
{
model.ImageUrl[0]; // "example0.png"
model.ImageUrl[1]; // null
model.ImageUrl[2]; // "example2.png"
}
I already noticed the "Index" hidden value helps send gaps correctly, but currently I'm receiving a list with 2 items, not 3. I would rather avoid declaring a dummy hidden value.

ASP.NET MVC 5 renders different bool value for hidden input

Given the following viewmodel:
public class FooViewModel
{
public bool IsBoolValue { get; set; }
}
and this view:
<input type="hidden" id="Whatever" data-something="#Model.IsBoolValue" value="#Model.IsBoolValue" />
The output of the hidden input field is this:
<input type="hidden" id="Whatever" data-something="True" value="value">
How come the value attribute is not set toTrue, but the data-something attribute is?
Is there a change in MVC 5 that would cause this, since in my MVC 4 apps this problem does not occur.
I think I've figured it out.
I believe the Razor viewengine is adhering to the HTML 5 way of setting boolean attributes, as described here:
What does it mean in HTML 5 when an attribute is a boolean attribute?
In HTML 5, a bool attribute is set like this:
<input readonly />
or
<input readonly="readonly" />
So the Razor viewengine takes your model's bool value and will render (in my case) the value attribute if Model.IsBoolValue is true. Otherwise, if it's false then the value attribute is not rendered at all.
EDIT:
As mentioned Zabavsky in the comments, to force the value of True or False to appear in the value attrbiute, simple use ToString():
<input type="hidden" value="#Model.BoolProperty.ToString()" />
<div class="field_warp_hidden">
<input type="checkbox" asp-for="ShowGoogleCaptcha" checked="#Model.ShowGoogleCaptcha" value="#Model.ShowGoogleCaptcha"/>
</div>
can set field_wrap_hidden is display:none;
checked and value must be set
I was using the hidden field in a partial view and I got an error when I used .ToString()
alternative option was to specify the value property explicitly even after specifying asp-for
<input type="hidden" value="#Model.TargetmarketsToChangeAvailability[i].Available" asp-for="TargetmarketsToChangeAvailability[i].Available" />

asp.net mvc how to bind to an empty checkbox value?

I am modifying an existing asp.net mvc application that creates a list of checkboxes from a list on the model, with property name "MyModelProperty" and additionally generates one more input element for "Select All" which has the following html:
<input name="MyModelProperty_SelectAll" type="checkbox" CHECKED="checked" value=""/>
What is the property declaration in the model that would create a boolean property that would bind to this existing element in the view?
I tried, 'public bool MyModelProperty_SelectAll {get;set;}' but it was returning null. Is that because the value is an empty string in the html input control?
Change your Model property for string:
public string MyModelProperty_SelectAll { get; set; }
Set some value for the checkbox, then in the server, if its checked, the value will be the given value, else you will see null.
<input name="MyModelProperty_SelectAll" type="checkbox" value="all"/>
EDIT:
If you want to bind this to a bool, you must provide a value="true" and a hidden field:
<input class="input-validation-error" id="MyModelProperty_SelectAll" name="MyModelProperty_SelectAll" type="checkbox" value="true">
<input name="MyModelProperty_SelectAll" type="hidden" value="false">
This example code above was generated using the Html.CheckBox helper.
If you don't use MVC htmlhelpers for generating checkboxes you must add an additional hidden element for your checkbox:
<input name="MyModelProperty_SelectAll" type="checkbox" value="true"/>
<input name="MyModelProperty_SelectAll" type="hidden" value="true"/>

Saving Set of Domains For a Parent

I have the following Domains:
class Attribute {
static hasMany = [attributeParameters: AttributeParameter]
}
class AttributeParameter {
String value
Integer sequenceNo
static belongsTo = [attribute: Attribute]
}
I have a form where I want to display all the existing AttributeParameters for an Attribute and allow the user to populate their values and click Save. On Save, each AttributeParameter (which already has an ID) needs to be updated.
I'm currently drawing a blank on how I need to create the HTML for this to work. I've tried this:
Code simplified to clarity:
<form>
<input type="hidden" name="attributeParameters[0].id" value="1" />
<input type="text" name="attributeParameters[0].value" value="1234567" />
<input type="hidden" name="attributeParameters[1].id" value="2" />
<input type="text" name="attributeParameters[1].value" value="name" />
</form>
def save() {
def attribute = Attribute.get(params.id)
attribute.properties = params
}
and it populates the collection correctly, but it doesn't work because the AttributeParameter isn't being fetched before the save, so it is failing with an error:
A collection with cascade="all-delete-orphan" was no longer referenced
by the owning entity instance: com.foo.Attribute.attributeParameters
UPDATE:
I modified the HTML to the following:
<form>
<input type="hidden" name="attributeParameters.id" value="1" />
<input type="text" name="attributeParameters.value" value="1234567" />
<input type="hidden" name="attributeParameters.id" value="2" />
<input type="text" name="attributeParameters.value" value="name" />
</form>
And the controller:
params.list('attributeParameters').each {
def ap = AttributeParameter.get(it.id)
ap.value = it.value
ap.save()
}
This works. My only concern is the order in which the parameters come in. If they always come into the params object in the same order they show up on the form, then I should be ok. but if they ever come in differently, I could be modifying the value of the wrong AttributeParameter.
So still looking for a better way or some sort of verification that they params will always be first in-first out.
UPDATE 2:
I ran across this post and it is what I want but I cannot change Attribute.attributeParameters into a List. They need to stay as a Set.
Could you do something like this:
<form>
<input type="text" name="attributeParameter.1" value="1234567" />
<input type="text" name="attributeParameter.2" value="name" />
</form>
Where you create the names and values dynamically from each AttributeParameter:
<g:textField name="attributeParameter.${attributeParameterInstance.id}" value="${attributeParameterInstance.value}" />
And then in your controller
params.attributeParameter.each {id, val->
def ap = AttributeParameter.get(id)
ap.value = val
ap.save()
}
That way you have the actual id of each parameter directly and it wouldn't matter which order they were processed.

Resources