Getting table value from view to controller - grails

I have a domain class, Report, with a referenced child class, prompt.
One the edit Report page you are allowed to reorder the order of prompts in a table. Then when the user goes to run the report, on that page the prompts are in said order.
The table on the Report edit.gsp page uses some jQuery to allow drag and dropping of the row, and it updates the display order number, but only on the UI side, nothing is going back to the database yet.
I would like to be able to pass this new order back to my update command, but cannot figure out how to grab the table row data for the life of me.
When searching almost all of the results are how to get data from the controller to the view, not vice-versa.
Here is the snippet of table code
<table id="prompts">
<thead>
<tr>
<th>${message(code: 'prompt.name.label', default: 'Name')}</th>
<th>${message(code: 'prompt.description.label', default: 'Description')}</th>
<th>${message(code: 'prompt.required.label', default: 'Required')}</th>
<th>${message(code: 'prompt.displaySeqno.label', default: 'Display Order')}</th>
</tr>
</thead>
<tbody>
<g:each in="${reportInstance.prompts.sort{it.displaySeqno}}" status="i" var="prompt">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}" onclick='window.location = "${createLink(controller: "prompt", action: "edit", id: prompt.id)}"'>
<td>${fieldValue(bean: prompt, field: "name")}</td>
<td>${fieldValue(bean: prompt, field: "description")}</td>
<td>${prompt.required}</td>
<td class="displaySeqno">${prompt.displaySeqno}</td>
</tr>
</g:each>
</tbody>
</table>
And then in the controller, I tried
params.list('displaySeqno')
But it would just return an empty array.
How can I get the value of the displaySeqno from within my controller class?
Thanks.

This is one of those time (which happens a lot) where a fundamental understanding of how HTTP / Java EE works would allow you to solve your problem very easily. Forms or no forms, you have to pass a value into the request that goes to the server for it to end up on the server. How is this
<td class="displaySeqno">${prompt.displaySeqno}</td>
ever going to get to the server, form or no form? The answer is, it is not. Assuming a typical form post you would need to store the value in a hidden field
<input type="hidden" name="displaySeqno" value="${prompt.displaySeqno}" />
Then it would make it to the server. If you're processing with Ajax of some sort, you would need to pass it in as a parameter via the API. Assuming jQuery, for example:
pseudo code ahead:
var params = $('#youFormId').serialize();
$.post('some/url/to/post/to', params, function(data) {
});
Bottom line is, if you want to pass something to the server, you have to provide the means for that to happen.

Related

Submit cell data from table in thymeleaf template

I have following code snippet:
<table class="table">
<thead>
<tr>
<th>Type</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<tr th:if="${list.isEmpty()}">
<td colspan="2">No Media Available</td>
</tr>
<tr th:each="media : ${list}">
<form th:action="#{/pages}" method="post">
<td><span th:text="${media.getType()}">Type</span></td>
<td><span th:text="${media.getTitle()}">Title</span></td>
<td><input name="submit" type="submit" value="add"/></td>
</form>
</tr>
</tbody>
Now to my question: How can I submit the content from the rows?
Another question: Is my approach to creating a form for each row makes sense at all?
If you want to have user-entered data sent to the server, then replace this:
<td><span th:text="${media.getTitle()}">Title</span></td>
with this:
<td><input name="title" th:value="${media.title}"></td>
Assuming the ${media.title} evaluates to "War and Peace" This will use the name field to submit data as title=War and Peace (with URL encoding for the spaces in the title: War%20and%20Peace).
Note the use of ${media.title} instead of ${media.getTitle()}. You should be able to refer to the field name, rather than the get method. Thymeleaf will use the getFoo() method for a field called foo, based on naming conventions.
There are other approaches, for example:
use a visible input field, but styled to look and behave like regular text (cannot be edited, and has no surrounding box).
use JavaScript to replace the default form submission process, and read your row data from the vanilla table, without a form - instead, with a button using a click event handler.
If you create one form for the entire table, you're going to get all the table's data submitted at once (arrays of title data, and so on).
Alternatively, if you have one form per table row, you have to consider what happens if a user edits multiple rows of data before hitting submit for one row. All those other unsent changes will potentially be lost.
A common solution is to avoid this problem, by forcing users to update records one at a time: The table does not use forms. Each row's button click opens a new modal dialog containing the data for only that one row (in a form) - which can then be edited and submitted.

