I have a problem with jplayer what I need to do is I want to play next track automatically when prev track is finished.
I have HTML as:
<div class="row-track active" data-track-id="30">
<div class="row-holder" data-src="url/30">
<span class="status">
<a href="javascript:;" data-toggle="tooltip" title="" class="play-pause no-pjax addTrack audio-element" data-audio="mp3_url" data-waveform="img_url" data-id="30" data-album-id="74" data-title="Usually Suspect" data-artist="Ambient Drama" data-original-title="#7">play/pause
</a>
</span>
</div>
</div>
<div class="row-track active" data-track-id="40">
<div class="row-holder" data-src="url/40">
<span class="status">
<a href="javascript:;" data-toggle="tooltip" title="" class="play-pause no-pjax addTrack audio-element" data-audio="mp3_url" data-waveform="img_url" data-id="40" data-album-id="74" data-title="Usually Suspect" data-artist="Ambient Drama" data-original-title="#7">play/pause
</a>
</span>
</div>
</div>
And in jplayer -> bind($.jPlayer.event.ended
I have done:
var nextSongId = $("div[data-track-id='"+event.jPlayer.status.media.trackId+"']").
next().attr('data-track-id');
var trackOnEnd = inPlaylist(nextSongId);
demo.play(trackOnEnd);
in demo.playlist I have an array of object.
inPlaylist function is as follows:
function inPlaylist(id) {
var state = null;
$.map(demo.playlist, function(elementOfArray, indexInArray) {
if(elementOfArray.trackId == id) {
state = indexInArray
}
});
return state
};
where status is nothing but the index of the object in an array of object.
In some places it working fine. But in some cases it gives me an error of
Cannot read property 'poster' of undefined
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 have a page that sorts things if you choose one of the options. The list of filters was too long so I added a div that shows/hides options. On page load some of the options are hidden via CSS with display: hidden. Code below just changes display from display: none to display: inline-block based on number of clicks.
var timesClicked = 0;
window.onload = function(){
document.getElementById("filter_attribute_217").onclick = function(){
timesClicked++;
if (timesClicked%2==0){
hide();
} else {
show();
}
};
This is show() function
function show(){
document.getElementById("filter_attribute_69").style.display="inline-block";
document.getElementById("filter_attribute_70").style.display="inline-block";
document.getElementById("filter_attribute_72").style.display="inline-block";
//all those other options
document.getElementById("filter_attribute_217").innerHTML = "less";
document.getElementById("filter_attribute_217").style.borderTop = "1px dashed #e1e4e6";
document.getElementById("filter_attribute_68").style.borderBottom = "none";
document.getElementById("filter_attribute_87").style.borderBottom = "none";
}
And this is hide() function
function hide(){
document.getElementById("filter_attribute_217").innerHTML = "more";
document.getElementById("filter_attribute_217").style.borderTop = "1px dashed #e1e4e6"
document.getElementById("filter_attribute_69").style.display="none";
document.getElementById("filter_attribute_70").style.display="none";
//all those other options
document.getElementById("filter_attribute_103").style.display="none";
}
This is working perfectly until I choose one of the options which means that some other disappear. Then when trying to use more/less button I will get errors like this one:
Uncaught TypeError: Cannot read properties of null (reading 'style')
at hide (user.js?sci=481:68:50)
at document.getElementById.onclick (user.js?sci=481:58:9)
Clicking it again shows the same error just with show() function.
I've tried checking if element exist in DOM structure with document.body.contains(YOUR_ELEMENT_HERE); but it always shows that all of the options exists. Checked it with
if(document.body.contains(element){
console.log("exists")
} else {
console.log("doesn't exist")
}
Console was always outputting "exists".
I then tried just ignoring the problem to see if others options will show with
function stoperror() {
return true;
};
window.onerror = stoperror;
But with the same result just without the error. I don't know why this is happening and how can I fix it. I need to add that all I can edit here is JavaScript and CSS. That's why I made another option (filter_attribute_217) and made it into my show more/less button.
Edit
Here's HTML code for basically every option. They only thing that is changing from option to option is id and href.
<div data-limit="3" class="group group-filter" id="filter_attribute_104">
<h5>
Transparent
</h5>
<ul>
<li class="" style="margin-right:15px;">
<a title="tak" href="/pl/c/Balls/119/1/default/1/f_at_104_0/1">
<i src="/libraries/images/1px.gif" alt="" class="px1" ></i>
<span>tak </span>
<em>(56)</em>
</a>
</li>
</ul>
<div data-limit="3" class="group group-filter" id="filter_attribute_68">
<h5>
White
</h5>
<ul>
<li class="" style="margin-right:15px;">
<a title="tak" href="/pl/c/Balls/119/1/default/1/f_at_68_0/1">
<i src="/libraries/images/1px.gif" alt="" class="px1" ></i>
<span>tak </span>
<em>(208)</em>
</a>
</li>
</ul>
I also have this in my JS code
window.addEventListener("DOMContentLoaded",(event) => {
document.getElementById("filter_attribute_217").innerHTML = "więcej";
document.getElementById("filter_attribute_217").style.borderTop = "1px dashed #e1e4e6";
});
This is an example with the code you provided. However your question is still not properly stated. I assume the HTML is getting generated dynamically? If so, I would make sure that the elements I'm trying to use are existing for sure while I call my JS. So I got rid of the window.onload you are using. Also, if you want to apply global changes, do not repeat the same things for each ID, just use a querySelectorAll('.classname') with a .forEach. Example:
let timesClicked = 0;
let show = () => {
document.querySelector('.group-filter').innerHTML = 'LESS';
document.querySelectorAll('.group-filter').forEach(elem => {
elem.style.display = 'flex';
// Other things...
});
}
let hide = () => {
document.querySelector('.group-filter').innerHTML = 'MORE';
document.querySelectorAll('.group-filter').forEach(elem => {
elem.style.display = 'none';
// Other things...
});
// Restore the first element's display
document.querySelector('.group-filter').style.display = 'flex';
}
document.getElementById('filter_attribute_104').addEventListener('click', () => {
timesClicked++;
if (timesClicked % 2 == 0) hide();
else show();
});
.hidden {display:none;}
<div data-limit="3" class="group group-filter" id="filter_attribute_104">
<h5>Transparent</h5>
<ul>
<li class="" style="margin-right:15px;">
<a title="tak" href="#">
<i src="/libraries/images/1px.gif" alt="" class="px1" ></i>
<span>tak </span>
<em>(56)</em>
</a>
</li>
</ul>
</div>
<div data-limit="3" class="group group-filter hidden" id="filter_attribute_68">
<h5>White</h5>
<ul>
<li class="" style="margin-right:15px;">
<a title="tak" href="#">
<i src="/libraries/images/1px.gif" alt="" class="px1" ></i>
<span>tak </span>
<em>(208)</em>
</a>
</li>
</ul>
</div>
<div data-limit="3" class="group group-filter hidden" id="filter_attribute_168">
<h5>Red</h5>
<ul>
<li class="" style="margin-right:15px;">
<a title="tak" href="#">
<i src="/libraries/images/1px.gif" alt="" class="px1" ></i>
<span>tak </span>
<em>(332)</em>
</a>
</li>
</ul>
</div>
I am pushing a new object in the array but couldn't see the new value updated on UI. I am using angular js here and updating a value. here is my code.
html
<ul id="list-wrapper-noti" class="dropdown-menu dropdown-menu-right style-3" >
<div infinite-scroll-disabled = "disableScroll" infinite-scroll='loadMoreNotifications()' infinite-scroll-distance='0' infinite-scroll-container="'#list-wrapper-noti'">
<li >
See all
<a class="pull-right" href="list.php?id=20" style=" color:#3C71C1;">Mark all as read </a>
</li>
<li style="height: 30px"></li>
<li ng-repeat = "notification in notifications track by $index">
<a style="text-decoration:none; color:#534D4D" href="{{notification.href}}" >
<div class="media">
<img src="https://papa.fit/routes/images/inst_logo/default.png" alt="fakeimg" class="img-circle pull-left" style="height:50px; width:50px;">
<div class="media-body">
<div class="media">{{notification.employee}} {{notification.action | lowercase}} {{notification.element}} {{notification.record_value}}</div>
<span class="muted">{{notification.time_string}}</span>
</div>
</div>
</a>
<div class="divider"></div>
</li>
controller
function addNewNotification(new_noti){
var obj = {"action":new_noti.data.action,"element":new_noti.data.element,"record_value":new_noti.data.record_value,"time_string":new_noti.data.time_string,"employee":new_noti.data.employee};
$scope.notifications.unshift(obj);
console.log($scope.notifications)
}
and from here I am calling this func
angular.element('#list-wrapper-noti').scope().addNewNotification(payload);
I don't know why it is not getting updated after push in array.please anyone help ?
Inject $timeout into your controller and try this:
$timeout(function() {
$scope.notifications.unshift(obj);
});
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');
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>