Why all the spans are changed instead of one? - javascript

I have prev and next button:
This is function of next button:
var nextFn = function(e)
{
var current = $('.active');
alert(current);
var prev = $('#prev');
pos = $('.active').attr('id');
$("#num").text('(' + pos + '/' + researchPlaces.length + ')');
$(current).next().attr("class", "active");
$(current).attr("class", "passive");
//e.stopPropagation();
};
When I click next, it supposed to show the next span. However, it also shows the next span in other li(s) in the page.
<li class="memberElement" style="width: 100%; padding: 10px 0 10px 0; border-bottom: 1px solid #ccc;">
<div class="MemberImageHolder" style="float:left">
<a href="#">
<img class="memberpic" src="picture.php?action=display&contentType=members&id=5&quality=medium" alt="">
</a>
</div>
<div class="memberDetails">
Charles Darwin
<div id="title">Professor</div><div id="unit">
<b>University of Ottawa</b>
</div>
<div id="address">
<a id="prev">Prev </a>
<span id="1" class="active">150 York Street</span>
<span id="2" class="passive">80 Elgin Street</span>
<span id="num" class="passive">(0/2)</span>
<a id="next"> Next</a>
</div>
</div>
<span class="divider"></span>
</li>
This is my one of the li(s). What's wrong?

I think is because of your selector :
$('.active');
This selector select all the control that has active class. I guess you have one active span in each li.
To modify class, you should use addClass instead of modifying the attribute :
$(current).next().addClass("active");
$(current).removeClass("passive");
This way you won't lose other class associated with your control.
Edit :
You can get the li by the link clicked :
$("#prev").click(function()
{
var li = $(this).closest("li");
var current = $(li).find('.active');
alert(current);
var prev = $('#prev');
pos = $('.active').attr('id');
$("#num").text('(' + pos + '/' + researchPlaces.length + ')');
$(current).next().attr("class", "active");
$(current).attr("class", "passive");
//e.stopPropagation();
});

If each div with class 'address' is structured as in your code you can try:
var current = $(this).parent().find('.active');

Related

Combine Javascript Functions into one

