Vue/Buefy - Hide dropdown on router-link click / SPA - javascript

I am having some issues using Buefy and Vue. I have a simple SPA (Single Page Application), that uses vue-router. I have a dropdown that looks like this:
<b-dropdown class="user-dropdown" v-model="navigation" position="is-bottom-left">
<a class="navbar-item" slot="trigger">
<span class="tag is-rounded has-text-weight-semibold avatar">OB</span>
</a>
<div class="columns is-marginless">
<div class="column has-text-centered">
<router-link to="home">
<b-icon class="is-large is-size-4" icon="ion-ionic ion-ios-search"></b-icon>
</router-link>
</div>
<div class="column has-text-centered">
<router-link to="dashboard">
<b-icon class="is-large is-size-4" icon="ion-ionic ion-ios-contact"></b-icon>
</router-link>
</div>
</div>
</b-dropdown>
Getting the dropdown to show works fine. It also hides if I click anywhere on the page, outside of the visible dropdown.
My problem is, that I have a single page application, so when I "change" page (click a link), the dropdown is still visible when the page changes.
Example:
On below page:
www.example.com/#/home
I click on the dropdown, which opens, and then click on the dashboard link, which gives me:
www.example.com/#/dashboard
But the dropdown is still visible.
Anyone know how I can do, so the dropdown will toggle when I click on the links inside it?
Update:
I use the Vue Dev tools in Chrome, and I can see that when I click on the dropdown so it toggles to active, I see this:
name:"active-change"
type:"$emit"
source:"<BDropdown>"
payload:Array[1]
0:true
And when I click anywhere on the page, to close the dropdown, it looks like this:
name:"active-change"
type:"$emit"
source:"<BDropdown>"
payload:Array[1]
0:false

Whatever the drop-down is watching for state isn't changing, because in a SPA it's just javascript. I don't know about the specifics regarding Buefy, but you'll have to set the state variable on router load, or watch some kind of variable to tell the menu that something in another part of your app is different.

Related

Trying to open a site in new tab in Angular but not working

