PrimeFaces radiobutton styles not updating when clicked via Javascript - javascript

I have a p:selectOneRadio setup as follows :
<p:selectOneRadio id="positionRadio" value="#{employeeBean.empPosition}" converter="#{empPositionConverter}" layout="custom"
required="true" requiredMessage="Please select a position">
<f:selectItems value="#{employeeBean.positionList}" var="pos"
itemLabel="#{pos.name}" itemValue="#{pos}" />
<p:ajax process="#this" update="#this"/>
</p:selectOneRadio>
<ui:repeat id="iterator" value="#{employeeBean.positionList}" var="template" varStatus="iterStat">
<div class="form-group" onclick="document.getElementById('employeeForm:positionRadio:#{iterStat.index}').click();">
<h:outputText styleClass="form-control" value="#{pos.name}"/>
<p:radioButton for=":employeeForm:positionRadio" itemIndex="#{iterStat.index}" />
<div style="display: inline">
<p style="display: inline">
<h:outputText value="#{pos.description}"/>
</p>
</div>
</div>
</ui:repeat>
I need to check the corresponding radio button if anything in the div containing it is clicked. I am attempting to do this using
onclick="document.getElementById('employeeForm:positionRadio:#{iterStat.index}').click();"
This is only half working. When I click on the div I do see the POST request fire, however the styles aren't updated so none of my radio buttons are checked client side.
This is of course because p:radioButton is rendered as a div with a hidden input radio element and a visible span that is styled accordingly. Why is the span style not updated when clicked via javascript and is there a way to fix it?
Using JSF 2.1.7, PrimeFaces 5.0 and Java 1.7

I have been working on this problem further and have a solution.
I would still prefer a different one, but my current solution is to update the styles manually via javascript.
First off I added a hidden input field outside the ui:repeat to track the previously clicked radio button index
<input type="hidden" name="prevClicked" id="prevClicked" value="-1"/>
I also gave the p:radioButton inside the ui:repeat an id of raBtn and moved the onclick javascript to a function as follows
function radioBtnDivClicked(event, radioIndex){
// check prevClicked field to revert styles if necessary
if(document.getElementById('prevClicked').value != -1){
var prevIndex = document.getElementById('prevClicked').value;
document.getElementById('employeeForm:iterator:' + prevIndex + ':raBtn').children[1].className = 'ui-radiobutton-box ui-widget ui-corner-all ui-state-default';
document.getElementById('employeeForm:iterator:' + prevIndex + ':raBtn').children[1].children[0].className = 'ui-radiobutton-icon ui-icon ui-icon-blank';
}
// set styles for clicked div
document.getElementById('employeeForm:positionRadio:' + radioIndex).click();
document.getElementById('employeeForm:iterator:' + radioIndex + ':raBtn').children[1].className = 'ui-radiobutton-box ui-widget ui-corner-all ui-state-default ui-state-active';
document.getElementById('employeeForm:iterator:' + radioIndex + ':raBtn').children[1].children[0].className = 'ui-radiobutton-icon ui-icon ui-icon-bullet';
document.getElementById('prevClicked').value = radioIndex;
// stop bubbling
event.stopPropagation();
}
This should be fairly simple to convert to jQuery.
Furthermore I only changed to onclick to
onclick="radioBtnDivClicked(event,#{iterStat.index});"
This works, but I prefer a solution in which the radio button behaves as it does when it is clicked directly(ie Primefaces handles the style changes).

You seem to be clicking on the 'wrong' html element. If you look at that id of the generated <p:radioButton... e.g. the first button in the custom layout example in the PrimeFaces showcase:
<div id="j_idt88:opt1" class="ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input value="Red" id="j_idt88:customRadio:0_clone" name="j_idt88:customRadio" class="ui-radio-clone" data-itemindex="0" type="radio">
</div>
<div class="ui-radiobutton-box ui-widget ui-corner-all ui-state-default">
<span class="ui-radiobutton-icon ui-icon ui-icon-blank ui-c"></span>
</div>
</div>
And create a click on the div with the 'ui-widget' class beneath it
So
$('#j_idt88\\:opt1 .ui-widget').click(); # The \\ is for escaping the colon in the jQuery selector)
Then it works. I tried this and tested in the PrimeFaces 6.0 showcase
You might need to use your own id's or see if there is some logic in the generated ones if you don't explicitly assign id's.

Related

How to add a class to a label

