How can set color to selectonemenu row - primefaces

how can I set color to p:selectOneMenu row,
I have a selectOneMenu with a client list. Canceled Customers want the row is red background color.
<p:selectOneMenu id="listaClientesmodi" value="#{clientesMB.selectedEmpClienteCancelarContrato}" converter="clientesConverter" panelStyle="width:500px"
effect="fade" var="p" style="width:500px" filter="true" filterMatchMode="contains">
<f:selectItems value="#{comunMB.itemsClientes}"/>
<p:column>
#{p.codigo} - #{p.nombre}
</p:column>
<f:ajax execute="#this" listener="#{clientesMB.cargarContratosClienteSelected}" render=":form2:panelDetalles :form2:panelEditContrato" />
</p:selectOneMenu>

If you want all rows to be painted:
.ui-selectonemenu-item {
background-color: aqua!important;
}
But if you want to make conditional painting; I found a bit complicated solution there can be another and much simpler solutions of course.
To be able to apply my solution you need a field which is the size of your clients those shown in the p:selectOneMenu. But more important thing you need to add text like canceled or whatever which will say to js function that item is need to be painted.
If comunMB.itemsClientes is shown in the p:selectOneMenu concatenate "canceled" string to canceled clients. Because the canceled clients need to be differentiated from others. And my solution requires it sorry for that was best I can do.
$(document).ready(function() {
for (var i = 0; i < '#{clientesMB.size}'; i++) {
if($(".ui-selectonemenu-items li:nth-child("+i+")").text().indexOf("Canceled") != -1) {
$(".ui-selectonemenu-items li:nth-child("+i+")").css({"background-color":"#ff1315"});
}
}
});
So; p:selectOneMenu generates a html list. If you investigate it from browsers developer settings, it's looking like:
<ul class="ui-selectonemenu-items">
<li>First Item</li>
<li>Second Item</li>
<li>Third Item</li>
</ul>
So function firstly selects the element from it's CSS class which is named as ui-selectonemenu-items and looks for it's children, and for each child it is looking for they are canceled or not.
indexOf function returns -1 when item doesn't include string of "canceled" so we are finding the elements which has "canceled" text and change their background color, that's it.

Related

How do I set the selected item from p:selectOneListBox using javascript/jquery

I am trying to dynamically set the selected item in the selectOneListbox using a button.
xhtml
<p:selectOneListbox id="basic1" widgetVar='commmentWidget' styleClass="commentClass" value="#{decisionTreeBean.option1}" style=" font-size: 12px;background-color:white;width:17em; height:13em; border-style:solid !important;border-width:0.5px !important; border-color:grey !important;" >
<f:selectItems value="#{decisionTreeBean.commentType}" var="X"
itemLabel="#{X}" itemValue="#{X}" />
</p:selectOneListbox>
Jquery
jQuery(".generateBtn").on("click",function(event){
name=PF('commmentWidget').selectItem($('.ui-selectonelistbox-item[data-label*="Other"]'));
console.log(name);
});
This is not working. Also, I do not have val() method on my widgetVar.
The PrimeFaces p:selectOneListbox does not have any attributes set on options/items so they can be used in 'jquery' selectors. So the 'index' in the list most be used for this component
PF('commmentWidget').selectItem(PF('commmentWidget').jq.find("ul.ui-selectlistbox-list li:eq(4)"));
Here, I used li:eq(4) to select the 4th element from the list.

nth-child(), including illegal children (malformed HTML)