I would like to combine the following javascript into one function. I believe this can be done with an array of id's instead of what i did. Suggestions are of course welcome.
So in my code i just copy/paste the code and change the ids:
thumbnail1, primary1
It's a boostrap 4 page with jquery-3.4.1 LINK to page: https://tools.apotamiefsi.info/service.html#_
I am currently studying some js, But i am really new on this. Sorry for any mistakes that i may have made, its my first question here although i have read 1000 answers :P
IF i knew how to use vars i would not ask :) As i said i have no clue about js.
HTML:
<a id="linkwed2" href="#img1" style="display: contents;"><main href="#img21" class="primary primary2" style="background-image: url(/images/products/wringers/wringer_730/Wringer.jpg)"></main></a>
<div class="row justify-content-center">
<div class="container thumbnails" style="display:contents;">
<a class="selected thumbnail thumbnail2" data-ref="#img21" data-big="/images/products/wringers/wringer_730/Wringer.jpg" style="padding: 6px;">
<div class="thumbnail-image" style="background-image: url(/images/products/wringers/wringers_thumbs/wringer_730/Wringer.jpg)"></div>
</a>
<a class="thumbnail2" data-ref="#img22" data-big="/images/products/wringers/wringer_730/Wringer2.jpg" style="padding: 6px;">
<div class="thumbnail-image" style="background-image: url(images/products/wringers/wringers_thumbs/wringer_730/Wringer2.jpg)"></div>
</a>
<a class="thumbnail2" data-ref="#img23" data-big="/images/products/wringers/wringer_730/WringerSteady.jpg" style="padding: 6px;">
<div class="thumbnail-image" style="background-image: url(/images/products/wringers/wringers_thumbs/wringer_730/WringerSteady.jpg)"></div>
</a>
</div>
</div>
jQuery:
$('.thumbnail1').on('click', function() {
var clicked = $(this);
var newSelection = clicked.data('big');
var $img = $('.primary1').css("background-image","url(" + newSelection + ") ");
clicked.parent().find('.thumbnail1').removeClass('selected');
clicked.addClass('selected');
$('.primary1').empty().append($img.hide().fadeIn('slow'));
});
$('.thumbnail2').on('click', function() {
var clicked = $(this);
var newSelection = clicked.data('big');
var $img = $('.primary2').css("background-image","url(" + newSelection + ") ");
clicked.parent().find('.thumbnail2').removeClass('selected');
clicked.addClass('selected');
$('.primary2').empty().append($img.hide().fadeIn('slow'));
});
The code for the light-box which is irrelevant
jquery:
$('.thumbnail1').on('click', function() {
var clicked = $(this);
var neaSelection = clicked.data('ref');
linkwed.href = (neaSelection);
});
$('.thumbnail2').on('click', function() {
var clicked = $(this);
var neaSelection2 = clicked.data('ref');
linkwed2.href = (neaSelection2);
});
And so on, i have like 7 on one page.
I expect the result to be something like:
an array of ids that would be matched with the clicked
image and then the above code without alternatives:
$('.ARRAY_ITEM').on('click', function() {
var clicked = $(this);
var newSelection = clicked.data('big');
var $img = $('.ARRAY2_ITEM').css("background-image","url(" + newSelection + ") ");
clicked.parent().find('.ARRAY_ITEM').removeClass('selected');
clicked.addClass('selected');
$('.ARRAY2_ITEM').empty().append($img.hide().fadeIn('slow'));
});
Your code/comments indicate a single "primary" image with a number of "thumbs" that update that image based on data-big attribute on each thumb.
Within the '.click' event, you can use this to refer to the thumb that was clicked, this gives you the new image url.
Giving each thumb the same class thumb and using this means you can write a single click handler.
Here's an example using text (from data- the same as your url) in a demonstrable form, showing all the concepts. You'll need to make tweaks such as setting the primary img src= to the new url, but the concepts are the same.
I've also added a simple method to show which item is selected as that was also part of the original code.
$(".thumb").click(function() {
var newcontent = $(this).data("big");
$(".primary").text(newcontent);
$(".thumb.selected").removeClass("selected");
$(this).addClass("selected");
})
.thumb { float:left; border: 1px solid #CCC; height:30px; cursor:pointer; }
.primary { clear:both; border: 1px solid blue; height: 60px; }
.selected { border: 1px solid green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='thumb' data-big='THUMB1'>thumb1</div>
<div class='thumb' data-big='THUMB2'>thumb2</div>
<div class='thumb' data-big='THUMB3'>thumb3</div>
<div class='thumb' data-big='THUMB4'>thumb4</div>
<div class='primary'>
PRIMARY
</div>
<div class="row justify-content-center">
<div class="container thumbnails" style="display:contents;">
<a class="selected thumbnail thumbnail2 main-thumb" data-ref="#img21"
data-big="/images/products/wringers/wringer_730/Wringer.jpg" style="padding: 6px;">
<div class="thumbnail-image"
style="background-image: url('https://www.edustoke.com/images/login-image.png')"></div>
</a>
<a class="thumbnail2 main-thumb" data-ref="#img22" data-big="/images/products/wringers/wringer_730/Wringer2.jpg"
style="padding: 6px;">
<div class="thumbnail-image"
style="background-image: url('https://www.edustoke.com/images/login-image.png')"></div>
</a>
<a class="thumbnail2 main-thumb" data-ref="#img23"
data-big="/images/products/wringers/wringer_730/WringerSteady.jpg" style="padding: 6px;">
<div class="thumbnail-image"
style="background-image: url('https://www.edustoke.com/images/login-image.png')"></div>
</a>
</div>
</div>
$('.main-thumb').on('click', function () {
var clicked = $(this);
var newSelection = clicked.data('big');
var $img = clicked.css("background-image", "url(" + newSelection + ") ");
$(clicked).addClass('selected').siblings().removeClass('selected');
$(clicked).empty().append($img.hide().fadeIn('slow'));
});

How to target a div with a same ID

I currently have some ASP.Net code that builds an output and then displays it through a string literal. The idea is that for every Receipt, there is a 'view more' button which toggles extra information that is display: none; to start with. I tried to use the eq() method to attempt to find which one I wanted to toggle because I am doing that inside the ul. My current code is this:
$("#btn-expand").click(function () {
var ldx = $("#list li .active").index(); // Get the list number so we know what ID to work with
var idx = $("#expand").next().index(); // Get the next ID index point
// Check that it isn't going negative
if (idx == -1 || ldx == -1) {
// If it is, reset ldx
ldx = 0;
idx = 0;
}
$("#expand").eq(ldx).toggle(); // Toggle that one
console.log(ldx);
});
The first button works fine and console.log shows 0 however, all the others do not show anything. A sample of my HTML looks like this:
<ul id="list">
<li class="active">
Something <br />
Something Again <br />
<span id="btn-expand">[View more]</span>
<div id="expand">
Something hidden
</div>
</li>
This <br />
Shows <br />
<span id="btn-expand">[View more]</span>
<div id="expand">
This is hidden until toggled
</div>
<li></li>
</ul>
There is a lot more li elements in the ul but that is how it is structured. I am also using <span class="btn" id="btn-next">Next</span> to loop through each li in the ul so I am really confused why the same method for doing it with the `#expand' won't work.
If anyone could point me in the right direction, I'd be appreciated. Thanks.
$(document).ready(function() {
$("#btn-next").click(function() {
var $list = $("#list li");
var idx = $(".active").removeClass("active").next().index();
if (idx == -1) {
idx = 0;
}
$list.eq(idx).addClass("active");
});
$("#btn-prev").click(function() {
var $list = $("#list li");
var idx = $(".active").removeClass("active").prev().index();
if (idx == -1) {
idx = 0;
}
$list.eq(idx).addClass("active");
});
$("#btn-expand").click(function() {
// Get the list number so we know what ID to work with
var ldx = $("#list li .active").index();
// Get the next ID index point
var idx = $("#expand").next().index();
// Check that it isn't going negative
if (idx == -1 || ldx == -1) {
// If it is, reset ldx
ldx = 0;
idx = 0;
}
// Toggle that one
$("#expand").eq(ldx).toggle();
console.log(ldx);
});
});
#list {
list-style: none;
}
.active {
display: block;
}
#btn-expand {
cursor: pointer;
font-size: 9px;
margin-left: 10px;
}
#expand {
display: none;
}
li {
display: none;
}
.btn {
background: none;
padding: 10px;
border: 1px solid #000;
margin-left: 50px;
cursor: pointer;
}
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<ul id="list">
<li class="active">
Something here
<br />Something here again
<span id="btn-expand"> [View More] </span>
<br />
<br />
<span id="expand">
This is hidden, shh..
</span>
</li>
<li>
You can see this
<br />Toggling shouldn't effect me
<span id="btn-expand"> [View More] </span>
<br />
<br />
<span id="expand">
But toggling should effect me!
</span>
</li>
</ul>
<span class="btn" id="btn-prev">Prev</span> - <span class="btn" id="btn-next">Next</span>
id should be unique in same document, replace the duplicate ones by general class, r.g :
<ul id="list">
<li class="active">
Something <br />
Something Again <br />
<span class="btn-expand">[View more]</span>
<div class="expand">
Something hidden
</div>
</li>
This <br />
Shows <br />
<span class="btn-expand">[View more]</span>
<div class="expand">
This is hidden until toggled
</div>
<li>
</li>
</ul>
Then replace id selector # in you script by class selector . :
$(".btn-expand").click(function() {
// Get the list number so we know what ID to work with
var ldx = $("#list li .active").index();
// Get the next ID index point
var idx = $(".expand").next().index();
// Check that it isn't going negative
if (idx == -1 || ldx == -1) {
// If it is, reset ldx
ldx = 0;
idx = 0;
}
// Toggle that one
$(".expand").eq(ldx).toggle();
console.log(ldx);
});
You could use just next() instead of all the code in your event :
$(this).next(".expand").toggle();
//OR
$(this).next().toggle();
Hope this helps.
$(".btn-expand").click(function() {
$(this).next(".expand").toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="list">
<li class="active">
Something <br />
Something Again <br />
<span class="btn-expand">[View more]</span>
<div class="expand">
Something hidden
</div>
</li>
<li>
This <br />
Shows <br />
<span class="btn-expand">[View more]</span>
<div class="expand">
This is hidden until toggled
</div>
</li>
</ul>
Change id's to classes and all you need then is:
$(".btn-expand").click(function() {
$(this).next().toggle();
$(this).text(function(_, oldText){
return oldText.indexOf('More') === -1 ? 'View More' :'View Less';
})
});
$(document).ready(function() {
$("#btn-next").click(function() {
var $list = $("#list li");
var idx = $(".active").removeClass("active").next().index();
if (idx == -1) {
idx = 0;
}
$list.eq(idx).addClass("active");
});
$("#btn-prev").click(function() {
var $list = $("#list li");
var idx = $(".active").removeClass("active").prev().index();
if (idx == -1) {
idx = 0;
}
$list.eq(idx).addClass("active");
});
$(".btn-expand").click(function() {
// Toggle
$(this).next().toggle();
});
});
#list {
list-style: none;
}
.active {
display: block;
}
#btn-expand {
cursor: pointer;
font-size: 9px;
margin-left: 10px;
}
li {
display: none;
}
.btn {
background: none;
padding: 10px;
border: 1px solid #000;
margin-left: 50px;
cursor: pointer;
}
.expand-inner {
display:inline-block;
width:100%;
}
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<ul id="list">
<li class="active">
Something here
<br />Something here again
<span class="btn-expand"> [View More] </span>
<span style="display:none;">
<div class="expand-inner">This is hidden, shh..</div>
</span>
</li>
<li>
You can see this
<br />Toggling shouldn't effect me
<span class="btn-expand"> [View More] </span>
<span style="display:none;">
<div class="expand-inner">But toggling should effect me!</div>
</span>
</li>
</ul>
<span class="btn" id="btn-prev">Prev</span> - <span class="btn" id="btn-next">Next</span>

How to get Slider to show next or previous on span click

I'm using a combination of bootstrap 3 and just writing from scratch.
When I click the image thumbnails, they do what they're supposed to do, but when I click the span arrows, it doesn't go to the next or previous image.
Here's the code:
var maximages = 6;
var startpath = "imgs"
var extension = ".jpg"
function calcslide(x) {
var currentimage = document.getElementById("bigpic").src;
var dotat = currentimage.indexOf(extension);
var stringnumber = currentimage.substr(dotat - 2, 2);
var nextnum = parseInt(stringnumber) + x;
if (nextnum < 1) {
nextnum = maximages;
}
if (nextnum > maximages) {
nextnum = 1;
}
var twodigitnum = ("0" + nextnum).slice(-2);
var showimg = startpath + twodigitnum + extension;
showbig(showimg);
}
function showbig(pic) {
document.getElementById("bigpic").src = pic;
}
.slider {
text-align: center;
}
#bigpic {
height: 500px;
}
.thumbs img {
height: 100px;
padding: 20px 0 20px 0;
}
<div class="slider">
<span class="glyphicon glyphicon-chevron-left btn btn-lg" alt="previous" onclick="calcslide(-1)"></span>
<img src="imgs/slider01.jpg" id="bigpic" />
<span class="glyphicon glyphicon-chevron-right btn btn-lg" alt="next" onclick="calcslide(1)"></span>
<div class="thumbs">
<span class="glyphicon glyphicon-chevron-left" alt="previous" onclick="calcslide(-1)"></span>
<img src="imgs/slider01.jpg" onclick="showbig(this.src)" />
<img src="imgs/slider02.jpg" onclick="showbig(this.src)" />
<img src="imgs/slider03.jpg" onclick="showbig(this.src)" />
<img src="imgs/slider04.jpg" onclick="showbig(this.src)" />
<img src="imgs/slider05.jpg" onclick="showbig(this.src)" />
<img src="imgs/slider06.jpg" onclick="showbig(this.src)" />
<span class="glyphicon glyphicon-chevron-right" alt="next" onclick="calcslide(1)"></span>
</div>
</div>
A slash / and a prefix is missing somewhere within your path construction.
Instead of:
var showimg = startpath + twodigitnum + extension
I would try:
var showimg = startpath + '/slider' + twodigitnum + extension

jquery textarea add link in text with costum popup

I have a textarea where users can enter some text en sometimes they use a little html in there to make it look better. Sometimes this goes a wrong so I tried to make it easier for them by adding a few images with functions. Like wrapping text in <b> <i> <u> <del> tags. This works great. Only now I want them to add url's and this is where I got stuck.
What I want:
I want a popup with a title bar and a url bar. after pressing OK I want the text to appear in the textarea where the user had left his cursor. the text in the textarea needs to look like ' + title + '. If a user selects some text i want that to appear in the popup title field.
If the add link button is pressed the script needs to look if there is a selection in the textarea
if there is a selection the script remembers that
the popup opens
in the title-input of the popup the selection appears.
the user fills in the url
the user presses the OK button
the popup disappears and the selected text gets replaced by a link
the link looks like ' + title + '
this is some code I have:
function wrapAsLink(url) {
var textArea = $('.area'),
len = textarea.value.length,
start = textarea.selectionStart,
end = textarea.selectionEnd,
sel = textarea.value.substring(start, end),
replace = '' + sel + '';
textarea.value = textarea.value.substring(0,start) + replace + textarea.value.substring(end,len);
$('.area').keyup();
}
and a fiddle
You can do something like this:
The fiddle.
Change your html as:
<div class="editor">
<div class="toolbar">
<span id="btnedit-bold" title="Vergedrukte text"><img src="images/bold.png" /></span>
<span id="btnedit-italic" title="Italic text"><img src="images/italic.png" /></span>
<span id="btnedit-underline" title="Onderstreep text"><img src="images/underline.png" /></span>
<span id="divider"> </span>
<span id="btnedit-delete" title="verwijder (doorstreep) text"><img src="images/delete.png" /></span>
<span id="divider"> </span>
<span id="btnedit-link" title="Insert link"><img src="images/link.png" /></span>
</div>
<textarea name="editor-preview" class="area" placeholder="Uw bericht"></textarea>
</div>
<p> </p>
<div class="editor-preview"></div>
<div id="prompt">
<div class="prompt-background"></div>
<div class="prompt-dialog">
<div class="prompt-message">
<p><b>Insert Hyperlink</b></p>
</div>
<form class="prompt-form">
<p>titel</p>
<input id="btnedit-title" type="text" style="display: block; width: 80%; margin-right: auto; margin-left: auto;">
<p>http://example.com/</p>
<input id="btnedit-url" type="text" style="display: block; width: 80%; margin-right: auto; margin-left: auto;">
<button id="btnedit-ok" class="btn-orange" onClick="$('#prompt').show();">OK</button>
<button id="btnedit-cancel" class="btn-orange" onClick="$('#prompt').hide();">cancel</button>
</form>
</div>
</div>
And add those to your javascript as:
$('#btnedit-bold').on("click",function(e) {
wrapText('b');
});
$('#btnedit-italic').on("click",function(e) {
wrapText('i');
});
$('#btnedit-underline').on("click",function(e) {
wrapText('u');
});
$('#btnedit-delete').on("click",function(e) {
wrapText('del');
});
$('#btnedit-link').on("click",function(e) {
var textArea = $('.area'),
len = textArea.val().length,
start = textArea[0].selectionStart,
end = textArea[0].selectionEnd,
selectedText = textArea.val().substring(start, end);
$('#btnedit-title').val(selectedText);
$('#btnedit-url').val('http://');
$('#prompt').show();
});
$('#btnedit-ok').on("click",function(e) {
e.preventDefault();
$('#prompt').hide();
replacement = '<a title="'+$('#btnedit-title').val()+'" href="'+$('#btnedit-url').val()+'" rel="external">' + $('#btnedit-title').val() + '</a>';
wrapLink(replacement);
});
$('#btnedit-cancel').on("click",function(e) {
e.preventDefault();
$('#prompt').hide();
});
function wrapLink(link) {
var textArea = $('.area'),
len = textArea.val().length,
start = textArea[0].selectionStart,
end = textArea[0].selectionEnd,
selectedText = textArea.val().substring(start, end);
textArea.val(textArea.val().substring(0, start) + link + textArea.val().substring(end, len));
$('.area').keyup();
}

childNodes.length 0 in Chrome / Correct In IE & FF

I have a div with children that I need to crawl looking for specific links. The HTML looks like so:
<div id="ctl00_LeftNav">
<h3>
Menu 1</h3>
<div>
<p>
<span>
<div style="padding-left: 0px; font-weight: bold;">
Opt 1</div>
<div style="padding-left: 10px;">
Opt 1a</div>
<div style="padding-left: 0px; font-weight: bold;">
Opt 2</div>
</span>
</p>
</div>
<h3>
Menu 2</h3>
<div>
<p>
<span>
<div style="padding-left: 0px; font-weight: bold;">
Opt 1</div>
<div style="padding-left: 0px; font-weight: bold;">
Opt 2</div>
<div style="padding-left: 10px;">
Opt 2a</div>
</span>
</p>
</div>
<h3>
Menu 3</h3>
<div>
<p>
<span>
<div style="padding-left: 0px; font-weight: bold;">
Opt 1</div>
<div style="padding-left: 0px; font-weight: bold;">
Opt 2</div>
</span>
</p>
</div>
</div>
The Javascript that I have works fine in IE / Firefox, but fails in Chrome:
function OnPageLoadCategorySelect(Category) {
var Root = $j('#ctl00_LeftNav').children();
var Tab = 0;
for (var i = 1; i < Root.length; i += 2) {
var Menu = Root[i].firstChild.firstChild.childNodes;
var MenuLength = Menu.length;
for (var j = 0; j < Menu.length; j++) {
var Link = Menu[j].innerHTML;
var Start = Link.indexOf('(');
var End = Link.indexOf(')');
var Res = Link.slice(Start + 1, End);
if (Res == Category) {
SelectedTabIndex = Tab;
OnLeftMenuSelection(Category);
$j('#ShopTabs').show();
$j('#ctl00_LeftNav').accordion('activate', Tab);
return;
}
}
Tab++;
}
}
In Chrome the 2nd for loop never executes because Menu.length is zero. What would be the best way to get these internal divs?
Solution
function OnPageLoadCategorySelect(Category) {
$j("#ctl00_LeftNav > div").each(function(Tab, el) {
$j('a', this).each(function() {
var id = $j(this).attr('href').replace('javascript:OnLeftMenuSelection(', '').replace(');', '');
if (id == Category) {
SelectedTabIndex = Tab;
OnLeftMenuSelection(Category);
$j('#ShopTabs').show();
$j('#ctl00_LeftNav').accordion('activate', Tab);
return false; // exit the loop
}
})
});
}
If I understand your code correctly, replace your whole function with this:
function OnPageLoadCategorySelect(Category) {
$j("#ctl00_LeftNav > div").each(function(Tab, el){
$j('a', this).each(function(){
var id = $j(this).attr('href').replace('javascript:OnLeftMenuSelection(','').replace(')','');
if( id == Category ) {
SelectedTabIndex = Tab;
OnLeftMenuSelection(Category);
$j('#ShopTabs').show();
$j('#ctl00_LeftNav').accordion('activate', Tab);
return false; // exit the loop
}
})
});
}
The first parameter of the each function is the zero based index. By supplying Tab, it counts it up for you.
You should consider using jQuery.
$('#ctl00_LeftNav').children("div").each(function(index) {
alert(index + ': ' + $(this).text()); // displays inner text of div
});
or this gets all children divs of the selector as pointed out by patrick
$('#ctl00_LeftNav > div').each(function(index) {
alert(index + ': ' + $(this).text()); // displays inner text of div
});
Source: here for loops

Categories