AngularDart table data binding not working

In a Chrome Packaged app, using angular.dart, in a component html I have the below table which is dispaying paginated contents of an object list; exp. jobs :
<tbody>
<tr id="{{job.jobID}}" ng-repeat="job in jComp.jobs | pagination:jComp.paginator.instance" ng-model="job" ng-click="jComp.selectJob(job.jobID)">
<td>{{job.jobID}}</td>
<td>
{{job.productID}}<br>
{{job.productDescription}}<br>
</td>
<td>{{job.productType}}</td>
<td><img alt="No thumb" ng-src="{{job.thumbFURL}}"/></td>
<td>{{job.status}}</td>
</tr>
</tbody>
then in my component I am showing a popup modal div to ask user to choose an action. When the user clicks to change the job.status, there is a second layer of confirmation modal, and once confirmed in the component I am finding the job from the jComp.jobs List and updating the status. In side the popup modal the status gets updated but on the table it still shows the old status. And then when I paginate to next page and come back it gets updated. Before page switch it stays the same ? I tried calling scope.apply() after updating the jobs list, but it doesn't help. I like to know what is paginator.goNext() or paginator.goPrev() doing that causes the table list to refresh. Not clear about how the two way data binding working in this scenario. ( pagination is done using angular_pagination package )
I tried using :
<td ng-bind="job.status"/>
instead of:
<td>{{job.status}}</td>
and it fixed this issue. I am not sure why double brackets were not registering the object in the list to the change listeners / watchers. As far as I understand two way binding should be working with {{}} but in this case something was breaking it. It might be a bug in double brackets.

Find and act on links based on value in a cell with Mechanize in Rails

