First of all I'm adding a button via js:
let newTextArea = "<div class='row mt-4'><div class='col'><button type='button' class='btn btn-light rimuovi' onclick='removeIt()'>Rimuovi</button></div</div>";
Once on the page, I might want to remove it so I'm calling that function on a click:
function removeIt(e) {
e.closest(".row").remove();
}
but I'm getting
Cannot read properties of undefined (reading 'closest') at removeIt
You just forgot to pass your element (e) in the paramters in your JS fonction on the HTML.
So, try with :
onclick = 'removeIt(this)';
Working example:
function removeIt(e) {
e.closest(".row").remove();
}
<div class="row">
<button onclick='removeIt(this)'>Rimuovi</button>
</div>
Hope this helps you.
As others mentioned, you forgot to pass "this" as a parameter to your removeIt() method. The "this" keywords refers to, in this case, the element in which the click listener is used (your button). With the "this" keyword set as a parameter, JS can now look for a "closest" element with the class "row". It starts from the button and goes up the dom-tree until it finds an element with a className "row" or until it reaches the root.
Working example:
<!DOCTYPE html>
<html>
<body>
<div class="row mt-4">
<div class="col">
<button
type="button"
class="btn btn-light rimuovi"
onclick="removeIt(this)"
>
Rimuovi
</button>
</div>
</div>
<script>
function removeIt(element) {
closest = element.closest('.row');
closest.remove();
}
</script>
</body>
</html>
The main issue is because you aren't providing the e argument when you call the removeIt() function in the onclick attribute.
However you should note that using an inline onclick attribute is not good practice. A better way to achieve what you need is to attach an unobtrusive delegated event handler which accepts the Event object as an argument. You can then use that Event to retrieve the Element object which triggered the handler. Something like this:
const rowTemplate = document.querySelector('#row-template');
const container = document.querySelector('.container');
const addBtn = document.querySelector('.add');
addBtn.addEventListener('click', () => {
container.innerHTML += rowTemplate.innerHTML;
});
container.addEventListener('click', e => {
if (e.target.matches('.rimuovi'))
e.target.closest('.row').remove();
});
<button class="add">Add</button>
<div class="container"></div>
<template id="row-template">
<div class="row mt-4">
<div class="col">
<button type="button" class="btn btn-light rimuovi">Rimuovi</button>
</div>
</div>
</template>
Related
Using Django, my buttons are created using a for loop and assigned values based on model values.
Based on which button is click, I want to update the "new_note_header" with the innerHTML of the button.
I have created the following JavaScript, which works but only when the first button clicked.
<script>
function ProjectSelect () {
var x = document.querySelector('button').innerHTML;
document.getElementById('new_note_header').innerHTML = x;
}
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('button').onclick = ProjectSelect;
});
</script>
<div class = project_container>
{% for project in projects %}
<button class = individual_project_container>
{{ project }}
</button>
{% endfor %}
</div>
<div class = note_header_container>
<div class = new_note_header, id = new_note_header>
New Note
</div>
</div>
I would be grateful for any help in adapting the JavaScript so it works for all buttons clicked.
querySelector will take the FIRST element that satisfies the selector
You could use querySelectorAll and assign a click event handler to each, but I recommend using delegation:
document.addEventListener('DOMContentLoaded', function() {
const nnHead = document.getElementById('new_note_header');
document.getElementById("project_container").addEventListener("click", e => {
const tgt = e.target.closest("button");
if (!tgt.matches(".individual_project_container")) return; // not a button
nnHead.textContent = tgt.textContent.trim();
});
});
<div class="project_container" id="project_container">
<button class="individual_project_container">Project 1</button>
<button class="individual_project_container">Project 2</button>
<button class="individual_project_container">Project 3</button>
</div>
<div class="note_header_container">
<div class="new_note_header" id="new_note_header">
New Note
</div>
</div>
How can I select a button based on its value and click on it (in Javascript)?
I already found it in JQuery:
$('input [type = button] [value = my task]');
My HTML Code for the Button is :
<button type="submit" value="My Task" id="button5b9f66b97cf47" class="green ">
<div class="button-container addHoverClick">
<div class="button-background">
<div class="buttonStart">
<div class="buttonEnd">
<div class="buttonMiddle"></div>
</div>
</div>
</div>
<div class="button-content">Lancer le pillage</div>
</div>
<script type="text/javascript" id="button5b9f66b97cf47_script">
jQuery(function() {
jQuery('button#button5b9f66b97cf47').click(function () {
jQuery(window).trigger('buttonClicked', [this, {"type":"submit","value":"My Task","name":"","id":"button5b9f66b97cf47","class":"green ","title":"","confirm":"","onclick":""}]);
});
});
</script>
What is the equivalent in JS and how may i click on it
(probably like this: buttonSelected.click(); ) .
And how do i run the javascript of the button clicked ?
Use querySelector to select it. Then click()
Your HTML has a button and not an input element so I changed the selector to match the HTML.
let button = document.querySelector('button[value="my task"]');
button.click();
<button type="submit" value="my task" id="button5b9f54e9ec4ad" class="green " onclick="alert('clicked')">
<div class="button-container addHoverClick">
<div class="button-background">
<div class="buttonStart">
<div class="buttonEnd">
<div class="buttonMiddle"></div>
</div>
</div>
</div>
<div class="button-content">Launch</div>
</div>
</button>
Otherwise, use this selector:
document.querySelector('input[type="button"][value="my task"]')
Note that if you have multiple buttons with the same value you'll need to use querySelectorAll and you'll get a list of all the buttons.
Then you can loop over them and click() them all.
Edit - new snippet after question edit
jQuery(function() {
jQuery('button#button5b9f66b97cf47').click(function() {alert('success')});
document.querySelector('button[value="My Task"]').click();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="submit" value="My Task" id="button5b9f66b97cf47" class="green ">
<div class="button-container addHoverClick">
<div class="button-background">
<div class="buttonStart">
<div class="buttonEnd">
<div class="buttonMiddle"></div>
</div>
</div>
</div>
<div class="button-content">Lancer le pillage</div>
</div>
you can try:
var elements = document.querySelectorAll("input[type = button][value=something]");
note that querySelectorAll returns array so to get the element you should use indexing to index the first element of the returned array and then to click:
elements[0].click()
and to add a event listener u can do:
elements[0].addEventListener('click', function(event){
event.preventDefault()
//do anything after button is clicked
})
and don't forget to add onclick attribute to your button element in html to call the equivalent function in your javascript code with event object
I am not recommended this way because of excess your coding but as you mentioned, below are the equivalent way.
$(document).ready(function() {
var selectedbuttonValue = "2"; //change value here to find that button
var buttonList = document.getElementsByClassName("btn")
for (i = 0; i < buttonList.length; i++) {
var currentButtonValue = buttonList[i];
if (selectedbuttonValue == currentButtonValue.value) {
currentButtonValue.click();
}
}
});
function callMe(valuee) {
alert(valuee);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<input type="button" class="btn" value="1" onclick="callMe(1)" />
<input type="button" class="btn" value="2" onclick="callMe(2)" />
<input type="button" class="btn" value="3" onclick="callMe(3)" />
Using JavaScripts querySelector in similiar manner works in this case
document.querySelector('input[type="button"][value="my task" i]')
EDIT
You might save your selection in variable and attach eventListener to it. This would work as you desire.
Notice event.preventDefault() -function, if this would be part of form it would example prevent default from send action and you should trigger sending form manually. event-variable itselfs contains object about your click-event
var button = document.querySelector('input[type="button"][value="my task" i]')
button.addEventListener('click', function(event){
event.preventDefault() // Example if you want to prevent button default behaviour
// RUN YOUR CODE =>
console.log(123)
})
I'm at very beggining stage and I'd like to know something.. Is there a way to set a variable like this (or a similiar way)?
<body>
<button id="button1" onclick="change(this.something);"> click me </button>
<button id="button2" onclick="change(this.lorem);"> or this one </button>
<div id="target"> change this content </div>
<script>
function change(variable)
{
document.getElementById("target").innerHTML = variable;
}
</script>
</body>
or something like this
<body>
<button id="button1" onclick="change(this.value(v1));"> click me </button>
<button id="button2" onclick="change(this.value(v2));"> or this one</button>
<div id="target"> change this content </div>
<script>
function change(value)
{
var v1 = "something";
var v2 = "lorem";
document.getElementById("target").innerHTML = variable;
}
</script>
of course both are not working.. just don't know how to find an answer.
Perhaps you mean to pass a string literal to the function, i.e. change('literal text'):
function change(variable) {
document.getElementById("target").innerHTML = variable;
}
<button id="button1" onclick="change('something');"> click me </button>
<button id="button2" onclick="change('lorem');"> or this one </button>
<div id="target"> change this content </div>
If you intent to set the contents of the div to something or lorem, then you should pass those using a string literal instead of trying to access a property on this.
<button id="button1" onclick="change('something');"> click me </button>
<button id="button2" onclick="change('lorem');"> or this one </button>
Using a string literal passes a String containing the value specified to the change function whereas using this.something is a property accessor which will try to get the value of the something property on the this object.
In your second example, you can't use v1 and v2 from the onclick handler because those variables are scoped inside your change function and aren't accessible from the outside.
I have the following HTML:
<div class="uploadimage" >
<img src="test.png" />
<div class="form-inline" >
<button type="button" class="fileupload"> <i class="fa fa-folder-open"></i>
<input type="file" class="upload">
</button>
<button type="button" class="btnupload"> <i class="fa fa-cloud-upload"></i> </button>
</div>
</div>
in jQuery I have the following code:
$(".fileupload input").change(function () {
var input = this;
// this works but I think there is a better way
var image = $(this).closest('.form-inline').siblings('img');
});
I already get the image element but Im sure the peformance of that is no good.
Any clue if there is a better way?
There are various ways you could do this,
One of the way is to find the container div in your case which contains relevant img
$(".fileupload input").change(function () {
// this works but I think there is a better way
var image = $(this).closest('.uploadimage').find('img');
});
For your concern of which way could be better,
.siblings() : If you refer the documentation here https://api.jquery.com/siblings/ , this method matches all the specified selector and creates a new elements. This method should be used according to me only when you are going to manipulate an element, like changing css and properties. Internally, ofcourse it might be triggering find to match / get the element.
.closest() : This https://api.jquery.com/closest/ will be better in your case as compare to .sibilings(). It will not create a new element also will find only required element you are trying to search in the DOM.
You could always use Event Delegation to access both the bound element and it's descendants that match the selector. Here is an example of a delegated event that allows me to target different elements from the event object with jQuery.on().
$('.uploadimage').on('change', 'input', function(event) {
console.log(event);
var input = $(event.currentTarget);
console.log(input);
var input = $(event.target);
console.log(input);
var image = $(event.delegateTarget).find('img');
console.log(image);
var image = $(event.delegateTarget.firstElementChild);
console.log(image);
}).find('input').change();
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="uploadimage" >
<img src="test.png" />
<div class="form-inline" >
<button type="button" class="fileupload"> <i class="fa fa-folder-open"></i>
<input type="file" class="upload">
</button>
<button type="button" class="btnupload"> <i class="fa fa-cloud-upload"></i> </button>
</div>
</div>
When the browser triggers an event or other JavaScript calls jQuery's
.trigger() method, jQuery passes the handler an Event object it can
use to analyze and change the status of the event. This object is a
normalized subset of data provided by the browser; the browser's
unmodified native event object is available in event.originalEvent.
For example, event.type contains the event name (e.g., "resize") and
event.target indicates the deepest (innermost) element where the event
occurred.
When jQuery calls a handler, the this keyword is a reference to the
element where the event is being delivered; for directly bound events
this is the element where the event was attached and for delegated
events this is an element matching selector. (Note that this may not
be equal to event.target if the event has bubbled from a descendant
element.) To create a jQuery object from the element so that it can be
used with jQuery methods, use $( this ).
I would usually do like this:
You can add/generate id to the img element, and add a reference to in in the a data attribute of the btn or any other item what has to refer to it. This is easy even if generating these elements in a loop.
HTML
<div class="uploadimage" >
<img id="testimg1" src="test.png" />
<div class="form-inline" >
<button type="button" class="fileupload" data-imgitem="testimg1"> <i class="fa fa-folder-open"></i>
<input type="file" class="upload">
</button>
<button type="button" class="btnupload"> <i class="fa fa-cloud-upload"></i> </button>
</div>
</div>
JS
$(".fileupload input").change(function () {
var input = this
var reference = $(this).data(imgitem); // get id
var image = $('#' + reference); // get DOM element by id
});
all. I have html layout like this:
<div class="row" id="1">
/*Other code has nothing to do with <div class="form-group col-lg-1">*/
<div class="form-group col-lg-1">
<input type="button" class="btn btn-default" onclick="updateLine()" value="Update">
</div>
</div>
I want to obtain the div's ID, in this case, which is 1.
This is what I did.
function updateLine() {
alert(this.parent().parent().attr("id"));
}
However, it failed, then I check
alert(this);
it returns to me the window object.
So the question is , how could I get the id's value, which is 1.
Thanks.
You need to pass this to the function as follows
<input type="button" class="btn btn-default" onclick="updateLine(this)" value="Update">
function updateLine(obj) {
alert(obj);
$(obj).closest('.row').attr('id'); // will return the id, note that numeric values like 1 are invalid
}
You do not need to pass this to the function. In an event handler this is the element clicked. However, to use .parent() etc on it you need the jQuery object for that element which is $(this)
Also, I would strongly recomment using .closest instead of .parent().parent(). Something like
$(this).closest('div.row').attr('id')
Way less likely to break when you make small layout changes...
The comments about using jQuery events instead of inline javascript are also good advice.
Example:
<div class="row" id="1">
/*Other code has nothing to do with <div class="form-group col-lg-1">*/
<div class="form-group col-lg-1">
<input type="button" class="btn btn-default" value="Update">
</div>
</div>
<script type="text/javascript">
$(function(){
function updateLine(event){
alert( $(this).closest('.row').attr('id') );
}
// If you have other buttons add a class like 'btn-update' and use that instead
$('body').on('click', '.btn-default', updateLine);
});
</script>
If you want to do inline event handlers, you need to pass this:
onclick="updateLine(this)"
then in js:
function updateLine(obj) {
alert($(obj).closest('.row').attr("id"));
}
However, I'd recommend removing the inline handler if possible and using jQuery to do the binding:
$('button').click(function() {
alert($(this).closest('.row').attr("id"));
});
What you are trying do is very bad practice. It will never work.
Firs, you should not use inline javascript.
Second, you should use real jQuery code.
Below you can see a working example.
<div class="row" id="1">
<div class="form-group col-lg-1">
<input type="button" class="btn btn-default" value="Update" id="someID" />
</div>
</div>
And your jQuery code should be like:
$(function () {
$('#someID').click(function () {
alert($(this).parents('div:eq(1)').prop('id'));
});
});
Here is a working example: http://jsfiddle.net/avramcosmin/Z9snq/
A bit late but what worked for me:
$(document).on('click', '.id', function(event) {
const elem = $(this);
})