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

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.

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

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 !

Assign a value to input field

let slider = document.getElementById("slider");
let rightBtn = document.getElementById("rightbutton");
let leftBtn = document.getElementById("leftbutton");
let element = document.getElementById("elementtype").innerHTML;
let celciusBoiling = document.getElementById("celciusboiling").value;
let chlorine = ["Chlorine", 100, 200];
function moveSliderRight() {
if (rightBtn.onclick) {
slider.value++;
}
}
function moveSliderLeft() {
if (leftBtn.onclick) {
slider.value--;
}
}
function main() {
moveSliderRight();
moveSliderLeft();
if (slider.value == parseInt(2)) {
element = chlorine[0];
celciusBoiling = chlorine[1];
}
}
main();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: peachpuff;
}
header {
width: 90%;
margin: 10px auto 0px;
}
header h1 {
text-align: center;
border: 1px solid black;
padding: 15px 0px;
}
.navbar {
width: 75%;
margin: 50px auto 50px;
padding: 10px 0px;
display: flex;
justify-content: space-around;
border: 1px solid black;
}
.navlinks {
border-right: 1px solid black;
width: 50%;
text-align: center;
display: block;
}
#nav3 {
border: none;
}
#intro {
margin: 0px auto 50px;
width: 40%;
text-align: center;
}
#slider {
-webkit-appearance: none;
background-color: grey;
width: 90%;
display: block;
margin: auto;
}
#slider::-webkit-slider-thumb {
cursor: pointer;
}
#slider::-moz-range-thumb {
cursor: pointer;
}
#valuetag {
text-align: center;
margin-top:25px;
}
h2 {
text-align: center;
font-size: 45px;
text-decoration: underline;
}
#display {
width: 90%;
margin-left: 50px;
margin-bottom: 50px;
font-size: 40px;
}
#display div {
display: inline-block;
width: 45%;
text-align: center;
}
span {
font-size: 15px;
}
.boiling {
margin-left: 6%;
}
.boilingpointslider {
text-align: center;
}
button {
margin: 20px 20px 20px 0px;
width: 75px;
}
<header>
<h1>Periodic Table Gases - Interative Slider</h1>
<nav>
<div class="navbar">
<div class="navlinks">Boiling Point</div>
<div class="navlinks" id="nav3">Melting Point</div>
</div>
</nav>
</header>
<div id="intro">
<p>Interact with the slider buttons to view the displayed properties held by gases, within the periodic table of elements.</p>
</div>
<h2 id="elementtype">Hydrogen</h2>
<div id="display">
<div class="boiling">
<h2>Boiling Point</h2>
<input id="celciusboiling" type="number" value="0"><span>℃</span>
<input id="fahrenboiling" type="number"><span>℉</span>
<input id="kelvinboiling" type="number"><span>K</span>
</div>
<div class="melting">
<h2>Melting Point</h2>
<input id="celciusmelting" type="number"><span>℃</span>
<input id="fahrenmelting" type="number"><span>℉</span>
<input id="kelvinmelting" type="number"><span>K</span>
</div>
</div>
<input type="range" min="0" max="9" value="0" id="slider">
<div class="boilingpointslider">
<button id="leftbutton" onclick="moveSliderLeft()">Left</button>
<button id="rightbutton" onclick="moveSliderRight()">Right</button>
</div>
I am having issues transferring a value to an input field.
Within the snippet linked their is a heading with the value hydrogen and to the bottom left their is a boiling point heading with a input field for celcius.
I'm trying to achieve a scenario whereby you move the slider along using the buttons and at each value the heading changes to a different element and the input value for just the celcius boiling point changes.
I can't get this to work though. The buttons are working to make the slider move left and right, but for whatever reason i cant get the value to appear within the input field or change the heading. I've displayed the code i have already to get the buttons to move the slider and a snippet of what i thought would allow the changes i want to take place when the slider value changes to 2. I cant get it to to work though
Thanks.
You don't show your HTML, but I presume that slider is an input (text or hidden).
The value attribute is a string, even if you assign it a number, so you need to first convert it to a integer if you want to increment or decrement it, like so:
slider.value = parseInt(slider.value)++ // or --
Note that also you are trying to parseInt(2) down in your main(), which makes no sense as 2 is already an integer.

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);
}
};

Images not showing up in IE8

I have a view with a table containing list of charges. I show a check mark image as one of the column. It is defined as input type as checkbox. The user can check/uncheck by clicking the column. he check mark image does not show up in IE8 at all. Following is the relevant inline css/script in the view (.cshtml).
input[type=checkbox].css-checkbox + label.css-label
{
padding-left: 25px;
height: 25px;
display: inline-block;
line-height: 25px;
background-repeat: no-repeat;
background-position: 0 0;
font-size: 15px;
vertical-align: middle;
cursor: pointer;
}
input[type=text].css-text
{
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
input[type=text].css-text + label.css-textlabel
{
padding-left: 25px;
height: 25px;
display: inline-block;
line-height: 25px;
background-repeat: no-repeat;
background-position: 0 0;
font-size: 15px;
vertical-align: middle;
cursor: pointer;
background-image: url(../images/checkmark.png);
}
input[type=checkbox].css-checkbox:checked + label.css-label
{
background-image: url(../images/check-mark-sm.png);
}
input[type=checkbox].css-checkbox.checked + label.css-label
{
background-image: url(../images/check-mark-sm.png);
}
.css-label
{
background-image: url(../images/checknomark.png);
}
The table in the view is loaded by reading the model in the view. Following is the code:
#for (int i = 0; i < Model.OpenCharges.Count; i++)
{
var style = (i + 1) % 2 != 0 ? "background1" : "background2";
var status = #Model.OpenCharges[i].Status;
var disabled = status != "Open" ? "disabled" : "checked=\"checked\" ";
<td style="padding: 5px;" class="body #style">
<input id="OpenCharges-Checkbox-#i" class="css-checkbox" type="checkbox" value="#Model.OpenCharges[i].AmountRemaining" IdForRecord="#Model.OpenCharges[i].Id" #disabled />
<label for="OpenCharges-Checkbox-#i" class="css-label"></label>
</td>
<td>
</td>
</tr>
}
For some reason, the check mark is not visible in IE8. I have spent long hours and nothing works for me. The same code works on all other browsers and versions of IE >8. Any ideas what I need to do?
Following things were attempted before posting this question:
Changed background-image:url to background:transparent url()
Used <!--[if lt IE 9]><script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script> <![endif]-->

Categories

Resources