How to send object that is retrived in a get request to a post requet | Spring Boot Thymeleaf - forms

Let's say I have rendered the output rom the get request on an html template, now I need to use this same data to pass to a post request via a button on a same page. How do I do that?
I'm trying to do something like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Customer Home</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div th:replace="fragments/header :: header">
</div>
<div class="container">
<p> Thanks for booking with Gamma Airlines, here are your booking summary: </p>
<table th:object="${booking} class="table table-bordered table-striped">
<tbody>
<tr>
<td>Source</td>
<td th:text="${routeStart}"></td>
</tr>
<tr>
<td>Destination</td>
<td th:text="${routeDestination}"></td>
</tr>
<tr>
<td>Booking Charges</td>
<td th:text="${bookingCharges}"></td>
</tr>
<tr>
<td>Booking Charges Currency</td>
<td th:text="${chargesCurrency}"></td>
</tr>
<tr>
<td>Booking Date</td>
<td th:text="${#calendars.format(bookingDate)}">July 11, 2012 2:17:16 PM CDT</td>
<tr>
<td>
<div class="col-sm-9">
<form action="#" th:action="#{/email}"
th:object="${booking}" method="post"
role="form">
<button type="submit" class="btn btn-primary btn-block">Email</button>
</form>
</div>
</td>
<td>
<div class="col-sm-9">
<form action="#" th:action="#{/genpdf}"
th:object="${booking}" method="post"
role="form">
<button type="submit" class="btn btn-primary btn-block">Generate PDF</button>
</form>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Edit: Somebody please help tell me a simple method to pass the object since I have to use it at many places and object contains many child object as well in some cases. eg. the following case:
<div style = "margin-top: 2cm" class="container">
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>Source</td>
<td>Destination</td>
<td>Amount</td>
<td>Currency</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr th:if="${offers.empty}">
<td colspan="5">No Offers</td>
</tr>
<tr th:each="offer : ${offers}">
<td th:text="${offer.route.from}"></td>
<td th:text="${offer.route.to}"></td>
<td th:text="${offer.price.amount}"></td>
<td th:text="${offer.price.currency}"></td>
<td>
<form action="#" th:action="#{/user/booking}"
th:object="${offer}" method="post"
role="form">
<button type="submit" class="btn btn-primary btn-block">Book</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
UPDATE 2:
I even changed the template by sending a new object in the get request and try to assign values one by one but I still get it as null in a controller.
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>Source</td>
<td>Destination</td>
<td>Amount</td>
<td>Currency</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr th:if="${offers.empty}">
<td colspan="5">No Offers</td>
</tr>
<tr th:each="offer : ${offers}">
<td th:text="${offer.route.from}"></td>
<td th:text="${offer.route.to}"></td>
<td th:text="${offer.price.amount}"></td>
<td th:text="${offer.price.currency}"></td>
<td>
<form action="#" th:action="#{/user/booking}"
th:object="${booking}" method="post"
role="form">
<input type="hidden" th:attr="value = ${offer.route.from}" th:field="*{routeStart}" />
<input type="hidden" th:attr="value = ${offer.route.to}" th:field="*{routeDestination}" />
<input type="hidden" th:attr="value = ${offer.price.amount}" th:field="*{bookingCharges}" />
<input type="hidden" th:attr="value = ${offer.price.currency}" th:field="*{chargesCurrency}" />
<button type="submit" class="btn btn-primary btn-block">Book</button>
</form>
</td>
</tr>
</tbody>
</table>
These are my get and post methods:
#RequestMapping(value="/user/booking", method = RequestMethod.GET)
public ModelAndView getOffers()
{
ModelAndView modelAndView = new ModelAndView();
AirlineOffer[] offersArray= airlineClient.getOffers();
List<AirlineOffer> offers = Arrays.asList(offersArray);
modelAndView.addObject("offers", offers);
Booking booking = new Booking();
modelAndView.addObject("booking", booking);
modelAndView.setViewName("user/booking");
return modelAndView;
}
/** POST method for submitting deposit request */
#RequestMapping(value = "/user/booking", method = RequestMethod.POST)
public ModelAndView book(#Valid Booking booking,
BindingResult bindingResult, HttpServletRequest request)
{
ModelAndView modelAndView = new ModelAndView();
......
}

