How to pass a parameter and get the event caller JS - javascript

I need to pass parameter from HTML to the JS function. I can't set unique id, because elements are in loop. So it looks like this:
#foreach ($meals as $meal)
<button class="btn btn-primary" onclick="addToCart('{{ $meal->id }}')">
#endforeach
But in calling function, I need access both to input parameter and event caller:
let addToCart = (id, caller) => {
console.log(id);
console.log(caller);
}
I tried to put this as second parameter, when calling function:
<button class="btn btn-primary" onclick="addToCart('{{ $meal->id }}', this)">
Well, it works, but my next task is to replace event caller with some other DOM element, using JQuery.
let addToCart = (id, caller) => {
caller.replaceWith("<h1>helloworld</h1>");
}
Unfortunately that replaces event caller with that, only as innerHTML of parent element, without interacting with tags. So, I'm getting smthing like this:
What can I do in that case?
UPD:
I'm getting this:
But I need THIS:

In case you meant to replace the button that fired the click event with a different html object instead of just replacing its text content like you did in your example, the key was using replaceWith on a jQuery object instead of calling it from an HTMLDocument.
The difference between https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceWith and https://api.jquery.com/replacewith/
So to force the invocation from the jQuery object, just use $(caller)
let addToCart = (id, caller) => {
$(caller).replaceWith( "<h1>helloworld</h1>" );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn btn-primary" onclick="addToCart('id', this)">click to replace</button>

Related

When ever I try onclick function, I get reference error

I am trying to use the on-click event in my javascript file. But, whenever, I use it, it says that the function is declared, but never used. Can you please help me resolve this issue? You can check the code below, as well as in the image.
let showtoDos = () => {
let li = "";
if(toDos) {
toDos.forEach((todo, id) => {
li += `<li class="task">
<label for="${id}">
<input class="clicked" type="checkbox" id="${id}" />
<p>${todo.name}</p>
</label>
<div class="settings">
<i id="ellipsis" class="fa-solid fa-ellipsis"></i>
<ul class="task-menu">
<li><i class="fa-solid fa-pen"></i>Edit</li>
<li onclick="deleteTask(${id})" class="delete" ><i class="fa-solid fa-trash"></i>Delete</li>
</ul>
</div>
</li>`;
});
}
taskBox.innerHTML = li;
}
showtoDos();
function deleteTask(deletedId) {
console.log(deletedId);
}
Moreover, you can check in the below image that, whenever I click on the delete button on the browser, it gives a reference error.
You have two different problems there:
The IDE is doing validation of your code showing warnings and can't
find any line calling that function. The only point you targeted
that function is when you defined the onclick attribute of the li
element but it happened inside a string literal and it doesn't count
for the linter. You can ignore this.
The javascript code you have in that file won't run in the global
scope so the function defined there won't be visible to the li item
when its event will fire. You should try attaching an event handler
via javascript so to be sure the handler will be attached until you
still have control of that scope.
Just after you showToDos() you can try to run the following:
//for each delete list item
document.querySelectorAll('li.task ul.task_menu li.delete')
.forEach( (o, i) => {
//bind an handler (deleteTask) for its click event (deleteTask should be in this scope now)
o.addEventListener("click", deleteTask);
});
DISCLAIMER:
Unfortunately that selector I used with querySelectorAll will get ALL those items even those that already got the handler attached (if any already existed with the same selector criteria). Before doing addEventListener, one strategy could be to check if there's already an handler for that event on that object.
A better solution would be to use that html code you crafted with a template string, create an html elements tree from there and call querySelectorAll(+attachEventHandler) from such object before appending it to taskbox. It wouldn't require you to make any check before attaching the event handler because you'll be targeting only the newly created ones.
Or you could as someone suggested to make that function available in the global scope but it wouldn't scale really well due to name collisions (this is one of the unsafe ways to do it):
var deleteTask = (/*args*/) => {/*code here*/}
You need to place your function in the global scope (window object in browser) if you want to access it like that, try:
window.deleteTask = function (deletedId) {
console.log(deletedId);
}

onClick function for the specific item in a map function

I have objects stored in my state (workitems) with different attributes such as id, title, description etc. I map them out in my render in a table to make them visible. So far so good. But when I try to ad a "onClick" inside of the map function, it will not only trigger for the specific element that was clicked on, but all workitems object in the map will trigger as well.
In my render;
{workitem.company ? workitem.company + " - " : ""}
{workitem.title}
<div className="description pt-2" onClick= {this.descriptionPopOut(workitem.description)> // My onclick function
<strong>Description: </strong>
{workitem.description ? this.trimWord(workitem.description.replace("...", ""), 850, "...")
: ""}{" "}
...
</div>
The onClick will lead to a very simple function that has an alert, and take the object description as input.
descriptionPopOut = (description) => {
alert(description);
}
Above will make the alert pop out with all the object description property, and not for the specific element that has been clicked. Is there any way to solve this?
Its because on each render your function is calling i.e
this.descriptionPopOut(workitem.description)
. While you want to call on when you click. You can either bind the function so that you can use it later when you click :
this.descriptionPopOut.bind(this, workitem.description)
or you can use fat arrow function to return function i.e
onClick = {() => this.descriptionPopOut(workitem.description)>
(It ensure it creates function reference and when you click it, it invokes your function with specific param)
You are calling function in each iteration.
Try doing like this:
this.descriptionPopOut.bind(this, workitem.description)
The problem is you are calling your function incorrectly.
Don't do this onClick = {this.descriptionPopOut(workitem.description)>
Since you want to pass a parameter do this
onClick = {() => this.descriptionPopOut(workitem.description)>

Parameter passing in JavaScript onclick: this.id versus other attributes

I suspect there is something basic about JavaScript parameter passing that I do not understand.
If I click on this button, I get an 'undefined' message in the alert box.
<button onclick="play_audio(this.src)" src="foo.m4a">▶</button>
If I click on this button, the string value is passed properly:
<button id="foo.m4a" onclick="play_audio(this.id)">▶</button>
Codepen here:
https://codepen.io/anon/pen/JBpMYo
A button does not have a src attribute. However, you can use this.getAttribute('src').
<button src="foo.m4a" onclick="play_audio(this.getAttribute('src'))" >▶</button>
<script>
function play_audio(src){
console.log("Playing "+src);
}
</script>
It is recommended that you usedata-src (you can use any prefix after data-, not necessarily src) and this.dataset.src instead (you can use the data-* attribute to embed custom data) because it will ensure that your code will not clash with HTML Element attributes for future editions of HTML. See the documentation.
<button data-src="foo.m4a" onclick="play_audio(this.dataset.src)" >▶</button>
<script>
function play_audio(src){
console.log("Playing "+src);
}
</script>

Automatically fill function arguments

in java and in android studio when we write a function like this:
function test (View v) { ... }
and put it in xml layout
<TextView
android:onclick="test" />
v as an argument filled automatically by java and when we click at that TextView v filled with property of that TextView clicked on
how can I define this in javascript and html tags ?
Thanks.
You can do something like this
function myFunction(element) {
element.innerHTML = "hello";
}
<button onclick="myFunction(this)">Click me</button>
Pass the clicked element that is stored in this as a parameter to the click function.
All you need to do is to add the "this" keyword, "this" keyword automatically gets the action of the current element if it clicked, checked, etc in cases of buttons, check-boxes, respectively...
I totally agree with Costin here.
HTML :
<button id="btn" onclick="someFunction(this)">Tap It</button>
JS:
function someFunction(element) {
element.innerHTML = "hello";
}
which means the someFunction will automatically get that the element is "button" here and on its click, the action needs to be performed is to change its HTML and display "hello".

how use entity key (or another object) for javascript call from html

How can I create a button that in his onClick event calls a function with an object? An entity key in my special case?
I populate a table of all objects in my database and want to add a delete button... The delete function needs the key, but I can't get this to work
something like the following does not work:
htmlString += "<td class='devicenameCol'><input id=\"deleteQuestion\" type=\"button\" value=\"löschen\" onclick=\"deleteQuestion(" + item.key + ");\"/></td>";
I use this HTML / Jinja code in a table to create buttons in a table row:
<td class="center"><input class="button" type="submit" name="eid={{ rows.eid }}" value="{{ rows.caption }}"></td>
where :
rows.eid contains the entity id
rows.caption contains the button text
And I use "eid=" as a token to find the button (token) in the request data.
There are a few ways to go about this. If you are using the onclickattribute, you can call the method with a parameter like so:
<button onclick="myFunction(value)" />
Depending on how you are populating the list, this might be simple. For instance if you are using ASP.NET MVC you could do the following
#foreach(var entity in myEntitireDatabase)
{
<button onclick="myFunction(#entity.Key)" />
}
However if you are populating the table using JavaScript, you might instead want to bind the key to a attribute, and read it from the element. For instance you could add a data-key attribute like so:
<button data-key="value" />
and the in JavaScript attach a handler for each button
button.addEventListener("click", myHandler)
and in the myHandler function, the this pointer is set to the element, so you could simply read the data-key attribute:
function myHandler(){
var key = this.getAttribute("data-key");
//Code to perform delete
}

Categories