I am trying to act on links found in a specific row in an HTML table.
The table has a column for a date and a column for city names which act as links. I need to find row with specific date and then cycle through the links found from the next cell on same row one after the another.
I reach the target page with Mechanize from the previous page (link to page is generated at previous page so direct link is not possible) and I am able to select the said table with this:
agent.page.search("//table[#class='calendar']")
But, after that, I am at a loss how to select the correct row based on the date in Date-column and click each of the links in turn (and naturally do stuff before moving on to the next city).
EDIT
I managed to make some progress. I am now able to get contents of correct cell in correct row IF I hardcode the date in. But I can't figure out how to use variable in place of hardcoded date and I also need to find a way to use just the date and not to include weekday as text in there as well.
agent.page.search("//table[#class='calendar']/tbody/tr/td[#class='date']
[text()='wed 27.8.2014']/following-sibling::td[1]/ul/li")
Example HTML below:
<table class="calendar">
<tr>
<th>Date</th>
<th>City</th>
</tr>
<tr class="odd">
<td class="date">thu 28.8.2014</td>
<td class="city">
<ul>
<li>London</li>
<li>Paris</li>
<li>Berlin</li>
</ul>
</td>
</tr>
<tr class="even">
<td class="date">wed 27.8.2014</td>
<td class="city">
<ul>
<li>London</li>
<li>Paris</li>
<li>Berlin</li>
</ul>
</td>
</table>
All help is greatly appreciated!
With further research I was able to find the answer my self. Of great help was this question and answer Nokogiri: How to select nodes by matching text? about partial matching in Nokogiri.
Following snippet is what works for me now and I am able to proceed.
date = Date.new(2014,8,27)
agent.page.search("//table[#class='calendar']/tbody/tr/td[#class='date']
[contains(text(),
\"#{date.strftime("%e.%-m.%Y")}\")]/following-sibling::td[1]/ul/li")

ExactTarget - How to add dynamic user created content in an Email Template

We have an email currently being created in back end code (C#) and sent through the ExactTarget API. I want to move this into a template in ExactTarget so that we don't have to maintain HTML written in StringBuilder() in C#. The issue is the content of the email is determined by what a user inputs. The user fills out a form of what samples they want then an email is sent to a person to fulfill the order.
So an example would be:
<tr>
<td>Product Number</td>
<td>Quantity</td>
</tr>
<tr>
<td>Product Number</td>
<td>Quantity</td>
</tr>
The maximum number of samples that can be ordered is 16. Is there a way to loop through content posted to ExactTarget to create the correct number of rows instead of hard coding 16 rows into the template and half of them being blank.
Please let me know if I need to be more specific about anything
You try just creating a Partial View as below,
#model IEnumerable<CartItems>
<table>
#foreach(var item in Model)
{
<tr>
<td>#item.Number</td>
<td>#item.Quantity</td>
<tr>
}
</table>
Call it from your C# Code as He suggested Here. Render a view as a string
As jordanm mentioned, here is an example in the ExactTarget documentation that covers this. You pass the custom input as XML during your triggered send and parse it / inject it into the HTML with AMPscript.
http://help.exacttarget.com/en/documentation/exacttarget/content/ampscript/using_ampscript_with_the_web_service_api/passing_content_to_a_triggered_send_message_at_send_time/

Struts2 How to create a table by iterating a list such that each row has a radio button?

I am trying to create a table to display some data using iterator over my list from action class. Each row has the properties of each object in the list.
<table class="TableA" cellpadding="5px" border="1">
<tr class="even">
<th></th>
<th>Col1</th>
<th>Col2</th>
</tr>
<s:iterator value="objectList" status="obj">
<tr
class="<s:if test="#obj.odd == true ">odd</s:if><s:else>even</s:else>">
<td></td>
<td><s:property value="objId" /></td>
<td><s:property value="objValue" /></td>
</tr>
</s:iterator>
I need a radio button in first cell of every row so that a row can be selected for edition or deletion.
I know this can be done using <input type="radio" ...>. But I need to use struts2's radio tag. But problem using this tag is that it generates a row for every radio tag (see here).
Is it possible ? If yes then how ?
I think the following syntax will be better for you as you want to select each row with radio button
<s:radio theme="simple" name="object_radio" list="#{objId:objId}"/>
This way you wont need the objId column too
This syntax will submit objId as the value of selected radio button.You can modify the syntax to change the display property of the radio button or make it blank
anu, your answer helped me a lot.
Also this link was of great help for me:
http://struts.apache.org/2.0.14/docs/how-do-i-render-a-single-radio-button.html
What I needed was a table where two of the columns were radio buttons, but each column was an independent group. Furthermore I did not want to show the key as the label/value for each radio button, since that information was displayed in the other columns. My rows were built iterating over a hashmap, where the key of the hashmap was the radio button value.
<s:iterator value="myHashMap">
<tr>
<td><s:radio name="selectedRadioValueFirstColumn" list="#{key:''}"/></td>
<td><s:radio name="selectedRadioValueSecondColumn" list="#{key:''}"/></td>
<%--....... (my other columns) .... --%>
<tr>
So I am setting the option value as the key of the hashmap, and the selected value will be stored in the string property "selectedRadioValueFirstColumn" and "selectedRadioValueSecondColumn".
Kaillash:
if i understand your requirements completely all you mean to say that when page getting displayed with struts2 radio button struts2 is automatically creating a row for each radio button.
if this is the case than that is default struts2 functionality,struts2 operates on template theme and the default theme (xhtml) will automatically generate some HTML markup for each struts2 tag.
if you want struts2 tags not to generate any extra markup use the theme as simple.it can be done per tag basis something like this
<s:radio key="personBean.gender" list="genders" theme="simple" />
or you can also set theme on the page basis..
create struts2.properties file in the root and put the following entry
struts.ui.theme=simple
i hope this will help you

Resources