Tapestry5 form in a table with ajax - ajax

I'm having a problem with tapestry5. I would like to make an ajax forms in a loop like this one. The problem is that even when I don't put the loop and only make a form inside a table with ajax, tapestry give me this exception:
"Forms require that the request method be POST and that the t:formdata query parameter have values".
<table>
<t:zone t:id="zone" id="zone">
<t:form zone="^">
<label>email</label>
<intput t:type="TextField" t:id="email" value="profile.email"/>
<input t:type="submit" t:id="save" value="Save"/>
</t:form>
</t:zone>
</table>
The most strange thing is when I put the table inside the form, it works fine, but I need put it out. Someone knows what's happening?

Though I'm not completely sure why this exception is happening, you can solve it by using the AjaxFormLoop in stead. Check out the example on the Jumpstart page.

Related

Struts 2 XML form validation breaks when new element that does not need validation is added

I am facing an issue that is really hard to debug. I have a JSP page that has some form elements on it that submit to a Struts2 action. I also have a XML form validation file to perform some validation on the submitted fields. The file has the naming convention 'actionName-validation.xml'
This works fine, but when I add a drop down box, outside of the form, the validation now fails. Instead it redirects to a blank page and my breakpoint in my action class is not hit.
Is there a way to turn on some kind of debugging or logging for the validation? Why would adding a tag outside of a form cause this to happen?
Here is the code on the JSP page:
<s:select id="dataSource" name="selectedDataSource" theme="simple" listValue="top"
headerKey="" headerValue="Choose Data" list="dataSources" size="1" />
<div id="forms">
<s:form method="post" action="MyAction" theme="simple">
<p>
<label class="input" for="name"
<span style="color:red;">*</span>
<span>Name</span><br>
<s:textfield theme="simple" name="name" maxlength="11" size="11" />
<br>
<s:fielderror theme="plain"><s:param value="'name'" /</s:fielderror></label>
</p>
<s:submit value="Create New" theme="simple" cssStyle="display: block; clear: left;"/>
</s:form>
</div>
If I remove the <s:select> tag, it works.
Any help would be greatly appreciated it.
EDIT2: I found the problem. I needed a get method for the list that is used to populate the select drop down inside the action that the form submits to.
I had one for the action that initially is called for the page, but when the validation fails and it re-loads that page from the form action class, it tries to re-populate the select drop down and needs a getter there. I feel silly for not finding that sooner. Would be nice if there were some type of logging or messaging of these types of issues.
thanks.
The error you are encountering is not a validation error (handled by the Validation Interceptor), but an error occurred when setting the parameters (raised by the Parameters Interceptor) and for which the Conversion Error Interceptor added a fieldError, which you are not seeing because
your INPUT result lands on a blank page and
you are using theme="simple" on the textfield, which forces you to add <s:fielderror fieldName="dataSource" /> to show it (or <s:fielderror /> to show them all).
Read how the INPUT result works, set your page as the INPUT page, print the errors, then you will discover the problem, that is most likely related to the fact that you've not specified a listKey attribute in your select, that is sending the description instead of the code of the datasource to selectedDataSource, which is probably an Integer.
I found the problem. I needed a get method for the list that is used to populate the select drop down inside the action that the form submits to.
I had one for the action that initially is called for the page, but when the validation fails and it re-loads that page from the form action class, it tries to re-populate the select drop down and needs a getter there. I feel silly for not finding that sooner. Would be nice if there were some type of logging or messaging of these types of issues.

How to recognaize which ajax form it is in Django?

I have view which takes care of all the Ajax submits from the client side. And to differentiate them by I uses different submit button names such as this one
<input type="submit" value="Send" name="send_message">
Suggested from this question.
The only problem is that from the view side it doesn't seems to carry the name to the server side so I cannot use the following if-statement
if 'send_message' in request.POST:
It works if I send it normally with page fresh. But I want to use it with Ajax.
I came up with a hack that you can add this name with jQuery. Simply by after serializing() your data you then concatenate the name attribute by data += "&send_message"
Then the if statement will work. But it doesn't seems so clean. So I wonder if there's a better way to handle this? Or should I make different views to handle the different Ajax calls I have?
You really should post each form to a different URL.
If not, you could add a hidden input with the name of the form as the value.
<input name="form_name" type="hidden" value="form_1" />
views.py:
form_name = request.POST['form_name']

Grails formRemote

