How to find the element and click by it's value? - javascript

I am doing a python selenium web driver project. Here is a button, I tried various ways, xpath, name,value,type,link text methods but it didn't work. I even tried to click by class name, but becuase the other button comes first, it clicks on that instead. Unlucky.
<li class="login_button">
<input type="button" value="Uygula" onclick="btnApply();">
<input type="button" onclick="window.location='/index.html'" value="Atla"> #I want to click this one.
</li>
I got this one also, but this is completely unrelated to this code above.
<li></li> #I wanna click this button.
As you can see, class, id, title all are the same. I can't click based on these. It seems there is only option that I can click through MyISP_PTM_35 thing but what is that? How to reach that?

There are three solutions that I think of immediately:
Find the element based on its value:
document.querySelectorAll("input").forEach(function(el){
if(el.value === "Atla"){
el.click();
}
});
<li class="login_button">
<input type="button" value="Uygula" onclick="btnApply();">
<input type="button" onclick="alert('Found It!')" value="Atla"> #I want to click this one.
</li>
Add a unique class to the element:
document.querySelector(".foo").click();
<li class="login_button">
<input type="button" value="Uygula" onclick="btnApply();">
<input type="button" class="foo" onclick="alert('Found It!')" value="Atla"> #I want to click this one.
</li>
Instead of finding the element, just so you can click it and perform some task, just perform the task:
function foo(){
alert("found it");
}
foo();
<li class="login_button">
<input type="button" value="Uygula" onclick="btnApply();">
<input type="button" onclick="foo()" value="Atla"> #I want to click this one.
</li>

Considering the HTML:
<li class="login_button">
<input type="button" value="Uygula" onclick="btnApply();">
<input type="button" onclick="window.location='/index.html'" value="Atla"> #I want to click this one.
</li>
To click on the element with value as Atla you can use either of the following locator strategies:
Using css:
let loginButton = driver.findElement(By.css("li.login_button input[value='Atla'][onclick*='index']"));
await loginButton.click();
Using xpath:
let loginButton = driver.findElement(By.name("//li[#class='login_button']//input[#value='Atla' and contains(#onclick, 'index')]"));
await loginButton.click();

Related

Simulate multiple form clicks with javascript

I have a product page on my website with product options, two with sub options. For those options with sub options they are using type="radio"
I've created javascript buttons which emulate clicking those sub options. I'd like to set up clearing the form and emulating the clicks all on one button. Currently I have a separate clear button, which still doesn't work.
Picture Example: http://i.imgur.com/uAlLBAK.jpg
Code examples below
Sub option code:
<li class="option">
<label for="09f0c74f3d92847ecfcf5837eb6b2f8b">
<input type="radio" class="validation" name="attribute[249]" value="127" id="09f0c74f3d92847ecfcf5837eb6b2f8b"/>
<span class="name">65cc</span>
</label>
</li>
<li class="option">
<label for="06fc48a0a3949a17c28162ea0eb1f406">
<input type="radio" class="validation" name="attribute[249]" value="128" id="06fc48a0a3949a17c28162ea0eb1f406"/>
<span class="name">75cc</span>
</label>
</li>
First button:
<input onclick="document.getElementById('06fc48a0a3949a17c28162ea0eb1f406').click(); document.getElementById('a596a2e871da26ba9b1cf7fffe325848').click();" type="button" value="0911" />
Second button:
<input onclick="document.getElementById('09f0c74f3d92847ecfcf5837eb6b2f8b').click(); document.getElementById('a596a2e871da26ba9b1cf7fffe325848').click();" type="button" value="0916" />
Clear options:
<input onclick="Clear();" type="button" value="Clear" />
<script type="text/javascript">// <![CDATA[
function Clear()
{
clearRadioGroup("09f0c74f3d92847ecfcf5837eb6b2f8b");
clearRadioGroup("a596a2e871da26ba9b1cf7fffe325848");
}
function clearRadioGroup(GroupName)
{
var ele = document.getElementsById(GroupName);
for(var i=0;i<ele.length;i++)
ele[i].checked = false;
}
// ]]></script>
In the above example the second button click would un-select the second element if the buttons were clicked in succession. Thoughts on at the very least being able to clear the form?
There is a typo in function clearRadioGroup. It should be
"var ele = document.getElementById(GroupName);" and not
"var ele = document.getElementsById(GroupName);".
The Clear function will work then.

