Render selectManyCheckbox without HTML table - jsf-2

is there a way to remove the table out of rendered html that is created by the h:selectManyCheckbox tag in server faces?
I am using twitter bootstrap and i placed the checkboxes inside a dropdown menu:
<ul class="dropdown-menu dropdown-menu-form">
<li><label class="checkbox"> <input type="checkbox" />
Activated
</label></li>
<li><label class="checkbox"> <input type="checkbox" />
Deactivated
</label></li>
</ul>
So the generated html table destroys the layout ...

You could just render a bunch of <h:outputLabel><h:selectBooleanCheckbox> inside <ui:repeat>. This way you've markup freedom. You'll only need to alter the model from e.g. List<T> to Map<T, Boolean> to represent the checked values and then loop over the map afterwards to collect checked ones.
A ready-to-use component is Tomahawk's <t:selectManyCheckbox> which has an additional layout attribute value of spread.

Related

Find a dynamic <input> tag with Capybara/Selenium

I have the following HTML:
<label for="file-input-76eb2" id="ember3042" class="c-text-input c-text-input o-grid-cell--6 file-upload ember-view">
<input id="file-input-76eb2" type="file" accept="text/csv" style="display: none;">
<span class="c-file-upload__input-filename"></span>
<a class="c-button c-button--single-action-primary c-file-upload__input-button">
Select
</a>
</label>
I have managed to get a Capybara::Node:Element corresponding to the label tag, but I can't get to the input. The id is dynamic- constantly changing. Moreover, I need to upload a file to this input tag.
Is there any information what I can do? This is all using google-chrome-headless.
This is using Ruby, with Capybara, with Selenium.
Looks like
label_element.find(:xpath, '//input') did it!

Grails: Removing Unwanted Brackets when Displaying Variable

I have a .gsp page where a student can select a course that they are in. That selection is then stored in an array list. I have another .gsp page that shows student details and within those details it shows which course they selected from the other page. However, when it displays the course it displays like this: "[courseName]", but I would like it to display without the brackets: "courseName".
This is my code for displaying the selection:
<g:if test="${studentDetails?.course}">
<li class="fieldcontain">
<span id="course-label" class="property-label">
<g:message code="student.course.label" default="Course(s)" /></span>
<span class="property-value" aria-labelledby="course-label">
<g:set var="course" value="${studentDetails?.course.courseName}" />
<g:message message="${course}" /></span>
</li>
</g:if>
So far I've tried displaying the variable with g:fieldValue, g:message, and just the variable itself without a tag. All methods display with the brackets. Any suggestions on how to remove the brackets are appreciated. If any other code is needed I can provide it. Thanks.
If your studentDetails?.course.courseName contains a List of courses and your want to display all of them, you need to convert it to a String. But default implementation of List.toString() uses brackets. Your could use .join(',') instead.
Like:
<g:if test="${studentDetails?.course}">
<li class="fieldcontain">
<span id="course-label" class="property-label">
<g:message code="student.course.label" default="Course(s)" /></span>
<span class="property-value" aria-labelledby="course-label">
${studentDetails.course.courseName.join(', ')}
</span>
</li>
</g:if>
Also I suggest to add .encodeAsHTML() if you got this data (course name) from a user, to escape any HTML content inside variables (avoid XSS, etc). Like:
${studentDetails.course.courseName.join(', ').encodeAsHTML()}

DropDownListFor not selecting the selected item in the SelectList

