I've made a stackblitz example here to show the issue:
https://stackblitz.com/edit/primeng-toolbar-demo-u21zmt?file=src%2Fapp%2Fapp.component.html
When clicking the remove button the popup menu shows in the wrong place.
I don't want to have to write custom CSS to position the menu every time I want to use it.
What am I doing wrong?
Switch the order in your html so
<p-button class="p-mr-2" #removeBtn type="button" icon="pi pi-chevron-down" label="Remove"
(click)="removeMenu.toggle($event)"></p-button>
<p-menu #removeMenu [model]="removeMenuItems" [popup]="true" appendTo="removeBtn"></p-menu>
becomes
<p-menu #removeMenu [model]="removeMenuItems" [popup]="true" appendTo="removeBtn"></p-menu>
<p-button class="p-mr-2" #removeBtn type="button" icon="pi pi-chevron-down" label="Remove"
(click)="removeMenu.toggle($event)"></p-button>
This will make the menu appear under "remove"
Related
I'm very new to programming & working on creating a website for a work project.
In it, there will be a multi-level (w/sub-menus) vertical sidebar on each page.
The problem I'm facing is that every time a user clicks on one link, the sidebar resets to its original state & will have to redo the same thing & not very UX friendly.
I took the template of the accordian sidebar from here.
I've looked at various search results on both stack overflow & google, but can't seem to understand how to get it working to retain the state of the sidebar, regardless of how many levels are opened.
Can someone please help me with the JS code to get it working?
UPDATE:
Nathan, thanks for writing mate! I really appreciate the help.
So based on your suggestion, I've written the following (shoddy) code that injects the 'checked' attribute to the input element.
But it isn't transferring over to the new/redirected html page when a user clicks on one of the sub-menus. What am I missing here?
var menuIndex = -1;
//extract all the input elements
var inputs = document.querySelectorAll('.parent-menu');
//Find index of the element from the array that has "checked == true"
function indexFinder() {
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked == true) {
menuIndex = i;
console.log(menuIndex);
}
};
}
//Function to set/inject the attribute
function attributeSetter() {
inputs[menuIndex].setAttribute('checked', 'checked')
}
//When a user clicks literally anywhere, it'll run the indexFinder function
//to check if any of the input elements were expanded (i.e. checked == true)
window.addEventListener('click', () => {
indexFinder();
});
//Run the attributeSetter function when a page loads
window.addEventListener('DOMContentLoaded', () => {
attributeSetter();
});
Welcome to the world of programming! Hopefully I can help you out a little!
So what you're asking is something that can easily get a little complicated.
In order to achieve what you're trying to do you need to specify how you want your menu to look on each individual page!
Allow me to present a few menu options for an imaginary site:
Home
Contact
Email
Mail
About
The Company
Our Owner
I've indented the page names based on how we want them to show up in our menu.
So for example you may click on "Contact" and it drops down with the Email and Mail options.
Well, if you take your regular code from that webpage and copy and paste it everywhere. Any time you reload a page (or travel to another page with the same code) it's gonna reset the code! Thus "closing" the menu. Think of it as some sort of multi-dimentional sci-fi. When you load a webpage, you are accessing the main flow of time, any time you make an update to that page it takes you to an alternate reality with that change! but once you reload the webpage you jump back to the main timeline as if you never made that change (when you get into more advanced web dev, this analogy will break down but it should work to help your understanding for now.)
So let's say I click on the Contact > Email option and it takes me to the Email page. Well, in order to make it seem like my changes to the menu bar (clicking "Contact" to expand the dropdown) are still active. I need to hardcode the change into the Email page!
Here's some sample code:
<nav class="nav">
<a class="navOption">Home<a>
<a class="navOption">Contact<a>
<div class="navDropdown">
<a class="navOption">Email<a>
<a class="navOption">Mail<a>
</div>
<a class="navOption">About<a>
<div class="navDropdown">
<a class="navOption">The Company<a>
<a class="navOption">Our Owner<a>
</div>
<nav>
By default the .navDropdown will be closed. However when we add a class to them .active they will expand! If this is my base menu, then how should I make it so that the "About" dropdown is expanded when you are on one of the About pages?
Simply by adding .active to that dropdown!
<nav class="nav">
<a class="navOption">Home<a>
<a class="navOption">Contact<a>
<div class="navDropdown">
<a class="navOption">Email<a>
<a class="navOption">Mail<a>
</div>
<a class="navOption active">About<a>
<div class="navDropdown">
<a class="navOption">The Company<a>
<a class="navOption">Our Owner<a>
</div>
<nav>
Now, my example is different from yours because it's meant more for JavaScript. However, you can use the same concept in your code too.
For you, instead of having a .active class to expand a dropdown menu. You are using a checkbox element! In your codem you have CSS which is checking to see if the checkbox is checked and then it is opening the dropdown menu if it is:
<input class="cd-accordion__input" type="checkbox" name ="group-1" id="group-1">
So, if we use this method on our example webpage. We could set it to be open by setting the checkbox to start out being checked. Like so:
<input class="cd-accordion__input" type="checkbox" name ="group-1" id="group-1" checked>
It's important to note that as you get better and better at web development (eventually learning JavaScript and a server side language such as PHP). You will be able to piece together more advanced methods to doing what we're trying to accomplish! But for now, I hope I was able to break this down for you!
I am using Angular7, npm 6.4.1, node 10.15.3.
I am just playing around with ngIf, this does nothing useful. I am using two buttons to toggle back and forth between displaying and hiding a header. While it was just an ngIf statement, it was working fine with the following code:
<p>Do you want to see the last header?</p>
<button (click)="yesHeader()">Yes please!</button>
<button (click)="noHeader()">PLEASE G-D NO!</button>
<h2 *ngIf="displayHeader" style="color:blue">Here it is in all its glory!</h2>
and
public displayHeader=false;
yesHeader(){
this.displayHeader=true
}
noHeader(){
this.displayHeader=false
}
And that worked fine, showing the header when clicking the yesHeader button and hiding it again when clicking the noHeader button.
However, when I added an ngIf Else block, it stopped toggling back and forth. The change was to the following:
<p>Do you want to see the last header?</p>
<button (click)="yesHeader()">Yes please!</button><button (click)="noHeader()">NO! NO!</button>
<h2 *ngIf="displayHeader; else noHeader" style="color:blue">Here it is in all its glory!</h2>
<ng-template #noHeader>
<h5>You don't know what you're missing!</h5>
</ng-template>
Now, it displays You don't know what you're missing! at start, and switches to the header if I click yes. But it doesn't toggle back to hiding the header if I click the no button after that.
What am I doing wrong and how can I get it to toggle back?
As an added datapoint, if I leave the else block, but take else noHeader out of the ngIf statement, it still doesn't toggle back. So seemingly the existence of the ng-template is what is stopping things up.
The issue is that there is a name conflict of noHeader. It being used in your example as both a method on the component class as well as the name of the ng-template. Try changing either the name of the method or name of the template:
<p>Do you want to see the last header?</p>
<button (click)="yesHeader()">Yes please!</button><button (click)="noHeader()">NO! NO!</button>
<h2 *ngIf="displayHeader; else noHeaderTemplate" style="color:blue">Here it is in all its glory!</h2>
<ng-template #noHeaderTemplate>
<h5>You don't know what you're missing!</h5>
</ng-template>
Here is an example in action.
Your template is called the same as function: noHeader.
You have name collision problem, you can't call noHeader function, Angular thinks you're referencing noHeader template reference.
<ng-template #noHeaderTemplate>
<h5>You don't know what you're missing!</h5>
</ng-template>
Or
hideHeader() {
this.displayHeader = false;
}
A proper IDE should tell you "Member noHeader is not callable".
For a Wordpress page, I am using filter buttons to filter the display of posts depending on their respective categories. The filter buttons work via a small javascript which turns on and off the display of the posts depending on the post-category the button is linked to.
Now, I would like to make these buttons accessible through a dropdown menu, which always shows which filter button is active. Putting them into a dropdown menu was no problem. However, with the next step I need some help: I would like the dropdown menu to always show the active filter button which the user has clicked on, at the top of the menu itself (i.e. instead of the menu's original title which is displayed when the page is loaded, before any buttons inside the menu have been clicked). How might that be possible?
Here's the html of the filter buttons inside the dropdown menu as well as the javascript which enables the filter buttons to filter the post-categories:
<div class="dropdown">
<button class="dropbtn">Dropdown Menu Title</button>
<div class="dropdown-content">
<button class="btn" id="category-filter1"> Filter 1 </button>
<button class="btn" id="category-filter2"> Filter 2 </button>
<button class="btn" id="category-filter3"> Filter 3 </button>
</div>
</div>
Javscript:
<script>
var $btns = $('.btn').click(function() {
if (this.id == 'all') {
$('.projects > .post').fadeIn(300);
} else {
var $el = $('.' + this.id).fadeIn(300);
$('.projects > .post').not($el).fadeOut(300);
}
$btns.removeClass('active');
$(this).addClass('active');
})
</script>
I think you are looking for this..
You must get the text from the active list and add it to the title div or button.
var textx = $(this).text();
$('.dropbtn').text(textx);
Example of whole code : https://jsfiddle.net/eh4chb48/
Only if i got ypur question right! :) ;)
I have a simple html menu, when a menu item is clicked a class of `mg_cats_selected" is added to the anchor tag (which is the menu item).
I would like to copy the text value of the active/selected anchor tag and display it in another div on the page, but I would like to only display it once. When a new item link is clicked, I want to remove the old value from the separate div that I've created it and display the new value of the new selected menu item.
I hope that makes sense.
This is the HTML menu
<div id="mgf_165" class="mg_filter mg_new_filters">
<a rel="163" id="163" class="mgf_id_163 mgf mg_cats_selected left_menu" href="javascript:void(0)">Bathrooms Sinks</a>
<a id="164" rel="164" class="mgf_id_164 mgf left_menu" href="javascript:void(0)">Bowed</a>
</div>
This is the jQuery and the div where I wanna display the text values.
<script type="text/javascript">
jQuery(document).ready(function(){
console.log('test');
jQuery("a.left_menu").click(function(){
var txt = jQuery("a.left_menu").text();
//$(this).attr('rel');
jQuery("#category").append(txt);
});
});
</script>
<div id="category">
</div>
At the moment when I click on, say, "Bowed", this displays in the div
Bathrooms SinksBowed
And if I click again on "Bathroom Sinks", the same thing repeats
Bathrooms SinksBowedBathrooms SinksBowed
How can I deal with that? And did I follow the correct logic here?
You are currently getting the text of all the menu items and then appending it to the div.
You need to get the text of the clicked menu item, and then set the content of the div to the text value of that menu item.
jQuery(this) // the clicked menu item
jQuery('#category').text('VALUE') // set the text content of the tag to VALUE
Working solution on JSFiddle..
See Inside the Event Handling Function to learn more about jQuery event handling.
document.getElementById('hello').click();
The above code works when inserted into the google chrome console - It displays the dropdown of 'hello' - What I'm trying to do is open up a dropdown when I click a whole table row, using the following code
<tr onclick="document.getElementById('hello').click();">
Here is the dropdown I'm trying to activate
<a href="#" id="hello" data-toggle="dropdown" class="btn dropdown-toggle"><i class="icon-cog">
Infact I do see the button being clicked when I click the row, but the dropdown does not toggle. Whats the best way to toggle the dropdown (The dropdown works if I simply click it, I'm trying to toggle it using javascript)
Thanks!
Try like:
<tr onclick='$("#hello").trigger("click");'></tr>
I am not sure about scenario, but this is what I came up with. Please note that I have changed tr to p for the demo. Change it back to suit your needs.
var helloID = document.getElementById("hello");
function initDropdown() {
helloID.click();
}
helloID.addEventListener("click", function(evt) {
alert ("Click triggered on ID : " + evt.target.id);
});
<p onclick="initDropdown();">Click Me</p>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<tr onclick="$('#hello').click();">