I have a simple situation and I thought it will be resolved easily. But got stuck.
I have a header component. There are two situations here:
Before login, the text in header component will be "LOGIN" and it will be clickable. On click, it will take me to another external url (lets assume https://www.external.com).
After login, the same header component but text will be "LOGGED IN" and it won't be clickable.
WHAT I TRIED
HTML File (header.html)
<div class="brand pull-left" (click)="onHeaderClick()">
<div class="logo"></div>
<h1>{{headerText}}</h1>
</div>
Typescript File (header.ts)
onHeaderClick() {
debugger;
if(!this.isLoggedIn) {
window.open('https://www.external.com', '_blank');
}
}
But, its not redirecting me to the specified url and not also opening a new tab.
Its just refreshing the same page.
Can anybody please help me out with any solution and also if it can be explained why its not working.
Thanks.
You should handle the logic of if it's clickable in the Template and not in the TS-logic.
Also don't use divs for onclick events, use buttons or links (in your case this is a link!). You can focus them with the keyboard and also click them with pressing spacebar while it's focused. If you use the semantically correct tag you won't have problems opening it in a new window.
Something like this:
<ng-template #contentTemplate>
<div class="logo"></div>
<h1>{{headerText}}</h1>
</ng-template>
<div *ngIf="!loggedIn; else loggedInBlock">
<a class="brand pull-left" href="https://www.example.com" target="_blank" >
<ng-container [ngTemplateOutlet]="contentTemplate">
</ng-container>
</a>
</div>
<ng-template #loggedInBlock>
<ng-container [ngTemplateOutlet]="contentTemplate">
</ng-container>
</ng-template>
And in your .ts file you have a boolean variable named loggedIn If you are logged in this is set to true, otherwise it's set to false.
If you have the same content in both containers, you can either create it's own component for this (and then just use something like app-header-content instead of the ng-container or you use, as I did in the example above, use a template.
Check Angular documentation for other ways to implement if-else logic

Problem with onclick event in parent & child component

I have 2 components in Vue.js :
Accordion header which open it's content after clicking on it.
Cog icon which open mini-modal menu.
Problem is that when I'm clicking on cog, I don't want accordion to open it's content.
Before click on cog:
After click on cog:
I thought about checking modal menu display status in Accordion (parent component) but I'm not sure it's good approach.
<i class="fa fa-cog" #click="toggleSettings"/>
<div
class="order-settings"
:class="{'order-settings__show':isSettingsOpen}">
<div class="order-settings__option"><p>Re-order</p></div>
<div class="order-settings__option"><p>Convert to subscription</p</div>
<div class="order-settings__option"><p>Download invoice</p></div>
<div class="order-settings__option"><p>Export to CSV</p></div>
</div>
Actual results: Accordion open after clicking on cog (wrong)
Expected results: Accordion doesn't open after clicking on cog
add the stop modifier to the cog click event like so
#click.stop="toggleSettings"
It's how you do event.stopPropagation() in Vue.js

Is it possible to have routerLink and a click event on same anchor tag?

I have a bunch of li elements and when the user clicks them, it opens a more detailed view of those elements in a different component.
However, it requres TWO clicks to show the data I want to show.
When the user click ONCE the component opens up with the empty view template.
When the user clicks AGAIN it then shows the populated data.
Can I not just put this in one anchor tag that routes me to me detailed view and emits the click event in one?
Is there a preferred method or better way to do this?
<ul>
<li *ngFor="let favorite of sortedFavorites; let i= index">
<a class= 'clickMe' (click)= "openContact($event, i)" routerLink= "/details">
<div *ngIf= "favorite.isFavorite">
<img class="smallImage" onerror="this.onerror=null;this.src='User Icon Small.png';"
src={{favorite.smallImageURL}} />
<h3><img src="Favorite — True.png">{{ favorite.name }}</h3>
<br>
<p>{{ favorite.companyName }}</p>
<hr>
</div>
</a>
</li>
</ul>
EDIT: Some people are suggesting that I use reslove guards to fetch the data before it is populated, but I am only pulling this from a local JSON file and passing it between my components.
you use click event for both. navigate to details page via programmatically using the router
this.router.navigate(['path']);
whatever process do in openContact() and then redirect on the details page.
add into constructor private router: Router

JS menu stops working when navigating to a different page

I'm having some issues with my JS menu. When the page loads the menu work great, and as expected. You click the option, then it displays the menu items.
However, once I click one of the menu items and navigate to a different page the menu stops working! When you click on the icon, the menu no longer appears. The page just sits there. When i look try debug in chrome it no longer "hits" the code.
I have noticed that if i refresh that page, the menu works again as expected :/
My JS code is below, what am I missing for this kind of issue to arise?
I have created a pen for this - http://codepen.io/alr3id/pen/bwdKxL
function MyMenus(jQuery) {
$(".p-menu-icon").on("click", function(event) {
var e = $(this).next(".p-menu");
e.hasClass("p-menu_open") || $(document).trigger("click"),
$(".p-modal-bg").toggleClass("p-modal-bg_active"),
e.toggleClass("p-menu_open"),
event.stopPropagation()
});
// Removes the menu open class.
$(document).on("click", function(t) {
var e = $(t.target)
, i = 1 === e.closest("p-menu").length;
i || ($(".p-menu.p-menu_open").removeClass("p-menu_open"),
$(".p-modal-bg").removeClass("p-modal-bg_active"))
});
}
// Load
$(document).ready(MyMenus);
Below is the HTML for the Menu
<nav class="p">
<div class="p-modal-bg"></div>
<div class="p-property">
<a class="p-property-name" href="/">
Logo Here
</a>
</div>
<div class="p-user">
<a class="p-menu-icon">
<div class="icon icon-navigator-toggle"></div>
</a>
<div class="p-menu p-menu_navigator">
<a class="p-menu-item p-menu-item_dashboard" href="/">Dashboard</a>
<a class="p-menu-item p-menu-item_orders" href="/orders">My orders</a>
<a class="p-menu-item p-menu-item_back-bar" href="/products">Products</a>
</div>
<a class="p-menu-icon p-menu-icon_account">
<div class="p-user-avatar_container">
<img alt="Example user" class="gravatar" src="{image here}">
</div>
</a>
<div class="p-menu p-menu_account">
<div class="p-menu-item_account-details">
<div class="p-user-avatar_container">
<img alt="Example user" class="gravatar" src="https://secure.gravatar.com/avatar/{image here}">
</div>
<div class="p-account-details-name">
Example User
</div>
<div class="p-account-details-email">example#example.com</div>
</div>
<a class="p-menu-item p-menu-item_settings" href="account">Account settings</a>
<a class="p-menu-item p-menu-item_messages" href="#">Messages</a>
<a class="p-menu-item p-menu-item_logout" href="#">Sign out</a>
</div>
</div>
</nav>
Well, this is something I didn't even consider, it turns out this issue is down to Rails and Turbolinks!
Due to the way Turbolinks loads pages it screws up
$(document).ready
to fix this you need to use...
$(document).on "turbolinks:load"
http://guides.rubyonrails.org/working_with_javascript_in_rails.html#turbolinks
Have you imported the JS file you are using in this page (new page where it stuck) too ? Try adding the code on another file also or move your js code to another js file and import it on that page.
Since it works at freshly loaded page the code itself shouldn't be a problem.
What comes to mind are class changes. Open up your browser's inspector and check if there are any class name changes that would resolve in loosing a listener.
Also try putting some console.log() inside each function so you are sure that both events aren't getting fired one after another.

Semantic UI modal closes on Twitter Typeahead selection

I have a Twitter Typeahead inside of a Semantic UI modal. The desired behavior is that the user can select something from the typeahead and still work within the modal before confirming their selection. However, if the user clicks on a selection, then the modal closes early. This only occurs when clicking; if the user uses the arrow keys to select an option, or uses Tab to complete, then the modal stays open as desired.
I've made a JSFiddle to demonstrate the problem. Minimal code summary below:
index.html:
<div id="pick-user-modal" class="ui modal"><i class="close icon"></i>
<div class="header">Select user</div>
<div class="content">
<input type="text" id="user-field" />
</div>
<div class="actions">
<a id="send-request" class="ui green button">Select user</a>
</div>
</div>
<a class="green ui button" id="show-pick-user-modal">Select user</a>
main.js:
$('#pick-user-modal').modal();
$('#show-pick-user-modal').click(function () {
$('#pick-user-modal').modal('show');
});
var $users = $('#user-field');
$users.typeahead({
name: 'users',
local: ["Andy","Betty","Charles","Dotty","Elton","Fred","Grace","Harriet",
"Ichabod","Jenny","Karen","Louise","Michael","Nathan","Oswald",
"Patricia","Quendy","Robert","Sylvia","Thomas","Ursula","Vivian",
"Wendy","Xavier","Yvonne","Zachary"]
});
function setUser(e,d){
alert(d.value);
}
$users.on('typeahead:selected',setUser);
$users.on('typeahead:autocompleted',setUser);
I've tried returning false from setUser and also calling e.preventDefault(), but neither has solved the problem.
I've seen exactly the same issue. The only thing that stops it from closing is setting closeable to false,
which is not a setting I would otherwise use.
When you enable debug mode for the modal, you get the following message:
I suspect that jquery isn't aware of the element.

Categories