Strange behaviour of values from tag - javascript

let's suppose the value of ${currentPage} is 5 i.e. we are on the fifth page
there are two links:
<a id="idArrow" href="#" data-currentpage="${currentPage-1}" title="${currentPage-1}">backward</a>
<!-- the title displays 4 -->
<a id="idArrow" href="#" data-currentpage="${currentPage+1}" title="${currentPage+1}">forward</a>
<!-- note, the title displays 6, it seems ok-->
a script to get a value:
$('body').on('click', '#idArrow', function() {
console.log("running idArrow");
var pageNumber = $("#idArrow").data('currentpage');
console.log('pageNumber '+pageNumber);
...
now the most interesting part...
if I press backward link then I get
running idArrow
pageNumber 4
if I press forward link then I get the same! how can it be?
running idArrow
pageNumber 4

You could use the this object provided by jQuery to event handling functions:
var pageNumber = $(this).data('currentpage');
Note that you should use unique id properties. $("#idArrow") refers to the first node with that id, and explains the behaviour you describe.
It would therefore be better to give a different selector to the on handler, like for instance a class that the elements share:
<a class="clsArrow" ... >
Code:
$('body').on('click', '.clsArrow', function(e) {
...
var pageNumber = $(this).data('currentpage');

Do something like this:
<a id="idArrow1" href="#" data-currentpage="${currentPage-1}" title="${currentPage-1}">backward</a>
<!-- the title displays 4 -->
<a id="idArrow2" href="#" data-currentpage="${currentPage+1}" title="${currentPage+1}">forward</a>
<!-- note, the title displays 6, it seems ok-->
javascript
$('body').on('click', '#idArrow1', function() {
console.log("running idArrow1");
var pageNumber = $("#idArrow1").data('currentpage');
console.log('pageNumber '+pageNumber);
...
$('body').on('click', '#idArrow2', function() {
console.log("running idArrow2");
var pageNumber = $("#idArrow2").data('currentpage');
console.log('pageNumber '+pageNumber);
...
Your issue is that you have 2 of the same id's make them unique and it should solve your issue

Related

Dynamic bootstrap modal, jQuery can not access html elements on first load

So i'm dynamically loading modal from my controller, with product information. Each product has a calculator to calculate price. The issue is when I open the modal the first time, I can remove the disable class from the calculate button. If i open/close/open it will work for every calculator on the page.
products.blade.php
foreach product
<a
class="btn-icon"
data-toggle="modal"
data-target="#publicModal"
data-url="{!! route('public.products.partials.calculator', ['product_id'=>$pp->product->id]) !!}"
data-title="Calculate cost"
data-size="modal-xl" >
<i class="fas fa-calculator"></i>
</a>
jquery
if(
custSQFT > 0 &&
custWidth > "0.00" &&
custLength > "0.00" &&
totalCost > 0
){
document.getElementById("calc-cost").classList.remove("disabled");
document.getElementById("calc-cost").classList.add("visible");
calcValid = true;
}else{
$('#calc-cost').prop("disabled",true).addClass('disabled')
calcValid = false;
}
Modal
<script type="text/javascript">
$('#publicModal').on('show.bs.modal', function (event) {
if(event.relatedTarget){
var button = $(event.relatedTarget) // Button that triggered the modal
}else{
var button = $('#loginButton');
}
var url = button.data('url') // Extract info from data-* attributes
var size = button.data('size')
var modal = $(this)
if (typeof(size) !== 'undefined') {
modal.find('.modal-dialog').addClass(size)
}
modal.find('.modal-body').load(url);
modal.find('.modal-title').html(button.data('title'))
});
$('#publicModal').on("hidden.bs.modal", function(){
$(".modal-body").html("");
$(".modal-title").html("Loading...");
});
</script>
So when I open up the modal, fill out the forms, I can console.log that I have made it inside the IF statement, but can not remove the visible class.
If I'm understanding correctly, you are having an issue with replacing the element in the dom with the same id.
I think probably easiest fix would be to add a unique id and capture that specific id to take action within your jquery.
Name the id uniquely, perhaps using the product id:
<a id='calc-cost-{{$pp->product->id}}' //... etc
Then you have a number of options to identify the current iteration, but I'll illustrate using blade instead of pure JS/Jquery for simplicity:
$('#calc-cost-'{{$pp->product->id}}).removeClass('disabled'); //etc
Normally, I'd add a data element on the <a> and grab the id through jquery to make it a little cleaner ( $('#calc-cost-'+grabbedIdVar)), but the above should give you an idea of how to go.
HTH.

Dynamically added class cannot be referenced for some reason

When I use clicks on a link, I add a class to the element:
<a class="js-link" data-category="cat123" href="#">some category</a>
The javascript is:
$(".js-link").click(function (e) {
e.preventDefault();
$(this).addClass(".js-category-selected");
});
When the user submits a search form, I am trying to get the link that was clicked:
var selectedCategory = $(".js-category-selected").data("category");
console.log('selectedCategory:' + selectedCategory);
This always returns undefined.
I can't seem to find the element. Is something wrong with this approach?
Is it because this class is added dynamically? But I'm not binding anything, just trying to located the element.
You were giving class name with a . while adding the class. Just give the name and access using . and to get data write the function inside a handler, outside it, it will be accessed before even the link will get new class and you will always get undefined.
Use $(this).addClass("js-category-selected"); instead of using $(this).addClass(".js-category-selected");
$(".js-link").click(function(e) {
e.preventDefault();
$(this).addClass("js-category-selected");
var selectedCategory = $(".js-category-selected").data("category");
console.log('selectedCategory:' + selectedCategory);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="js-link" data-category="cat123" href="#">some category</a>
You need to remove the . at the start of the class you're adding:
$(".js-link").click(function(e) {
e.preventDefault();
$(this).addClass("js-category-selected");
var selectedCategory = $(".js-category-selected").data("category");
console.log('selectedCategory:' + selectedCategory);
});
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<a class="js-link" data-category="cat123" href="#">some category</a>

Why .attr("data-number", num_to_string ) and .data('number') are working in combination? [duplicate]

This question already has answers here:
get wrong value in data attribute jquery
(4 answers)
Closed 5 years ago.
I want change repeatedly the attribute value of data-number="2" when .next is clicked. It works at the first attempt that means the browser gives data-number value as 3. But when I click next times, it doesn't change. It remains 3.
Here my code:
<a class="prev" data-number="1">❮</a>
<a class="next" data-number="2">❯</a>
</div>
<script>
$(document).ready( function(){
$('a.next').on( 'click', function(){
var image_num = parseInt($(this).data('number')) + 1 ;
var num_to_string = image_num.toString();
var prev_value = $(this).attr("data-number", num_to_string );
console.log(prev_value);
} );
} );
</script>
I want to have the value as 3, 4, 5 ....
You didn't update the intended data-number-attribute, because you have to use data as well to update it. So I replaced this line:
$(this).attr("data-number", num_to_string )
with this line:
$(this).data("number", num_to_string);
$(document).ready(function () {
$('a.next').on('click', function () {
var image_num = parseInt($(this).data('number')) + 1;
var num_to_string = image_num.toString();
var prev_value = $(this).data('number', +num_to_string);
console.log(num_to_string);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="prev" data-number="1">❮</a>
<a class="next" data-number="2">❯</a>
</div>
The reason for this behaviour is that jquery handles data-attribute (data-number) differently than ordinary attributes like id because when dealing with data-attributes the DOM-element is actually not altered unlike with ordinary attributes, as this link states.
That's why both methods data and attr work different and can therefore not be used in combination as they are used in the question, because attr works with updated DOM-values but data does not.
Hope this helps.
If you use data() jQuery will automatically cast numeric data attribute values to number
$('a.next').on('click', function() {
var $el = $(this);
// increment the data object value of number property
$el.data().number ++;
console.log('New number:', $el.data('number'))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Next

Triggering 2 tabs with one click

I found 'one click triggers 2' but it doesn't seem to be what I am wanting - perhaps only because the one click is changing 2 slides not tabs. I want one click to switch tabs on 2 tab sets. My tabs are called tab1,2,and 3 and legendtab1,2, and 3.
I am only testing from the legendtabx set and have <div class="tabbable">
<script language="javascript" type="text/javascript">
document.getElementById('legendtab1').onclick , document.getElementById('tab1').onclick = function() {
<a href="#legendtab1" data-toggle="tab")Standard</a>;
<a href="#tab1" data-toggle="tab")Standard</a>;
document.getElementById('legendtab2').onclick, document.getElementById('tab2').onclick = function() {
<a href="#legendtab2" data-toggle="tab")Sprint</a>;
<a href="#tab2" data-toggle="tab")Sprint</a>
document.getElementById('legendtab3').onclick, document.getElementById('tab3').onclick= function() {
<a href="#tab3" data-toggle="tab")Ski</a>
<a href="#legendtab3" data-toggle="tab")Ski</a>;
}
</script>
This results in, in each case, triggers the tabx tabs but not the legendtabx. strangely even though in the case of tab3 the hrefs are in the reverse order, As you can likely tell, I am not a strong js programmer but I think it is js that should be able to do the job.
A little bit about why this need. It is a Joomla site and on the main content are 3 tabs with information about each of 3 types of events. In the module we show the symbols associated with each of the 3 types of events. So, when a visitor looks at the ski info on one area, I want the other area to display the related info about skiing.
You forgot to end your function's with ending }'s. You were also not assigning your onclick function correctly for the 'legendtab' onclicks. This may work better for you.
<script language="javascript" type="text/javascript">
var switchTab1 = function() {
<a href="#legendtab1" data-toggle="tab")Standard</a>;
<a href="#tab1" data-toggle="tab")Standard</a>;
}
var switchTab2 = function() {
<a href="#legendtab2" data-toggle="tab")Sprint</a>;
<a href="#tab2" data-toggle="tab")Sprint</a>
}
var switchTab3 = function() {
<a href="#tab3" data-toggle="tab")Ski</a>
<a href="#legendtab3" data-toggle="tab")Ski</a>;
}
document.getElementById('legendtab1').onclick = switchTab1;
document.getElementById('tab1').onclick = switchTab1;
document.getElementById('legendtab2').onclick = switchTab2;
document.getElementById('tab2').onclick = switchTab2;
document.getElementById('legendtab3').onclick = switchTab3;
document.getElementById('tab3').onclick = switchTab3;
</script>

Clever work-around for my current script?

I'm currently utilizing JavaScript to allow users to watch multiple videos on a page. There is one big player at the top of the page, and below it are smaller thumbnails of more videos.
In theory, it works fine. However, there is one major problem: ALL videos load at the same time as the page loads.
See this page for reference. I have assigned JavaScript alerts to each individual videos to exemplify the problem (video1, video2, etc.).
Is there a easy fix, without having to rewrite the entire page, to have the videos load when they are clicked on, not when the page loads? Here's what the code looks like so far:
Javascript that calls the video:
function playVideo(cap, file, streamer, alertmsg) {
var so = new SWFObject('player/player-licensed_5_2.swf', 'ply1', '586', '330', '9');
so.addParam('displaywidth', '586');
so.addParam('displayheight', '330');
so.addParam('allowfullscreen', 'true');
so.addParam('allowscriptaccess', 'always');
so.addVariable('skin', 'player/skins/glow.zip');
so.addVariable('controlbar', 'over');
so.addVariable('plugins', 'captions-1');
so.addVariable('captions.file', cap);
so.addVariable('dock', 'true');
so.addVariable('image', 'landing_img/video.jpg');
so.addVariable('file', file);
so.addVariable('streamer', streamer);
so.addVariable('autostart', 'false');
so.write('player1');
window.alert(alertmsg);
}
The thumbnail for the video:
<div class="mini_player1"> <a href="#" class="vidpic" title="">
<!-- thumbnail-->
<img src="images/1_panda.jpg" alt="Video 1" class="vidpic" />
<span class="play-button"><img src="images/yt.png" alt="Play"></span>
</a>
</div>
<div class="content_mini_player1 cmp">
<script>
playVideo('<caption file>', '<videofile>', '<streamer>', 'video1');
</script>
</div>
The script that 'replaces' the content in bigplayer with the new selected video:
jQuery(function ($) {
$(".mini_player1, .mini_player2, .mini_player3, .mini_player4, .mini_player5, .mini_player6, .mini_player7, .mini_player8, .mini_player9, .mini_player10, .mini_player11, .mini_player12, .mini_player13, .mini_player14, .mini_player15, .mini_player16, .mini_player17, .mini_player18, .mini_player19, .mini_player20").click(function () {
var player_content_id = "content_" + $(this).attr("class");
var player_content = $("." + player_content_id).html();
$(".big_player").html('');
$(".big_player").html(player_content);
});
});
Any suggestions? Maybe consolidate playVideo and the jQuery function? Any help would be greatly appreciated.
Firstly, in the thumbnail code, there is a random closing </a> tag. Unless there is code you didn't post, I'd suggest removing it.
Secondly, your jQuery can be simplified much further. Currently, you are using the following selector:
$(".mini_player1, .mini_player2, .mini_player3, .mini_player4, .mini_player5, .mini_player6, .mini_player7, .mini_player8, .mini_player9, .mini_player10, .mini_player11, .mini_player12, .mini_player13, .mini_player14, .mini_player15, .mini_player16, .mini_player17, .mini_player18, .mini_player19, .mini_player20")
Wow! That is...wow.
Assign the players a single class they can all relate to across the board, select by that class and then run the each() method i.e.:
$(".mini-player").each(function() {
var player_content_id = "content_" + $(this).attr("class");
var player_content = $("." + player_content_id).html();
$(".big_player").html('');
$(".big_player").html(player_content);
});
Lastly, when you call a function in a script tag like you are doing:
<script>
playVideo('<caption file>', '<videofile>', '<streamer>', 'video1');
</script>
This WILL run the playVideo() function. Consolidating playVideo() and the jQuery code would be your best bet i.e. (using the same construct above):
$(".mini-player").each(function() {
var player_content_id = "content_" + $(this).attr("class");
var player_content = $("." + player_content_id).html();
$(".big_player").html('');
$(".big_player").html(player_content);
//Add event handler
$(this).on('click',function() {
playVideo('<caption file>', '<videofile>', '<streamer>', 'video1');
});
});
Your inline JavaScript function playVideo is going to be called when the page loads. You will want to remove it from there and do something like this:
<div onclick="playVideo()" class = "mini_player1">

Categories