I'm working with HTML similar to this (coming from a third party web site - this is how the code is served, and I have no control over it):
<ul class"list">
<li>first list item</li>
<li>second list item</li>
<div>
<li>third list item</li>
<li>fourth list item</li>
</div>
<li>fifth list item</li>
<li>sixth list item</li>
</ul>
How can I select the fifth list item using CSS? With Javascript, if I use document.querySelectorAll('ul li') in the DOM, I get an iterable NodeList with all 6 of the <li> elements.
So then let list_items = document.querySelectorAll('ul li') allows me to access the fifth list item using list_items[4]. But if I try document.querySelectorAll('ul li:nth-child(5)') it doesn't work because, apparently, CSS only sees 4 <li> elements (the direct children of <ul>).
Is there a way to do this with CSS, or do I need to rework my approach?
* Edit *
I need to be able to select any of the li elements, arbitrarily, based on user input. The presence and number of li elements after the div section varies. I can correctly select any of the li elements before the div using something like ul > li:nth-of-type(${index_from_user_input}) - or within the div using something like ul > div > li:nth-of-type(${index_from_user_input}). I'm initially counting the number of lis and using that as the basis for the indexing...so if user input indicates that I need to select the third li, for example, I want to be able to simply use something like ul li:nth-of-type(3).
But if index_from _user_input points to an element after the div, then it doesn't work correctly, since CSS doesn't recognized the lis within the div, so the index numbers are off in my selector. I was hoping for a cleaner solution that uses only ul li:nth-child() or ul li:nth-of-type() so that I wouldn't have to check how many lis are within and after the div. I suspect it's just not possible, given the bad markup, but I'm not 100% sure of that, so I figured I'd ask here, in case somebody might have a clever way to do it. Otherwise, I can just rework the code and approach the whole thing differently.
this is how the code is served, and I have no control over it
Oh, you really do. You can just remove the erroneous div from the list with javascript.
Working Example:
/* IDENTIFY ELEMENTS */
var list = document.getElementsByTagName('ul')[0];
var erroneousDiv = list.getElementsByTagName('div')[0];
var select = document.getElementsByTagName('select')[0];
var button = document.getElementsByTagName('button')[0];
/* IDENTIFY LIST ITEMS */
var allListItems = document.querySelectorAll('ul li');
var listItemsToMove = erroneousDiv.getElementsByTagName('li');
var numberOfListItemsToMove = listItemsToMove.length;
/* REARRANGE LIST ITEMS AND REMOVE ERRONEOUS DIV */
for (var i = 0; i < numberOfListItemsToMove; i++) {
list.insertBefore(listItemsToMove[0], erroneousDiv);
}
list.removeChild(erroneousDiv);
/* SELECTOR FUNCTION */
function selectListItem() {
for (var i = 0; i < allListItems.length; i++) {
allListItems[i].removeAttribute('style');
}
var selected = select.value;
var listItem = document.querySelector('ul li:nth-of-type(' + selected + ')');
listItem.style.color = 'blue';
listItem.style.fontWeight = 'bold';
}
button.addEventListener('click', selectListItem, false);
ul, form {
display: inline-block;
margin-right: 80px;
vertical-align: middle;
}
<ul class"list">
<li>first list item</li>
<li>second list item</li>
<div>
<li>third list item</li>
<li>fourth list item</li>
</div>
<li>fifth list item</li>
<li>sixth list item</li>
</ul>
<form>
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</select>
<button type="button">Select List Item</button>
</form>

Adding tabindex dynamically

I'd like to add tabindex to all form elements. The form is dynamic and I can't add it to the HTML. I would like to run it as a function.
If there are several radio buttons with the same name, each must have it's own tabindex value. Most of the form elements on page start as <input>, except <select>. How do I account for that?
I guess I will need to run a loop and add the attribute, right?
var n = 1;
$('input, select').each(function() {
$(this).attr('tabindex', n++);
});
Strange question, but yes that's the basic idea:
$(":input:not(:hidden)").each(function (i) { $(this).attr('tabindex', i + 1); });
This uses :input to get everything including buttons and text areas. :not(:hidden) will just exclude the hidden inputs to avoid unnecessary tabs.
Might be better to avoid n++ to set different tabindex numbers.
Instead, try setting tabindex to 0:
$(':input:visible').each(function() {
$(this).attr('tabindex', '0');
});
tabindex="0" means that the element should be focusable in sequential keyboard navigation, but its order is defined by the document's source order.
~ developer.mozilla.org
The :input selector basically selects all form controls.
The :visible selector basically selects all elements that are visible.
or as suggested in the comments, if you have no other changes to apply to each visible input, then this should be enough:
$(':input:visible').attr('tabindex', '0');
Here, I described how can add aria-selected and tabindex value dynamically via jquery. I also want to see that how accessibility work with tablist, tab, and tabpanel role and how aria attributes work.Hope helps this code :
var $tabs = $('.tabs');
var $panels = $('.panel');
$tabs.on('click', 'a', function (e) {
e.preventDefault();
var id = $(this).attr('href');
// Find the currently visible tab and panel and hide them
$tabs.find('[aria-selected="true"]').attr({
'aria-selected': false,
'tabindex': -1
});
$(this).attr({
'aria-selected': true,
'tabindex': 0
});
});
Tab Wrapper:-
<ul class="tabs" role="tablist">
<li role="presentation">Tab 1</li>
<li role="presentation">Tab 2</li>
<li role="presentation">Tab 3</li>
</ul>
<div class="tab-panels">
<div class="panel" id="tab-1" role="tabpanel" aria-hidden="false">…</div>
<div class="panel" id="tab-2" role="tabpanel" aria-hidden="true">…</div>
<div class="panel" id="tab-3" role="tabpanel" aria-hidden="true">…</div>
</div>
One approach is to move an element higher in the DOM. The element at the top of the DOM tree will be focused first using Tabs as compared to lower ones.
For what's it's worth, I don't think you actually need to use an each loop here or even $(this).
jQuery is configured to execute functional arguments in place of plain values and runs the function once per loop, similarly to how an each loop would work.
You can read more on how that works in the official jQuery documentation here: .val( function )
So rather than using an each loop, you can accomplish the same effect using just this:
let n = 1;
$(':input:visible').attr('tabindex', function() { return n++; });
or if you're okay using the modern ES6 arrow function syntax—
let n = 1;
$(':input:visible').attr('tabindex', () => n++);
Using () => n++ instead of just n++ here allows jQuery to run the function for each instance's value rather than taking in the initial value of n++ and applying it to all matching elements.

