Change div content after its clicked and clicked again - javascript

This is the jQuery code that basically opens and closes a div:
jQuery('#filter_werk').find('.raven-sortable').addClass('opened');
var toggle = document.getElementById('deknop');
var slider = document.querySelector('.raven-sortable');
toggle.addEventListener('click', toggleSlider, false);
function toggleSlider(){
if (slider.classList.contains('opened')) {
slider.classList.remove('opened');
slider.classList.add('closed');
} else {
slider.classList.remove('closed');
slider.classList.add('opened');
}
}
</script>
What I'm trying to do is change the content of the following div from "FILTER +" to "FILTER -" and back again to "FILTER +" when its clicked again
<div id="deknop">FILTER +</div>
Could this be done without breaking the current jQuery code?
Thank you!

As I understood the function toggleSlider works fine so try:
function toggleSlider(){
if (slider.classList.contains('opened')) {
slider.classList.remove('opened');
slider.classList.add('closed');
toggle.innerHTML = "FILTER +";
} else {
slider.classList.remove('closed');
slider.classList.add('opened');
toggle.innerHTML = "FILTER -";
}
}

You can add some logic to your toggleSlider() function that will change your #deknop text based on what it currently is (either ‘FILTER +’ or ‘FILTER -‘ like this:
function toggleSlider(){
$('#deknop').html($('#deknop').text() == 'FILTER +' ? 'FILTER -' : 'FILTER +');
if (slider.classList.contains('opened')) {
slider.classList.remove('opened');
slider.classList.add('closed');
} else {
slider.classList.remove('closed');
slider.classList.add('opened');
}
}

