I'm experiencing something that seems quite wrong with events and jquery.
I have the following simple HTML list
<ul>
<li><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus-sign"></span></button> Chocolate</li>
<li><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus-sign"></span></button> Butter</li>
<li><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus-sign"></span></button> Milk</li>
<li><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus-sign"></span></button> ugar</li>
</ul>
and the following JavaScript:
$(document).on("click", "button", function(evt) {
console.debug("got a click in", evt.target);
});
When I click in a button I get
got a click in <span class="glyphicon glyphicon-minus-sign"></span>
and not in the button.
Why?
The target property of event objects points to the originator of the event; here, it’s the element that was the first target of the click, and that was apparently the <span>.
If you want the element selected by .on(), jQuery provides it as this.
$(document).on("click", "button", function(evt) {
console.debug("got a click in", this);
});
(Note that you don’t have to wait for $(document).ready when using delegation rooted in document.)
Any element can receive a click event. If it doesn't handle it the event will "bubble up" through parent elements.
Related
I'm trying to change the href on this element:
"<button onclick="smoothscroll()" class="btn btn-white btn-small" href="#contacto">blah blah <i class="fas fa-chevron-right"></i></button>"
It doesn't have an ID so I tried like this:
document.getElementsByClassName('btn btn-white btn-small')[0].href="https://www.mysite.cl/#"
But it doesn't seem to work.. any ideas? I have other element that works just like I want this button to work:
"<button onclick="smoothscroll()" class="btn" href="#">blah blah</button>"
But I also tried this:
document.getElementsByClassName('btn btn-white btn-small')[0].href="#"
And it doesn't work either
It is not advised to use href as attribute for html button, use this instead..
<a href = '#blablabla'>Scroll to bla bla bla </a>
Then add this css property to the page
html {
scroll-behavior: smooth;
}
The above css will automatically cause smooth scrolling each time a user scrolls by clicking a link.
But if you insist
Try this.. Change your buttons to
"<button onclick="smoothscroll(this)" class="btn btn-white btn-small" href="#contacto">blah blah <i class="fas fa-chevron-right"></i></button>"
Then your smoothscroll() function should look like..
function smoothscroll(button){
button.setAttribute('href', 'Your new link');
}
If you already know what the href is then select it using that.
Since href is not standard to a button Element, to update the href attribute, use setAttribute.
const button = document.querySelector('button[href="#contacto"]')
button.setAttribute('href', "#");
console.log(button)
<button onclick="smoothscroll()" class="btn btn-white btn-small" href="#contacto">blah blah <i class="fas fa-chevron-right"></i></button>
If you have control of the html, then you should look to change the button to an a element instead.
I have many <li> with specific data-id, want to get innerHtml of first <Div>
For Example on this sample, it would to be: "World"
<li class="dd-item" data-id="1123066248731271" data-slug="" data-new="1" data-deleted="0"><div class="dd-handle">World</div> <span class="button-delete btn btn-danger btn-xs pull-right" title="Delete" data-owner-id="1123066248731271"> <i class="fa fa-times" aria-hidden="true"></i> </span><span class="button-edit btn btn-success btn-xs pull-right" title="Edit" data-owner-id="1123066248731271"><i class="fa fa-pencil" aria-hidden="true"></i></span></li>
This is my code, that doesn't help:
var target = $('[data-id="1123066248731271"]');
alert(target.firstChild.innerHTML);
document.querySelector('[data-id="1123066248731271"]').textContent
Maybe this is what you need?
Being a jquery element, you can use find() method to find all the div elements inside him, with first(), you get the first element, finally, with html(), you get its content.
var target = $('[data-id="1123066248731271"]');
alert(target.find('div').first().html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="dd-item" data-id="1123066248731271" data-slug="" data-new="1" data-deleted="0"><div class="dd-handle">World</div> <span class="button-delete btn btn-danger btn-xs pull-right" title="Delete" data-owner-id="1123066248731271"> <i class="fa fa-times" aria-hidden="true"></i> </span><span class="button-edit btn btn-success btn-xs pull-right" title="Edit" data-owner-id="1123066248731271"><i class="fa fa-pencil" aria-hidden="true"></i></span></li>
first problem $('[data-id="1123066248731271"]') returned a object of all elements with [data-id="1123066248731271"]. for target the first element, you need add [0] after : $('[data-id="1123066248731271"]')[0]
now if you want target the div element you need specify div into $ like: $('[data-id="1123066248731271"] div')[0]. Now you got the first div and you can get innerHTML with : target.innerHTML
The full code :
var target = $('[data-id="1123066248731271"] div')[0];
alert(target.innerHTML);
and without Jquery ( more simply i think ) :
var target = document.querySelector('[data-id="1123066248731271"] div');
alert(target.innerHTML);
Perhaps you want to use firstElementChild instead of firstChild?
Or you could use the CSS selector [data-id="1123066248731271"] > div:first-child:
var target = $('[data-id="1123066248731271"] > div:first-child');
alert(target.innerHTML);
Edit:
I noticed a translation error. I don't use jQuery myself, so instead of $ I used document.querySelector. But the behavior of $ corresponds to document.querySelectorAll instead. Sorry...
This should work fine:
var target = $('[data-id="1123066248731271"] > div:first-child')[0];
alert(target.innerHTML);
or this:
var target = document.querySelector('[data-id="1123066248731271"] > div:first-child');
alert(target.innerHTML);
As a non-jQuery user, I personally prefer the latter.
I have a page with many articles. Each article has a delete button. How can I identify the button clicked for the article?
Currently I have this:
<button type="button" id="delete-article" class="btn btn-small btn-danger">Delete</button>
$('#delete-article').on('click', function(e) {
console.log('Test delete article');
});
This logs 'Test delete article' according to the number of articles on the page.
You can attach the event on button and use this object to refer the currently clicked button:
$('button').on('click', function(e) {
console.log(this.id);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="delete-article" class="btn btn-small btn-danger">Delete</button>
<button type="button" id="delete-article-2" class="btn btn-small btn-danger">Delete</button>
You can use your event variable to get the target of the event (that is, the element responsible) and from there get its id, like this:
let btnId = event.target.id;
However, for that to work properly you should assign unique ids to your buttons. If you want to provide other data (or you don't want to use id) you can append custom attributes, like data-value or similar, and use it like this:
let myValue = event.target.getAttribute('data-value');
You need to establish relation between article and corresponding button, one way to implement is by using HTML5 data attribute.
assign data-articleId to article id in button element and when you click the button you can access which button was clicked by using Jquery .data() function.
<button type="button" data-articleId='123' class="btn btn-small btn-danger delete-article">Delete</button>
$('.delete-article').on('click', function(e) {
$(this).data('articleId'); //will return 123;
console.log('Test delete article');
});
If all the buttons have this markup
<button type="button" id="delete-article" class="btn btn-small btn-danger">Delete</button>
Then the DOM sees them as just one button, you should find a way to attach unique ids to your buttons
You can get an object of clicked button then you can get any details from that object like an index or whatever you want.
$('#delete-article').click(function(){
console.log($(this));
console.log($(this).index());
});
You can directly achieve it by using the JavaScript.
document.addEventListener('click',(e)=>{
console.log(e.target.id)
})
<button type="button" id="delete-article1" class="btn btn-small btn-danger">Delete1</button>
<button type="button" id="delete-article2" class="btn btn-small btn-danger">Delete2</button>
<button type="button" id="delete-article3" class="btn btn-small btn-danger">Delete3</button>
<button type="button" id="delete-article4" class="btn btn-small btn-danger">Delete4</button>
<button type="button" id="delete-article5" class="btn btn-small btn-danger">Delete5</button>
<button type="button" id="delete-article6" class="btn btn-small btn-danger">Delete6</button>
<button type="button" id="delete-article7" class="btn btn-small btn-danger">Delete7</button>
I want to change the content of a span in my form
HTML:
<form action="javascript:submit()" id="form" class="panel_frame">
<label>Origin:</label>
<div class="input-group" id="input-group">
<input type="text" id="origin" name="origin" class="form-control">
<span class="input-group-btn">
<button id="btn-default" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>
</span>
</div>
What I want change is che content of <span class="input-group-btn"> with
<button id="btn-default" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
So what change is: the icon pushpin to remove and the action useCurrentPosition to clearPosition.
I' using jquery and despite I've read other answer about similar question on Stack like: How can I change the text inside my <span> with jQuery? and how to set a value for a span using JQuery I haven't solved the issue.
I tried:
$("#input-group span").html('
<button id="btn-default" class="btn btn-default" type="button" onclick="br_bus.useCurrentPosition()">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>
');
,giving an id to the span and also modify the full div, but none solved my problem.
What am I missing?
Here's a way to overcome the problem of changing the onclick attribute, which is bad practice, without storing a Global var, and using jQuery delegation (learn to use it, it's really good):
$(document).on('click','.btn', positionChange); // Give that button an id on his own and replace '.btn' with '#newId'
// Not using an anonymous function makes it easire to Debug
function positionChange(){
var $btn = $(this), // Caching jQuery elements is good practice
$span = $btn.find('span'), // Just caching
pushpinApplied = $span.hasClass('glyphicon-pushpin'); // Check which icon is applied
( pushpinApplied ) ? useCurrentPosition() : clearPosition();
$span.toggleClass( 'glyphicon-pushpin glyphicon-remove' );
}
Rather than changing the function called in the onclick attribute I suggest having a flag in one function to define the logic it should follow.
For example:
function positionChange(this){
var $this = $(this);
if(!$this.data("currentpositionused")){
//useCurrentPosition() code here
$this.data("currentpositionused", true);
}
else {
//clearPosition() code here
$this.data("currentpositionused", false);
}
Then change your HTML to:
<button class="btn btn-default" type="button" onclick="positionChange(this)">
If you want to change only the onclick attribute of the button inside the particular span you can use the following in your script.,
$(document).ready(function(){
$("span.input-group-btn button").attr("onclick","clearPosition()");
});
EDIT
$(document).ready(function(){
$("span.input-group-btn button").attr("onclick","clearPosition()");
$("span.input-group-btn button span").attr("class","Your_class");
});
And also learn about how to change/add/remove attribute values....
Try this:
$("span.input-group-btn").html('<button class="btn btn-default" type="button" onclick="clearPosition()">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>');
Is it like This ?
how to change onclick event with jquery?
$("#id").attr("onclick","new_function_name()");
jquery change class name
$("#td_id").attr('class', 'newClass');
If you want to add a class, use .addclass() instead, like this:
$("#td_id").addClass('newClass');
I've a button under one class. They are configured to be dual-actioned.
They are disabled before a certain event. Their DOM while they are disabled:
<div class="doc-buttons">
<a href="#" onclick="actualsize();" id="tip-size" class="left btn btn-white btn-rounded btn-sm icon-size tooltipstered" disabled="disabled">
<i></i>
</a>
<a href="#" onclick="scaletofit();" id="tip-fit" class="left btn btn-white btn-rounded btn-sm icon-fit tooltipstered" disabled="disabled" style="display: none;">
<i></i>
</a>
...
After a certain event, they are enabled and their DOM changes to:
<div class="doc-buttons">
<a href="#" onclick="actualsize();" id="tip-size" class="left btn btn-white btn-rounded btn-sm icon-size tooltipstered">
<i></i>
</a>
<a href="#" onclick="scaletofit();" id="tip-fit" class="left btn btn-white btn-rounded btn-sm icon-fit tooltipstered" style="display: none;">
<i></i>
</a>
...
...
...
All I have to do is to Assert (using TestNG) that they are enabled and disabled at the right time (sounds pretty simple!)
ele1 = _driver.findElement(By.xpath("//a[#id='tip-size']"));
ele2 = _driver.findElement(By.xpath("//a[#id='tip-fit']"));
ele1,2 represent the locator of these button/s.
System.out.println("ele1.getAttribute("disabled")");
System.out.println("ele2.getAttribute("disabled")");
To my surprise, above print statements always return TRUE irrespective of the state of the buttons (enabled or disabled)
How should I assert them in their disabled and enabled state?
PS: I'm new to WebDriver, Java and TestNG. Any explanation, link to blogs, etc. would be highly appreciated
Yours should work. Not sure why does not. But, another workaround could be to check if the attribute present with JavaScriptExecutor
boolean hasTipSize = (boolean) ((JavascriptExecutor)driver).executeScript("return document.getElementById('tip-size').hasAttribute('disable')");
boolean hasTipFit = (boolean) ((JavascriptExecutor)driver).executeScript("return document.getElementById('tip-fit').hasAttribute('disable')");
They should return true if disabled attribute present else false
The elements should be re-initialized after the so-called "event".
Steps :
1. Capture the elements ele1, ele2.
ele1.getAttribute("disabled") will be "true/disabled"
ele2.getAttribute("disabled") will be "true/disabled"
Perform the event (which changes the state of the elements)
Now capture the elements once again.
ele1 = _driver.findElement(By.xpath("//a[#id='tip-size']"))
ele2 = _driver.findElement(By.xpath("//a[#id='tip-fit']"));
Now extract the element properties/attributes.
ele1.getAttribute("disabled") should be updated
ele2.getAttribute("disabled") should be updated