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
Related
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) });
}
}
}
I want to get first name by html template with i show it by method Get.
I did controller and it doesnt't see name which I give by the html template.
This controller should get this paramert from template. I have exeption on my browser There was an unexpected error (type=Bad Request, status=400).
Required String parameter 'first_name' is not present
Please can u tell me where i did mistake ?
this is my service:
public class ReadFamily {
#Autowired
ChildRespository childRespository;
private RestTemplate restTemplate;
public ReadFamily(){
restTemplate = new RestTemplate();
}
public ChildForm findChild(String firstName){
return restTemplate.getForObject("http://localhost:8080/findP/"+firstName,ChildForm.class);
}
public String firstNameFormat(ChildForm childForm) {
return childForm.getFirstName();
}
public String secondNameFormat(ChildForm childForm) {
return childForm.getSecondName();
}
public String sexFormat(ChildForm childForm) {
return childForm.getSex();
}
public String peselFormat(ChildForm childForm) {
return childForm.getPesel();
}
}
controller:
#Autowired
ReadFamily readFamily;
#GetMapping("findP")
public String findPerson(Model model){
model.addAttribute("childForm",new ChildForm());
return"Find";
}
#RequestMapping (value = "findPersonResult", method = RequestMethod.POST)
public String findPerson(Model model,
#RequestParam ("first_name") String firstName) {
System.out.println(firstName);
ChildForm childInfo = readFamily.findChild(firstName);
model.addAttribute("firstName",readFamily.firstNameFormat(childInfo));
model.addAttribute("secondName",readFamily.secondNameFormat(childInfo));
model.addAttribute("pesel",readFamily.peselFormat(childInfo));
model.addAttribute("sex",readFamily.sexFormat(childInfo));
return "Find";
}
and template:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Find person</title>
</head>
<body>
<form th:object="${childForm}" action="/findPersonResult" method="post">
<input type="text" th:field="*{firstName}" placeholder="firstName"> <br/>
<input type="submit" value="Find">
</form>
<h2>Persons</h2>
<form action="/findP" method="get">
<div id="show" >
<h1 th:text="${firstName} "></h1>
<h1 th:text="${secondName} "></h1>
<h1 th:text="${pesel} "></h1>
<h1 th:text="${sex} "></h1>
</div>
</form>
</body>
</html>
Change
#RequestParam ("first_name") String firstName
to
#RequestParam ("firstName") String firstName
So what I want to do is take a string from a textarea and pass it to an action method overload (string paramJSON).
Action method:
public ActionResult SendMail(string templateName, string receiver, string paramJSON)
{
var paramDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(paramJSON);
new SendMailClient().Send(templateName, receiver, paramDictionary);
if(Request.IsAjaxRequest())
{
return RedirectToAction("SendPartial", "TestMail");
}
return View();
}
Textarea:
#Html.TextAreaFor(a => a.TestParametrar, new { id = "paramTxt" })
Your html helper
#Html.TextAreaFor(a => a.TestParametrar, new { id = "paramTxt" })
generates a textarea with name="TestParametrar". When you submit a form, it sends back the values of each controls name and value attributes in this case TestParametrar: 'The text you entered' You method needs to include a parameter with the same name, for example
public ActionResult SendMail(string TestParametrar, ....)
and the value of the parameter will be the text entered in the form control.
However, since you view is based on a model, then it is better to just post back to the model and all properties will be bound
public ActionResult SendMail(YourModel model)
which has the added benefit of validating your properties. For example, if property TestParametrar has the [Required] attribute, then if the user does not enter a value, ModelSTate will be invalid and the view can be returned for correction.
#using (Html.BeginForm("SendMail2"))
{
#Html.TextAreaFor(a => a.TestParametrar, new { id = "paramTxt" })
<input type="submit" value="Send Message" />
}
And:
public ActionResult SendMail2(string TestParametrar)
{
return SendMail("myTemplate", "hello#world.com", TestParametrar);
}
I'm attempting to make a simple page that will compare multiple form submissions.
I have a html page with a form, and a for-loop that generates a div for each item in a list of form submissions. The list is passed from the controller. I am trying to maintain the list in the controller rather than rely on a database.
When I try to resubmit the form, which should add another object to the list, the list re initializes.
In debugging, I see that the list is empty when the form gets submitted. I'm unsure as to the correct terminology, but it seems that the list is emptied whenever the view is rendered. Is there a way to maintain list contents?
I know there are better ways to do this, and welcome any advice. I'm still learning, so pleas go easy.
Thanks!
This is the simplified controller.
namespace MvcApplication2.Controllers
{
public class HomeController : Controller
{
List<paymentPlan> plansList = new List<paymentPlan>();
public ActionResult Index()
{
return View(plansList);
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
paymentPlan Project = new paymentPlan();
Project.customerName = Convert.ToString(collection["customerName"]);
plansList.Add(Project);
return View(plansList);
}
}
}
This is my simplified view.
#model List<MvcApplication2.Models.paymentPlan>
#using (Html.BeginForm("index", "home", FormMethod.Post, new { Id = "signupForm" }))
{
<label for="customerName">Customer Name:</label>
<input type="text" name="customerName" class="form-control required" />
#Html.ValidationSummary(true)
<input type="submit" value="Calculate" class="btn btn-primary" />
}
#{
bool isEmpty = !Model.Any();
if (!isEmpty)
{
foreach (var i in Model)
{
<div>
Name: #i.customerName
</div>
}
}
}
This is my simplified model.
namespace MvcApplication2.Models
{
public class paymentPlan
{
public string customerName { get; set; }
}
}
I think that's a question of controller and asp.Net MVC lifecycle !
A controller lifetime is the same as the request, for each request a new controller is created and once the work is done it's disposed!
So try to remove this List<paymentPlan> plansList = new List<paymentPlan>(); and work with TempData[] or ViewData[] or Session[] like this :
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
Session["plansList"] = ((List<paymentPlan>)Session["plansList"])!=null? (List<paymentPlan>)Session["plansList"] : new List<paymentPlan>();
return View((List<paymentPlan>)Session["plansList"]);
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
paymentPlan Project = new paymentPlan();
Project.customerName = Convert.ToString(collection["customerName"]);
((List<paymentPlan>)Session["plansList"]).Add(Project);
return View(plansList);
}
}
check this : http://www.asp.net/mvc/overview/getting-started/lifecycle-of-an-aspnet-mvc-5-application
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.