Alright, I finally resolved it using the following in my form:
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>Source</td>
<td>Destination</td>
<td>Amount</td>
<td>Currency</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr th:if="${offers.empty}">
<td colspan="5">No Offers</td>
</tr>
<tr th:each="offer, stat : ${offers}">
<td th:text="${offer.route.from}"></td>
<td th:text="${offer.route.to}"></td>
<td th:text="${offer.price.amount}"></td>
<td th:text="${offer.price.currency}"></td>
<td>
<form action="#" th:action="#{/user/booking}"
th:object="${booking}" method="post"
role="form">
<input type="hidden" th:value="${offer.route.from}" name="routeStart" />
<input type="hidden" th:value = "${offer.route.to}" name="routeDestination" />
<input type="hidden" th:value = "${offer.price.amount}" name="bookingCharges" />
<input type="hidden" th:value = "${offer.price.currency}" name="chargesCurrency" />
<button type="submit" class="btn btn-primary btn-block">Book</button>
</form>
</td>
</tr>
</tbody>
All it took was to remove th:field and add the name attribute.

Related

PartialView on each list items

I have a in item list in each row has an edit button, which is supposed to open a partial view with the elements data to edit.
In the loop I use to fill tge datatable, I also create the partial views for each row element.
When I click the buton it always opens the first element partial view, even if I press the Nth element.
How do I get the code to open the corresponding partial view?
Code:
<table class="table table-hover" id="tabela_rota">
<thead>
<tr>
<th>
</th>
<th>
Cliente
</th>
<th>
Rota
</th>
<th>
Distância Ideal
</th>
<th>
Ativa
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<partial>
#{await Html.RenderPartialAsync("Edit", item);}
</partial>
<tr>
<td width="15">
</td>
<td width="15%">
#Html.DisplayFor(modelItem => item.id_cliente)
</td>
<td width="25%">
#Html.DisplayFor(modelItem => item.nome)
</td>
<td width="15%">
#Html.DisplayFor(modelItem => item.distancia_ideal)
</td>
<td width="10%">
#Html.DisplayFor(modelItem => item.activa)
</td>
<td>
<button type="button" class="btn btn-outline-primary" onclick="openNavEdit()">
Editar
</button>
<button type="button" class="btn btn-outline-danger">Delete</button>
</td>
</tr>
}
</tbody>
</table>
JS Function:
function openNavEdit() {
document.getElementById("mySidepanelEdit").style.width = "350px";
}
View:
#model GestaoCircuitos.Models.Rota
#{
ViewData["Title"] = "Editar";
}
<div id="mySidepanelEdit" class="sidepanel">
<div id="top_title">
<h6 id="nova_rota">Editar Rota</h6>
<button class="closebtn" onclick="closeNavEdit()">×</button>
</div>
<div class="row form-row-rotas">
<div class="col-12">
<form asp-action="Edit" class="form-rotas">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="id" />
<div class="form-label-group">
<input id="nome" class="form-control" placeholder="Nome" />
<label asp-for="nome" class="control-label">Nome</label>
<span asp-validation-for="nome" class="text-danger"></span>
</div>
<div class="form-label-group">
<input type="text" asp-for="distancia_ideal" class="form-control" placeholder="Distância ideal" />
<label asp-for="distancia_ideal" class="control-label">Distância ideal</label>
<span asp-validation-for="distancia_ideal" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="activa" /> Ativa
</label>
</div>
<div class="form-group">
<input type="submit" value="Editar" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
It's because you're opening based on ID. An ID attribute needs to be unique throughout a document. If you select on an ID, you'll only get the first element.
You'll have to give each edit modal either a unique ID or a class to select from. Try this:
#model GestaoCircuitos.Models.Rota
#{
ViewData["Title"] = "Editar";
}
<div id="sidepanel-edit-#(item.id)" class=" sidepanel">
<div id="top_title">
<h6 id="nova_rota">Editar Rota</h6>
<button class="closebtn" onclick="closeNavEdit(#(item.id))">×</button>
</div>
<div class="row form-row-rotas">
<div class="col-12">
<form asp-action="Edit" class="form-rotas">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="id" />
<div class="form-label-group">
<input id="nome" class="form-control" placeholder="Nome" />
<label asp-for="nome" class="control-label">Nome</label>
<span asp-validation-for="nome" class="text-danger"></span>
</div>
<div class="form-label-group">
<input type="text" asp-for="distancia_ideal" class="form-control" placeholder="Distância ideal" />
<label asp-for="distancia_ideal" class="control-label">Distância ideal</label>
<span asp-validation-for="distancia_ideal" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="activa" /> Ativa
</label>
</div>
<div class="form-group">
<input type="submit" value="Editar" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Above, we add a unique id for each edit edit form. Then we can reference those unique id attributes in the main template:
<table class="table table-hover" id="tabela_rota">
<thead>
<tr>
<th>
</th>
<th>
Cliente
</th>
<th>
Rota
</th>
<th>
Distância Ideal
</th>
<th>
Ativa
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<partial>
#{await Html.RenderPartialAsync("Edit", item);}
</partial>
<tr>
<td width="15">
</td>
<td width="15%">
#Html.DisplayFor(modelItem => item.id_cliente)
</td>
<td width="25%">
#Html.DisplayFor(modelItem => item.nome)
</td>
<td width="15%">
#Html.DisplayFor(modelItem => item.distancia_ideal)
</td>
<td width="10%">
#Html.DisplayFor(modelItem => item.activa)
</td>
<td>
<button type="button" class="btn btn-outline-primary" onclick="openNavEdit(#(item.id)">
Editar
</button>
<button type="button" class="btn btn-outline-danger">Delete</button>
</td>
</tr>
}
</tbody>
</table>
and your Javascript would look like:
function openNavEdit(id) {
document.getElementById("sidepanel-edit-" + id).style.width = "350px";
}
function closeNavEdit(id) {
document.getElementById("sidepanel-edit-" + id).style.width = "0";
}
Something to note, I'm assuming your model has an id attribute.

