Why is my checkbox styling not working? - javascript

I made some custom checkboxes and radio buttons. I styled them as follows with CSS:
input[type="checkbox"]:checked + label:after,
input[type="checkbox"][checked="checked"] + label:after,
input[type="radio"][checked="checked"] + label:after,
input[type="radio"]:checked + label:after {
position: absolute;
display: block;
float: left;
height: 10px;
width: 10px;
top: 4px;
left: -19px;
z-index: 2;
background: #b7b7b7;
content: "";
}
input[type="checkbox"]:checked + label:after,
input[type="checkbox"][checked="checked"] + label:after {
background: none;
top: 1px;
left: -20px;
font-family: 'FontAwesome';
font-size: 12px;
color: #b7b7b7;
content: "\f00c";
}
The html of these elements looks like this
<div class="checkbox" ng-repeat="group in groups.initData.groups"
ng-checked="groups.modalData.access_groups[$index+1]">
<input type="checkbox"
class="group-checkbox">
<label><% group.group %> </label>
</div>
Then i initialize them like this with JQuery when my angular view loads:
$('.checkbox').click(function () {
if ($(this).children('input').prop("disabled"))
return;
if ($(this).children('input').prop("checked"))
$(this).children('input').prop("checked", false);
else
$(this).children('input').prop("checked", true);
$(this).children('input').change();
});
/* Radio handler */
$('.radio').click(function () {
if ($(this).children('input').prop("disabled"))
return;
var name = $(this).children('input').attr("name");
$(this).children('input[name="' + name + '"]').prop("checked", false);
$(this).children('input').prop("checked", true);
$(this).children('input').change();
});
I don't understand why the styling doesn't apply? My angular code works and it correctly puts the checked="checked" attribute on the elements that are true for my expression

font-family: 'FontAwesome';
is the problem here . Though you can style checkboxes ,there are some limitations. Like, if you are using some custom font-family , It wont work . Remove the font family and use following unicode content, and It should work.
content: "\2714";

Related

custom css switch does not run javascript function

I have a custom switch in CSS that I am using in a template for django. I am loading the javascript file properly but when I go to use the switch I don't get the expected result. The expected result is that the background would change colour this does not work using the switch. I added a button into the template to see if the button would work which it did,
javascript file:
function darkModen() {
var element = document.body;
element.classList.toggle("dark-mode");
}
HTML switch this does nothing:
<div class="onoffswitch" style="position: fixed;left: 90%;top: 4%;" onclick="darkMode()">
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" onclick="darkMode">
<label class="onoffswitch-label" for="myonoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
HTML button that does do what is expected.
<button onclick="darkMode()">Toggle dark mode</button>
CCS if this is causing the problem:
.onoffswitch {
position: relative; width: 90px;
-webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
display: none;
}
.onoffswitch-label {
display: block; overflow: hidden; cursor: pointer;
border: 2px solid #000000; border-radius: 20px;
}
.onoffswitch-inner {
display: block; width: 200%; margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
font-size: 16px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
box-sizing: border-box;
}
.onoffswitch-inner:before {
content: "ON";
padding-left: 5px;
background-color: #FAFAFA; color: #A87DFF;
darkMode()
}
.onoffswitch-inner:after {
content: "OFF";
padding-right: 5px;
background-color: #FAFAFA; color: #999999;
text-align: right;
}
.onoffswitch-switch {
display: block; width: 18px; margin: 6px;
background: #2E2E2E;
position: absolute; top: 0; bottom: 0;
right: 56px;
border: 2px solid #000000; border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
right: 0px;
background-color: #27A1CA;
}
body {
color: black;
}
.dark-mode {
background-color: rgb(66, 66, 66);
color: white;
}
I have been trying to understand how the button works and the switch doesn't. Does this happen because I cant use onclick inside a div tag? I am also wondering if django could cause this if there is special way to use javascript in django. I can see that the javascript file as been loaded prpperly into the site as I can get to: http://127.0.0.1:8000/static/lighting.js and see the script here.
I suggest you create an event handler for the checkbox and listen for the change event to determine whether it is checked or not to make sure that you are properly applying the dark-mode class to the body tag.
Here's a possible solution:
var body = document.body;
var checkbox = document.querySelector("#onoffswitch");
checkbox.addEventListener("change", function(event) {
var target = event.target;
var isChecked = target.checked;
if (isChecked) {
body.classList.add("dark-mode");
} else {
body.classList.remove("dark-mode");
}
});
.dark-mode {
background-color: grey;
color: white;
}
<div>
<label for="onoffswitch">
<span>Toggle dark mode on or off.</span>
</label>
<input type="checkbox" name="onoffswitch" id="onoffswitch" />
</div>
Also, the onclick event on the div element is probably not what you want, at least in your situation since you're using a checkbox to determine whether the dark-mode should be applied or not.
However, the onclick attribute on the input element that you have is missing the parenthesis (onclick="darkMode()"), so if you really want to go that route, you could still do it, but I'd recommend just dealing with the checkbox itself and checking if it's checked or not.
function toggleDarkMode() {
document.body.classList.toggle("dark-mode");
}
.dark-mode {
background-color: grey;
color: white;
}
<div>
<label for="onoffswitch">
<span>Toggle dark mode on or off.</span>
</label>
<input
type="checkbox"
name="onoffswitch"
id="onoffswitch"
onclick="toggleDarkMode()"
/>
</div>
Please check onclick function name your calling onclick="darkmode()" but in javascript you write
function myFunction() {
var element = document.body;
element.classList.toggle("dark-mode");
}
please change myFunction with darkmode
it will be look like
function darkmode() {
var element = document.body;
element.classList.toggle("dark-mode");
}
Hopefully now it work