I have DateFrom and DateTo fields. I want to submit those data to action which will do some business logic but nothing changes on the original GSP, and nothing is updated. How do I manage this? I've tried this:
<g:formRemote name="formName" url="[action: 'myAction']">
Everything is fine but except my action tries to render myAction.jsp.
This is a great place to read how it works.
Basically you need to specify what controller as well:
<g:formRemote name="formName" update="updateMe" url="[controller: 'controller', action:'myAction']">
The "updateMe" is the id of an html-object, preferably div, that you want to alter after submit (but it's not mandatory). It also uses the actionName.gsp to "supply" the answer, this is why you need to have this page create as well.
Remote forms are a bit tricky in the beginning, but they're super simple once you get a hang of it!
This is how I did it:
GSP:
<g:formRemote name="formName" update="updateMe" url="[controller: 'controller', action:'myAction']">
<div id="updateMe">
<g:render template="updateTemplate"/>
</div>
Action:
...
render template:"updateTemplate"
updateTemlate and updateMe div are both empty.
If you have better solution please tell me.
you can use remoteFunction
you need to write submit button inside form and then after it will fire action and some changes shown into div..

Requests with AJAX in a portlet (Liferay)

I have an issue with my portlet and I don't know exactly how to solve it.
My portlet adds or retrieves info from liferay's DB by inserting a name in 2 text fields.
After pressing the submit button, I see the response from the server, a JSON response like this:
{"id":301,"name":"Pepo"}
If a user correctly inserted or if the search throws a good result. I have to go back in the browser to see the portal again.
How can I use AJAX to pass the following URL dynamically from the portlet to the server without refreshing the page afterwards?
http://localhost:8080/c/portal/json_service?serviceClassName=com.liferay.test.service.TrabajadorServiceUtil&serviceMethodName=findByName&servletContextName=TrabajadorPlugin-portlet&serviceParameters=[param1]&param1=NameInsertedByUser
Now I'm using the <form> tag like this:
<%
//Shows "New Employee" in the text field when portlet is rendered, or gets the user input and pass it as a param to the URL
PortletPreferences prefs = renderRequest.getPreferences();
String employee = (String)prefs.getValue("name", "New Employee");
%>
<form id="postForm" method="post" action="http://localhost:8080/c/portal/json_service">
<input name="serviceClassName" type="hidden" value="com.liferay.test.service.TrabajadorServiceUtil" />
<input name="serviceMethodName" type="hidden" value="create" />
<input name="servletContextName" type="hidden" value="TrabajadorPlugin-portlet" />
<input name="serviceParameters" type="hidden" value="[param]" />
<input name="param" type="text" value="<%=employee%>" />
<input type="submit" value="Submit"/>
</form>
I understand how AJAX works, but I need some help to create my function in order to achieve the URL to be correctly sent to the server for both GET and POST requests. This is my first try with AJAX.
Thank you very much, hope somebody understands my problem and could help me.
First of all, I see no point at all to use JSON services here. Just write ordinary portlet with MVC Controller, and in controller write action handling for corresponding actions (storing data, searching etc).
In controller you can directly call static methods like create or findByName from java class com.liferay.test.service.TrabajadorServiceUtil (or TrabajadorLocalServiceUtil) - that's how people usually do it.
If for some reason you really must use JSON, you should of course do these actions with AJAX calls - and render results using JavaScript.
Updating after question update:
The easiest and most correct way to send AJAX requests in Liferay would be to use AlloyUI JS framework that's a part of Liferay. You can read more on how to send AJAX requests with it here: http://www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/4733559
In order to accomplish your goal I'd suggest implementing processAction(ActionRequest actRequest, ActionResponse actResponse) method in your controller/portlet.
In order to actually send data to it you'll have to have actionURL, which you can create using for example portlet:actionURL tag:
<portlet:actionURL /> or with Java code PortletURL actionUrl = portletResponse.createActionURL();
Then just submit your form using POST to this URL, and in actionRequest you'll have your parameters.

Firefox 3.5.2 Refresh(F5) causes Highlighted Form value to get copied to next field

I am having a strange issue in Firefox 3.5.2 with F5 refresh.
Basically, when I focus on an input field and hit f5 the contents of that input field gets copied to the next form field after the F5 refresh.
But, if you inspect the HTML source code, the values are correctly loaded.
I am not having this issue in IE8 or Safari 4.0.3.
The problem does not occur if I do a hard refresh or run window.location.refresh(true).
After F5 Refresh: http://i805.photobucket.com/albums/yy339/abepark/after.jpg
Here's an overview of what's going on.
I believe the thing you should look into is the autocomplete attribute,
you should set it to off on the input box. However be careful since this will trigger two effects.
When you refresh the page it won't remember the old values
The default dropdown of the already used values on that input box will also be disabled.
If you want to keep the second behavior you should set the autocomplete attribute back to on with JS.
Browsers can remember form field contents over a refresh. This can really throw your scripting off if it is relying on the initial value of a field matching what's in the HTML. You could try to prevent it by calling form.reset() at the start.
Different browsers have different strategies for detecting when a form or a field is the same as in the previous page. If you have clashing names, or names that change on reload, it is very possible to end up confusing them. Would have to see some code to work it out for sure.
In the backend, I am using ASP.NET MVC 1.0 with the Spark View engine. When I examine the source code after an F5 refresh in Firefox 3.5.2, the page renders correctly; however, if you look at the page visually the adjacent form field field gets populated with the value from the previous field.
I included enough code so you can just get an idea of what I'm trying to do.
Again, the rendering is fine and the final view/HTML code is fine. It's what I see on the screen that is incorrect. I am using hidden vars; but the issue occurred before using it as well.
Note in the code below, I have 2 distinct ID fields: "date_{projectTask.ProjectTaskId}" and "finishDate_{projectTask.ProjectTaskId}, which gets renders to something like "date_1" and "finishDate_2".
<table>
<for each="ProjectTask projectTask in projectTasksByProjectPhase">
<input type="hidden" value="${projectTask.ProjectTaskId}" />
<tr>
<td class="date">
<div class="box">
<div class="datefield">
<input type="text" id="date_${projectTask.ProjectTaskId}" value="${startDate}" /><button type="button" id="show_${projectTask.ProjectTaskId}" title="Show Calendar"><img src="~/Content/yui/assets/calbtn.gif" width="18" height="18" alt="Calendar" ></button>
</div>
</div>
</td>
<td>
<div class="box">
<div class="datefield">
<input type="text" id="finishDate_${projectTask.ProjectTaskId}" value="${finishDate}" /><button type="button" id="finishShow_${projectTask.ProjectTaskId}" title="Show Calendar"><img src="~/Content/yui/assets/calbtn.gif" width="18" height="18" alt="Calendar" ></button>
</div>
</div>
</td>
</tr>
</for>
</table>
FYI: ${} are used to output variables in the Spark View engine.
I am also using the YUI 2.7 Connection to make Ajax calls to update the datebase for "change" and "enter/tab key press" events. I am able to verify that the AJAX calls are made correctly and the form field values are still valid.
The problem occurs when I just do a F5 refresh; for some reason, the "finishDate_1" gets populated with the value from "date_1".
This problem occurs just by clicking on "date_1" and hitting F5; so, the adjacent field just gets populated even if there are no AJAX calls.
Here's the Javascript code I call towards the end of the body"
YAHOO.util.Event.onDOMReady(
function() {
var idList = YAHOO.util.Dom.getElementsBy(function (el) { return (el.type == 'hidden'); }, 'input');
len = idList.length;
var startDatePickers = new Array();
var finishDatePickers = new Array();
for (var i = 0; i < len; i++) {
var id = idList[i].value
startDatePickers[i] = new DatePicker("date_" + id, "show_" + id, "cal_" + id);
startDatePickers[i].valueChanged.subscribe(updateDate, 'S');
finishDatePickers[i] = new DatePicker("finishDate_" + id, "finishShow_" + id, "finishCal_" + id);
finishDatePickers[i].valueChanged.subscribe(updateDate, 'F');
}
}
}
The form field gets copied over before any Javascript code is processed because I call the Javascript code towards the end of the body after all HTML is rendered. So, I'm guessing it's a refresh issue in Firefox? What do you guys think?
As you can see above, I created my own calender date picker objects which allows you to either enter the date in the text manually or by clicking on a button to view the calendar and select a date. Once you enter or select the date, an AJAX call will be made to update the datebase in the back end.
Thanks everybody for the quick responses.
#Anonymous: whoever you are, you are awesome!
#bobince: thanks for the feedback as well.
I added a dummy form tag with the attribute autocomplete="off" and that solved the problem!
I was scratching my head because I didn't get this issue in Safari 4.0.3 or Internet Explorer 8.
<form action="" autcomplete="off">
<!-- my code -->
</form>
The values were loading correctly in the back end (ASP.NET MVC 1.0/Spark View engine) and the HTML source code reflected this, but the input field values were not getting populated correctly. I was using the YUI Connection Manager and Javascript to support edit-in-place and the date pickers.
I tried changing the XHR call to a GET call instead of POST and the same issue was happening.
Anyway, the problem was that the Firefox was not setting the correct values for the input fields for F5 refreshes.
Again, thanks so much! You guys rock!
All element id's must be unique, if two elements have same id's then that could be reason why Firefox inserts same values to elments that didn't orginally have those values entered.
I had a similar problem related to my question at Input control shows incorrect value, even 'though inspect element shows the right value is there
The problem occurred for me in Firefox, but not Chrome, for some but not all controls on the form, and when I pressed F5, but not ctrl-F5.
The "dummy form" seems to have resolved it for me.

Resources