I am working on an ASP.NET MVC3 application and I cannot get a DropDownListFor to work with my property in a particular editor view.
My model is a Person and a person has a property that specifies it's "Person Type". PersonType is a class that contains a name/description and an ID. I can access the available PersonTypes within the application through my static/shared class called ApplicationSettings.
In the Edit Template view for my Person I have created a SelectList for debugging purposes:
#ModelType MyNamespace.Person
#Code
Dim pTypesSelectList As New SelectList(MyNamespace.ApplicationSettings.PersonTypes, "ID", "Name", Model.PersonType.ID)
End Code
I am then providing this SelectList as a parameter to the DropDownListFor that is bound to the PersonType property of my Person.
I am also printing the Selected property of each item in the SelectList for debugging purposes:
<div style="text-align: center; margin: 5px 0 0 0;">
<div>
#Html.LabelFor(Function(model) model.PersonType)
</div>
<div>
#Html.DropDownListFor(Function(model) model.PersonType, pTypesSelectList)
#Html.ValidationMessageFor(Function(model) model.PersonType)
<br />
<br />
<!-- The following is debugging code that shows the actual value-->
#Model.Type.Name
<br />
#Model.Type.ID
<br />
<br />
<!--This section is to show that the select list has properly selected the value-->
#For Each pitem In pTypesSelectList
#<div>
#pitem.Text selected: #pitem.Selected
</div>
Next
</div>
</div>
The view is bound to a Person whose PersonType property is "Person Type # 2" and I expect this to be selected; however the HTML output of this code looks like this:
<div style="text-align: center; margin: 5px 0 0 0;">
<div>
<label for="PersonType">PersonType</label>
</div>
<div>
<select id="PersonType" name="PersonType">
<option value="7e750688-7e00-eeee-0000-007e7506887e">Default Person Type</option>
<option value="87e5f686-990e-5151-0151-65fa7506887e">Person Type # 1</option>
<option value="a7b91cb6-2048-4b5b-8b60-a1456ba4134a">Person Type # 2</option>
<option value="8a147405-8725-4b53-b4b8-3541c2391ca9">Person Type # 3</option>
</select>
<span class="field-validation-valid" data-valmsg-for="PersonType" data-valmsg-replace="true"></span>
<br />
<br />
<!-- The following is debugging code that shows the actual value-->
Person Type # 2
<br />
a7b91cb6-2048-4b5b-8b60-a1456ba4134a
<br />
<br />
<!--This section is to show that the select list has properly selected the value-->
<div>
Default Person Type selected: False
</div>
<div>
Person Type # 1 selected: False
</div>
<div>
Person Type # 2 selected: True
</div>
<div>
Person Type # 3 selected: False
</div>
</div>
</div>
As you can see the printed Selected properties for the items in the SelectList shows that the 3rd item is "Selected". But what is driving me crazy is that the option that corresponds with this is Not Selected.
Generally, the Selected property in SelectList will be totally ignored by the HTML helpers unless there's no other option. If DropDownListFor can find the value by other means, it will insist on using that value.
In this case, it will use the value of model.PersonType(.ToString()) - but that's not what you want, judging by the model.PersonType.ID you pass to the SelectList.
More info in the answer here.
Workaround
One easy workaround that should work would be to set:
ViewData["PersonType"] = model.PersonType.Id.
The helper looks in ModelState first if it exists - i.e. on POST. This should work already, since ModelState["PersonType"] will be populated with the actual selected value that was posted.
After ModelState it will look in ViewData - with ViewData["PersonType"] first, and only then ViewData.Model.PersonType. In other words, you can "override" the value on your model with a value set directly on ViewData.
Better (IMO) solution
The more general, "better practice", way to solve it (which also avoids having a custom model binder in order to translate the POST'ed ID back to PersonType) is to use a ViewModel instead of working with full models in your view:
Have a PersonTypeID property - instead of PersonType.
Populate it with PersonType.ID
use this in your view
VB.NET: Html.DropDownListFor(Function(model) model.PersonTypeID), or
C#: Html.DropDownListFor(model => model.PersonTypeID)
When form is POST'ed, translate the ViewModel (including PersonTypeID => PersonType) back into the actual model in your POST Action.
This may seem like more work, but generally there tend to be many occasions in a project where you need more view-specific representations of your data to avoid too much inline Razor code - so translating from business objects to view models, while it may seem redundant and anti-DRY at times, tends to spare you of a lot of headaches.
Are you sure that your ModelState for "PersonType" key before rendering the view is empty? As JimmiTh commented is going to search for the value in the ModelState first. It happened to me too, you can try
#Html.DropDownList("PersonTypeFake", Function(model) model.PersonType, pTypesSelectList) and it should select the right option.

select checkbox with hidden input type

Folks,
I am using watir-webdriver, I have a piece in my HTML DOM which gets generated on the fly when I enter some credentials, this piece has a bunch of checkboxes, the number of checkboxes vary, I have to select one checkbox, below is an example of this, here I want to select the second checkbox(the one that has value "BS" for the input type hidden but the value for input type checkbox is same for all):
<li class="dir">
<input type="checkbox" value="1" onclick="$(this).next('.should_destroy').value = (this.checked?0:1)" name="should_not_destroy">
<input class="should_destroy" type="hidden" value="1" name="import[dir_attributes][][should_destroy]">
<input type="hidden" value="" name="import[dir_attributes][][id]">
<input type="hidden" value="Automation" name="import[dir_attributes][][path]">
<span class="dir_mode">Include</span>
Automation
</li>
<li class="dir">
<input type="checkbox" value="1" onclick="$(this).next('.should_destroy').value = (this.checked?0:1)" name="should_not_destroy">
<input class="should_destroy" type="hidden" value="1" name="import[dir_attributes][][should_destroy]">
<input type="hidden" value="" name="import[dir_attributes][][id]">
<input type="hidden" value="BS" name="import[dir_attributes][][path]">
<span class="dir_mode">Include</span>
BS
</li>
I may be able to do this with XPATH, but wanted to try a non XPATH solution. The input type hidden has the appropriate value that I need, for example above the second checkbox has value "BS" for input type hidden. I tried to use the hidden method like this:
h = ##browser.hidden(:value, "BS")
h.select
But I dont know what to do after this. I am trying to select the checkbox based on the value of the hidden element. Any feedback is much appreciated.
I would suggest using the visible elements instead. I think it makes it easier to read the test and seems more stable.
Try:
##browser.li(:class => 'dir', :text => /BS/).checkbox.set
Here we go, I think this will do it
Since you have to select the checkbox based on the hidden, you're going to have to go up a level to the containing li, then drill down to the checkbox
#browser.hidden(value: 'BS').parent.checkboxes.first.set

Grails filterPane plugin to fit page layout

I would like to have the filterPane to be inserted in my own div in order to fit my page layout. Basically I want to get rid of the default pop-up behavior and harmonize filterPane with the other elements of the application.
this is my gsp
<div class="filter">
<p>
<filterpane:isFiltered>
<filterpane:currentCriteria domainBean="demoracer.Pilot" />
</filterpane:isFiltered>
</p>
<g:formRemote method="post" name="form_search" url="${[action:'list']}" update="listContainer" >
<filterpane:filterPane customForm="true" formName="form_search" domainBean="demoracer.Pilot"
filterProperties="name," id="filterpaneContainer" />
<g:actionSubmit value="Apply Filter From Outside Filter Pane" action="list" />
</g:formRemote>
</div>
but the pane do not show up.
Thanks
Since the filterpane generates its own div, can't you just use the div it generates and restyle it to fit your layout? You can specify the id, class, and style attributes of the container div it generates. That should be more than enough to restyle it any way you'd like.
it doesn't seems possible since the html is statically created by the taglib
def output = """\
<div id="${containerId}"
class="filterPane ${containerClass ?: ''}"
style="display:none;${containerStyle}">
<h2>${title}</h2>
${openFormTag}
<input type="hidden" name="filterProperties" value="${propsStr}" />
<table cellspacing="0" cellpadding="0" class="filterTable">
"""

Resources