Well,
if I had to do this jQuery-style, I would either way try to separate the data from the view. Something like:
(() => {
const state = {
sliderOpen: true,
};
const $slider = $('.raven-sortable');
const $toggle = $('#deknop');
const updateView = () => {
if (state.sliderOpen) {
$slider.addClass('opened').removeClass('closed');
} else {
$slider.addClass('closed').removeClass('opened');
}
$toggle.text(`FILTER ${state.sliderOpen ? '+' : '-'}`);
};
const onToggleClick = () => {
state.sliderOpen = !state.sliderOpen;
updateView();
};
$toggle.click(onToggleClick);
updateView();
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="raven-sortable">Raven sortable</button>
<button id="deknop"></button>

Related

Remove a JavaScript class method from eventlistener inside another method of the same class

Description & Goal
I have a list with items and clicking on an item shows a detail view, shows a close button and add the eventlistener for closing this item to the button.
By clicking on this button the detail view should be closed and the eventlistener should be removed.
I can't use an anonymous function because removing won't work with it (See here and here).
Problem
Removing doesn't work.
Code
export default class ToggleDetails {
constructor(jobAdId) {
this.jobAdId = jobAdId
this.opened = false
}
toggle() {
const jobAdContainer = document.getElementById(this.jobAdId)
// doing some other css manipulation for the detail view
this.handleCloseButton()
}
handleCloseButton() {
const closeButton = document.getElementById('uh-job-detail-close-button')
const $this = () => {
this.toggle()
}
if (this.opened === true) {
closeButton.classList.remove('uh-job-detail-close-button-show')
closeButton.removeEventListener('click', $this)
this.opened = false
} else {
closeButton.classList.add('uh-job-detail-close-button-show')
closeButton.addEventListener('click', $this)
this.opened = true
}
}
}
HTML structure
"Solution"/Workaround
I solved it, by cloning and replacing the button with itself. The clone doesn't have the eventlisteners (Thanks to this post)
handleCloseButton () {
const closeButton = document.getElementById(
'uh-job-detail-close-button')
closeButton.classList.toggle('uh-job-detail-close-button-show')
if (this.opened === true) {
const elClone = closeButton.cloneNode(true)
closeButton.parentNode.replaceChild(elClone, closeButton)
this.opened = !this.opened
} else {
closeButton.addEventListener('click',
() => { this.toggle() })
this.opened = !this.opened
}
}
Try using a named function and passing the value of this into toggle:
export default class ToggleDetails {
constructor(jobAdId) {
this.jobAdId = jobAdId
this.opened = false
}
toggle(t) {
// doing some other css manipulation for the detail view
t.handleCloseButton()
}
handleCloseButton() {
const closeButton = document.getElementById('uh-job-detail-close-button')
let listenerToggle = () => {
this.toggle(this);
};
if (this.opened === true) {
closeButton.classList.remove('uh-job-detail-close-button-show')
closeButton.removeEventListener('click', listenerToggle)
this.opened = false
} else {
closeButton.classList.add('uh-job-detail-close-button-show')
closeButton.addEventListener('click', listenerToggle)
this.opened = true
}
}
}

Preserve Navigation bar (Hide/Show) when navigated to Other module

How to preserve the navigation bar (minimized position) when navigated to other module.
Collapsed Navigation Bar
sidebar-collapse will not preserve if navigated to other page.
Do you want your nav-bar to change from big to small when you move to a different place?
(sorry, I'm not allowed to comment yet).
Do you want your nav-bar to change from big to small when you move to a different place? It is always nice if you add some code :)
const menuToggle = document.querySelector('.menu-toggle');
const mainUl = document.querySelector(".main-ul");
const navBtn = document.querySelectorAll(".nav-a");
// Open and close meny on click
menuToggle.addEventListener("click", function () {
menuToggle.classList.toggle("open");
mainUl.classList.toggle("open");
});
// Close menu when clicked on an a-tag in the menu
navBtn.forEach((button) => {
button.addEventListener("click", function () {
navBtn.forEach((button) => button.classList.remove("active"));
this.classList.add("active");
mainUl.classList.toggle("open");
menuToggle.classList.toggle("open");
});
});
This is demo and source code I created
https://minhhungit.github.io/2020/10/16/011-keep-menu-toggle-state-after-page-reload/
namespace J {
export function storageSet(name, val) {
if (typeof (Storage) !== "undefined") {
localStorage.setItem(name, val);
} else {
//window.alert('Please use a modern browser to properly view this template!');
}
}
export function storageGet(name) {
if (typeof (Storage) !== "undefined") {
return localStorage.getItem(name);
} else {
return null;
}
}
}
In _Layout.cshtml put this code
<script type="text/javascript">
$().ready(function () {
new DailyTimelog.Common.SidebarSearch($('#SidebarSearch'), $('#SidebarMenu')).init();
// ...
// ...
$(window).bind("load resize layout", doLayout);
doLayout();
});
</script>
// Add these lines
<script type="text/javascript">
let sidebarToggleButton = $('.main-header .sidebar-toggle');
if (sidebarToggleButton) {
$(sidebarToggleButton).on('click', function (e) {
e.preventDefault();
let isSidebarCollapse = $('body').hasClass('sidebar-collapse');
J.storageSet('IS_SIDEBAR_COLLAPSE', !isSidebarCollapse);
});
}
</script>
And LeftNavigation.cshtml
<script type="text/javascript">
function openWindow(url, width, height) {
height = height || (screen.availHeight - 60);
// ...
// ...
}
// Add these lines
let isSidebarCollapseCache = J.storageGet('IS_SIDEBAR_COLLAPSE');
if (isSidebarCollapseCache == 'true') {
$('body').toggleClass('sidebar-collapse', true);
}
else {
$('body').toggleClass('sidebar-collapse', false);
}
</script>
``
#minhhungit Thank you for your demo.
I have used cookie implementation similar to ThemePreference.
Views/Shared/_Layout.cshtml
var theme = !themeCookie.IsEmptyOrNull() ? themeCookie : "blue";
// Add following lines
var sbNavCookie = Context.Request.Cookies["SBNavigationPreference"];
var sbNav = !sbNavCookie.IsEmptyOrNull() && sbNavCookie == "true" ? true : false;
in Body Tag,
<body ... class="...#(sbNav?" sidebar-collapse":"")">
In Script Tag,
<script type="text/javascript">
$().ready(function () {
// Add new lines
let sidebarToggleButton = $('.main-header .sidebar-toggle');
if (sidebarToggleButton) {
$(sidebarToggleButton).on('click', function (e) {
e.preventDefault();
let isSidebarCollapse = $('body').hasClass('sidebar-collapse');
$.cookie('SBNavigationPreference', !isSidebarCollapse, {
path: Q.Config.applicationPath,
expires: 365
});
});
}

How to change image and text at the same time on click

I'm trying to change my text and image on click (mobile only) but it's not working. Only the image can be changed with the function I wrote. Could anyone help me with that, please?
Here is the live code: https://codepen.io/oleanderek/pen/OdNzME
document.querySelectorAll(".nav__label").forEach((el) => {
el.addEventListener('click', changeArrow);
el.addEventListener('click', changeText);
});
function changeArrow() {
var arrow = this.getElementsByClassName('arrow')[0];
if (arrow.classList.contains("down-arrow")) {
arrow.classList.remove("down-arrow");
arrow.classList.add("up-arrow");
} else if (arrow.classList.contains("up-arrow")) {
arrow.classList.remove("up-arrow");
arrow.classList.add("down-arrow");
}
}
function changeText() {
var changeText = this.getElementsByClassName('showText')[0];
if (changeText.classList.contains("showText")) {
arrow.classList.remove("showText");
arrow.classList.add("hideText");
} else if (changeText.classList.contains("hideText")) {
arrow.classList.remove("hideText");
arrow.classList.add("showText");
}
}
If you delete the class to change, the variable you define remains undefined. Therefore, you must define a class that you will not change. I added newClass This works fine.
HTML
<p class="newClass showText">.</p>
Javascript
document.querySelectorAll(".nav__label").forEach((el) => {
el.addEventListener('click', changeArrow);
el.addEventListener('click', changeText);
});
function changeArrow() {
var arrow = this.getElementsByClassName('arrow')[0];
if (arrow.classList.contains("down-arrow")) {
arrow.classList.remove("down-arrow");
arrow.classList.add("up-arrow");
} else if (arrow.classList.contains("up-arrow")) {
arrow.classList.remove("up-arrow");
arrow.classList.add("down-arrow");
}
}
function changeText() {
var changeText = document.querySelector(".newClass");
if (changeText.classList.contains("showText")) {
changeText.classList.remove("showText");
changeText.classList.add("hideText");
} else if (changeText.classList.contains("hideText")) {
changeText.classList.remove("hideText");
changeText.classList.add("showText");
}
}

if statement within function breaks javascript

I'm stumped with this one and would really appreciate someone's help.
I'm customizing highslide for integration with wordpress. Via the following code within the highslide.config.js file I'm adding a class name to certain elements and passing different attributes through an onClick call depending on certain conditions.
Everything works until I add the following code:
if(hsGroupByWpGallery){
slideshowGroup: this.parentNode.parentNode.parentNode.id
};
When the above code is present, not only does that one statement not execute, but the whole thing stops working. Even if the if statement is something like if(1=1){}; it still breaks.
If I have instead simply slideshowGroup: this.parentNode.parentNode.parentNode.id or nothing (the two options I'm looking for), both do what I would expect. I just need an if statement to switch between them.
Here's the relevant code:
jQuery(document).ready(function() {
var hsCustomGalleryGroupClass = 'fbbHighslide_GalleryGroup';
var hsCustomGalleryGroupChecker = 0;
var hsGroupByWpGallery = true;
jQuery('.' + hsCustomGalleryGroupClass).each(function(){
hsCustomGalleryGroupChecker++;
return false;
});
if (hsCustomGalleryGroupChecker > 0){
jQuery('.' + hsCustomGalleryGroupClass).each(function(i, $item) {
var grpID = $item.id;
jQuery('#' + grpID + ' .gallery-item a').addClass('highslide').each(function() {
this.onclick = function() {
return hs.expand(this, {
slideshowGroup: grpID
});
};
});
});
} else {
jQuery('.gallery-item a').addClass('highslide').each(function() {
this.onclick = function() {
return hs.expand(this, {
// This is the problem if statement
if(hsGroupByWpGallery){
slideshowGroup: this.parentNode.parentNode.parentNode.id
};
});
};
});
};
});
Thanks in advance.
The problem is you are trying to assign a conditional property.. you can't have a if condition inside a object definition like that
jQuery('.gallery-item a').addClass('highslide').each(function () {
this.onclick = function () {
var obj = {};
//assign the property only if the condition is tru
if (hsGroupByWpGallery) {
obj.slideshowGroup = this.parentNode.parentNode.parentNode.id;
}
return hs.expand(this, obj);
};
});
Another way to do the same is
jQuery('.gallery-item a').addClass('highslide').each(function () {
this.onclick = function () {
//if the flag is true sent an object with the property else an empty object
return hs.expand(this, hsGroupByWpGallery ? {
slideshowGroup: this.parentNode.parentNode.parentNode.id
} : {});
};
});
I think you might want this, based on the other code:
jQuery('.gallery-item a').addClass('highslide').each(function() {
this.onclick = function() {
if(hsGroupByWpGallery){
return hs.expand(this, {
slideshowGroup: this.parentNode.parentNode.parentNode.id
});
}
};
});

tinymce custom-button replace content

I added a custom 'quote' button.
ed.addButton('blockquote', {
title : 'blockquote',
cmd : 'mceblockquote',
image : url + '/img/blockquote.gif',
onclick : function() {
var blockquoteActive = tinyMCE.activeEditor.controlManager.get('blockquote').isActive();
if (blockquoteActive) {
//replace <blockquote> tags ?!
//set Button inactive
}
else {
ed.selection.setContent('<blockquote>' + ed.selection.getContent() + '</blockquote><br />');
}
}
});
ed.onNodeChange.add(function(ed, cm, n) {
cm.setActive('blockquote', n.nodeName == 'IMG');
})
When I click the button, everything works fine. The selection is quoted.
How do I replace the blockquote-tags when klicking the button again?
How do I set the button inactive?
Regards,
saromba
it worked thanks...
I've made some changes (maybe / probably improvements).
When nothing is selected, do nothing
When text is already quoted
When user marked the text with a double-click, the blockquote element will now be removed
onclick : function() {
var blockquoteActive = tinyMCE.activeEditor.controlManager.get('blockquote').isActive();
var selection = ed.selection.getContent();
if (blockquoteActive) {
if (selection) {
var parElem = ed.dom.getParent(ed.selection.getNode(), 'blockquote');
var inner = parElem.innerHTML;
ed.dom.remove(parElem);
ed.selection.setContent(inner);
}
else return
}
else {
if (selection) {
ed.selection.setContent('<blockquote>' + ed.selection.getContent() + '</blockquote><br />');
}
}
}
Try this. You may modify it a bit.
ed.addButton('blockquote', {
title : 'blockquote',
cmd : 'mceblockquote',
image : url + '/img/blockquote.gif',
onclick : function() {
var blockquoteActive = tinyMCE.activeEditor.controlManager.get('blockquote').isActive();
if (blockquoteActive) {
//replace <blockquote> tags ?!
content = ed.selection.getContent();
content.replace(/<\/?blockquote>/ig,'');
ed.selection.setContent(content);
//set Button inactive
// works only if blockquote is registered at the controlManager
ed.controlManager.setActive('blockquote', false);
}
else {
ed.selection.setContent('<blockquote>' + ed.selection.getContent() + '</blockquote><br />');
}
}
});

Categories