I have this code, when submited the form dont refresh, someone know how refresh after submit on october cms?

<form data-request="onSend" data-request-update="'{{ __SELF__}}::attbanco': '#banco' "
data-request-flash >
<table>
<tr>
<td>Nome: </td> <td ><input type="text" id="nome" name="nome"></td>
</tr>
<tr>
<td>Idade: </td> <td ><input type="number" id="idade" name="idade" value="{{usuario.idade}}"></td>
</tr>
<tr>
<td>Telefone: </td> <td ><input type="text" id="telefone" name="telefone" value="{{usuario.telefone}}"></td>
</tr>
</table>
<button type="submit" >Enviar</button>
<input type="hidden" value="{{usuario.id}}" name="id">
this code work, saves the values on database, but i need manually refresh page to see the result on my
screen, someone know how refresh after submit?
Please, explain most simple possible, i am newbie
The best way to do what you want is to put the form in a partial and update it when the form is submitted.
Replace your form with this:
<div id="specialForm">
{% partial __SELF__~"::specialForm" %}
</div>
Create a partial to describe the form; I used specialForm. It should reload the form and clear the content.
<form data-request="onSend" data-request-update="'{{ __SELF__}}::attbanco': '#banco', '{{ __SELF__ }}::specialForm': '#specialForm' "
data-request-flash >
<table>
<tr>
<td>Nome: </td> <td ><input type="text" id="nome" name="nome"></td>
</tr>
<tr>
<td>Idade: </td> <td ><input type="number" id="idade" name="idade" value="{{usuario.idade}}"></td>
</tr>
<tr>
<td>Telefone: </td> <td ><input type="text" id="telefone" name="telefone" value="{{usuario.telefone}}"></td>
</tr>
</table>
<button type="submit" >Enviar</button>
<input type="hidden" value="{{usuario.id}}" name="id">
</form>

Protractor expect specific text siblings of selector

