Handling multiple <input>s with the same name in spring-mvc - html

Please take a look at codes below. Four text boxes are displayed.
If I input "1" and "2" to former text-boxes, these are binded as comma-separated "1,2" as I expected.
However, if I input "2001/01/01" and "2001/01/02" in rest of two-boxes are binded "2001/01/01". "2001/01/01" is only binded surprisingly. First parameter seems having a priority to bind.
I want to know where is defined the specifications(HTTP or SpringMVC or ...?) about that in order to understand deeply and accurately. Can someone help me?
Form
public class SampleForm {
private String name;
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
JSP
<form:form modelAttribute="form" method="post">
<form:input path="name" />
<form:input path="name" />
<form:input path="date" />
<form:input path="date" />
<p>
<input type="submit" name="register" value="register" />
</p>
</form:form>

It's logical. Multiple strings can be represented as one String by being comma-separated. Multiple Date objects can't be represented as one Date object.
You can try using String[] and Date[] instead.

private List<Date> date= new ArrayList<Date>();
public List<Date> getDate() {
return date;
}
public void setDate(List<Date> date) {
this.date= date;
}
It will solve your problem.

Related

Multiple attribute for <input> type="email" does not work under ASP.Net-Core

Under ASP we could bound a control with a model which has member
public string Contact { get; set; }
or directly <input type="email" asp-for="item.Contact"> or through corresponding HTML helper
As well we could use Data Annotation instead of implicitly declare type in Razor page
[EmailAddress]
public string Contact { get; set; }
But what to do if I would like to enter the list of email addresses separated by comma?
It is correct that unbounded HTML5 code <input type="email" multiple> works under latest browsers:
Multiple attribute for type="email" does not work. But when I am trying to bound it to the model it looks like EmailAddressAttribute is applied to the model and only one email address could be validated
Like #pcalkins said, the browsers will not separate it for you, you have to implement some split emails functionality like so
// 1. put this helper in your utilty class
private IEnumerable<string> GetEmails(string input)
{
if (String.IsNullOrWhiteSpace(input)) yield break;
MatchCollection matches = Regex.Matches(input, #"[^\s<]+#[^\s,>]+");
foreach (Match match in matches) yield return match.Value;
}
// 2. now call it to get list of emails
// for e.g. string strEmails = "Last, First <name#domain.com>, name#domain.com, First Last <name#domain.com>..";
string allContactsWithCommas = model.contactsWithCommas;
IEnumerable<string> emails = GetEmails(allContactsWithCommas );
// 3. try to give it something custom to validate
//[Required, MinLength(1, ErrorMessage = "Some validation error")]
[YourClassHoldingObject]
public List<int> Contact { get; set; }
// 4. or implement something custom in for your validation object, so the broswer knows how to handle/waht to call for validation
public class YourClassHoldingObject : IValidatableObject
{
[Required]
List<int> Contact
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// your contact logic validation here
if (Contact.Count < 1)
{
// some validation using System.ComponentModel.DataAnnotations
// - please customize for your needs
yield return new ValidationResult(
$"At least one email should be specified.", new[]
{ System.ComponentModel.DataAnnotations.EmailAddressAttribute().IsValid(
// for e.g. "email#istart.work") });
Contact) });
}
}
}

Getting input value with freemarker

I simply forgot how to work with freemarker. I tried to create input, after submission which value of it gonna be displayed on the other page. It looks awful but here is my code :
#GetMapping("/form1")
public String getForm(){
return "form1";
}
#GetMapping("/name11/{Name}")
public String formPos(#PathVariable("Name") String name, Model model){
model.addAttribute("name", name);
return "name11";
}
html named form1
<form action="/name11" method="post">
<input name="Name" >
<button>put</button>
</form>
html named name11
<body>
<h1>${name}</h1>
</body>
#GetMapping("/form1")
public String getForm() {
return "form1";
}
#PostMapping("/name11")
public String formPos(#RequestParam("Name") String name, Model model) {
model.addAttribute("name", name);
return "name11";
}
form1 in static directory as form1.html
name11 in template directory as name11.ftlh

ASP.NET runtime error:code blocks are not supported in this context-with ListView

i have this listView and textBox:
<table>
<tr><td>Reciver:<table><tr>
<asp:ListView ID="showRecivers" runat="server"><td><%# Eval("name")%></td> </asp:ListView>
</tr></table>
<asp:TextBox ID="reciver" runat="server" OnTextChanged="style_Recivers" AutoPostBack="true"></asp:TextBox>
</td></tr></table>
the list the listview is bound to:
public List<Reciver> recivers = new List<Reciver>();
and the function style_Recivers:
protected void style_Recivers(object sender, EventArgs e)
{
string[] separator = new string[] { "," };
string[] reciversArray = reciver.Text.ToString().Split(separator, StringSplitOptions.None);
reciversArray = reciversArray.Distinct().ToArray();
for (int i = 0; i < reciversArray.Length; i++)
{
recivers.Add(new Reciver(reciversArray[i]));
}
this.showRecivers.DataSource = recivers;
this.showRecivers.DataBind();
}
and class Reciver:
public class Reciver
{
public string name;
public Reciver(string name)
{
this.name = name;
}
public string getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
}
what my idea is, that when a couple of names eneted to the textBox with a , saperator, the style_Reciver function is activated and each name is shown in the ListView right away.
but it doesnt work, it gives me the error
ASP.NET runtime error:code blocks are not supported in this context
and marks this line:
<asp:ListView ID="showRecivers" runat="server"><td><%# Eval("name")%></td> </asp:ListView>
for starter. probably more thing wont work but this is the first thing.
how can i fix it? Thanks for the help
EDIT:
it works after i added <ItemTemplate>
now it gives me a different bug:
Reciver' does not contain a property with the name 'name'
whhat is the problem now?
The List View content here should be wrapped into ItemTemplate:
<asp:ListView ID="showRecivers" runat="server">
<ItemTemplate>
<td><%# Eval("name")%></td>
</ItemTemplate>
</asp:ListView>
Update. Also there is a problem with your class declaration. Here is how it should be declared in C# conventional way:
public class Reciver
{
public string _name;
public Reciver(string name)
{
this.name = name;
}
public string name
{
get { return this._name; }
set { this._name = value; }
}
}

Why doesn't Razor view properly call ToString() on my struct

I have a Money class that looks like this (simplified):
public class Money
{
private readonly decimal _amount;
public decimal Amount
{
get { return _amount; }
}
public Money(decimal amount)
{
_amount = amount;
}
public override string ToString()
{
return _amount.ToString("c2");
}
public static implicit operator Money(decimal value)
{
return new Money(value);
}
}
In my Razor view, I want to render a money value like this:
<p>This is my money value:
#Model.MyNullableMoneyValue
</p>
When I run the View, instead of using the Money struct's ToString() method which should result in something like "$10.00", it renders as though it was calling ToString() on the decimal amount, i.e. like "10.0000".
Adding ToString() myself fixes the issue:
<p>This is my money value:
#Model.MyNullableMoneyValue.ToString()
</p>
Why? What's going on?

How to provide JSON data to Dojo tree using Struts2 framework

I'm currently developing a web application using Struts2 framework. This application requires to dynamically update the objects on the screen based on data received from another application.
At the moment, I would like to implement a dynamic tree view which nodes are updated periodically with data provided by an Action class. I’m trying to do so using the dojo.dijit.tree object from the dojo toolkit. I’m aware that I can do so using the dojo tags which are part of the struts framework, however, it lacks much of the functionality that I need (persistence, open and close branches dynamically, etc) therefore, I have opted for using the dojo toolkit instead.
My problem with the dojo.dijit.tree is that I don’t know how to provide its data using a JSON result type. I have already created a class which returns a JSON result type with the same structure needed by the dojo tree component. I have tested the generation of a dojo tree using a file “test.txt” which was generated by the class and it works as expected. However, I would like to pass the JSON data directly to the dojo.dijit.tree component without saving a file on disk. When I execute the application I get a “save as” window to save the returned JSON result.
This is my struts.xml file:
<struts>
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="devResult" class="gui.JsonAction">
<result name="success">/start1.jsp</result>
</action>
</package>
<package name="example" namespace="/" extends="json-default">
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult"></result-type>
</result-types>
<action name="getJSONResult" class="gui.JsonAction">
<result type="json"/>
</action>
</package>
This is the jsp file which displays the tree:
<head>
<title>Testing Tree</title>
<style type="text/css">
#import "js/dojo/dojo/resources/dojo.css";
#import "js/dojo/dijit/themes/nihilo/nihilo.css";
</style>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"
djConfig="isDebug: true,parseOnLoad: true">
</script>
<script type="text/javascript">
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.Tree");
dojo.require("dojo.parser");
</script>
<body class="nihilo">
The Tree:<br><br>
<s:url id="devResult" action="jsonAction.action"></s:url>
<div dojoType="dojo.data.ItemFileReadStore" href="%{devResult}" jsid="popStore" />
<div dojoType="dijit.Tree" store="popStore" labelAttr="sname" label="Tree" />
</body>
This is the Action class which produces the JSON result:
public class JsonAction extends ActionSupport {
private static final long serialVersionUID = 7392602552908646926L;
private String label = "name";
private String identifier = "name";
private List<ChildrenClass> items = new ArrayList<ChildrenClass>();
public JsonAction() {
ChildrenClass item1 = new ChildrenClass("name1", "cat");
ChildrenClass item2 = new ChildrenClass("name2", "cat");
ChildrenClass item3 = new ChildrenClass("name3", "cat");
ChildrenClass item4 = new ChildrenClass("name4", "cat");
items.add(item1);
items.add(item2);
items.add(item3);
items.add(item4);
}
public String execute() {
return SUCCESS;
}
public void setLabel(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getIdentifier() {
return identifier;
}
public void setItems(List<ChildrenClass> lists) {
this.items = lists;
}
public List<ChildrenClass> getItems() {
return items;
}
}
This is the ChildrenClass which is used in the class above:
public class ChildrenClass {
private String name;
private String type;
private ChildrenClass[] children;
public ChildrenClass() {
name = "DefaultName";
type = "DefaultType";
}
public ChildrenClass(String aName, String aType) {
name = aName;
type = aType;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setChildren(ChildrenClass[] children) {
this.children = children;
}
public ChildrenClass[] getChildren() {
return children;
}
}
I would like to ask to the stackoverflow reader to please indicate me how to do to read the JSON data in the jsp file in order to populate the dojo tree. In addition, I would like to ask how can I refresh the content of it periodically.
PS: If somebody has a better method to implement something similar to this, I would be glad to receive your comments.
Thanks in advance.
I have found out a way to pass data directly from a JSON result to a dojo.dijit.tree component. Setting the "url" parameter to the action name which returns the json result type.
This is my new body of the .jsp file:
Simple Tree:<br><br>
<div dojoType="dojo.data.ItemFileReadStore" url=getJSONResult handleAs="json" jsid="popStore" />
<div dojoType="dijit.Tree" store="popStore" labelAttr="sname" label="PID 512" />