This is the button that triggers the side menu open / close on Moodle boost theme. I am trying to keep the menu hidden by default on page load.
So, I need to set <button aria-expanded="true" to <button aria-expanded="false" on page load. However, all the Javascript snippets I have tried need the element to have an 'Id' or a 'Name'; and this button has neither.
Question : How to I change the <button aria-expanded="true" to <button aria-expanded="false" on page load - without changing the source code of Moodle ?
<button aria-expanded="true"
aria-controls="nav-drawer"
type="button"
class="btn nav-link float-sm-left mr-1 btn-secondary"
data-action="toggle-drawer"
data-side="left"
data-preference="drawer-open-nav">
<i class="icon fa fa-bars fa-fw "
aria-hidden="true" aria-label="">
</i>
<span class="sr-only">Side panel</span>
</button>
Tried so far : I have searched if someone has done this already. Could not find anything. Tried several onload Javascript snippets, but nothing worked. Will appreciate some guidance & help.
You can look for the icon or a more specific element since the icon can be used more than once (or select it with :nth-child) and look up the previous element with jQuery. Then change the attribute of the button accordingly.
$('.icon fa fa-bars fa-fw').prev().attr("aria-expanded","false");
Below is the link to my codepen solution written in pure javascript and here is the explanation:
var btn = document.querySelectorAll("button"), dropdownBtn;
window.onload = function(){
for (var i=0; i<btn.length; i++) {
if(btn[i].getAttribute("data-action") == "toggle-drawer") {
console.log(btn[i]);
btn[i].setAttribute("aria-expanded", "false");
break;
}
}
};
Since you don't have any unique class or id o your button so went ahead and assumed that any one of the data-attribute on your button is unique (in this case data-action). Also, I assumed that your HTML document has many buttons hence I selected all the buttons and then iterated all over them to find the data-action attribute and as soon as I found it I set its aria-expanded value to false and exited the loop.
And all these happened while the document is loading.
Related
I have an if/else statement for our navigation where when a user clicks on the link associated with the dropdown-toggle class a submenu pops up.
We have multiple links on our navigation with the dropdown-toggle class. I only need to target 1 not all of them that's why I'm using .eq(0).
When the submenu appears a new class called open gets injected to the parent <li>.
For some reason I can't get this if/else statement to fully work. I have the first half working but not the second.
For the else portion I'm trying to add what would happen if the open class got injected and the active-nav-tab class gets added.
active-nav-tab is the class used for the state when users are on the current page. active-nav-tab is supposed to disappear when a user clicks on dropdown-toggle of the current page only and when they click outside the window of the submenu. Then when a user clicks on a navigation link with dropdown-toggle, the active-nav-tab again is supposed to appear on the current page. Hopefully that makes sense. I've been at this for like two days.
Code Below:
$('.dropdown-toggle').click(function (e) {
if ($(this).not('open')) {
$('.dropdown-toggle').eq(0).removeClass('active-nav-tab');
alert('test1');
}
else {
$('.dropdown-toggle').eq(0).addClass('active-nav-tab');
alert('test2');
}
});
HTML
<li>
<a class="link dropdown-toggle active-nav-tab" role="button">
<span class="tab-icon icon-header-language"></span>
<span class="tab-text">Region</span>
</a>
</li>
<li class="open">
<a class="link dropdown-toggle" role="button">
<span class="tab-icon icon-header-language"></span>
<span class="tab-text">Region</span>
</a>
</li>
<li>
<a class="link dropdown-toggle" role="button">
<span class="tab-icon icon-header-language"></span>
<span class="tab-text">Region</span>
</a>
</li>
I don't know what I'm exactly missing. Any help is gladly appreciated.
Thanks!
The quickest change you can make to your code to get the behavior you want is to replace
if ($(this).not('open')) {
With
if ($('.dropdown-toggle').eq(0).hasClass('active-nav-tab')) {
But without knowing your use case or how many "dropdown-toggle" elements you have it's hard to say if this would be a complete solution or not.
This seems to have solved my issue more or less. I'll see what QA says lol
Thank you!
$('.active-nav-tab').click(function (e) {
if ($(this).parents().hasClass("open")) {
$(this).addClass('active-nav-tab');
alert('activated');
}
else {
$(this).removeClass('active-nav-tab');
alert('deactivated');
}
});
this will process clicking on the first element with "dropdown-toggle" class
$('.dropdown-toggle:first').click(function () {
$(this).toggleClass("active-nav-tab");
if ($(this).hasClass("active-nav-tab")) {
alert ("Tab activated");
} else {
alert ("Tab deactivated");
}
}
also jQuery function not(selector) should be used on enumeration of objects to filter it.
I'm trying to click a button that brings up an edit screen on the same page.
Eg. Click "edit user", edit screen pops up on the same page without redirecting, change name, save. This button does not redirect to a new page.
The code for this button is the following:
<i class="fa fa-pencil"></i> Edit
For some reason I can click every other button on this website that's in the same exact form but I can't click this one. There are no IDs at all so calling by the class name is the only other method I know.
This is what I've tried:
setTimeout(function() {
document.getElementsByClassName(" btn btn-xs btn-inverse btn-modify")[0].click();
}, 3000);
I tried using some Jquery instead as well but no luck. Am I doing something wrong or is this all that I can really do? The other buttons I clicked either redirected me to a different site or just brought up some information on the same screen.
Thanks in advance.
Edit:
It seems that when I try iterating through the different buttons, who all have similar starting class names, I can iterate and click every button except for the edit button. So it's safe to assume that this isn't an issue with the code, so thank you everyone for the help and suggestions.
Edit #2:
Here is the code for all three buttons:
<div class="btn-group"><i class="stm stm-goog"></i>  
<i class="fa fa-pencil"></i> Edit
<i class="fa fa-bar-chart"></i><button type="submit" class="btn btn-xs btn-danger btn-submit"><i class="fa fa-trash-o"></i></button></div>
When searching for elements by class, it's better to use:
document.querySelector(); // Finds first matching element only
and
document.querySelectorAll(); // Finds all matching elements
instead of document.getElementsByClassName() as this returns a "live node list" and hinder performance.
When searching for classes with these methods, remember to include the dot (.) to signify classes and when multiple classes are used, do not include spaces. The spaces are only used when setting multiple classes.
Also, if there is only one class that is unique to the element you wish to find, you only need to search on that one class.
Lastly, only use a elements for navigation. If you simply need something to click, just about any object can have a click event handler.
var edit = document.querySelector(".btn-modify");
edit.addEventListener("click", function(){ console.log("clicked")});
setTimeout(function() {
edit.click();
}, 3000);
// Addtional test
var edit = document.querySelectorAll(".btn.btn-xs.btn-inverse")[1];
edit.addEventListener("mouseover", function(){
console.log("moused over");
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="btn-group">
<a href="https://google.com" target="_blank" class="btn btn-xs btn-inverse">
<i class="stm stm-goog">X</i> <!-- <-- You missed a semi-colon here. -->
</a>
<a href="#" data-id="29508"
class="btn btn-xs btn-inverse btn-modify">
<i class="fa fa-pencil"></i> Edit
</a>
<a href="#" data-page-modal="https://*randomwebsite*.com/manage/stats/301&q=11"
class="btn btn-xs btn-inverse">
<i class="fa fa-bar-chart">X</i>
</a>
<button type="button" class="btn btn-xs btn-danger btn-submit"><i class="fa fa-trash-o"></i>TEST</button></div>
Because you are trying to select the element by its class you need to loop through the elements.
So if you wanna use jQuery you would do like so:
$(".btn-modify").each(function(){
$(this).click(function(){
your code here
});
});
If you want to fetch the element having all the class, try this:
JQuery
$(".btn.btn-xs.btn-inverse.btn-modify")
Plain JavaScript
document.querySelectorAll(".btn.btn-xs.btn-inverse.btn-modify")
Giving a space in between a class names in a css like selector meant that (next one) is a nested element in any depth. use . to indicate its a class, and write them together (without a space) you are searching for elements having all the lasses. And getElementsByClassName is not a css like selector, its can take only a class name and all those element having that class.
I can't seem to make the drop-down work. When you click on 'action' nothing happens.
I double-checked the CSS and JS links and all seems ok, tried with Bootstrapv4 and 3.3.7 and none works. Any thoughts?
Check my app https://codepen.io/thomasfaller/pen/NpGpPP
<iframe height='265' scrolling='no' title='XE.com WebApp' src='//codepen.io/thomasfaller/embed/NpGpPP/?height=265&theme-id=0&default-tab=html,result&embed-version=2' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'>See the Pen <a href='https://codepen.io/thomasfaller/pen/NpGpPP/'>XE.com WebApp</a> by Thomas Faller (<a href='http://codepen.io/thomasfaller'>#thomasfaller</a>) on <a href='http://codepen.io'>CodePen</a>.
You are trying to use bootstrap dropdown as a select input. Dropdowns are supposed to just call some actions, not behave like "select" elements. So there is no such functionality out of the box as you want. You have to have some JS to make it work.
So my very quick and dirty solution just to make it work:
1) Assign id="selected" to currently selected value:
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-eur" aria-hidden="true" id="selected"></i>
</button>
2) Assign onclick handler on dropdown items:
<a class="dropdown-item" onclick="select('eur')"><i class="fa fa-eur" aria-hidden="true"></i></a>
3) And this handler could be like this:
function select(currency) {
let selected = document.getElementById('selected');
selected.className = `fa fa-${currency}`
}
Codepen: https://codepen.io/anon/pen/KWdOxa
But you still have to save somehow a selected value to make your calculations proper in JS code.
So you had better use a special bootstrap element for select inputs - https://silviomoreto.github.io/bootstrap-select/
I'm wanting to swap the second class of Bootstraps 'glyphicon' span, but instead of toggling the class, It's adding it behind, thus not changing the class at all.
I'm new(ish) to jQuery / Javascript and I just can't get my head around this.
Heres the
<nav class="navbar navbar-top" style="position:fixed; width:100%;">
<a class="navbar-brand" href="#">Project name</a>
<a class="navbar-brand" href="#" style="float:right;">
<span class="glyphicon glyphicon-tasks" id="whiter"></span>
</a>
And the script is below:
$('.glyphicon').click(function(){
$(this).toggleClass('glyphicon-chevron-up');
I get all the classes instead of just glyphicon-chevron-up, Im getting:
<span class="glyphicon glyphicon-tasks glyphicon-chevron-up"></span>
Removing the glyphicon-tasks class on Element inspect displays the Chevron, so some how it is being blocked and the tasks glyph isnt being swapped.
I think you want to swap glyphicon-tasks and glyphicon-chevron-up. You need to toggle both class like following.
$(this).toggleClass('glyphicon-tasks glyphicon-chevron-up');
This is because your function is set to class, which mean all elements with the given class.
To focus a specific element, provide, for example, an unique ID.
Here, you already got one.
$('#whiter').click(function() {
$(this).toggleClass('glyphicon-chevron-up');
});
I guess this can help
$('.glyphicon').click(function(){
$(this).removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-up');
}
If you want to have a bit more control, use jQuery to its fullest, apply a data variable to multiple glyphicons (chances are that you'll be checkboxes, folder icons, tree icons):
<nav class="navbar navbar-top" style="position:fixed; width:100%;">
<a class="navbar-brand" href="#">Project name</a>
<a class="navbar-brand" href="#" style="float:right;">
<span><i class="glyphicon glyphicon-tasks" data-tasks="firstCollection" data-mycolor="white" data-icontype="taskIcon"></i></span>
</a>
...plus, elsewhere in your page, another glyphicon, for example (this will not be used, affect or be affected by our code):
<i class="glyphicon glyphicon-unchecked" id="checkbox_Analytics" data-foldername="group_Analytics" data-icontype="groupCheckbox"></i>
...while, on the other hand, this will be affected by our code (because of foldername match):
<i class="glyphicon glyphicon-check" data-foldername="2014" data-icontype="childCheckbox"></i>
...and in JS, toggle their values without affecting each and every other glyphicon:
$('i[data-icontype="taskIcon"]').on('click', function() {
$('i[data-tasks="firstCollection"]').toggleClass('glyphicon-tasks glyphicon-chevron-up');
console.log("current state now displays CHEVRON UP (true/false)? ["+$(this).hasClass('glyphicon-chevron-up')+"]");
});
...
$('i[data-icontype="childCheckbox"]').on('click', function() {
$('i[data-foldername="2014"]').toggleClass('glyphicon-check glyphicon-unchecked');
// Notice that you can also access the `data-foldername` variable directly for each element which has it
var layerFolderName = $(this).closest('i').data('foldername');
console.log("Changed glyphicon chevron in: "+layerFolderName);
});
NOTE1: one style of using glyphicons, places them inside <i> tags and references them directly thusly.
NOTE2: "white" is not, in general, a good idea for an id. I recommend another data variable, data-mycolor, which might in turn be germane to your code's logic. In this example, it is set, but not really used.
I am working with a plugin that provides IDX data for listings on a WordPress website. The plugin uses jQuery to query a database for information that it displays on the page. The plugin is not very customizable past simple styling and I would like to insert a link to save to favorites
The link for saving to favorites can be found by viewing this page:
http://angelandpatty.com/homes-for-sale-details/8635-La-Entrada-Avenue-Whittier-CA-90605/PW14217291/306/
All the property details pages have the "save to favorites" button at the top of the page. This is what I found with the inspector:
<a data-toggle="modal" data-target="#ihfsaveListing" class="btn btn-primary btn-detail-leadcapture save-listing-btn"> <span class="hidden-xs"> <i class="glyphicon glyphicon-heart fs-12"></i> Save To Favorites </span> <span class="visible-xs fs-12"> Save To<br>Favorites </span> </a>
I am assuming the data-target is what is causing the button to take action.
What I would like to do is find a way to insert this same button, perhaps with a different icon like a thumbs up or a star, into the property stubs.
The property stubs are viewable on pages like this:
http://angelandpatty.com/homes-for-sale-in-friendly-hills/
I would like to find a way to insert this possibly after #ihf-main-container .col-xs-9
If there is any way to do this with Javascript or with jQuery I sure would like to know.
Thank you for all of your assistance. I tried searching for some situation like this but was unlucky
Are you looking for the following answer?
var button = $('<a data-toggle="modal" data-target="#ihfsaveListing" class="btn btn-primary btn-detail-leadcapture save-listing-btn"> <span class="hidden-xs"> <i class="glyphicon glyphicon-heart fs-12"></i> Save To Favorites </span> <span class="visible-xs fs-12"> Save To<br>Favorites </span> </a>');
$('#ihf-main-container .col-xs-9:first').after(button);
See: http://api.jquery.com/after/
.after(content [, content ] )
Description: Insert content, specified by the parameter, after each element in the set of matched elements.
You may need to initialize the button as required.