How can update an <input/> field in tapestry by AJAX request - ajax

I have a project developed with tapestry 5.
I need to update a input field (which is inside a form) using an AJAX request.
Page.tml is something like this:
<form>
<t:zone t:id="myZone">
<input type="text" t:type="TextField" t:value="product.code"/>
</t:zone>
<t:actionlink t:id="generateCode" zone="myZone">Generate</t:actionlink>
</form>
And Page.java
Object onActionFromGenerateCode() {
return myZone.body();
}
When click in "Generate" link, tapestry throws an exception. Don't let me update a zone inside a form:
java.lang.RuntimeException
The component must be enclosed by a Form component.
How can I update this input field?
thanks

Changing pieces of a form via ajax gets tricky as a FormSupport instance must be available on the Environment in the serverside event.
It might be easier to either:
Put the entire form in a zone and refresh the whole form
Execute some javascript from the serverside event
Here's how option 2 could work:
TML
<form>
<input id="productCode" type="text" t:type="TextField" t:value="product.code" />
<!-- note that async is a recent addition to eventlink in tapestry 5.4 -->
<!-- Use a dummy zone for previous versions -->
<t:eventlink event="generateCode" async="true">Generate</t:eventlink>
</form>
Java
#Inject JavaScriptSupport jss
void onGenerateCode() {
String productCode = generateProductCode();
jss.addScript("$('#productCode').val('%s');", productCode); // assuming jquery
}
Note, it is possible to dynamically change a form via ajax, it's just tricky as I said. Examples include AjaxFormLoop and the FormInjector

Related

Pass data from Thymeleaf template to springboot controller

I have simple web application written using Springboot and Thymeleaf templates. Report controller receives the data from form and builds the TestPlanReportResponse object which is added as model attribute like this:
#PostMapping("/report")
public String homeSubmit(#ModelAttribute HomeFormInput homeFormInput, Model model, Errors errors) {
final TestPlanReportResponse response = new TestPlanReportResponse(homeFormInput);
model.addAttribute("allData", response);
return "charts";
}
I can work with that data in "charts" thymeleaf template and show the data I need, but I need to send exactly the same object back to controller when button is clicked, but i getting TestPlanReportResponse
object as parameter with nulls set.
#PostMapping("/report/send")
public String sendReport(#ModelAttribute TestPlanReportResponse reportData, Model model) {
//reportData contains just nulls
}
Here is how my button is set in charts template:
<form action="#" th:action="#{/report/send}" th:object="${allData}" method="post">
<button type="submit">Send the report</button>
</form>
So my question is how to send the object back from thymeleaf template? Should i create a hidden input and put there the "allData" object just to send it back? It looks for me like dirty hack. What would be the appropriate way to pass data back? I want to have this app stateless so don't to store the data on a server side.
When I used to work with Spring and Thymeleaf and form, we had the same issue, passing the data back and forth between a form, the template, and different controllers.
And what you suggest is what we did, we used hidden input as dirty as it may look,it was the standard suggested answer, we did not find anything better.
You need to create an input, with a type a value and link it to a field, like this:
<form action="#" th:action="#{/report/send}" th:object="${allData}" method="post">
<input type="hidden" th:value="*{allDataValue1}" th:field="*{allDataField1}" />
//Do this for all your attributes/values that you wish to pass to the controller
<button class="btn btn-info btn-lg btn-block" type="submit">Send the report</button>
</form>
Though, i found this answer, you can try looking into this thread

UWP get form in webviewer returning 'about:blank' rather than form values