JQuery Multiple Hidden Values

I have the following HTML;
<ul class="list-group">
<li class="list-group-item">
www.andrewspiers.co.uk
<input type="hidden" name="url" value="www.andrewspiers.co.uk">
</li>
<li class="list-group-item">
wikipedia.org
<input type="hidden" name="url" value="wikipedia.org">
</li>
</ul>
The plan is to add a button to each row and then get the value from the hidden field when the button is clicked.
I have this;
alert( $('input[name="url"]').val() );
But that returns the value of the first row no matter which button is clicked.
This should work:
$('button').click(function(){
console.log($(this).closest('li').find('input[name="url"]').val())
})
You need to use $(this) within the click function to refer to that specific element and then traverse the DOM accordingly (multiple ways to skin a cat on this one) to get the hidden input.
jsFiddle example
Assuming your buttons are placed inside the same li, you need a more specific selector:
alert( $(this).siblings('input[name="url"]').val() );
You can add buttons like this :
$('.list-group-item').each(function(){
$(this).append('<input class="clicked" type="button" value="Click me"/>')
})
YOu can then get value of each hidden according to the button like this:
$('.clicked').on('click',function(){
var hiddenval =$(this).parent().find('input[name="url"]').val();
console.log(hiddenval);
})

Getting active buttons in button-group (bootstrap)

I have a button group and am willing to update some other field on change according to the active buttons.
See the jsfiddle here
This is the HTML, copied from the documentation:
<div class="btn-group arrActiviteit arrUpdate" data-toggle="buttons">
<label class="btn btn-primary active" data-wat='foo'>
<input type="checkbox"> Item 1
</label>
<label class="btn btn-primary" data-wat='bar'>
<input type="checkbox"> Item 2
</label>
<label class="btn btn-primary" data-wat='something'>
<input type="checkbox"> item 3
</label>
<label class="btn btn-primary" data-wat='orElse'>
<input type="checkbox"> item 4
</label>
</div>
The Button row acts like it should do.
Then I watch for a click event on the .arrUpdate div for change. I've got multiple button groups which all have the .arrUpdate class. That's the reason for the second class: .arrActiviteit
$('.arrUpdate').click(function(e){
val = ''; // for holding the temporary values
$('.arrActiviteit label').each(function(key, value){
if(value.className.indexOf('active') >=0){
val += value.dataset.wat
}
})
// just for debug reasons.
$('#hierHier').html(val);
})
But it appears that the 'active' class gets added after the click event is fired. So the value in #hierHier is always behind one click, so to say.
How can I resolve this?
Or is there a better way to retrieve all the active buttons in this checkbox-array?
SOLVED
update: better solution Twitter Bootstrap onclick event on buttons-radio
http://jsfiddle.net/hA423/7/
I solved it using a timeout to make your function run after bootstrap events...
There must be some other ways to do it...
$('.btn').on('click',function(e){
setTimeout(count);
})

two forms, two divs, appending data from only one form to only one div?