How can I wrap lines of text in an unordered list?

I have some nested tables in a containing "column" table. The bottom table just contains a multi-line text area where the user can post comments. When the user saves the page I want to capture each separate line of comment as an element in an unordered list. Here is the HTML:
<td><strong>Key Messages:</strong><asp:Label runat="server" ID="messagesLabel"></asp:Label>
<div id="messagesDiv" runat="server">
<asp:TextBox runat="server" ID="MessagesTextbox" Width="100%" TextMode="MultiLine" Height="100" Columns="10"></asp:TextBox>
<asp:Button runat="server" ID="clearMessages" Text="Clear Messages" OnClick="ClearMessages_Click" />
</div>
</td>
My problem is that when the unordered list is posted back to the page, very long lines stretch the table beyond the desired width. I would like to have longer comments wrap at some point while still remaining just one element in the list -- ie, one bullet. I have tried setting the MaxLength and Columns properties with no luck.
EDIT:
I tried the first suggestion using:
ul
{
width: 50px;
}
li
{
width: 50px;
}
but it had not effect on the layout. The layout did not change for any value of width.
I tried to use the second solution but I don't have the CSS property "word-wrap" available in my editor. I am programming in Visual Web Developer Express 2010 which supports CSS 2.1 so, as far as I understand, I should be able to set this property but I can't. I tried it anyway and it had no effect on the layout.
EDIT:
Here is how I am creating the list:
XmlDocument xdoc2 = new XmlDocument();
xdoc2.Load(messagesFileLocation);
XmlNodeList messagesList = xdoc2.GetElementsByTagName("message");
if (messagesList.Count > 0)
{
string unorderedList = "<ul>";
for (int i = 0; i < messagesList.Count; i++)
{
XmlNode node = messagesList.Item(i);
string message = node.InnerText.ToString();
unorderedList += "<li>" + message.ToString() + "</li>";
}
unorderedList += "</ul>";
messagesDiv.InnerHtml = unorderedList;
}
The user edits are actually saved to an XML file first and then posted back to the page.
Specify the width of the ul and li elements and your content should wrap. Also set the parent elements to a height:auto; so the height changes as the size of the content increases.
If you post more code, I can give you a better idea.
yes i think its possible check this
http://www.w3schools.com/cssref/css3_pr_word-wrap.asp
and this
http://webdesignerwall.com/tutorials/word-wrap-force-text-to-wrap

Flex ItemRenderer: rendering the source item of a drag

When an item is being dragged from/within a list in the default implementation, it is shown as selected during the drag (and a separate item renderer, in dragging state, is shown as the drag image), so:
<s:ItemRenderer>
<s:Label text="{data}" color.selected="0xFF0000" color.dragging="0x00FF00" />
</s:ItemRenderer>
renders as:
Is there a straightforward way to change the state of the source of the drag (the red, selected, "Bar") to something other than "selected" for the duration of the drag?
In the ideal, I would add color.dragSource="0x0000FF" to the item renderer code above, and "Bar" would be red while selected, but blue once the dragging had begun. When the drag was complete, it would revert to red (or, if no longer selected, black).
What if you did an eventListener on drag start that set the selected item in the list to -1? -1 says that nothing should be selected.
Edit: added below code to support:
<s:List id="myList" dragStart="startDrag(event)"/>
private var dragIndex:int;
private function startDrag(e:Event):void
{
dragIndex = myList.selectedIndex;
myList.selectedIndex = -1;
}
private function stopDrag(e:Event):void
{
myList.selectedIndex = dragIndex;
}