how to find modal has scrolled to the end -EmberJS - javascript

i'm newbie to emberJS and i want to enable a button when it comes to the scroll end in a modal. so i tried several ways but it didn't work
View
<div class="modal--dialog--body">
<div class="app_tour--section--terms_container" id="message-container">
<ul class="app_tour--section--ul">
<li></li>
//so many lists to scroll
<li></li>
</ul>
</div>
Controller
import Ember from 'ember';
export default Ember.Controller.extend({
didTransition() {
Ember.run.later('afterRender', () => {
let objDiv = document.getElementById("message-container");
if(objDiv.scrollTop == objDiv.scrollHeight)
console.log(objDiv.scrollTop)
}, 100);
return true;
},
actions: {
close: function() {
this.send('closeModal');
}
}
});

Welcome to getting started with Ember! Like many things, there's a pretty useful addon that will make your life simpler for this: https://github.com/alphasights/ember-scrollable
That provides a scrollable-container and exposes an action when you've reached scroll bottom.
{#ember-scrollable onScrolledToBottom=(action "close")}}
add terms and consitions here
{{/ember-scrollable}}

I used basic jQuery to get the DOM’s element I was targeting and listen to the scroll event with the help of Rechardo and it worked.
you can check it via her post on medium
https://medium.com/#futoricky/ember-js-detect-scrolling-events-on-html-element-using-component-ac6b2630021a

Related

How to hide the Sidebar Nav Menu when a User clicks outside of it using Vue js?

My SPA has an Admin Dashboard with a Sidebar Navigation Menu that is visible by default when the viewport is larger than 991px. When the viewport is less than 991px, the Navbar disappears and you have a hamburger icon that you can click to Toggle(show/hide) the Sidebar Menu. Right now the menu will only hide if you click on the little hamburger menu icon a second time. What I want is to close/hide the menu if a User clicks anywhere outside of it. I'm using Bootstrap-Vue for my UI.
So I have a <b-navbar toggleable="md" type="dark" variant="info"></b-navbar>.
What I'd like to do is something like this, but I know I'm mixing Javascript and Vue js and not sure exactly how to set this up.
data() {
return {
sidebarMenu: true
}
}
<section class="app-sidebar" v-if="sidebarMenu">
<div class="main-panel" #click="hideSidebarNavMenu">
methods: {
hideSidebarNavMenu() {
this.sidebarMenu = false;
},
const navbarTogglerButton = document.querySelector(".navbar-toggler");
navbarTogglerButton.addEventListener('click', function(event) {
this.sidebarMenu = true;
})
}
This main-panel div will contain all of the data for every page, so no matter where they click this hideSidebarNavMenu function should get fired.
I need this code to work only when the viewport is less than 991px.
Again, I'm getting some syntax errors in my methods, I believe because I'm trying to write Javascript in my methods attribute.
This is the idea.
Thank you.
The problem is that methods must contains… methods and not code like const navbarTogglerButton … This is probably the error you have
attach your event to .navbar-toggler
<div class="navbar-toggler" #click="showSidebarNavMenu">
methods: {
hideSidebarNavMenu() {
this.sidebarMenu = false;
},
showSidebarNavMenu() {
this.sidebarMenu = true;
},
}
I just realized now that in the Free Admin theme that I'm using, when a user clicks on the Hamburger button to toggle the Sidebar, all it does is just add and remove a class called active on the nav element.
Element:
<nav id="sidebar" class="sidebar sidebar-offcanvas active">
And so this is how I solved it:
mounted() {
var mainPanelDiv = document.querySelector(".main-panel");
var navbar = document.querySelector("#sidebar");
mainPanelDiv.addEventListener('click', function(event) {
navbar.classList.remove('active');
});
}

Ionic Dragula, setOptions mirrorContainer is null. Loading before DOM

I have an ionic project that is using dragula, but I'm having an issue setting the mirrorContainer. I'd like to make the container something other than the default body because I believe that's what is attributing to a strange scrolling problem I'm having while dragging.
I've created my bag in html
<div class="step-container--line" [dragula]='"bag"' id="mirror">
<div class="card">
....
</div>
Then in the JS, I've initialized dragula in the constructor and started to set its options.
constructor(private dragulaService: DragulaService) {
dragulaService.setOptions('bag', {
moves: function (el, container, handle) {
return handle.className === 'step__menu__button';
},
direction: 'vertical',
//mirrorContainer: document.getElementById('mirror')
});
dragulaService.drag.subscribe((value) => {
this.onDrag(value.slice(1));
});
dragulaService.drop.subscribe((value) => {
this.onDrop(value.slice(1));
});
}
The problem is; when I add mirrorContainer: document.getElementById('mirror') to the setOptions, my mirror container comes back as null. I'm assuming because this loads before the DOM does and there's no instance of #mirror yet.
If I moved everything down into ionViewDidLoad(){}, I get an error stating that the bag 'bag' already exists.
I'm not sure the best way to initialize or add to the options after the DOM loads. Any ideas?
I know I'm late to the party but I had the same issue using Angular 11.
After your element is in the DOM and is available you can do this.
ionViewDidLoad() {
(this.dragulaService as any).groups['bag'].options.mirrorContainer = document.getElementById('mirror');
}

Scroll to a certain element of the current page in Angular 4

Upon clicking a button (which is bottom of the page), I want to go to a certain element (in my case, #navbar) which is in the top of the current page, but I don't know how to do it. I've tried the following code with no avail.
<nav class="navbar navbar-light bg-faded" id="navbar">
<a class="navbar-brand" href="#">
{{appTitle}}
</a>
<!-- rest of the nav link -->
</nav>
<!-- rest of the page content -->
<!-- bottom of the page -->
<button class="btn btn-outline-secondary" (click)="gotoTop()">Top</button>
In angular component:
import { Router } from '#angular/router';
/* rest of the import statements */
export class MyComponent {
/* rest of the component code */
gotoTop(){
this.router.navigate([], { fragment: 'navbar' });
}
}
I would really appreciate if someone helped me out with a solution and explained why my code hadn't worked.
Please note that element (navbar) is in other component.
You can do this with javascript:
gotoTop() {
let el = document.getElementById('navbar');
el.scrollTop = el.scrollHeight;
}
This will bring the DOM element with id="navbar" into view when the method is called. There's also the option of using Element.scrollIntoView. This can provide a smooth animation and looks nice, but isn't supported on older browsers.
If the element is in a different component you can reference it several different ways as seen in this question.
The easiest method for your case would likely be:
import { ElementRef } from '#angular/core'; // at the top of component.ts
constructor(myElement: ElementRef) { ... } // in your export class MyComponent block
and finally
gotoTop() {
let el = this.myElement.nativeElement.querySelector('nav');
el.scrollIntoView();
}
Working plunker.
I know, you want to scroll to a specific element in the page. But, if the element is in the top of the page, then you can use the following:
window.scrollTo(0, 0);
document.getElementById("YOUR_DIV_ID").scrollIntoView({ behavior: 'smooth' });
I think your way didn't work because of the empty router.
this.router.navigate(['/home'], { fragment: 'top' });
would work if 'home' is declared as a route and you have the id="top" element on it.
I know you would like it to be "pure Angular way", but this should work (at least):
gotoTop(){
location.hash = "#navbar";
}

How to create a subnav in ember.js

This issue has been stumping me for days. I need a subnav to display under the main nav in the application template when a user visits the 'about' page. I feel like I must be missing some vital concept because I keep reading that if something is extremely hard to do in Ember than you're probably doing it wrong. And I feel like Ember should be able to handle a simple subnav with ease.
I would like the subnav to display on the skinny white horizontal bar below the main nav when "ABOUT" is clicked.
I can't put the subnav in the about template since the nav code is in the application template.
My Router:
App.Router.map(function() {
this.resource("about", function() {
this.route("philosophy");
this.route("leadership");
this.route("staff");
this.route("affiliations");
});
this.route("conditions");
this.route("programs");
this.route("testimonials");
});
I can't render a partial inside the application template because I only want it displayed when someone is at the /about url.
I've tried plain old jQuery show and hide with this:
App.ApplicationController = Ember.ObjectController.extend({
currentRouteChanged: function() {
if(this.get('currentRouteName').indexOf('about') > -1) {
$("ul").removeClass("sub-nav-list-hide");
$("ul").addClass("sub-nav-list-show");
}
}.observes('currentRouteName')
});
And it works when you click about, but when you hit the back button or navigate to another page the subnav doesn't hide.
I'm stuck and I feel like I'm making this way too difficult.
I would set a property in the application controller from within App.AboutRoute
App.AboutRoute = Ember.Route.extend({
activate: function(){
this.controllerFor('application').set('renderAboutSubNav', true);
},
deactivate: function(){
this.controllerFor('application').set('renderAboutSubNav', false);
}
});
and then check the property in the application template.
{{#if renderAboutSubNav}}
{{render 'about/subnav'}}
{{/if}}
Here is an example jsbin
That looks elegant to me!
We can do in application controller something similar.
App.ApplicationController=Ember.Controller.extend({
renderAboutSubNav:function(){
var reg = new RegExp("^about\.");
return reg.test(this.get('currentPath'));
}.property('currentPath')
});

Ember Collapsible Container

I'm using Ember.js with handlebars and I need to make a div within my page collapse/expand when clicked. I know how to do this in jQuery, but I can't use any jQuery. Does anyone know how to accomplish this? Also I don't want to just toggle a hide attribute, I need the full sliding up and down feature for collapsing. If anyone has any ideas, I'd really appreciate it.
Thanks
Clicking on your view will cause a click event to be triggered. You can code your animation in any manner you want inside a click event handler in your view:
CollapsableView = Ember.View.extend({
click : function(event) {
this.$().toggle('fast');
}
})
The proper way of doing this in Ember is via the awesome Liquid Fire addon.
The outline:
Install Liquid Fire into your project.
Define a transition like this:
this.transition(
this.hasClass('transition-spoiler'),
this.toValue(true),
this.use('toDown'),
this.reverse('toUp')
);
In your controller/component, create a property spoilerIsVisible and a toggleSpoiler property:
spoilerIsVisible: false,
actions: {
toggleSpoiler: function() {
this.toggleProperty('spoilerIsVisible');
}
}
In your page/component template, create a button and a spoiler wrapper like this:
<button {{action 'toggleSpoiler'}}>
{{if spoilerIsVisible 'Show spoiler' 'Hide spoiler'}}
</button>
{{#liquid-if spoilerIsVisible class="transition-spoiler"}}
<p>Dumbledore dies</p>
{{/liquid-if}}
Note that you can wrap steps 3-4 into an x-spoiler component or something.
I do something similar, but with a tree-structure. I have written a blog post about this previously here: http://haagen-software.no/blog/post/2012-05-05-Ember_tree
It has the features you need in it, in that it adds and removed elements from the DOM when the nodes are clicked on.
A working example can be seen in an app I am currently building here: https://github.com/joachimhs/EurekaJ/tree/netty-ember/EurekaJ.View/src/main/webapp

Categories

Resources