I have a slider with two slides, both containing an identical form. When I submit from one or the other form, I want to append the data from that form into the slide containing the form. I can obtain data from only one form, but I just can't get the append to only work on one slide. It always adds to both. I can't just use different IDs because I will be using ajax to change the non-visible slide based on forward or back slide navigation so the slider is theoretically infinite.
Here is my html (simplified for easier viewing):
<div class="flexslider">
<ul class="slides">
<li>
<ul class="table">
<li>
<div class="clearfix">
<span class="nameSpan">Customer One</span>
</div>
</li>
</ul>
<form class="addNewCustomerForm" method="post">
<h1>Add New Customer</h1>
<input type="text" name="customerName" id="customerName">
<input class="button" type="submit" value="Add New Customer">
</form>
</li>
<li>
<ul class="table">
<li>
<div class="clearfix">
<span class="nameSpan">Customer One</span>
</div>
</li>
</ul>
<form class="addNewCustomerForm" method="post">
<h1>Add New Customer</h1>
<input type="text" name="customerName" id="customerName">
<input class="button" type="submit" value="Add New Customer">
</form>
</li>
</ul>
</div>
And here is my javascript (Again, simplified):
$(".addNewCustomerForm").submit(function(event) {
$.post('addNewCustomer.asp', $(this).serialize(), function(result){
$(".table", this).append(result);
$(".newLine").slideDown();
})
return false;
});
You probably want something like this
$(".addNewCustomerForm").submit(function(event) {
var thisForm = $(this);
$.post('addNewCustomer.asp', $(this).serialize(), function(result){
thisForm.parent().find('.table').append(result);
$(".newLine").slideDown();
})
return false;
});
(tested it locally, changed first to find)
That's because $(".table", this) matches both slides.
You can solve this by giving each slide and id, like id="slide1"
Then do $("#slide1") (or slide2) depending on which was submitted.
You basically need the bind the form to the slide, since each slide has it's own form.
Similarly you might need to do a similar thing for $(".addNewCustomerForm"). Give each form a unique id and bind one submit handler to #slide1, and the other to #slide2

jQuery + Appending a clone multiple times, at different times?

I have this form which has a section where a user can specify an indefinite number of value pairs, specifically, a language and a level of proficiency.
I have the DOM structured like this:
<ul id="language-list">
<li class="user-language-item">
<select name="language[]" class="user-language-select">...</select>
Level: <select name="proficiency[]">...</select>
<input type="button" value="Remove" class="remove-language" />
</li>
<li class="user-language-item">
<select name="language[]" class="user-language-select">...</select>
Level: <select name="proficiency[]">...</select>
<input type="button" value="Remove" class="remove-language" />
</li>
<li class="user-language-item">
<select name="language[]" class="user-language-select">...</select>
Level: <select name="proficiency[]">...</select>
<input type="button" value="Remove" class="remove-language" />
</li>
</ul>
<input type="button" value="Add another language..." id="add-a-language" />
If the user clicks on the Add another language... button, a new list item containing the same form elements should be inserted to the list.
And here is my code:
$(function(){
//Save a clone of one list item during initialization.
var liItem = $('.user-language-item').last().clone();
$('#add-a-language').click(function(){
//Append the clone to the list item. But this only works once!
$('#language-list').append(liItem);
});
//Note that there might be an instance where there are no list items present, which is why I opted to clone the a list item during initialization.
$('.remove-language').live('click', function(){
$(this).parents('li.user-language-item').fadeOut(500, function(){
$(this).remove();
});
});
});
But the clone seems to be only usable once. Upon clicking the Add a language... button the second time, no list item is appended. (Interestingly, when I output the variable on the console, it still contains the clone!)
One way around this would be saving the HTML mark-up as a string, but I am avoiding this approach as the elements are dynamically loaded via PHP, and I'd rather just change one part of my code whenever I need to modify the mark-up.
How can I possibly make this work?
You will have to clone it every time when you want to add
$('#add-a-language').click(function(){
var liItem = $('.user-language-item').last().clone();
//Append the clone to the list item. But this only works once!
$('#language-list').append(liItem);
});
Demo
As per comment:
Keep one li like this:
<li class="user-language-item hidden" id="placeHolderLi">
<select name="language[]" class="user-language-select">...</select>
Level: <select name="proficiency[]">...</select>
<input type="button" value="Remove" class="remove-language" />
</li>
Where .hidden just marks it to display:none;
.hidden{
display:none;
}
Then while cloning you always clone this li and make it visible so that even if user has deleted all the li, new elements can still be added.
$('#add-a-language').click(function(){
var liItem = $('.user-language-item:first').clone(true).show();
//Append the clone to the list item. But this only works once!
$('#language-list').append(liItem);
});
Demo

Categories