I have a list on a user control and a jquery script that works when an li is clicked. This works fine. I want to change the class on the selected li but having trouble making this work. I tried this in a fiddle and no problem - but in my actual page - no good.
the fiddle is at https://jsfiddle.net/u6sykb8d/7/
the actual jquery script is
$(document).ready(function () {
$('.listButtons li').on("click", function () {
$('.selected').removeClass("selected");
$(this).addClass("selected");
var tabid = $(this).attr('id');
var cont = $(this).closest($(".container"));
var tabs = ["tabAddress", "tabPeople0", "tabPeople1", "tabPeople2", "tabPeople3", "tabPeople4"];
var divs = ["divAddress0", "divPeople_0", "divPeople_1", "divPeople_2", "divPeople_3", "divPeople_4"];
var indx = tabs.indexOf(tabid);
for (var i = 0; i < divs.length; i++) {
if (i == indx) {
cont.find($("div[id$='" + divs[i] + "']")).show();
}
else {
cont.find($("div[id$='" + divs[i] + "']")).hide();
}
}
});
});
the rest of the script works, the lines removing and adding the class don't seem to work.
Any ideas?
embarrassed to say but after digging through the code the problem turned out to be an extra space in the css file 'li .selected' instead of 'li.selected' . Thanks for the help
Related
First time on stackoverflow, so please don't beat me up too much.
I'm working with an existing code from codepen and trying to figure out how to make the tables expand one at a time.
Currently if we click on more than one "+" icon, they remain open, wondering how we can make it so that previous items expanded will close when clicking on the "+" sign.
I tried adjusting the layout here to no avail:
$('.js-tdToggle').on('click', function(){
if(window.innerWidth < 681){
$(this).toggleClass("fa-plus-square fa-minus-square");
var trParent = $(this).parent().parent();
trParent.toggleClass("collapse");
} else {
$(this).toggleClass("fa-plus-square fa-minus-square");
var tdParent = $(this).parent();
tdParent.next("td").toggleClass("collapse");
}
});
Original Source Codepen
You have to add code where you do the opposite action on every other toggle. JQuery's .not() function is very useful for this. With my changes the JavaScript looks like this:
$('.js-tdToggle').on('click', function() {
var $otherToggles = $(".js-tdToggle.fa-minus-square");
if (window.innerWidth < 681) {
$(this).toggleClass("fa-plus-square fa-minus-square");
$otherToggles.not(this).toggleClass("fa-minus-square fa-plus-square");
var trParent = $(this).parent().parent();
trParent.toggleClass("collapse expand");
var $otherParents = $otherToggles.parent().parent();
$otherParents.removeClass("expand").addClass(" collapse");
} else {
$(this).toggleClass("fa-plus-square fa-minus-square");
$otherToggles.not(this).toggleClass("fa-minus-square fa-plus-square");
var tdParent = $(this).parent();
tdParent.next("td").toggleClass("collapse expand");
var $otherParents = $($otherToggles).not(this).parent();
$otherParents.next("td").toggleClass("expand collapse");
}
});
You can refer to my forked pen to see it in action: codepen.io
I'm using a lightbox script which uses a data attribut to know which images are part of a gallery.
To initialize a gallery, I have to do the following:
var selector = 'a[data-imagelightbox="a"]';
var lightbox = $( selector ).imageLightbox({});
If I wan't another gallery on the same page I have to add another:
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
I tried to use another selector and the .each function to get it working without writing this 2 code lines for each gallery. But it is not working. The problem is the data attribute groups all images with this attribute to one gallery. If I'm trying it without a, b, c or d - i always get one large gallery and not 3 seperate gallerys.
So, does anybody have a solution how I can use an unknown number of gallerys on one page, without having to define each gallery in Javascript?
I made a JSBIN, so it should be easier to try it out:
http://jsbin.com/goqije/1/
Thanks for your help!
Fixed it myself by doing it this way:
$('ul').each( function() {
var id = $(this).find('a').attr('data-imagelightbox');
var selector = 'a[data-imagelightbox="' + id +'"]';
var lightbox = $( selector ).imageLightbox({
quitOnDocClick: false,
onStart: function() { overlayOn(); closeButtonOn( lightbox ); arrowsOn( lightbox, selector ); },
onEnd: function() { overlayOff(); closeButtonOff(); arrowsOff(); },
onLoadStart: function() { },
onLoadEnd: function() { $( '.imagelightbox-arrow' ).css( 'display', 'block' ); }
});
});
Attribute selector maybe?
instead of doing :
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
and
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
Just do it with a attribute selector :
var selector = 'a[data-imagelightbox]';
var lightbox = $( selector ).imageLightbox({});
Or even better, you can use a naming convention for all the gallery data attributes as follows:
gallery-1 , galery-2 , gallery-3 and then use a attribute selector as follows:
var selector = 'a[data-imagelightbox^="gallery"]';
var lightbox = $( selector ).imageLightbox({});
Solution two
The above solution seems to have a conflict, here's a slightly different solution that leverages "naming convention" (gallery-1 , gallery-2 ... etc.) and a for loop , see this example here. Notice how I am using a for loop to iterate over all the a elements and turn their color red:
HTML code here:
One
Two
Three
jQuery code here:
$(function () {
str_elm = $('a');
for (var i = 0; i < str_elm.length ; i++) {
data_val = $(str_elm[i]).attr('data-test');
str_temp = "a[data-test=" + '"'+ data_val + '"' + "]";
$(str_temp).css({'color' : 'red'});
};
});
Fiddle here.
You can change the JS as follows to suit your needs:
$(function () {
str_elm = $('a[data-imagelightbox^="gallery"]');
for (var i = 0; i < str_elm.length ; i++) {
data_val = $(str_elm[i]).attr('data-test');
str_temp = "a[data-test=" + '"'+ data_val + '"' + "]";
$(str_temp).imageLightbox({}); // initialization here
};
});
so i've got this script:
window.onload = function() {
var myValues = localStorage.getItem("myValues") ? JSON.parse(localStorage.getItem("myValues")) : [];
var myTables = localStorage.getItem("tableValues") ? JSON.parse(localStorage.getItem("tableValues")) : [];
makeDuplicates(myTables);
var divElements = document.querySelectorAll("#namefield");
for(var i = 0; i < myValues.length; i++) {
alert("In table: " + divElements[i].textContent + ", trying to change: "+myValues[i]);
divElements[i].textContent = myValues[i];
}
}
I did a little test with alert, the element it gets is right and myValue[i] exists but the value in div does not change with the code below alert. I don't know what else should i show in this occasion or is this enough?
As for more clarification - the similar code works in another javascript i'm using for another .html and this particular page loads the table in which i have td which content will be changed before the for cycle starts (got it with alert).
Any ideas why the change does not occur?
Added images for clarification:
This is a link to a HTML: http://pastebin.com/x5sbbj6b
I am trying to get a line of JQuery script to read every paragraph string found in a div and split that paragraph every time there is a ','. My issues is that I am unable to POST all of the array at once, so the replaceWith function only outputs the first value of the array because the rest of the array is deleted when the for condition returns to increment to myArray[1].
Is there anyway for me to post every value in the 'array of splits' to separate html elements without leaving the initial string and/or turning every created element a child of the previous element?
DEMO
http://jsfiddle.net/ry25Q/
HTML
<div class="data">
<i>days_of_week</i>
<p>mon,tue,wed,thur,fri,sat,sun</p>
</div>
<div>
<input type="button" class="btnClick Button" value="Click" />
</div>
JS CODE
$(function () {
$('.btnClick').click(function () {
var data = $('.data p').text();
var splitter = data.split(',');
for (var i = 0; i < splitter.length; i++) {
$(".data p").replaceWith("<span class='dataseg'>" + splitter[i] + "</span>")
}
});
});
You don't need a loop. Since you're only replacing one p element, just call .replaceWith() once with the full HTML string you're inserting.
DEMO: http://jsfiddle.net/Vfk4e/
$(function () {
$('.btnClick').click(function () {
var p = $('.data p');
var splitter = p.text().split(',');
var open = "<span class='dataseg'>";
var close = "</span>"
p.replaceWith(open + splitter.join(close + open) + close)
});
});
Can't you just add $('.data p').text(''); before your for statement? This will clear the contents,t hen your .append from your fiddle will work just fine.
$(function () {
$('.btnClick').click(function () {
var data = $('.data p').text();
var splitter = data.split(',');
$('.data p').text('');
for (var i = 0; i < splitter.length; i++) {
$(".data p").append("<span class='dataseg'>" + splitter[i] + "</span>")
}
});
});
Try to create a variable for the span element you wish to replace the <p> element with. Then inside of your for loop, sequentially add your data to the span element. After the loop, close your span and then call replaceWith() with the span variable.
$(function () {
$('.btnClick').click(function () {
var data = $('.data p').text();
var splitter = data.split(',');
var daySpan = "<span class='dataseg'>";
for (var i = 0; i < splitter.length; i++) {
daySpan += splitter[i];
}
daySpan += "</span>";
$(".data p").replaceWith( daySpan );
});
});
Demo: http://codepen.io/imajedi4ever/pen/kpzCD/?editors=101
I have a form with a textarea and list of tags from database( already queried and displayed under the textarea ) and want to add these tags (seperated by comma) on textarea and remove if the tag is already there as user click on them.
I think I know what you mean, please have a look at this fiddle
http://jsfiddle.net/joevallender/QyqYW/1/
The code is below. tags would come from the server and selectedTags is the managed array of current selections. you could load data from the server into selectedTags too if necessary, if for instance editing an existing tagged post. If you did this, you'd refactor the code in the click() function out to its own function so it could be run on document ready too.
I've included some class toggling and a debug screen so you can see what is going on.
HTML
<textarea id="tags"></textarea>
<div id="tagButtons"></div>
<div id="debug"></div>
and JavaScript
var tags = [
'JavaScript',
'jQuery',
'HTML5',
'CSS3'
];
var selectedTags = [];
for(var i = 0; i < tags.length; i++) {
var el = $('<span>').text(tags[i]);
$('#tagButtons').append(el);
}
$('#tagButtons span').click(function(){
var val = $(this).text();
var index = selectedTags.indexOf(val);
if(index > -1) {
var removed = selectedTags.splice(index,1);
$(this).removeClass('selected');
$('#debug').prepend($('<div>').html('Removed: ' + removed));
} else {
selectedTags.push(val);
$(this).addClass('selected');
$('#debug').prepend($('<div>').html('Added: ' + val));
}
$('#tags').val(selectedTags.join(', '));
});
EDIT Here is one that works in both directions http://jsfiddle.net/joevallender/QyqYW/14/