$(this).attr("data-id") returning undefined - javascript

I'm building a webshop and on every item there is a button to add that item to the shopping cart.
<?php
$i = 0;
$path = "../images/women/winter/winter1";
$lang = "description_".get_param();
if(!$result = $db->query("SELECT * FROM cloths;")){
die("There was an error running the query [".$db->error."]");
}
while($winter = $result->fetch_assoc()){
echo "<div class = \"boxsale $winter[image]\">
<img src = \"$path.jpg\"/>
<div class = \"test\"> $winter[$lang] </div>
<select>
<option>S</option>
<option>M</option>
<option>L</option>
<option>XL</option>
<option>XXL</option>
</select>
<button class = \"addToCart\" onclick = \"executeJS()\"> <i class = \"fa fa-shopping-cart\" data-id = \"$i\" aria-hidden=\"true\"></i></button>
</div>";
$i++;
}?>
</div>
when you click on the button the executeJS() in the last few lines gets called from a seperate file.
addToCart.js
function executeJS(){
var id = $(this).attr("data-id");
$.ajax( {
type: "GET",
url: "ajax.php?id=" + id + "&action=add"
})
.done(function(){
alert("Product has been added.");
});
}
i wanted to grab the data-id from the button that has been clicked, with
$(this).attr("data-id"); but all i get is a header that has undefined as data-id.
id=undefined&action=add
can anyone please point me in the right direction?
thanks

