I have this javascript function which should redirect me to
http://localhost:8888/ID OF A PRODUCT/add-to-cart".
But instead I got this:
http://localhost:8888/undefined/add-to-cart".
$('.add-to-cart').on('click', function () {
var productId = $(this).find('.indexImg').attr('id');
$.ajax(productId+"/add-to-cart",
{
});
});
<img class="indexImg" src="{{$product->image}}" id="{{$product->id}}">
Can someone help me to get ID of a product ?
HTML:
#foreach($products as $product)
<div class="col-md-3">
<div class="box-product">
<div class="img-wrapper item">
<a href="/product/{{$product->id}}/{{$product->slug}}">
<a class="thumbnail" href="/product/{{$product->id}}/{{$product->slug}}" style="margin-bottom: 0px; border: none;">
<img class="indexImg" src="{{$product->image}}" id="{{$product->id}}">
</a>
</a>
<div class="tags">
#if($product->discount > 0)
<span class="label-tags"><span class="label label-danger">Išpardavimas</span></span>
#endif
<span class="label-tags"><span class="label label-info">Nauja</span></span>
</div>
<div class="option">
<i class="fa fa-shopping-cart add-to-cart" aria-hidden="true" style="color: white"></i>
</div>
</div>
Do one thing
Change
<i class="fa fa-shopping-cart add-to-cart" aria-hidden="true" style="color: white"></i>
With
<i class="fa fa-shopping-cart add-to-cart" aria-hidden="true" style="color: white" id="{{$product->id}}"></i>
and get by
$(this).attr('id');
So the code will be
$('.add-to-cart').on('click', function () {
var productId = $(this).attr('id');
$.ajax(productId+"/add-to-cart",
{
});
});
$('.add-to-cart').on('click', function (event) {
var productId = event.target.id;
$.ajax(productId+"/add-to-cart",
{
});
});
.find is try to find inside current element u need to go up then find indexImg
$('.add-to-cart').on('click', function () {
var productId = $(this).parents('.box-product').find('.indexImg').attr('id');
$.ajax(productId+"/add-to-cart",
{
});
});
The way you are trying to get product ID based on DOM is incorrect. The jQuery .find() method looks for specified elements within the elements, i.e. its descendants. If you look at the HTML, you'll see that the div elements containing the add-to-cart button and the image whose id attribute you are trying to fetch are on the same level.
So you've got to change the way you are traversing to reach the id attribute of the <img> tag.
var productId = $(this).closest('.box-product').find('.indexImg').attr('id');
Related
Goal: Change style of an element in a forEach loop
Issue: Style not being applied
In my loop, if I console.log(element), I do get the right list of filtered elements.
Running this works, but I want my function to modify every element that match my filter:
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview[0].style.color = 'yellow'
All elements are correctly assigned.
function changeNotificationColor() {
// Notification button that opens list of notifications
let notifyButton = document.querySelector('.dropdown-toggle.o-no-caret[title="Conversations"]');
notifyButton.addEventListener('click', function () {
// List of notifications - each notification is contained in a .o_last_message_preview class
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview.forEach(function (element) { if (element.innerText.includes('Marine')) {element.style.color = 'yellow'}})
})
}
changeNotificationColor();
HTML Notifications Dropdown button:
<a class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="true" title="Conversations" href="#" role="button">
<i class="o_mail_messaging_menu_icon fa fa-comments" role="img" aria-label="Messages"></i> <span class="o_notification_counter badge badge-pill">366</span>
</a>
HTML template of a notification node (each notification creates one of these nodes):
<div class="o_preview_info">
<div class="o_preview_title">
<span class="o_preview_name">
You have been assigned to Backorder xx
</span>
<span class="o_preview_counter">
(1)
</span>
<span class="o_last_message_date ml-auto mr-2"> 3 minutes ago </span>
</div>
<div class="o_last_message_preview">
Marine
</div>
<span title="Mark as Read" class="o_discuss_icon o_mail_preview_mark_as_read fa fa-check"></span>
</div>
I don't know what your issue is, but it's not in the code that you showed; this works fine:
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview.forEach(function (element) { if (element.innerText.includes('Marine')) {element.style.color = 'yellow'}})
<div class="o_last_message_preview">This contains Marine</div>
<div class="o_last_message_preview">This does not</div>
<div class="o_other_message_preview">This has a different class</div>
I am using ajax to display product data and then delete on click a specific on using the product id but am not able to get the product id as it is showing undefine can you guys suggest something.
In this code first I am getting the product details for the cart dropdown menu and then displaying it in list format with delete button through the first ajax and then on clicking delete should delete the element in the second ajax using the elements product id which I have saved inside data-r but on console, it showing undefined can anyone tell me what is the issue. As I know that the elements are created dynamically but I am not getting a solution
function TopCartVal() {
// Used Route inside the ajax
var url = "{{ route('pdt.details', ':id') }}";
var yui = "{{ route('delete_fr.cart', ':id') }}";
// Ajax Structure
$.getJSON( "{{ route('my.cart','json') }}", function( data ) {
console.log(data);
var Cart = $('#cart_dp_sec_pdt_desc');
// Loop for data
$.each(data, function(key , value) {
console.log(value);
url = url.replace(':id', value.product_id);
yui = yui.replace(':id', value.product_id);
Cart.append(`
<div class="row">
<div class="col-xs-4">
<div class="image">
<a href="`+url+`">
<img src="{{ asset('')}}`+value.image+`" alt=""/>
</a>
</div>
</div>
<div class="col-xs-7">
<h3 class="name">
`+value.product_name+`
</h3>
<div class="price">`+value.currency+value.product_price+`</div>
</div>
<div class="col-xs-1 action">
<a href="#"
data-r"`+value.id+`"
class="cart_dp_btn_ctn_delete">
<i class="fa fa-trash"></i>
</a>
</div>
</div>
`);
});
});
}
// delete part
$(document).on('click', '.cart_dp_btn_ctn_delete', function(e){
e.preventDefault();
var id = $(this).attr('data-r'); // id of to be deleted element
var yui = "{{ route('delete_fr.cart', ':id') }}";
yui = yui.replace(':id', id);
console.log(yui);
console.log(id); // it is showing undefined`enter code here`
// $.getJSON( yui, function(data){
// TopCartVal();
// });
});
You are missing an = here:
data-r"`+value.product_id+`"
But using template literals correctly will make it easier to see
`<div class="row">
<div class="col-xs-4">
<div class="image">
<a href="${url">
<img src="{{ asset('')}}${value.image}" alt=""/>
</a>
</div>
</div>
<div class="col-xs-7">
<h3 class="name">
${value.product_name}
</h3>
<div class="price">${value.currency+value.product_price}</div>
</div>
<div class="col-xs-1 action">
<a href="#" data-r="${value.product_id}" class="cart_dp_btn_ctn_delete">
<i class="fa fa-trash"></i>
</a>
</div>
</div>`
I am populating a based on the values from an object.
var myJSON =[
{
"ID":1417,
"BF":74,
"IL":17,
"Tw":17
},
{
"ID":1415,
"BF":63,
"IL":7,
"Tw":19
},
{
"ID":1414,
"BF":297,
"IL":2,
"Tw":30
},
{
"ID":1413,
"BF":114,
"IL":39,
"Tw":69
},
{
"ID":1412,
"BF":592,
"IL":14,
"Tw":24
},
{
"ID":1411,
"BF":151,
"IL":18,
"Tw":57
}
]
I want to read values from this JavaScript object and populate it in the HTML below:
<div>
<a class="resp-button__link">
<div class="res-button res-button--kof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span>document.write(javascript:getBF(1415));</span>
</div>
</div>
</a>
<a class="resp-button__link">
<div class="res-button res-button--bhof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span>document.write(javascript:getIL(1415));</span>
</div>
</div>
</a>
<a class="resp-button__link">
<div class="res-button res-button--thof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span>document.write(javascript:getTw(1415));</span>
</div>
</div>
</a>
</div>
There are many such divs on the page and none of them have an id on them.
UPDATE: I have updated the HTML with css classes and given the outer div an ID.
<div id="1415">
<a class="kof">
<div class="res-button res-button--kof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span>BF</span>
</div>
</div>
</a>
<a class="bhof">
<div class="res-button res-button--bhof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span>IL</span>
</div>
</div>
</a>
<a class="thof">
<div class="res-button res-button--thof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span>Tw</span>
</div>
</div>
</a>
</div>
Can you suggest how to retrieve the values now and populate the span.
Live Demo
Updated: Live Demo
The reason you're not seeing your functions get called is that you've just put the text document.write(javascript:getIL(1415)); (for instance) in the spans. If you wanted that interpreted as code, you'd need script tags around it. But then you'd also need your functions to be globals (which they aren't currently — which is good).
document.write has essentially no place in modern web programming. Instead, if you need to apply this data to the spans after the fact, I'd probably use data-* attributes to specify the type of information (e.g., "BF" or "Tw") and the ID:
<span data-type="BF" data-id="1415"></span>
then find the spans with those attributes and fill them in:
$("span[data-type][data-id]").each(function() {
const span = $(this);
const type = span.attr("data-type");
const id = span.attr("data-id");
const ob = findById(id);
const val = ob && ob[type];
if (val) {
span.text(val);
}
});
Note that I just have a single findById function there, rather than individual accessors for each bit of information, since we can just use the type from the span as the name of the property to get.
Live Example:
$(function () {
const myData = [
{
"ID":1417,
"BF":74,
"IL":17,
"Tw":17
},
{
"ID":1415,
"BF":63,
"IL":7,
"Tw":19
},
{
"ID":1414,
"BF":297,
"IL":2,
"Tw":30
},
{
"ID":1413,
"BF":114,
"IL":39,
"Tw":69
},
{
"ID":1412,
"BF":592,
"IL":14,
"Tw":24
},
{
"ID":1411,
"BF":151,
"IL":18,
"Tw":57
}
];
const findById = id => myData.find((elem) => elem.ID == id);
$("span[data-type][data-id]").each(function() {
const span = $(this);
const type = span.attr("data-type");
const id = span.attr("data-id");
const ob = findById(id);
const val = ob && ob[type];
if (val) {
span.text(val);
}
});
});
<div>
<a class="resp-button__link">
<div class="res-button res-button--kof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span data-type="BF" data-id="1415"></span>
</div>
</div>
</a>
<a class="resp-button__link">
<div class="res-button res-button--bhof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span data-type="IL" data-id="1415"></span>
</div>
</div>
</a>
<a class="resp-button__link">
<div class="res-button res-button--thof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span data-type="Tw" data-id="1415"></span>
</div>
</div>
</a>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You might consider reformatting your data so that instead of an array of objects, you have an object with a property for each ID. So instead of:
const myData = [
{
"ID":1417,
"BF":74,
"IL":17,
"Tw":17
},
{
"ID":1415,
"BF":63,
"IL":7,
"Tw":19
},
// ...
];
you'd have:
const myData = {
1417: {
"ID":1417, // You could include this ID or leave it out
"BF":74,
"IL":17,
"Tw":17
},
1415: {
"ID":1415,
"BF":63,
"IL":7,
"Tw":19
},
// ...
};
Then we don't need findById(id) anymore, just myData[id].
You can't write json values using document.write. Because using document.write() after an HTML document is fully loaded, will delete all existing HTML and write the document.write content. So better to use another way to set the content,
Like:
document.getElementById("demo").innerHTML = 'content'
In your case you can put like this,
<a class="resp-button__link">
<div class="res-button res-button--kof resp-sharing-button--small">
<div aria-hidden="true" class="resp-sharing-button__icon resp-sharing-button__icon--solid">
<span id="content1415"></span> <!--added id to span element-->
</div>
</div>
</a>
In javascript,
document.getElementById("content1415").innerHTML = getBF(1415);
For your specific code -
Remove the lines $(function () { and });
You need to execute the method getIL(...) etc. Write those in the Javascript file or <Script> tags.
You can assign ID to each span tag and do like this
// HTML
<span id="1415"></span>
// JS code
var _1415 = document.getElementByID('1415);
_1415.innerHTML = getIL('1415);
This will put the value of 1415 in the span tag.
You can use loops and some dynamic code to reduce the number of repetitions.
I want to get the id/class/both of the anchor tag, regardless of where it falls in the tag hierarchy. Example below is strange but realistic for my purposes because our website is accessed through a CMS that I have no control over. If people add multiple levels of formatting at different times, the CMS likes to add new span's...
So, having the live with the above facts, I want to pin down specific anchor tags by their id/class/both, but I don't always know where they will be located in the tag drill-down.
<div id="div_id_A" class="div_class_A">
<div class="div_class_A">
<a href="#" id="anchor_id_A" class="anchor_class_A">
<span class="span_class_A">
<span id="span_id_B">
<span id="span_id_C" class="span_class_C">
<p>
Click Me
</p>
</span>
</span>
</span>
</a>
</div>
</div>
I have started off like such,
var dataLayer = dataLayer || [];
document.addEventListener('click', function(event) {
var telm = event.target.parentNode.className;
var delm = 'anchor_id_A';
console.log(telm);
if (telm == delm) {
dataLayer.push({
'youClicked': telm
});
console.log(dataLayer);
};
});
*WHERE: telm = target element; delm = desired element.
To clarify. I am specifying anchor for a reason, it is not simply for the example. As I am restricted by our CMS, I can't go in and add markup to pre-defined code (i.e. template), but I do need to know what link was clicked as exactly as possible (for Google Analytics), so that I can track down what users are ignoring, not seeing, or prefering.
You can navigate up the hierarchy until you reach the anchor element, then just read its ID.
See here:
var dataLayer = dataLayer || [];
document.addEventListener('click', function(event) {
var el = event.target;
while (el.parentElement && el.tagName != 'A') {
el = el.parentElement;
}
dataLayer.push({
'youClicked': el
});
console.log(dataLayer);
alert(el.id);
});
<div id="div_id_A" class="div_class_A">
<div class="div_class_A">
<a href="#" id="anchor_id_A" class="anchor_class_A">
<span class="span_class_A">
<span id="span_id_B">
<span id="span_id_C" class="span_class_C">
<p>Click Me</p>
</span>
</span>
</span>
</a>
</div>
</div>
What you're trying to achieve, is probably something like this :
var dataLayer = [];
document.addEventListener('click', function(event) {
var needle = 'anchor_class_A'; // The class of the element you're looking for
var closest = event.target.closest("." + needle);
if(closest && closest.id) {
dataLayer.push({
'youClicked': closest.id
});
alert(JSON.stringify(dataLayer, null, '\t'));
}
});
<div id="div_id_A" class="div_class_A">
<div class="div_class_A">
<a href="#" id="anchor_id_A" class="anchor_class_A">
<span class="span_class_A">
<span id="span_id_B">
<span id="span_id_C" class="span_class_C">
<p class="clicker">
Click Me
</p>
</span>
</span>
</span>
</a>
</div>
<div class="div_class_A">
<a href="#" id="anchor_id_X" class="anchor_class_A">
<span class="span_class_A">
<span id="span_id_Y">
<span id="span_id_Z" class="span_class_C">
<p class="clicker">
Click Me
</p>
</span>
</span>
</span>
</a>
</div>
</div>
I want to update the click event of the hyperlink onClick and want to update the html inside the hyperlink in jquery
HTML
<a class=" save" href="javascript:void(0);" onclick="save_unsave('unsave','UID','ID',this);">
<div class="jopt_iconwrap" title="Unsave" alt="Unsave" >
<span class="saved"></span>
</div>
Unsave
</a>
Now onlick of save_unsave function i want to update the html design as below:
<a class=" save" href="javascript:void(0);" onclick="save_unsave('save','UID','ID',this);">
<div class="jopt_iconwrap" title="Save" alt="Save" >
<span class=""></span>
</div>
Save
</a>
I am trying to do this in the function:
jQuery
if(type == 'save')
{
var new_type = "'unsave'";
jQuery(elem_obj).html("");
jQuery(elem_obj).html('<a onclick="save_unsave('+new_type+','+uid+','+id+',this);" class="saved" href="javascript:void(0);"><div class="jopt_iconwrap" title="Unsave" alt="Unsave"><span class="saved"></span></div>Unsave</a>');
}
else if(type == 'unsave')
{
var new_type = "'save'";
jQuery(elem_obj).html("");
jQuery(elem_obj).html('<a onclick="save_unsave('+new_type+','+uid+','+id+',this);" class=" save" href="javascript:void(0);"><div class="jopt_iconwrap" title="Unsave" alt="Unsave"><span class="mico"></span></div>Save</a>');
}
How can we do this in jquery.Please help me in the i have the elmenet object in the function.
simply i will suggest you to use replaceWith() in place of .html() it will work properly for you.
$('a').click(function() {
if ($(this).hasClass('save')) {
$(this).removeClass('save').addClass('unsave');
$(this).text('Unsave')
$(this).attr('id','save')
} else {
$(this).removeClass('unsave').addClass('save');
$(this).text('Save')
$(this).attr('id','unsave')
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a class=" save">
<div class="jopt_iconwrap" title="Save" alt="Save">
<span class=""></span>
</div>
Save
</a>
Try this way
You can replace the onclick event, like this:
$('.save')[0].onclick = function() {
save_unsave('save', 'UID', 'ID', this);
}