I have a table like this with many numbers, below particular row from this table.
<tr>
<td>5100<td>
<td> Number description<td>
<td>long number description<td>
<td>
<input class="checkbox" type="checkbox" checked="" value="5100" name="id_rola[]">
<td>
<td>
<a href="javascript:documeny.frolazak_5100.submit();">
<b><img src="temp/img/foto.gif"></b>
</a>
<td>
<tr>
Whats i try to do was for this number check checkbox and next click link, but with this i have a problem. Firstly when i do check("5100") this show me unable to find checkbox "5100", and next when i try click link with find(:xpath, "//a[#href="javascript:document.frolazak_5100.submit();]").click , this show me unable to find xpath.
For any suggestion thx.
EDIT: ANSWERS
Check checkbox with particular value:
find(:css, ".checkbox[value='5100']").set(true)
Click on image in link in row:
To do this i wrote:
all('tr').each do |tr|
next unless tr.has_text?('5100')
#href = tr.all('td a')[0][:href]
end
visit #href
But this solution was be sloowly, so first i puts #href and then i could manipulate directly with params in this href and instead using method all simply visit this href. BTW why i dont think about it earlier :)
Related
I have a simple table and I have checkbox inside that table. If checkbox is selected I want to display other features.
My code:
<table>
<tr th:each="obj,iterationStatus : ${objs}">
<td th:text="${obj.name}"></td>
<td><input type="checkbox" name="firstcheckbox"></td>
<td th:if="isChecked">
<!-- do something -->
</td>
</tr>
</table>
How I do this without using javascript and backbean?
In this case you have two options, the first option you don't want but is not a bad option is using Javascript: creating a function called isChecked.
Otherwise, you can know if a checkbox is checked with thymeleaf in the case you are in a form which calls itself. You could do something like if(firstcheckbox != null) and, of course, your checkbox would have a value <input type="checkbox" name="firstcheckbox" value="value">. Finally, you must add as attribute in your model: model.addAttribute("firstCheckbox", firstCheckbox);
Im running into an issue, and I think the issue is with how my page.all is pulling radio button questions in.
So here is the HTML for the table itself (Multiple questions with 5 radio button choices a piece):
<table class="table table-striped table-stuff table-collapsible">
<colgroup>
<thead>
<tbody>
<input id="0_answer_question_id" value="9966" name="response[answers][0][answer_id]" type="hidden">
<tr>
<td class="heading">
<td class="option">
<div class="radio-inline radio-inline--empty">
<input id="question_1_1" value="1" name="response[answers_attributes][0][answer_opinion]" type="radio">
<label for="question_1_1">Strongly Disagree</label>
</div>
</td>
<td class="option">
<td class="option">
<td class="option">
<td class="option">
</tr>
<input id="response_1_question_id" value="9966" name="response[answers_attributes][1][answer_question_id]" type="hidden">
<tr>
<input id="response_1_id" value="<a number>" name="response[answers_attributes][1][id]" type="hidden">
<Same as above repeated 5 times with numbers changed>
</tbody>
</table>
Im using:
page.all('table.table-stuff tbody tr', minimum: 6).each do |row|
row.all("td label").sample.trigger('click')
end
To get each row and select one from it. HOWEVER, I notice "sometimes" a row will not have one selected. My theory is the "heading" (which has a <label> itself is accepting one of the clicks perhaps? (since from my understanding of how page.all works it's grabbing every tbody tr within the table...but is maybe grabbing the heading too? (since it contains a td label?)
Also when a table is named something like table table-striped table-stuff table-collapsible...how can you tell what the actual table "name" is? (I didn't write this website, just doing tests for it). When putting it in the page.all('table.<etc>')?
If the heading td (it's not expanded in your example) also contains a label element (so it would be included in the results of your all call) then you just need to change the CSS selector so it wouldn't be included - something like
row.all("td.option label").sample.trigger('click') # only choose labels contined in tds with the class of 'option'
or
row.all("td:not(.heading) label").sample.trigger('click') # choose labels contained in tds without the class of 'heading'
On your second question about table names, I don't really understand what you're asking. Tables don't have name attributes, they could have an id attribute or a caption containing some text which could then be used to find them with capybara via find(:table, 'id or caption text') or within_table('id or caption text') { code to execute within scope of the table }. Rather, you seem to be talking about the classes on the element which are specified in a CSS selector with '.'. Therefore a CSS selector to match a table element with all the classes you listed would be - 'table.table.table-striped.table-stuff.table-collapsible'
Note: If you're sure there's always only 5 choices you could add the :count option to your find to make sure your selector is only finding those items
row.all("td.option label", count: 5).sample.trigger('click')
I have the following HTML snippet:
<divv id="items">
<trr>
<td>
<p>Cars</p>
<a>Toyota</a>
<a>Opel</a>
<a>Audi</a>
</td>
</tr>
<tr>
<td>
<p>Planes</p>
<a>A320</a>
<a>B787</a>
<a>B767</a>
</td>
</tr>
<div/>
What I want is to create a XPath query so I can retrieve only the Cars.
Currently I am using this: //div[#id='items']/tr/td. But with this I get also the Plane items. I do not know how to test for the 'p' tag.
Anyone can help me ?
Thanks.
//div[#id='items']/tr/td[p='Cars']
The last predicate tests the existence of a <p> child element with Cars text content and thus filters out the <td> with <p>Planes</p>.
If picking the first group is enough, then you can use:
//div[#id='items']/tr/td[1]
I need to update the value of a textField, using a value on the server, based on the value the user chooses in a g:select. In code:
<g:select name="description" from="${momentum.MoneyTransType.prodList}" value="${moneyInstance?.description}"
noSelection="['':'-Select Description-']" onChange="${remoteFunction(action:'setHowMuch', update:[success:'howMuch', failure:'failure'],
params:'\'selection=\' + this.value', options=[asynchronous:false])}"/>
<g:textField id="howMuch" name="howMuch" value="${moneyInstance?.howMuch}"/>
It's not working. If I give the "update:[success:" a div id, all is good, but that's not what I want. I need to allow the user to enter in a free flow description (which I'll have in another textfield), and a free flow amount. I guess I could hide a div and then listen for changes to that div via jQuery, and then update the amount textField. Should I be able to update a textField using the remoteFunction "update" capability or using another grails capability?
Strangely, putting in a temporary 'toHide' div with a jQuery change function isn't working to update the textField, i.e. the following alert, etc, isn't firing:
$('#toHide').change(function() {
alert(" I got changed, value:");
$("#howMuch").text($(this).val());
});
Well, after writing all the below, I reread your question and see you stated you know it works with a div. So the rest of my answer might not be helpful, but what's wrong with using a div? An empty div won't display anything, so you don't need to hide it. So FWIW:
Put your <g:textField ...> in a template.
Add a div where where you want the template to be rendered. In other
words, replace the current <g:textField ..> with <div id=updateme name=updateme></div>
In your setHowMuch action, render the template.
For example, I do:
In view:
<g:select class='setTagtypeValue-class'
name='tagtype-${i}-header'
from="${org.maflt.ibidem.Tagtype.list(sort:'tagtype').groupBy{it.tagtype}.keySet()}"
value="${setTagtypeValue?.tagtype?.tagtype}"
valueMessagePrefix="tagtype"
noSelection="${['null':'Select One...']}"
onchange="${remoteFunction(action:'options', update:'tagtype-options-${i}',
params:'\'tagtype=\' + this.value +\'&i=${i}\'' )}" />
Controller action:
def options = {
def i = params.i ?: 0
def tagtypes = Tagtype.findAllByTagtype(params.tagtype)
render(template:"tagtypeList", model:[tagtypes:tagtypes,i:i])
}
tagypeList Template:
<table>
<tr>
<th></th>
<th><g:message code="tagtype.lookup"
default="Lookup Table" /></th>
<th><g:message code="tagtype.regexpression"
default="Field Rule" /></th>
<th><g:message code="tagtype.uicomponent"
default="UI Component" /></th>
</tr>
<g:each in="${tagtypes}" var="tagtype" status="j">
<tr>
<td><g:radio name="setTagtypesList[${i}].tagtype.id" value="${tagtype.id}"
checked="${(setTagtypeValue?.tagtype?.id == tagtype.id ||
(!setTagtypeValue?.tagtype?.id && j==0))}"></g:radio></td>
<td>${tagtype.lookupTable}</td>
<td>${tagtype.regexpression}</td>
<td><g:message code="${'uicomponent.' + tagtype.uicomponent.id}"
default="${tagtype.uicomponent.uicomponent}" />
</td>
</tr>
</g:each>
</table>
This code is from the metadataset (called field set in the UI) screen in http://www.maflt.org/products/Ibidem.
How should I initiate a delete action from my view?
Creating a new form-tag for each entity just doesn't seem right :-)
<% foreach (var subscriber in group.Subscribers) { %>
<tr>
<td><%= subscriber.Email %></td>
<td><%= Html.ActionLink("[edit]", "edit", "subscriber", new {id=subscriber.SubscriberId}, null) %></td>
<td>
<form id="delete-subscriber-form" method="post" action="<%= Url.Action( "delete", "subscriber", new { #subscriberId = subscriber.SubscriberId }) %>">
<input type="submit" value="Delete" />
</form>
</td>
</tr>
<% } %>
How would you do it?
I normally use checkboxes on the side of the items. Then I can have action links (buttons, whatever) that apply an action to the selected items (such as delete).
you can use CSS and Javascript , add 'forDel' css class for all the elments you want to delete , if you are going to use jquery you can do it like this:
$(".element").each(function(){
$(this).data("id","the id of the element in db")
});
$(".element").toggle(function(){
$(this).addClass("forDel");
},function(){
$(this).removeClass("forDel");
});
and then on pressing the delete button:
var idsForDel;
$(".forDel").each(function(){
idsForDel = $(this).data("id"); + ";";
})
you can pass the idsForDel to the Controller ... and split it in the server side.
It depends on the situation, if you are doing CRUD operations you would normally go with one <form> tag per operation (delete,edit,new). If, however, you are displaying a list and you want to be able to 'multiple delete' items with one click then you will have to approach it from a different angle as you need to encapsulate all the required information into one form.
EDIT
Having had another look at your post above I notice you are providing a 'Delete Button' against each element in the list. For atomic actions like this (i.e. the user expects something to happen straight after they have clicked a button) I would definitely use one form per item.
What I wrote above still applies...