I ran through the following Javascript to create a click function to toggle an active state and expand an element to show the full text.
$ = jQuery.noConflict();
$( document ).ready( function() {
$(".toggle_container").hide();
var toggle = function(el, direction) {
if (direction === 'open') {
var content = $(el).toggleClass("active").prev();
var curHeight = content.height();
content.css('height', 'auto');
var autoHeight = content.height();
content.height(curHeight).animate({height: autoHeight}, 100).promise().then(setTimeout(function(){content.removeClass("limited")}, 650));
} else {
var content = $(el).toggleClass("active").prev();
content.height(curHeight).animate({height: '70px'}, 100).promise().then(function(){content.addClass("limited")});
}
}
jQuery(".togglefeaBtn").on("click", function(){
if ($.trim($(this).text()) === 'Read MORE') {
$(this).text('Close');
toggle(this, 'open');
} else {
$(this).text('Read MORE');
toggle(this, 'close');
}
return false;
});
});
The issue that I've noticed is that when loaded on an iPad $(this), when in the click function, or $(el), when in the toggle function return a blank value, however, $(this).text('...') works perfectly.
Is there an issue with the way I'm using the click function, or do touch devices require a different set up?
Shouldn't it be toggle($(this), 'close'); not this? The context of this hasn't been defined.
You can also change $(el) to just be el.
var $ = jQuery.noConflict();
$( document ).ready( function() {
$(".toggle_container").hide();
var toggle = function(el, direction) {
if (direction === 'open') {
var content = el.toggleClass("active").prev();
var curHeight = content.height();
content.css('height', 'auto');
var autoHeight = content.height();
content.height(curHeight).animate({height: autoHeight}, 100).promise().then(setTimeout(function(){content.removeClass("limited")}, 650));
} else {
var content = el.toggleClass("active").prev();
content.height(curHeight).animate({height: '70px'}, 100).promise().then(function(){content.addClass("limited")});
}
}
jQuery(".togglefeaBtn").on("click", function(){
if ($.trim($(this).text()) === 'Read MORE') {
$(this).text('Close');
toggle($(this), 'open');
} else {
$(this).text('Read MORE');
toggle($(this), 'close');
}
return false;
});
});
After continuing to wrestle with this issue, I opted to take a much simpler route and scrap the Javascript method to animate the reveal and just use CSS Transform with max-height. The code got a lot smaller, and works nearly everywhere.
$ = jQuery.noConflict();
$( document ).ready( function() {
$(".toggle_container").hide();
jQuery(".togglefeaBtn").on("click", function(){
if ($.trim($(this).text()) === 'Read MORE') {
$(this).text('Close');
$(this).toggleClass("active");
$(this).prev().css('max-height', '500px');
$(this).prev().removeClass("limited");
} else {
$(this).text('Read MORE');
$(this).toggleClass("active");
$(this).prev().css('max-height', '70px');
$(this).prev().addClass("limited");
}
return false;
});
});
Related
I have just noticed that on mobile and when resized to mobile my tabs are not clicking and changing and wondering if anyone can see why?
I created a fiddle here: https://jsfiddle.net/a6k70p0L/2/
Works fine in desktop view, but when resized the click events does seem to fire and change.
JS:
$(document).ready(function() {
var originalTabs = $('.originalTabs').html();
function clearTabs(){
$('.originalTabs').html(originalTabs);
}
//clearTabs();
//desktopTabs();
function desktopTabs(){
clearTabs();
// cretate tabs for desktop
var headers = $("#tab_description h6");
$('#tab_description h6').each(function(i){
$(this).nextUntil("h6").andSelf().wrapAll('<div class="tab" id="tab-'+i+'"/>');
});
for( var i = 0; i < headers.length; i++ ) {
$('.tabs').append('<li class="">'+headers[i].innerHTML+'</li>');
}
$('ul.tabs').each(function(){
var active, content, links = $(this).find('a');
var listitem = $(this).find('li');
active = listitem.first().addClass('active');
content = $(active.attr('href'));
$('.tab').hide();
$(this).find('a').click(function(e){
$('.tab').hide();
$('ul.tabs li').removeClass('active');
content.hide();
active = $(this);
content = $($(this).attr('href'));
active.parent().addClass('active');
content.show();
return false;
});
});
headers.remove(); // remove headers from description
$('#tab-0').show(); // show the first tab
}
function mobileTabs(){
clearTabs();
//alert("loaded mobile");
var headers = $("#tab_description h6");
$(headers).each(function(i) {
$(this).append('');
//$(this).nextUntil("h6").andSelf().wrapAll('<div class="aTab" id="tab-'+i+'"/>');
});
$('#tab_description h6').first().trigger('click').addClass("active");
$('#tab_description h6').first().nextUntil("h6").show();
}
var tabClick = function() {
//alert("clicked");
var accordionContent = $('#tab_description p, #tab_description ul, #tab_description table, #tab_description iframe, #tab_description div');
$('#tab_description h6').removeClass("active");
if (!$(this).hasClass("active")){
$(this).addClass("active");
}
// Check if current accordion item is open
var isOpen = $(this).next().is(":visible");
// Hide all accordion items
accordionContent.hide();
// Open accordion item if previously closed
if (!isOpen) {
$(this).nextUntil('h6').show();
}
// Disabled to stop on mobile auto scrolling down to product description when clicking through...
$('html, body').animate({
scrollTop: $(this).offset().top - 15
}, 2000);
return false;
}
//bind to resize
$(window).resize( function() {
if(isMobileLandscapeOnly.matches || isTabletLandscapeOnly.matches){
desktopTabs();
$('#tab_description h6').on("click, touchstart", tabClick);
} else if(isMobilePortraitOnly.matches || isTabletPortraitOnly.matches){
mobileTabs();
$('#tab_description h6').on("click, touchstart", tabClick);
} else if(isDesktop) {
desktopTabs();
}
});
//check for the orientation event and bind accordingly
window.addEventListener("orientationchange", function() {
if(isMobileLandscapeOnly.matches || isTabletLandscapeOnly.matches){
desktopTabs();
$('#tab_description h6').on("click, touchstart", tabClick);
} else if(isMobilePortraitOnly.matches || isTabletPortraitOnly.matches){
mobileTabs();
$('#tab_description h6').on("click, touchstart", tabClick);
} else if(isDesktop) {
desktopTabs();
}
}, false);
if(isMobileLandscapeOnly.matches || isTabletLandscapeOnly.matches){
//alert("Mobile / Tablet (Portrait)");
desktopTabs();
$('#tab_description h6').on("click, touchstart", tabClick);
//console.log(originalTabs);
} else if(isMobilePortraitOnly.matches || isTabletPortraitOnly.matches){
//alert("Mobile / Tablet (Portrait)");
mobileTabs();
$('#tab_description h6').on("click, touchstart", tabClick);
} else if(isDesktop) {
//alert("Desktop");
desktopTabs();
}
});
Wrap your $('ul.tabs').each... in function and call the function when you have done all your appending of a/h6 tags in mobile. Or call your appending functions before the each statement.
The each statement fires and applies to everything that is currently available in the DOM, as your appending function hasn't started yet...the each statement doesn't know it's there. Then your appending stuff happens in your mobile functions and the each statement doesn't know it exists(as it is fired before the mobile functions).
Edit - Working Answer
Check the updated fiddle here: https://jsfiddle.net/a6k70p0L/6/
I've mentioned my changes in the comment below.
When you are using append() with an event like onclick() you should use delegate()jQuery function.
Example :
$("body").delegate('.class', 'click' ,function()
{
//do something
});
It is very helpfull. You can read the cause of this usage in other post on Stackoverflow.
I've got to a point where my accordions open up at the same time - see http://www.bootply.com/Go4t29rYyF
When you click on "tab1" all the "tab1s" open, when you click on "tab2" all the "tab2s" open - great! But I cant open "tab1s & tab2s" at the same time, it only works when I close one of the tabs first before opening another. The issue is with my js but cant work it out.
$(function () {
var $active = true;
$('.panel-title > a').click(function (e) {
e.preventDefault();
});
$('.number1-collapse').on('click', function () {
if (!$active) {
$active = true;
$('.panel-title > a').attr('data-toggle', 'collapse');
$('.number1').collapse('hide');
} else {
$active = false;
$('.number1').collapse('show');
$('.panel-title > a').attr('data-toggle', '');
}
});
$('.number2-collapse').on('click', function () {
if (!$active) {
$active = true;
$('.panel-title > a').attr('data-toggle', 'collapse');
$('.number2').collapse('hide');
} else {
$active = false;
$('.number2').collapse('show');
$('.panel-title > a').attr('data-toggle', '');
}
});
});
I've tidied up your code and changed to using the toggle method instead of having various flags. The problem is that you are sharing the active flag between them. Here is the improved code and Bootply:
$(function () {
$('.panel-title > a').click(function (e) {
e.preventDefault();
});
$('.number1-collapse').on('click', function () {
$('.number1').collapse('toggle');
});
$('.number2-collapse').on('click', function () {
$('.number2').collapse('toggle');
});
});
You may want to specify which elements you are effecting in your function using the event parameter
Example:
$('.number2-collapse').on('click', function (event) {
var panelTitle = $(event.currentTarget).find('.panel-title > a');
var number = $(event.currentTarget).find('.number2');
if (!$active) {
$active = true;
$(panelTitle).attr('data-toggle', 'collapse');
$(number).collapse('hide');
} else {
$active = false;
$(number).collapse('show');
$(panelTitle).attr('data-toggle', '');
}
});
This is an example. You may need to alter this code for it to work in your situation
I have a button on my page
<button id="show1" class="morelinkblack">Find Out More</button>
When clicked it runs this code
$("#show1").click(function(){
$(".hidden-div1").slideToggle("slow");
});
Is there a way of changing the text to say "Close" instead of "find out more" while the div is visible?
You can do:
$("#show1").click(function(){
var that = $(this);
$(".hidden-div1").slideToggle("slow", function() {
if ($(this).is(":visible")) {
that.text("Close");
} else {
that.text("Find out more");
}
});
});
Based on the comments, the div could be opened or closed depending on where the user is directed from. A simple check in the DOM ready can set the text accordingly:
$(".hidden-div1").is(":visible") ? $("#show1").text("Close") : $("#show1").text("Find out more");
Maybe this :
$("#show1").click(function () {
var $div = $(this);
$(".hidden-div1").slideToggle("slow").promise().done(function () {
$div.text(function () {
return $(this).is(":visible") ? "Close" : "Find Out More"
});
});
});
Updated code
$("#show1").click(function() {
var el = $(this);
$(".hidden-div1").slideToggle("slow", function() {
if ($(this).css('display') == 'none') { // <- Updated here to check if div is close or open
el.text('Find Out More');
} else {
el.text('Hide More');
}
});
});
Update button text on document ready / page load
$(document).ready(function() {
if ($(".hidden-div1").css('display') == 'none') {
$("#show1").text('Find Out More');
} else {
$("#show1").text('Hide More');
}
});
I'm trying to show this CSS on the first click and remove it on the next but toggleClass doesnt seem to work and neither does my code below. All I can get is the CSS to show and it never gets removed. This is for use on Safari on iOS. Thanks for the help!
var menu_enabled = false;
$('#nav a').click(function () {
if (menu_enabled == true) {
$(this).removeClass('sf-js-enabled');
var menu_enabled = false;
}
else {
var menu_enabled = true;
$(this).addClass('sf-js-enabled');
}
});
You should checkout .toggleClass(), looks like it's exactly what you're wanting.
$('#nav a').click(function () {
$(this).toggleClass('sf-js-enabled');
});
Perhaps using the .className attribute?
var menu_enabled = false;
$('#nav a').click(function () {
if (menu_enabled == true) {
$(this).className = "";
menu_enabled = false;
}else
{
menu_enabled = true;
$(this).className = 'sf-js-enabled';
}
});
I'm not exactly sure what you're trying to accomplish overall, but addClass and removeClass should work just fine. I would add an ID or class to the element that you want to have the click attached to but that's just a personal preference.
$(document).ready(function(){
$('#element').click(function(){
if($('#element').hasClass('sf-js-enabled')){
$('#element').removeClass();
}
else{
$('#element').addClass('sf-is-enabled');
}
});
});
I wonder if anyone can help to finally resolve an issue I brought up on SO a while back.
I am unable to untoggle these dropdown menus by clicking outside of the button, or anywhere else on the page.
Please see this jsFiddle.
I've seen folks using stopPropagaton() but am unsure how to apply it here.
Any ideas how to do this?
My toggling code:
var cur = null;
$(".toggle").click(function(e){
$('#nav ul:visible').hide();
if(cur == null || cur.currentTarget != e.currentTarget)
{
if(cur != null)
{
$(cur.currentTarget)
.children('a:first').children('span').removeClass('fc-state-active');
}
cur = e;
$(cur.currentTarget)
.children('a:first').children('span').addClass('fc-state-active');
$(cur.currentTarget)
.children('ul').show();
}
else
{
$(cur.currentTarget)
.children('a:first').children('span').removeClass('fc-state-active');
cur = null;
}
});
I believe the following should work for you. This utilizes jQuery's focusout() function:
$(".toggle").click(function(){
$('#nav ul:visible').hide();
$('span.fc-state-active').removeClass('fc-state-active');
$(this).children('a:first').children('span').addClass('fc-state-active');
$(this).children('ul').show();
}).focusout(function(){
$('#nav ul:visible').hide();
$('span.fc-state-active').removeClass('fc-state-active');
});
And here's an updated fiddle: jSFiddle
EDIT: The following works in FF & Chrome
New Fiddle: jsFiddle
$(".toggle").click(function(){
$('#nav ul:visible').hide();
$('span.fc-state-active').removeClass('fc-state-active');
$(this).children('a:first').children('span').addClass('fc-state-active');
$(this).children('ul').show();
hide = false;
});
$(document).click(function(){
if(hide){
$('#nav ul:visible').hide();
$('span.fc-state-active').removeClass('fc-state-active');
}
hide = true;
});
Reason: $(document).click() is called after $(".toggle").click()
EDIT 2: The working fiddle can be found here: jSFiddle
var hide;
$(".toggle").click(function(){
var active_span = $(this).children('a:first').children('span');
var active_ul = $(this).children('ul');
$(active_span).toggleClass('fc-state-active');
$("span.fc-state-active").not(active_span).removeClass('fc-state-active');
$(active_ul).toggle();
$("#nav ul:visible").not(active_ul).hide();
hide = false;
});
$(document).click(function(){
if(hide){
$('#nav ul:visible').hide();
$('span.fc-state-active').removeClass('fc-state-active');
}
hide = true;
});