We have a mobile app which shows an html page with some javascript in a webviewer.
In this page we have a form. IT looks something like:
<form method="get" action = "" id="mainform">
<input name="EXAMPLE_NAME" id"EXAMPLE_NAME" placeholder="" type="text" maxlength="35"/>
</form>
So far so good. The user is able to view this input and fill it in with data. They then press a button on the xaml page which calls a function that does:
Browser.Eval("submitMainForm()")
In the javascript on the page we have that function, which looks like:
function submitMainForm() {
var x = document.getElementById("mainForm").submit();
}
Back in the C# code we have handlers for the resulting navigation. They look like:
async void OnNavigating(object sender, WebNavigatingEventArgs e)
{
and
void OnNavigated(object sender, WebNavigatedEventArgs e)
{
This works well in iOS and Android. We get the WebNavigatingEventArgs in the handler, and the value from the field that we are showing in the webviewer (inside of mainform) are stored in there.
So, for example, e.Url in the OnNavigating and OnNavigated handlers would look something like:
"file:///storage/emulated/0/Android/data/com.example.exampleapp/files/Example.html?EXAMPLE_NAME=Test"
We parse this string to get the values we care about (Test, in this case), and all is well.
On UWP, however, things work a lot less well. On Navigating is never called at all, and the call to OnNavigated just has "about:blank" stored in its WebNavigateEventArgs url value.
Does anyone know what might be going on here, and/or have a way that I can fix it? I need a way to get the results from my call to the get form as I do in the other 2 platforms, rather than "about:blank". Ideally, I'd also like to get the OnNavigated call, but the important thing is the data.
Thanks for your assistance
For html form submitting, you need add the action url that used to received parameter. For example:
<form id="Myform" action="HomePage.html">
First name:<br>
<input type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br><br>
<input type="submit" value="Submit">
</form>
When you invoke submit, the firstname lastname field will be sended to HomePage.html page. I create HomePage that Build Action is Content in native uwp project.
Please note you could not create html in forms project. Otherwise the webview could get navigate to the right url.
This is code sample please check.

Thymeleaf, Spring nested backing object is not binding the values on form submit

I have a nested object and I'm using it as a model for a form.
public AgeBracketSet implements Serializable{
private String id;
private List<AgeBracket> ageBrackets;
/* Getters and Setters */
}
I have successfully bound all the properties of this object to the form and I can visualize their values when the view state is rendered. Here's a simplified version of how I'm doing it with Thymeleaf. Essentially, I loop through the items of the list and get their attributes.
<form id="bracketForm" role="form" th:action="${flowExecutionUrl}" th:object="${ageBracketSet}" method="post">
<input th:id="'bracketSet_'+*{id}" th:field="*{id}" />
<th:block th:each="bracket,loop : *{ageBrackets}" th:id="'bracket_'+${bracket.id}">
<input th:id="'fromAge_'+${bracket.id}" th:field="*{ageBrackets[__${loop.index}__].fromAge}" />
<input th:id="'toAge_'+${bracket.id}" th:field="*{ageBrackets[__${loop.index}__].toAge}" />
</th:block>
</form>
However, when I make changes in the form and submit it, the model remains unchanged. I have confirmed this by debugging the service that receives the form data. The model does not have the changes made in the form. Am I doing anything wrong here?
I am embarrassed to say I've found the solution. The values simply weren't posted to the webflow for a lack of a 'name' attribute in each input. Using the same dynamically generated ID as a name did the job, and the bindings were correct for each item of the list. Like this:
<input th:id="'fromAge_'+${bracket.id}" th:name="'fromAge_'+${bracket.id}" th:field="*{ageBrackets[__${loop.index}__].fromAge}" />
Thanks to everyone who took the time to read this silly post. I'll be more careful next time ;)

Hidden field "ufprt" being added to Razor Umbraco Form - Why?

I have got a form (below) that is posted to an umbraco surface controller.
#using (Html.BeginUmbracoForm("AddToBasket", "Basket"))
{
<h1>#Model.productSelectionModel.Product.Title - #Model.productSelectionModel.Product.Price.ToString("C")</h1>
<ul>
#foreach (var productOption in Model.productSelectionModel.ProductOptions)
{
<li>#productOption.Option.Title</li>
#Html.DropDownList(productOption.Option.Id.ToString(), productOption.ValuesInOptions.ToSelectList(f => f.OptionValue.OptionValue1,
f => f.Id.ToString(),
"Select"));
}
</ul>
<input type="submit" value="Add To Basket">
}
When I look at the HTML rendered for this form it seems to have added a hidden field called ufprt. Does any one know what this is? Why is it being added, I'm not using it any where ( I don't think I am anyway)
Any ideas?
<input name='ufprt' type='hidden' value='6C01896EF3D5F430F9ED041DD2B0D31F89FA969A085C6F4FDEC3C9D4B906846E7AA80041CEA12573E9F58C1740893B770AAE3319FAA8FA35C89A54D301CFE31B85ADC0D3D9506D208DB068D1257C5F0D5F1B3B90FD59A5C2938EED0A2EB1168AD4573CD5D043D47A8F1AA789E988CC614686B89BE57D35DA8EAAA110044C393F' />
It is to route the form to the correct controller/action method (Umbraco has the ability to route forms via that input value rather than the typical MVC approach of using the URL). I believe this is particular to surface controllers (i.e., it wouldn't apply to a normal controller, API controller, or RenderMvcController).
It is not a CSRF token as another answer indicates. If it were, it would likely have a name of "__RequestVerificationToken" as indicated here: http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-%28csrf%29-attacks
EDIT: This information has been added here: https://github.com/kgiszewski/LearnUmbraco7/blob/a97e85e5ad17e2ba9fc463f02c76885911046b57/Chapter%2006%20-%20Surface%2C%20WebAPI%20and%20RenderMVC%20Controllers/02%20-%20Surface%20Controllers.md#special-routing

ASP MVC 3 is it possible to identify the <input> id in the controller [post] method?

I'm using a so as to edit an object, with an <input type="submit"> for validation
I've also another input, type="button" with an onclick event for the cancel button (with a redirect). However, this use a JS call, which I'd like to avoid.
I'd rather prefer to process the validation or cancel choice within the controller, so as to be NoScript compliant.
So is it possible to retrieve, within the controller post method, the id of the <input> that was clicked in the <form>?
Thanks
You can set the name of your
<input type="submit" name="submitButton" />
Then in your controller:
if(Request["submitButton"] != null) {
// ...
}
I'm not sure if I understand you, but if your cancel button does a redirect, it should end in a GET, and your submit button does a POST, that's how you should difference both request.
Check the [HttpPost] attribute in controller action methods.

Resources