The problem is because $(this) is not correctly being applied to the element you're trying to access. When using a string based onclick handler (onclick="test()"), this refers to the window, and NOT the element you're trying to access.
function test() {
console.log(this.id);
}
Link
If you want to use the string based onclick notation, pass your element in explicitly, and do $(element).
<button class = \"addToCart\" onclick = \"executeJS(this)\" data-id = \"$i\" />
Javascript:
function executeJS(element){
var id = $(element).data('id');
...
Personally, skip the attr-id all together, and simply pass your id directly:
<button class = \"addToCart\" onclick = \"executeJS($id)\" />

It looks like this may be pointing to the window instead of the button.
You can fix this by manually looking for the button:
var id = $(".addToCart").attr("data-id");
This will only really work if you only have one button. What you should do is use jquery to attach the event to the button.
In your javascript:
$(".addToCart").click(function(e){
var id = $(e.target).attr("data-id");
$.ajax({
type: "GET",
url: "ajax.php?id=" + id + "&action=add"
})
.done(function(){
alert("Product has been added.");
});
})
The e.target refers to the button that is being clicked.

Use regular function (function(){}) instead of arrow function:
$(document).on("click",".deleteBtn",function(){
//Your Code
});

Since you're using jQuery, this is how you should be doing it. First, remove the inline event handler in your PHP (e.g. onclick = \"executeJS()\")
The other issue is that your buttons don't have a data attribute but their <i> children do.
Next, create your jQuery event handler, binding to the button. By doing this you can use $(this).find('i') to get the fontawesone <i> element and its data attribute, .attr("data-id"):
$('button.addToCart').click(function() {
var id = $(this).find('i').attr("data-id");
$.ajax({
type: "GET",
url: "ajax.php?id=" + id + "&action=add"
})
.done(function() {
alert("Product has been added.");
});
})
jsFiddle example

Related

How do I pass reference of the p tag when ever the button is clicked?

This is how i have created the button
<button type="submit" id="likebtn" onclick="likedpost(this) " data-postid="<%=blog._id%>" data-author="<%=user.username%>">Like</button>
<span ><p id="likescounter"><%=blog.likes%> </p></span> // I want to pass the reference of this p (id) when clicked the above button
This is my liked post function-
function likedpost(el)
{
var id = el.dataset.postid;
var author = el.dataset.author;
console.log("id form likedpost function =" +id+"and author of this post is="+author);
console.log('post liked');
var request = $.ajax({
type: "POST",
url: "api/index/like",
data: {id: id, author:author},
async:false,
dataType:"html",
success: function(data){
findingnumberoflikes(data);
console.log("action performed successfully")
},
error: function(){
console.log("error occured");
}
});
}
function findingnumberoflikes(data)
{
console.log("the data returned is "+ data);
$(#likescounter).html(data); // here I can not select the likescounter id
console.log("likes counter updated");
}
Basically, I want to select the respective p with jquery's $ selector and update its data but it is giving me private identifiers are not allowed outside class bodies error.
How can I do that. Thank you!
There is a list of above buttons and p tag are for every blog post in the databse. Sorry! earlier I couldn't frame my question better.
Although we can do this with sibling selector etc.. I suggest you to arrange this differently for example,
<span ><p id="likescounter"><%=blog.likes%> </p></span>
in this line, change id="likescounter" to something that would give likescounter+blogid
something that would replace like the following
<span ><p id="likescounter-<%=blog._id%>"><%=blog.likes%> </p></span>
you wanna get "id=likescounter-1" for blog id 1, id="likescounter-2" for blog id 2 etc...
so essentially the id will be unique for each with "likescounter-" and corresponding blogid combied with it.
then in the button click function, simply do this
function likedpost(el){
var id = el.dataset.postid;
// Here's the reference to the element
// with jquery syntax it would be
var likesCounter = $("#likescounter-"+id)
// for vanilla js it would be
var likesCounter = document.getElementById("likescounter-"+id)
...
}

$(this).attr('id') gives blank values in jQuery

I have a link as follows:
<a href="#" id="<?php $res['id'];?>" class='bid_accept'>Accept</a>
I need to pass the value of id to another page using Framework7 as follows:
$$('.bid_accept').on('click', function (e) {
e.preventDefault();
var value = $(this).attr('id');
var jsonstring = JSON.stringify(value);
myApp.confirm('Are you sure?', 'Custom Title',
function (jsonstring) {
myApp.alert('Your name is "' + value + '". You clicked Ok button');
},
function () {
myApp.alert('You clicked Cancel button');
}
);
});
I receive alerts as:
Your name is "". You clicked Ok button
I also tried:
var value = this.id;
Why am I not getting the id value?
If you use JSON.stringfy(value) it means you are setting that ID out of a JSON value, i do not know if i am write but the ID attribute takes a 1 word name and JSON.stringfy() produces multiple words separated by spaces. Let alone i think IDs have a specific number of characters so you might be intializing a very long name.
Not really sure what you want to achieve but HTML allows you to add attributes of your own and read them in JQuery like:
<a href="#" myAttr="<?php $res['id'];?>" class='bid_accept'>Accept</a>
such that when you click your code will be like:
$$('.bid_accept').on('click', function (e) {
var value = $(this).attr('myAttr');
....
}
This line has error
<a href="#" id="<?php $res['id'];?>" class='bid_accept'>Accept</a>
change it to
<a href="#" id="<?php echo $res['id'];?>" class='bid_accept'>Accept</a>
And in jquery part instead of $ you have to use $$.
var value = $$(this).attr('id'); // check $$ sign

How can I get ID from "ul" dynamic tag

I have the next situation.
I have a button in HTML code. When I press one of the options from the button I call a function that constructs the content from other button.
I have a ul tag in HTML code with a list of li tags inside. The value of this li tags are generated dynamically with a query database.
When I generate the options from li tags I assign a different ID to each other.
Here you can see the code that I have for the second button:
<div class="dropdown" class="btn-group-lg" id="test">
<button name="selSensor" id="seltipoSensor" class="btn btn-primary dropdown-
toggle" type="submit" data-toggle="dropdown">
<span>Select one option</span>
</button>
<ul class="dropdown-menu" id="test2">
</ul>
</div>
Here you can see the code that I have to generate the li tags inside the button.
<script type="text/javascript">
function selectedUbi(ubicacion){
var datos = {
"arg" : ubicacion
};
$.ajax({
data: datos,
url: 'condatabase/calculos_bdd2.php',
type: 'post',
success: function (response) {
if(response){
document.getElementById("test2").innerHTML = "";
var ul = document.getElementById("test2");
for (i=0;i<response.length;i++){
var li = document.createElement("li");
li.appendChild(document.createTextNode(response[i][i+1]));
li.setAttribute("id", "element"+i);
li.setAttribute("onclick",myFunction);
ul.appendChild(li);
}
}
},
dataType:"json"
});
}
</script>
The question that I have is...
how can I get the ID from the li tag that I generate dynamically?
I tried to use "getElementByID" and "getElementByTagName" but as the ID is dynamic I have no idea to caught the value.
For example the button have the next options to select:
- apple (ID= element0)
- bannana (ID= element1)
- carrot (ID= element2)
When I select the option "bannana" I need to get the ID "element1".
You can use querySelectorAll on your container to get a list of elements and then read their attribute id.
function getIds(container){
return [...container.querySelectorAll('li[id]')].map(li => li.getAttribute('id'));
}
However, I would rather recommend to create a data layer abstraction to handle operations related to data fetching, etc... in order to avoid a strong coupling on your html structure and your "logic" code.
function createStore(){
return {
async fetch(arg){ /*... return your data (and cache it etc */ }
};
}
so your button handlers can share that "store"
const store = createStore();
document.getElementBy('button1').addEventListener('click', () => {
store.fetch().then(data => { /* do something with your data like updating html ... */})
});
document.getElementBy('button2').addEventListener('click', () => {
store.fetch().then(data => { /* do something with your data like updating html ... */})
});
//etc

get autogenerated id of list item on click not working [duplicate]

Given this HTML code:
<td role-id="#Model.Id">
#Model.Name
<div class='glyphicon glyphicon-edit update_user' onclick='UpdateRole()'></div>
</td>
I need to retrieve role-id when clicking on the div.
JS code:
function UpdateRole() {
$("#ModalUser").show();
var role_id = $(this).parent().attr("role-id");
var user_id = $(this).parent().parent().attr("user-id");
console.log(role_id);
console.log(user_id);
};
Both values are undefined, how can I get role-id without this?
Better approach is to use jQuery event binding, but using your approach, pass this context from called function:
Problem: In your example, this is not the element on which event is invoked but window!
function UpdateRole(that) {
$("#ModalUser").show();
var role_id = $(that).parent().attr("role-id");
var user_id = $(that).parent().parent().attr("user-id");
console.log(role_id);
console.log(user_id);
};
<td role-id="#Model.Id">
#Model.Name
<div class='glyphicon glyphicon-edit update_user' onclick='UpdateRole(this)'></div>
</td>
Using jQuery event-binding:
function UpdateRole() {
$("#ModalUser").show();
var role_id = $(this).parent().attr("role-id");
var user_id = $(this).parent().parent().attr("user-id");
console.log(role_id);
console.log(user_id);
}
$('.update_user').on('click', UpdateRole);
<td role-id="#Model.Id">
#Model.Name
<div class='glyphicon glyphicon-edit update_user' onclick='UpdateRole(this)'></div>
</td>
You should register your event using jQuery, this makes it much easier to find the calling element:
$('.update_user').click(UpdateRole);
You can now:
function UpdateRole() {
var clickedElement = $(this);
$("#ModalUser").show();
var role_id = clickedElement.parent().attr("role-id");
var user_id = clickedElement.parent().parent().attr("user-id");
console.log(role_id);
console.log(user_id);
};
this is very simple you need to update this line with . data-* is html5 new attribute for setting and getting data
$(".update_user").on("click",function(){
elm=$(this).parent().data("role-id");
elm // this element consist of role id, now you can use this variable
});

Update dynamically generated list item (generated using PHP) after ajax call

The following HTML code is being echoed using a while loop in PHP which is adding a list item after fetching data from database.
PHP:
echo '
<li>
<div class="collapsible-header">
<div class = "left">
<div class = "issueStatusIcon" style = "background-color:'.$smallCircleColor.';">'.$smallMsg.'</div>
<span class = "issueTitle" style = "font-family: robotoBold">'.$issueTitle.'</span>
</div>
<div class = "issueButtonsGroup">
<form id = "archiveIssueForm'.$i.'" issue-name = "'.$issueTitle.'" action = "archiveIssue.php">
<input type = "hidden" value = "'.$issueID.'" name = "issueID"/>
</form>
<a class = "right archiveIconButton" onclick = "ajaxIssueArchive('.$i.')" href = "#">
<i class="material-icons black-text issueOptions archiveIcon">archive</i>
</a>
<a class = "right"><i class="material-icons black-text issueOptions">edit</i></a>
</div>
</div>
</li>
';
This is the preview image of the generated list:
Notice the cursor over the archive button which archives the list item. The class for that button is archiveIconButton (you can find it in the above code). When the button is clicked, archiveIssueForm is submitted via AJAX (each form has a unique identifier variable $i appended to its id).
Following is the JQuery AJAX code:
JQuery:
<script>
function ajaxIssueArchive($num){
$.ajax({
type: "post",
url: "archiveIssue.php",
data: $('#archiveIssueForm' + $num).serialize(),
success: function(data){
$fetchIssueName = $('#archiveIssueForm' + $num).attr("issue-name");
$toastText = $fetchIssueName + " has been archived";
Materialize.toast($toastText, 3000);
$('#archiveIssueForm' + $num).html(data);
}
});
}
</script>
After archiving any list item, it gets deleted from the database. I want to update the ul element which contains these list items so that the list item which gets deleted doesn't gets displayed after the AJAX form submission.
Assume the id of ul to be issueListUL.
What i'm currently getting is the whole code of the html page displayed in the li item. I am certainly doing something wrong, any help would be appreciated!
After archiving a list item:
I was able to solve this issue in the following way, The JQuery script in the question should be changed like this:
JQuery:
<script>
function ajaxIssueArchive($num){
$.ajax({
type: "post",
url: "archiveIssue.php",
data: $('#archiveIssueForm' + $num).serialize(),
success: function(data){
//assigning the updated ul's html to a variable
$afterIssueArchival = $(data).find("#issueListContainer").html();
//toast
$fetchIssueName = $('#archiveIssueForm' + $num).attr("issue-name");
$toastText = $fetchIssueName + " has been archived";
Materialize.toast($toastText, 3000);
//updation of ul's html, ID of the ul which contains all the list items is assumed to be 'listContainer'
$("#issueListContainer").html($afterIssueArchival);
}
});
}
</script>
When updating an element's html, just extract the element's updated html code from data attribute in the ajax code (as show in the above code) and update the existing element's html with it!
Hope this helps people with the same problem as mine! :D

Categories