Xpath of Radio button is not working: Xpath is not clickable?

I am trying to get the Xpath of the code but its showing not clickable.
I tried in chrome console and somehow make the xpath clickable but dont know how to use the xpath in selenium code.
In chrome console it work if you write like this
$x("//*[#id='no-voucher-id']")[0].click()
Here is my code:
#FindBy(xpath = "//input[#id='no-voucher-id']")
private lateinit var selectedNoVoucher: FluentList<FluentWebElement>
selectedNoVoucher.click();
HTML CODE:
<div className="Voucher-container-section" >
<div className="radio-item">
<input type="radio" id="yes-voucher-id" name="voucher" value="Yes"/>
<label For="yes-voucher-id">Yes</label>
</div>
<div className="radio-item">
<input type="radio" id="no-voucher-id" name="voucher" value="No"/>
<label htmlFor="no-voucher-id">No</label>
</div>
</div>
css
.radio-item {
display: inline-block;
position: relative;
padding: 0 6px;
margin: 10px 0 0;
}
.radio-item input[type='radio'] {
display: none;
}
.radio-item label {
color: #FFFFFF;
font-weight: normal;
}
.radio-item label:before {
content: " ";
display: inline-block;
position: relative;
top: 5px;
margin: 0 5px 0 0;
width: 20px;
height: 20px;
border-radius: 10px;
background-color: white;
}
.radio-item input[type=radio]:checked + label:after {
border-radius: 11px;
width: 12px;
height: 12px;
position: absolute;
top: 9px;
left: 10px;
content: " ";
display: block;
background: #EE4823;
}
Error Message:
org.openqa.selenium.TimeoutException: Expected condition failed: Element [[ChromeDriver: chrome on Ubuntu] -> xpath: //input[#id='no-voucher-id']] is not clickable (tried for 15 second(s) with 500 MILLISECONDS interval)
I expect the output is the radio button should be clickable
If the element is in the view point then you can use this selector :
I would recommend you to use ID over xpath or any other locator :
for clicking on Yes radio button : yes-voucher-id
#FindBy(id="yes-voucher-id")
var selectedNoVoucher
selectedNoVoucher.click();
Just make sure that the ID should be unique.
You can replace the id for No button in similar way.

Changing a span field to an input field for updating information

I am creating a way to edit dynamic content. I found a question on here that got me started in terms of changing text (spans in my case) into input fields.
Currently, I can't figure out the following issue. When you click "Edit" (on the right side) the input fields replace the span (this is what I want), but when when you click outside of the input the input fields add new span fields instead of replacing the input fields.
I am wanting the styling and the fields to constantly stay in their original place.
Does anyone see what I am doing wrong?
var projID = '';
//Obtaining ID and Editing the projects
$(document.body).on('click', '.recEdit', '[data-editable]', function() {
projID = $(this).parent().data('recid');
console.log('Project ID is..... ' + projID);
var $el = $(this).parent().children().find('span');
var $input = $('<input/>').val( $el.text() );
$el.replaceWith( $input );
var save = function(){
var $p = $('<span data-editable class="recBaseFormat" />').text( $input.val() );
$input.replaceWith( $p );
};
/**
We're defining the callback with `one`, because we know that
the element will be gone just after that, and we don't want
any callbacks leftovers take memory.
Next time `p` turns into `input` this single callback
will be applied again.
*/
$input.one('blur', save).focus();
});
.recentProjectCont {
width: 98%;
height: 85px;
border-bottom: 1px solid #ccc;
padding: 10px 0;
margin: 0 10px;
display: block;
position: relative;
}
.recentProjectImg {
width: 100px;
height: 85px;
display: inline-block;
vertical-align: top;
}
.recentProjectImg img {
width: 100%;
height: 100%;
object-fit: cover;
}
.recProjInfoCont {
display: inline-block;
vertical-align: top;
width: 80%;
height: 100%;
margin-left: 20px;
}
.recInfoCont1, .recInfoCont2 {
height: 100%;
display: inline-block;
vertical-align: top;
}
.recInfoCont1 {
width: 40%;
}
.recInfoCont2 {
width: 52%;
text-align: right;
}
.recBaseFormat, .projectViews {
letter-spacing: .1rem;
line-height: 1.4em;
color: #2f2f2f;
display: block;
margin-bottom: 5px;
}
.recProjName {
font-size: 1.1rem;
font-family: 'Muli', sans-serif;
}
.recInfoStat, .projectViews {
font-size: .7rem;
font-family: 'Nunito', sans-serif;
}
.recEdit {
position: absolute;
top: 20%;
left: 97%;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="recentProjectCont">
<div class="recProjInfoCont">
<div class="recInfoCont1">
<span class="recProjName recBaseFormat" data-editable>Name</span>
<span class="recInfoStat recBaseFormat recAlt" data-editable>Alt</span>
<span class="recInfoStat recBaseFormat recCat" data-editable>Category</span>
</div>
<div class="recInfoCont2">
<span class="recInfoStat recBaseFormat" data-editable>Status</span>
<span class="recInfoStat recBaseFormat" data-editable>Creator</span>
</div>
</div>
<div class="recEdit">Edit</div>
</div>
This code could definitely be optimized, but it should get you going in the right direction. There were a few issues with your code. The issue I mentioned above, which is that your selector was only targeting the last span element within the parent element. We can solve that by using the each method to loop over every span within the parent. Another issue is that you were losing the classes for your spans when you were replacing them with inputs. I've solved that by saving a list of classes for each span before replacing them with an input so that they can be reapplied when they are converted back to spans. Finally, you were firing the save function for all inputs on blur of any input, meaning that the user would only be able to edit one span and then when they clicked out, all inputs would have been converted back. Instead, now it will only convert back when you unfocus each specific input.
var projID = '';
//Obtaining ID and Editing the projects
$(document.body).on('click', '.recEdit', '[data-editable]', function() {
projID = $(this).parent().data('recid');
console.log('Project ID is..... ' + projID);
$(this).parent().children().find('span').each(function() {
var classList = $(this).attr('class');
$input = $('<input/>').val($(this).text());
$(this).replaceWith($input);
$input.on('blur',function() {
$(this).replaceWith('<span data-editable class="' + classList + '">' + $(this).val() + '</span>');
});
});
});
.recentProjectCont {
width: 98%;
height: 85px;
border-bottom: 1px solid #ccc;
padding: 10px 0;
margin: 0 10px;
display: block;
position: relative;
}
.recentProjectImg {
width: 100px;
height: 85px;
display: inline-block;
vertical-align: top;
}
.recentProjectImg img {
width: 100%;
height: 100%;
object-fit: cover;
}
.recProjInfoCont {
display: inline-block;
vertical-align: top;
width: 80%;
height: 100%;
margin-left: 20px;
}
.recInfoCont1, .recInfoCont2 {
height: 100%;
display: inline-block;
vertical-align: top;
}
.recInfoCont1 {
width: 40%;
}
.recInfoCont2 {
width: 52%;
text-align: right;
}
.recBaseFormat, .projectViews {
letter-spacing: .1rem;
line-height: 1.4em;
color: #2f2f2f;
display: block;
margin-bottom: 5px;
}
.recProjName {
font-size: 1.1rem;
font-family: 'Muli', sans-serif;
}
.recInfoStat, .projectViews {
font-size: .7rem;
font-family: 'Nunito', sans-serif;
}
.recEdit {
position: absolute;
top: 20%;
left: 97%;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="recentProjectCont">
<div class="recProjInfoCont">
<div class="recInfoCont1">
<span class="recProjName recBaseFormat" data-editable>Name</span>
<span class="recInfoStat recBaseFormat recAlt" data-editable>Alt</span>
<span class="recInfoStat recBaseFormat recCat" data-editable>Category</span>
</div>
<div class="recInfoCont2">
<span class="recInfoStat recBaseFormat" data-editable>Status</span>
<span class="recInfoStat recBaseFormat" data-editable>Creator</span>
</div>
</div>
<div class="recEdit">Edit</div>
</div>
Finally, as others have mentioned, another option would be to use the contenteditable attribute on your spans. This is an HTML solution for editing HTML elements that are not editable by default. It essentially does the same thing you're trying to do with Javascript, but it's much cleaner. It also has very good browser support. One drawback to this solution would be that it will not be immediately clear to the user that the element is editable like it would be with an actual button that says "Edit." But there are some solutions for that as well.
<span contenteditable="true">You can edit me</span>
You could use juste the contenteditable attribute toggle each click !

Adding Inputs to a Form Dynamically Via Javascript

I'm fixing up a form that had a series of areas with two or three duplicate inputs for things like employer name, position, etceteras. I thought it would be easier to just dynamically add them with an onclick button but I am having two major problems: (1) When the onclick event create a new line of inputs the label attributes seems to abandon their css and (2) When you click into the input of the form the label should raise up, but the inputs no longer raise their respective labels.
My questions are (1) What is required to amend the css to keep the labels relative to their inputs and (2) Why/How are the inputs working in the first level of inputs and then not the second? Also, how can I fix this?
Any help would be great!
I've recreated the problem in a minor way in the code pen below. If you click inside the inputs you'll understand what I mean by "raising."
CodePen Example : http://codepen.io/theodore_steiner/pen/WGOaAR
HTML:
<p class="subtitleDirection">Please list your employment histroy in chronological order, beginning with your current position (Limit of Three)</p>
<div class="clearFix"></div>
<div id="employmentHistory">
<div class="input-group" id="employment-history-1">
<input type="text" name="job_1" />
<label class="schoolBoard">School Board</label>
<input type="text" name="position_1" />
<label class="position">Position</label>
<input type="text" name="years_1" />
<label class="years">Years</label>
<button type="button" id="add_job()" onclick="addJob()" value="+">+</button>
</div>
</div><!--end of employmentHistory Div-->
CSS:
input
{
background: none;
border: 1px solid #21a1e1;
margin: 15px;
margin-top: 25px;
margin-left: 15px;
margin-bottom: 25px;
display: inline-block;
height: 30px;
width: 320px;
float: left;
}
.input-group label
{
position: absolute;
left: 17px;
top: 42px;
font-style: italic;
font-size: 17.5px;
color: #999;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
pointer-events: none;
transition: all 0.2s ease;
}
.input-group input:focus+label,
.input-group input.has-value+label {
top: 20px;
font-size: 12px;
color: #aaa;
}
input:focus,
input:active
{
outline: none;
}
input[type="text"],
input[type="email"]
{
border: none;
border-bottom: 1px solid #b3c1cc;
}
.input-group
{
position: relative;
}
#teaching-experience-years input
{
margin-left: 70px;
}
#teaching-experience-years label
{
left: 421px;
}
#employment-history-1 input
{
width: 220px;
float: left;
}
#employment-history-1 label.position
{
left: 265px;
}
#employment-history-1 label.schoolBoard
{
left: 15px;
}
#employment-history-1 label.years
{
left: 514px;
}
JS:
var i = 1;
function addJob()
{
if( i <= 3 )
{
i++;
var div = document.createElement("div");
div.innerHTML = '<div class="input-group" id="employment-history-1"><label class="schoolBoard">School Board</label><input type="text" name="job_'+i+'"><label class="position">Position</label><input type="text" name="position_'+i+'"><label class="years">Years</label><input type="text" name="years_'+i+'"><button type="button" id="add_job()" onclick="addJob()" value="+"></button></div>';
document.getElementById("employmentHistory").appendChild(div);
}
};

Lets chose just one image from two using javascript

I have 4 images on the html site just two are visible . Thumbs Up and thumbs down. I have javascript code and i want the user can choose only one of the possibilities. If user click on thumbs up or down it get donker color. But my script lets allow user choose both possibilities.
i want this
Html Code:
<body>
<img id="myImage" onclick="changeImage()" src="../Image/kleindownglow.jpg">
<img id="myImage2" onclick="changeImage2()" src="../Image/kleinupglow.png">
</body>
Script
function changeImage() {
var image = document.getElementById('myImage');
if (image.src.match("glow")) {
image.src = "../Image/kleindown.jpg";
} else {
image.src = "../Image/kleindownglow.jpg";
}
}
function changeImage2() {
var image2 = document.getElementById('myImage2');
if (image2.src.match("upglow")) {
image2.src = "../Image/kleinup.png";
} else {
image2.src = "../Image/kleinupglow.png";
}
}
Thank you for any help
HTML
<p>
<input type="checkbox" id="test1" />
<label for="test1">Red</label>
</p>
CSS
/* Base for label styling */
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
position: absolute;
left: -9999px;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
position: relative;
padding-left: 25px;
cursor: pointer;
}
/* checkbox aspect */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
content: '';
position: absolute;
left:0; top: 2px;
width: 24px; height: 24px;
border: 1px solid #aaa;
background: #f8f8f8;
border-radius: 3px;
}
[type="checkbox"]:not(:checked) + label:before
{
background-image: url('https://cdn1.iconfinder.com/data/icons/freeapplication/png/24x24/Bad%20mark.png');
}
[type="checkbox"]:checked + label:before
{
background-image: url('https://cdn1.iconfinder.com/data/icons/icojoy/noshadow/standart/gif/24x24/001_18.gif') !important;
}
/* checked mark aspect */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
position: absolute;
top: 0; left: 4px;
font-size: 14px;
color: #09ad7e;
transition: all .2s;
}
/* checked mark aspect changes */
[type="checkbox"]:not(:checked) + label:after {
opacity: 0;
transform: scale(0);
}
[type="checkbox"]:checked + label:after {
opacity: 1;
transform: scale(1);
}
/* disabled checkbox */
[type="checkbox"]:disabled:not(:checked) + label:before,
[type="checkbox"]:disabled:checked + label:before {
box-shadow: none;
border-color: #bbb;
background-color: #ddd;
}
[type="checkbox"]:disabled:checked + label:after {
color: #999;
}
[type="checkbox"]:disabled + label {
color: #aaa;
}
/* accessibility */
[type="checkbox"]:checked:focus + label:before,
[type="checkbox"]:not(:checked):focus + label:before {
border: 1px dotted blue;
}
/* hover style just for information */
label:hover:before {
border: 1px solid #4778d9!important;
}
JQuery
$("input[type='checkbox']").change(function(){
var checkedSt=$(this).prop('checked');
alert(checkedSt ? "Like" : "UnLike");
});
DEMO
Indeterminate added
DEMO
Here's JSBin that solves your issue: http://jsbin.com/fiwadinosemi/1/edit
What it does:
If both are unselected and you press one of them - pressed item is glowed
If one item is glowed and you press it - it just removes glowing effect
If one item is glowes and you press other one - other one is glowed and old one is unglowed
So, this is normal behavior for up/downvote buttons
If you want to make your code work, you would need to add a reference to the opposite image in your code and set that image to the unselected version.
If I were to do this, it would be pure CSS with a sprite and radio buttons.
HTML:
<input type="radio" name="vote1" class="vote" id="down1" value="down" /><label for="down1"></label>
<input type="radio" name="vote1" class="vote" id="up1" value="up" /><label for="up1"></label>
<hr/>
<input type="radio" name="vote1" class="vote" id="down2" value="down" /><label for="down2"></label>
<input type="radio" name="vote1" class="vote" id="up2" value="up" /><label for="up2"></label>
CSS:
.vote { display: none; }
.vote + label {
display: inline-block;
width:55px;
height:65px;
background-image: url(http://i.imgur.com/oRg1EVq.png);
}
.vote[value="up"] + label {
background-position: 55px 66px;
}
.vote[value="up"]:checked + label {
background-position: 55px 0px;
}
.vote[value="down"] + label {
background-position: 0px 66px;
}
.vote[value="down"]:checked + label {
background-position: 0px 0px;
}
Image:
Imgur
Fiddle:
http://jsfiddle.net/coL4LhtL/

Categories

Resources