I've seen some similar questions, but couldn't find the right solution for me. I have a textfield:
<div class="ui-input-text ui-body-inherit ui-corner-all ui-mini ui-shadow-inset ui-input-type-text">
<input type="text" name="FreiFeld3" data-model-binding="FreiFeld3" class="fw-model-binding"
data-set-visibility-id="id_15_gen" id="id_16_gen" data-framework-widget-name="textinput" maxlength="300"></div>
with an associated label:
<label for="id_16_gen">Name</label>
Now I simply need to add a class to this label with javascript or jquery, so it looks like this:
<label for="id_16_gen" class="app-required-label">Name</label>
I've tried various things with toggle class and so on but nothing worked. Everytime the class got added to the input tag with the same id, but not to the label.
For Explanation: I have some Checkboxes and when some are checked, this textfield with label appears. When it appears I need to add the class to change its optic, because it needs to be a required field then. (After the label change, I'm going to add required attribute)
Add class to label like this :
$("label[for='id_16_gen']").addClass("app-required-label");

How to prevent checking checkbox when added dynamically to a div?

so I've been struggling with this issue.
I want to add a checkbox into a div dynamically by clicking a button. Let's say I already have 2 checkboxes in the div, then I uncheck those 2. When I click the button, the checkboxes become 3 (which is what I want), but all those 3 will be checked. What I want is when I add a checkbox, the other checkbox(s)' checked state remain the same as before.
Here is my code (http://jsfiddle.net/gr2o47wt/4/):
HTML:
<div id="chkbox_container">
<input type="checkbox" checked>Check<br />
</div>
<input type="button" value="Add CheckBox" onClick="addCheckBox();">
JavaScript:
function addCheckBox() {
txt = "<input type=\"checkbox\" checked>Check<br />";
document.getElementById('chkbox_container').innerHTML += txt;
}
Thanks in advance for your answers! :)
You can use insertAdjacentHTML() rather than manipulating the innerHTML:
<input type="button" value="Add CheckBox"
onClick="document.getElementById('chkbox_container').insertAdjacentHTML('beforeend','<input type=\'checkbox\' checked=\'checked\' />Check<br />');">
JS Fiddle demo.
The problem you had was that the original HTML (as returned by innerHTML) is from the source of the page, not the DOM; and therefore the checked/unchecked nature of the checkbox originally in place was restored.
insertAdjacentHTML() simply adds the HTML string in the specified place ('beforeend' in this case).
More or less as an aside, it's worth trying, where possible, to keep your event-handling outside of your HTML elements; and binding those event-handlers in the JavaScript itself. This makes for somewhat easier maintainability, and would lead to code like the following:
// note that I gave the button an 'id' for simplicity:
var button = document.getElementById('addCheckboxes');
button.addEventListener('click', function () {
document.getElementById('chkbox_container').insertAdjacentHTML('beforeend', '<input type=\'checkbox\' checked=\'checked\' />Check<br />');
});
JS Fiddle demo.
Finally, some of your HTML is invalid (or at least erroneous), an <input /> is a void element, it can have no descendants; therefore it either has no closing tag (just: <input>) or self-closes (<input />).
Further, the text beside the checkboxes is a little misleading, usually with an HTML form the text beside the <input /> will focus that input; that's achieved by using a <label> element to associate the text with the control, for example:
<label><input type="checkbox" /> click</label>
JS Fiddle demo.
Or:
<input type="checkbox" id="inputElementID" />
<label for="inputElementID">click</label>
But this latter form does require the dynamic generation of ids (which is a little beyond the scope of this question).
References:
insertAdjacentHTML().

Replacing Radio Box with image (Javascript or Jquery)

I am currently overlaying a radio box on top of a unique image (found help here on stackoverflow: How can I display the checkbox over the images for selection? and http://jsfiddle.net/erSBP/1/) and it's working like the example.
However, I would like to remove the radio box so that only the unique image remains and is clickable and sends the checked value just as a normal radio button would.
The radio box input ID's are generated dynamically so I can't specify what they are named.
Is there any way to do this with Javascript or JQuery?
My current configuration is:
<div class="answer">
<div class="answer-image">
<img style="border-width:0px;" src="/images/white.jpg">
</div>
<input id="Questions8404" type="radio" onclick="javascript:setTimeout('__doPostBack(\'965968404\',\'\')', 0)" value="8404" name="96596">
</div>
Your code is messed up. Firstly, don;t use setimeout. Just call dopostback. Secondly, you're using a javascript url on an onlick attribute. Don't do that unless you calling it through the href attribute for who knows what reason. All in all, don't use javascript urls. Here's what your code should look like
<div class="answer">
<div class="answer-image">
<img style="border-width:0px;" src="/images/white.jpg">
</div>
<input id="Questions8404" type="radio" onclick="__doPostBack(\'965968404\',\'\')" value="8404" name="96596">
</div>
If you were looking to do this with a checkbox, you could do something like this with jquery​
$(document).ready(function () {
$(".answer").each(function() {
var p = $(this).find("input:checkbox");
p.hide();
$(this).find("img").click(function() {
p.prop("checked", true);
});
});
});
As this will set the input to hidden, and trigger a click event to select the checkbox. It will match the Image and the Input as contained in same "answer" div. You could adapt this to work with a radio, you would just need to know which option you wanted to select.

Make a jquery icon visible using on keyup event

Stumped at this part. I have a simple html input, and a jquery ui icon. What I want to do is have the icon hidden untill a "keyup" event of some sort is fired on the html input. Currently have the css property of the icon set to display:none;, but how would I use javascript to display this after some text is put into the html input?
--Here's my code
<input id="solo1" /> <div id="saveButton" class="ui-state-default ui-corner-all" title="Save" style="float:left; display:none; height:20px;" ><span class="ui-icon ui-icon-disk"></span></div>
Try something like below
$("#solo1").keypress(function(){
$("#saveButton").show();
});
You could use Javascript, or jQuery...first, a Javascript example:
<input id="solo1" onKeyUp="document.getElementById('saveButton').style.display = 'block';" />
Preferably, in jQuery, and this is all Javascript now:
$("#solo1").keyup(function(){
$("#saveButton").show();
});

Javascript onChange affecting CSS styles

I am trying create a 'live' view where our clients can edit the colors of a php page that they will embed into their own page.
By entering a hex value in each of the text fields, it should instantly change the background color value set for it's relative div.
<!--Enter a hex color to change the background of id="box1" -->
<input name="color1" id="color1" type="text" size="6" maxlength="6" onchange="DOTHIS(change background color of 'box1' to this value);" />
<br />
<!--Enter a hex color to change the background of id="box2" -->
<input name="color2" id="color2" type="text" size="6" maxlength="6" onchange="DOTHIS(change background color of 'box2' to this value);" />
<br />
<!--Enter a hex color to change the background of id="box2" -->
<input name="color3" id="color3" type="text" size="6" maxlength="6" onchange="DOTHIS(change background color of 'box3' to this value);" />
<hr />
<div id="box1" style="background-color:#ff0000">HELLO 1</div>
<div id="box2" style="background-color:#00ff00">HELLO 2</div>
<div id="box3" style="background-color:#0000ff">HELLO 3</div>
This is probably simple to someone, but after a couple of days, I cannot find the right way to do it.
UPDATE:
After seeing the direction of the answers, I thought I'd better add the following..
How would this work if the id names were not related?
example:
id="maincolor" -> affected id="hello"
id="fontcolor" -> affected id="world"
id="buttoncolor" -> affected id="foo"
This is why I thought it might be better to inline javascript for each element?
There are only four colours to change, plus an option to hide various divs containing text and one checkbox to hide the title..
The system is here: https://www.overseasmortgagefinder.co.uk/affiliates/generator.php
As you can see from the left side, our users can customise how the 'sourcing system' will look on their site.
What I am trying to do is create a 'live view' window on the right instead of the static help guide.
Is this any clearer as to my goal?
Well here's a fairly dynamic approach using jquery.
Change the format of the id's of your inputs to color-box1, color-box2 and color-box3 respectively.
<script type="text/javascript">
$(function() {
// assigns a onChange event to all inputs with ids that start with "color-box"
$("input[id^=color-box]").change(function () {
// validate user's input here
// if valid, grab id of changed input & remove the "color-" part
var id = $(this).attr("id").split("-", 2)[1];
// set color of div using the id above
$("div#"+id).css("background-color","#"+$(this).val());
});
});
</script>
If you need a pure javascript solution, just shout..
Solution without using jquery:
Remove onchange from your inputs, as onchange wont be fired until the user leaves (blur) the field.
Add onkeyup="changeBackground(this)" for each input field
Add this javascript function to your page:
changeBackground = function(source) {
if (/^[a-f0-9]{3}|[a-f0-9]{6}$/.test(source.value)) { // test for a valid hex color
var boxId = source.id.replace('color', 'box');
document.getElementById(boxId).style.backgroundColor = '#'+source.value;
}
}
Here is this fiddle to test.
How about this:
onchange="document.getElementById('box' + this.id.charAt(this.id.length - 1 )).style.backgroundColor = this.value;"
Also, you have two </form> closing tags. I'd get rid of the first one.

Categories