I have a List<Bill> bills. Bill is a bean that has id, amount, date, billDescription.
I want to display a checkboxlist of Bill objects. So I use:
<s:checkboxlist list="bills" name="selectedBills"
listKey="id" listValue="displayLabel"/>
my Bill.getDisplayLabel() prints out: "amount date billDescription"
40.00 5/1/2011 Electric Bill
1005.25 6/12/2012 Gas Bill
Problem is it is not aligned. I want to customize my displayLabel so that the amounts align up, the dates align up, and the billDescription aligns up. It should display as:
[ ] 40.00 5/1/2011 Electric Bill
[ ] 1005.26 6/12/2012 Gas Bill
with a checkbox in front of each. Essentially I want to generate this code:
<table>
<tr>
<td><input type="checkbox" name="selectedBills" value="9" id="selectedBills-1"/></td>
<td style="text-align: right">40.00</td>
<td>5/1/2011</td>
<td>Electric Bill</td>
</tr>
<tr>
<td><input type="checkbox" name="selectedBills" value="9" id="selectedBills-2"/></td>
<td style="text-align: right">1005.26</td>
<td>6/12/2012</td>
<td>Gas Bill</td>
</tr>
</table>
How do I do this? The first column should have the checkbox, but the last 3 columns are 3 different parts of the label. I tried putting in the <td> code inside my Bill.getDisplayLabel() but struts escapes it so that the actual <td> tags show up!
Any ideas will be appreciated.
updated: I already know how to vertically display the checkboxes by customizing the freemarker templates.
How about using struts iterator? I haven't tested this code properly. But I hope it could give you some idea :
<table>
<s:iterator value="bills" var="bill">
<tr>
<td><input type="checkbox" name="selectedBills" value="${bill.id}" id="selectedBills-2"/></td>
<td style="text-align: right">${bill.amount}</td>
<td>${bill.date}</td>
<td>${bill.description}/td>
</tr>
</s:iterator>
</table>
This is what I ended up using in the end:
<s:iterator value="bills" var="bill" status="rowstatus">
<tr>
<td>
<input type="checkbox" name="selectedBills" value="${bill.id}"
id="selectedBills-${rowstatus.index}" />
</td>
<td style="text-align: right">${bill.amount}</td>
<td >${bill.serviceDate}</td>
<td>${bill.label}</td>
</tr>
</s:iterator>
and this works. The problem with this is, if I have other fields on the JSP that fails validation, this will not work. I'll have to put in additional jstl to make checked="checked" at the end of the <input type="checkbox" ...>
Related
I am working on a Java-Project with html/ftl and so on...
I have a ftl file with a list like this:
<table id="availableHOs">
<tr>
<th>#</th>
<th>Street</th>
<th>Town</th>
<th>Capacity</th>
</tr>
<#list availableOffers as ho>
<tr>
<td>${ho.id}</td>
<td>${ho.addressData.street}</td>
<td>${ho.addressData.town}</td>
<td>${ho.capacity}</td>
</tr>
</#list>
</table>
(That is a template which we got from the university.)
My problem is that the Link in the table (with the title "Make Booking" uses a GET and not a POST. Could somebody help me to change this to a POST?
I only have an example with a submit button and a form:
<form method="POST" action="guestgui?action=projekteSuchenU">
But I dont know how I would use this in the table.
In summary, I would like to have a table / list where I have a link for each line that works with POST
I am abolut new in this topic, so please sorry for my bad explanation!
Thank you!
Add form instead tag 'a':
<table id="availableHOs">
<tr>
<th>#</th>
<th>Street</th>
<th>Town</th>
<th>Capacity</th>
</tr>
<#list availableOffers as ho>
<tr>
<td>
<form method="POST" action="guestgui?action=selectHolidayOffer&hid=${ho.id}">
<input type="submit" value="${ho.id}"/>
</form>
</td>
<td>${ho.addressData.street}</td>
<td>${ho.addressData.town}</td>
<td>${ho.capacity}</td>
</tr>
</#list>
</table>
There are 2 tables here:
The table below is using purely container to display populate the tables from database whereas the one above is using datatable.
However i wish to duplicate the last column of displaying a icon menu for edit and delete actions which is contained inside actions.jsp inside the table above.
This is my partial code in view.jsp displaying the datatables.
<%
List<Guestbook> guestbookList = GuestbookLocalServiceUtil.getGuestbooks(scopeGroupId);
request.setAttribute("guestbookList", guestbookList);
%>
<table id="gbdb" class="table table-bordered table-striped" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<c:forEach items="${guestbookList}" var="guestbook">
<tr>
<td>${guestbook.name}</td>
<td>${guestbook.status}</td>
<td><jsp:include page="${actions.jsp}" flush="true" /></td>
</tr>
</c:forEach>
</tbody>
</table>
However as you can see my function of diplaying actions.jsp is not similar to the method for using container where i can just referenced the path using
<td> <liferay-ui:search-container-column-jsp
align="right"
path="/guestbookadminportlet/guestbook_actions.jsp" /></td>
Please help me with the correct way of displaying by referencing to actions.jsp
You should not include whole jsp as an action column if using jQuery data-table,
Let's assume you need to add Delete book action so your td should be replace by following code.
<td>
<portlet:actionURL name="<%=DELETE_BOOK%>" var="deleteBookUrl">
<portlet:param name="bookId" value="${book.id}"/>
</portlet:actionURL>
<input type="button" onclick="location.href='${deleteBookUrl}'" value="Delete"/>
</td>
Hope this will help you.
I want to find and compare the heading in the table. Then click on the delete button that in the next 3 rows of the heading.
Example: Lets say a given input is Heading 2. I want to search Heading 2 and see if it exists then click on the delete button that is associated with 'Heading 2' (like 3-4 rows after).
So far this is the code that i came close to. The only problem is that it always click the first selection instead of where i want it to go.
String HeadingName = "Heading 2"
driver.findElement(By.xpath("//tr[contains(.,'" + HeadingName + "')]/tr[position()=4]/td[2]/div/a[2]")).click();
This is what the table and it's code looks like.
Heading 1
Name: Joe
Gender: Male
Options: Update | Delete
Heading 2
Name: Jenny
Gender: Female
Options: Update | Delete
<table>
<tbody>
<tr>
<th class="st-head-row" colspan="2">Heading 1</th>
</tr>
<tr class="even">
<td class="st-key">Name:</td>
<td class="st-val">Joe</td>
</tr>
<tr class="even">
<td class="st-key">Gender:</td>
<td class="st-val">Male</td>
</tr>
<tr class="even last-row">
<td class="st-key">Options:</td>
<td class="st-val">
<div style="white-space:nowrap;">
<a id="save" href="linkaddress">save</a>
|
<a id="delete" href="linkaddress">delete</a>
</div>
</td>
</tr>
<tr>
<th class="st-head-row" colspan="2">Heading 2</th>
</tr>
<tr class="even">
<td class="st-key">Name:</td>
<td class="st-val">Jenny</td>
</tr>
<tr class="even">
<td class="st-key">Gender:</td>
<td class="st-val">female</td>
</tr>
<tr class="even last-row">
<td class="st-key">Options:</td>
<td class="st-val">
<div style="white-space:nowrap;">
<a id="save" href="linkaddress">save</a>
|
<a id="delete" href="linkaddress">delete</a>
</div>
</td>
</tr>
</tbody>
</table>
Try this code , hope it will help you.
driver.findElement(By.xpath("//tr/th[contains(text(),'" + HeadingName + "')]//following::tr[3]/td[2]/div/a[2]")).click();
Thanks
Try next code with xpath
String headingName = "Heading 2";
driver.findElement(By.xpath("//th[text()='"+ headingName +"']/parent::tr/following-sibling::tr[#class='even last-row']/td[#class='st-val']/div/a[#id='delete']")).click();
If it works, for detailedinfo how this xpath is created look here - http://www.w3schools.com/xpath/xpath_axes.asp
I'd try and keep the XPath a bit more "semantic", e.g.
//tr[th = 'Heading 2']/following-sibling::tr[starts-with(td[1], 'Options')][1]//a[. = 'delete']
Here I'm looking specifically for the "delete" link in the next "Options" row, rather than something more fragile like "the second link in the next-but-two row".
I actually made an answer that surprisingly worked for me.
dUtil.findElement(By.xpath("//tr/th[contains(text(),'" + headingName + "')]/../following::tr[3]/td[2]/div/a[2]")).click();
I got every condition I wanted.
Searches for the heading that is similar to the given input heading
Clicks the link 'Delete' that is 3 rows bellow the searched element
Should work even if there are more than one batch of rows (batch meaning from heading to delete)
The batch doesn't have to be in order.
I am having some problems currently trying to untick checkboxes in an iframe. The situation is it is currently possible to set some checkboxes to default ticked and some not. I need 1 specific checkbox ticked, so the sensible thing to do is run a loop that iterates through all the checkboxes and unchecks them all.
Here is where I am running into issues. I will post a sample of the HTML that the checkboxes are contained in. (This isn't mine so I can't edit the HTML unfortunately).
This is how the example looks in a situation where there are 3 different types of checkbox in the iframe.
<fieldset id="testing">
<legend>testing</legend>
<table>
<tbody>
<tr>
<td class="EXAMPLE">
<table id="CHECKBOXTYPE1">
<tbody>
<tr>
<td style="vertical-align:top;white-space:nowrap;" title="">
<input id="CHECKBOXTYPE1-01" type="checkbox" value="on" onclick="DOES STUFF;"/>
</td>
<td style="vertical-align:top;white-space:nowrap;" title="">TITLE1</td>
</tr>
<tr>
<td/>
<td id="CHECKBOXTYPE2-01" style="display:none;white-space:nowrap;vertical-align:top;padding:0px;">
<table>
<tbody>
<tr>
<td style="vertical-align:top;" colspan="3">
<select id="field" style="width:100%;">
<option value="1">STUFF1 </option>
<option value="2">STUFF2 </option>
<option value="3">STUFF3 </option>
<option value="4">STUFF4 </option>
</select>
</td>
<td style="vertical-align:bottom;padding-left:6px;" rowspan="2">
<textarea id="CHECKBOXTYPE2-01-COMMENTS" cols="50" rows="2" style="margin:0px;height:50px;" type="text" onclick="DOES STUFF">Please Insert Notes...</textarea>
</td>
</tr>
<tr>
<td style="vertical-align:bottom;">
<input type="CHECKBOXTYPE2-01-BUTTON" onclick="DOES STUFF" value="<" style="height:100%;width:32px;"/>
</td>
<td style="vertical-align:bottom;">
<input id="CHECKBOXTYPE2-01-INPUT" type="input" readonly="" style="width:112px;"/>
</td>
<td style="vertical-align:bottom;">
<input type="CHECKBOXTYPE2-01-BUTTON" onclick="DOES STUFF" style="width:32px;height:100%;" value=">"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="field_label">
<table id="CHECKBOXTYPE3">
<tbody>
<tr>
<td style="vertical-align:top;">
<input id="CHECKBOXTYPE3-01" type="checkbox" title="" onclick="DOES STUFF"/>
</td>
<td style="vertical-align:top;" title="">CHECKBOX NAME</td>
<td style="vertical-align:top;">
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
The code I have attempted to iterate is
try{
for(int i=0; i < 30; i++){
WebElement relCheckBoxes = driver.findElement(By.xpath("html/body/div[3]/fieldset/table/tbody/tr[i]/td/table/tbody/tr/td[1]"));
if(relCheckBoxes.isSelected()){
relCheckBoxes.click();
}
}
}
catch(Exception e){
System.out.printf("didn't work");
}
Obviously this is not the most optimised piece of code, but right now I'm just struggling to find something that works :\ I just want to run through the checkboxes, turn off all of them, then turn on the one that I need after.
Thank you.
If you want to uncheck all the checkboxes use the following code. It is much efficient!
//Get the complex table
WebElement mainTable = driver.findElement(By.xpath("html/body/div[3]/fieldset/table"));
//Find all the input tags inside the mainTable and save it to a list
List<WebElement> checkBoxes = mainTable.findElements(By.tagName("input"));
//iterate through the list of checkboxes and if checked, uncheck them
for (WebElement checkbox : checkBoxes) {
if (checkbox.isSelected()) {
checkbox.click();
}
}
I dont see any frame inside your code. If there is a frame use the below code 1st
//switch to the frame
driver.switchTo().frame("framename/index");
Hope this helps you :)
There are a couple of problems here:
1) Your XPath is incorrect. You have:
"html/body/div[3]/fieldset/table/tbody/tr[i]/td/table/tbody/tr/td[1]"
Instead, it should be:
"html/body/div[3]/fieldset/table/tbody/tr[" + i + "]/td/table/tbody/tr/td[1]"
Otherwise, you're just looking for a table row with a non-numerical index 30 times!
2) XPath indices are 1-based rather than 0-based (crazy, I know). Since your loop starts with i=0, it starts off by trying to find the non-existent zeroth element. findElement throws an exception when it cannot locate an element that matches the search criterion, so the loop ends immediately. Try starting the loop with i=1 instead.
I have two list on my request on jsp. First one is productGroupName, and the second is products.
Now, I show these like below.
<html:form action="/priceOrder"> <table width="100%" id="tableStyle" style="font: message-box;padding: 20px;">
<logic:iterate id="productGroups" name="productGroup">
<tr>
<td>
<h3 style="background-color: #720D00; color: white;"><bean:write
name="productGroups" property="prodGroupName" /></h3>
<table width="100%" id="tableStyle" style="font: message-box; color: white; padding: 20px; background: #F15A00;">
<tr>
<td width="200px"><strong>Product Name</strong></td>
<td width="100px"><strong>How Many</strong></td>
<td><strong>Info</strong></td>
</tr>
<logic:iterate id="product" name="products">
<tr>
<c:if test="${(productGroups.prodGroupID) == (product.prodGroupID)}">
<td>
<html:checkbox property="productChecked" ><bean:write name="product" property="prodName"/></html:checkbox> <br />
</td>
<td><html:text property="quantity" styleId="check" size="5"/></td>
<td><bean:write name="product" property="prodDesc" /></td>
</c:if>
</tr>
</logic:iterate>
</table>
</td>
</tr>
</logic:iterate>
<tr align="center" style="background-color: #F15A00;"><td height="50px">
<html:submit styleId="buton" property="method"><bean:message key="button.order" /></html:submit>
</td></tr>
<tr><td></td></tr>
</table></html:form>
As you see firstly I iterate productGroupNames, showing if productID is equal to productGroupID under productGroupName. But I have a problem on getting check box and quantity info. I need which product is checked and how many that is wanted.
Instead of doing a form submit directly, submit it through a JS function. In your JS function, since you're iterating your list and giving the checkbox and text field the same name, you'll get an array with the same name.
That is you'll get an array of the IDs. You can get the index of the selected checkbox, get the quantity, get the corresponding list element and populate separate hidden form variables with the value. Then submit it.
An alternative approach would be to have a hidden variable associated with each checkbox which provides some mapping between the list and the checkbox.
I don't do Struts, but their documentation at least says that you need the <html:multibox> for this.