I have a table like this:
<table>
<tbody>
...
<tr>
<td>
<div class="radio-inline">
<input name="sms_provider" type="radio" value="2" id="2">
<label class="text-gray-dark" for="2"> </label>
</div>
</td>
<td data-label="Server name">ServerA3</td>
<td data-label="Description"></td>
<td data-label="Status">
<label class="text-success">
<clr-icon shape="check"></clr-icon>
Default
</label>
</td>
<td data-label="Actions">
<a href="http://example.com/public/smsconfigurations/2/edit" data-tooltip="Edit Server">
<clr-icon shape="pencil" size="22" style="width: 22px; height: 22px;"></clr-icon>
</a>
</td>
</tr>
...
</tbody>
</table>
Now I wanna to check ServerA3 has Default status or no. As matter of fact I expect ServerA3 has Default text as siblings. What should I do?
I try with this code, but it doesn't work:
expect(element(by.xpath('//td[contains(text(), "ServerA3")]')).getWebElement().getDriver().findElement(by.css('*[data-label="status"]')).getText()).toContain('Default');
var status = element(by.xpath('//tr[td[.="ServerA3"]]/td[#data-label="Status"]'))
.getAttribute('innerText');
expect(status).toEqual('Default')

spring mvc and freemarker - how to post a form ?

I am unsure about doing simple crud operation with spring and freemarker.This is what I tried to do.
springTag.ftl
<!DOCTYPE html>
<html xmlns:sec="http://www.springframework.org/security/tags" >
<head>
......
<#import "/spring.ftl" as spring />
..........
<head>
......
</head>
<body>
<#fragment.header/>
<form action="/listController/springTag" method="post" >
<#spring.bind "student" />
<table>
<tr>
<td>Name:</td>
<td><input path="student.name" /></td>
</tr>
<tr>
<td>Age:</td>
<td><input path="student.age" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form>
........................
</body>
How do I get the values in controller ? I have specified the model attribute as student . I am a newbee here . Can someone help ?
I found the answer.
<form action="/listController/springTag" method="post" >
<#spring.bind path= "student" />
<table>
<tr>
<td>Name:</td>
<td> <#spring.formInput "student.name" /> </td>
</tr>
<tr>
<td>Age:</td>
<td><#spring.formInput "student.age" />
<#spring.showErrors "student.age","error" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form>
This was the change I made.

To Get Text From A Locater Using Selenium IDE

<br>
<br>
To add new COT click on "Add New COT"
<div class="stepandbutton">
<div class="globalbuttoncell">
<a class="buttonlink blockpage" onclick="javascript:addnewcot();" href="#">Add New COT</a>
</div>
</div>
<input id="ComingFromForm" type="hidden" value="ComingFromForm" name="ComingFromForm">
<input id="priorCOT" type="hidden" value="" name="priorCOT">
<input id="rtncode" type="hidden" value="false" name="rtncode">
<input id="refresh" type="hidden" value="NO" name="refresh">
<input id="PDate" type="hidden" value="" name="PDate">
<table>
<thead>
<tr>
<th align="center"> *Trade Class</th>
<th align="center">*Description</th>
<th>Category </th>
<th>Exclude from AMP</th>
<th>Exclude from AMP 5i</th>
<th>Exclude from ASP</th>
<th>Exclude from BP</th>
<th>Exclude from NFAMP </th>
<th>Exclude from Texas </th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td align="center">
<input id="COT" class="data" type="text" value="" style="width:100px;" name="COT">
</td>
<td align="center">
<input id="Desc" class="data" type="text" value="" style="width:250px;" name="Desc">
</td>
<td align="center">
<select id="COTCategory" class="data small" name="COTCategory">
</td>
<td align="center">
<td align="center">
<td align="center">
<td align="center">
<td align="center">
<td align="center">
</tr>
</tbody>
</table>
</form>
<br>
<br>
I need to verify only ""To add new COT click on "Add New COT""" which is in the 3rd line is present.I have tried with //br[contains(text(),"To add new COT click on "Add New COT"")]. But it showing error that locator is not found.Please suggest another ways to verify it.
This is ugly but would "work":
<tr>
<td>verifyText</td>
<td>//body</td>
<td>*To add new COT click on "Add New COT"*</td>
</tr>
But as the commenter above mentions you don't want the br element. What you want to locate on is the element that you didn't provide that lives ABOVE the code you attached to. That would be best.