Hide Ionic TabBar on specific subpages (IONIC 3) - css

I want to hide my tabbar on multiple specific pages. My main focus is to hide it on my Login page, Register page, and a comment page. I have tried tabsHideOnSubPages: true, but when i do this my UserProfile page
(which is a subpage) hides the tabbar. The tabbar must also be visible on the UserProfile page but then again not on my previous mentioned subpages (login, register etc..).
I am currently using Ionic Framework : ionic-angular 3.2.0
Does anyone know how i can fix this?

I can give you a quick hotfix for that.
Copy this Code into your .ts page file.
The function will execute when the page is loaded.
If you want to hide the tabbar then do this line of code:
tabs[key].style.display = 'none';
If you want to show it use this code by simply changing 'none' it to 'flex'.
tabs[key].style.display = 'flex';
This code is an angular function wich basicly means it executes when page is loaded.
ngAfterViewInit()
Full code:
ngAfterViewInit() {
let tabs = document.querySelectorAll('.show-tabbar');
if (tabs !== null) {
Object.keys(tabs).map((key) => {
tabs[key].style.display = 'none';
});
}
}
You can also use this code to show the tabbar again if you leave the page.
ionViewWillLeave() {
let tabs = document.querySelectorAll('.show-tabbar');
if (tabs !== null) {
Object.keys(tabs).map((key) => {
tabs[key].style.display = 'flex';
});
}
}
Hope this helped you.

You can try this.
Just put tabsHideOnSubPages in your config like this:
#NgModule({
declarations: [ MyApp ],
imports: [
IonicModule.forRoot(MyApp, {
tabsHideOnSubPages: true,
}, {}
)],
bootstrap: [IonicApp],
entryComponents: [ MyApp ],
providers: []
})

Related

Google Identity - sign In with google button not visible when go to other screen and comeback

I am trying to integrate the Google SSO using the Google Identity API's for the Angular 14 application.
The problem I am facing is, I can see the Sign In with Google button when I first come into Login screen. But if I go to other screen then do logout and when I am back to Login screen, the Sign In with google button is no more visible and I have to force refresh (Ctrl+Shift+R) to make it visible.
I have already gone through Why does the Sign In With Google button disappear after I render it the second time?
but it is unclear how to make feasible in my case.
As I can see an Iframe will be rendered during the 1st time and if I come back again to login page from other page I can not see the Iframe and the SignIn button is not visible.
Here is the code to load the sign in button from angular component
ngOnInit() {
// #ts-ignore
window.onGoogleLibraryLoad = () => {
// #ts-ignore
window.google.accounts.id.disableAutoSelect();
};
this.loadGoogleSSOScript('2.apps.googleusercontent.com');
}
loadGoogleSSOScript(clientId: string) {
// #ts-ignore
window.onGoogleLibraryLoad = () => {
// #ts-ignore
google.accounts.id.initialize({
client_id: clientId,
itp_support: true,
callback: this.handleCallback.bind(this),
});
// #ts-ignore
google.accounts.id.renderButton(
// #ts-ignore
document.getElementById('g_id_onload'),
{ theme: 'filled_blue', size: 'medium', width: '200px' }
);
// #ts-ignore
google.accounts.id.prompt(); // also display the dialog
};
}
Here is the link for Stackblitz which has full code.
How to solve this issue?
The way I solved this problem was to move the button to another place in the dom rather than allow it to be destroyed when my component is destroyed.
When I need the button again, I move it again. I use "display:none" when I'm storing the button in another location in the dom.
Here's an example of moving the button:
// to be called in onDestroy method of component that renders google button
storeButton() {
const con = this.document.getElementById(this.storageConID);
const btn = this.document.getElementById(this.googleButtonID);
con!.insertBefore(btn as any, con?.firstChild || null);
}
However, I found that trying to move the button between locations too quickly, with multiple consecutive calls to el.insertBefore would actually cause the button to disappear from the dom altogether for some reason.
In my case, I was navigating between a login and a signup page and both needed to display the button. To get around that issue, I used a MutationObserver and made sure that I didn't try to move the button out of it's "storage" location until it was actually there.
I added this to my index.html as a place to store the button when it shouldn't be displayed.
<div id="google-btn-storage-con">
<div id="google-btn" class="flex-row justify-center items-center hidden"></div>
</div>
The div with the id "google-btn" is the element I pass into the google.accounts.id.renderButton method to render the button initially on the page.
When I need to display the google button, then I move the div with the id "google-btn" into my component.
I hope that this little bit of code and explanation is enough. I would share more but the actual implementation of all this is hundreds of lines long (including using MutationObserver and dynamically loading the gsi script).
In Angular you shouldn't directly access the DOM to get the element, you can use ViewChild.
//HTML
<div #gbutton></div>
//TS
export class LoginComponent implements OnInit, AfterViewInit {
#ViewChild('gbutton') gbutton: ElementRef = new ElementRef({});
constructor() { }
ngAfterViewInit() {
google.accounts.id.initialize({
client_id: clientId,
itp_support: true,
callback: this.handleCallback.bind(this),
});
google.accounts.id.renderButton(
this.gbutton.nativeElement,
{
type: "standard", theme: "outline",
size: "medium", width: "50", shape: "pill", ux_mode: "popup",
}
)
}

Displaying sidebar items according to user role

I want to display the sidebar items of vx-sidebar according to user role. I'm using acl plugin. There are two users admin and editor. Both have different sidebar items. I have set the roles and everything.But everytime user login, the sidebar items doesn't render initially, I have to refresh the page then the sidebar items render according to role. I am using firebase firestore. And i am setting the initial role as the user.uid found in two different collections of admin and editor.
I have also set the user role in the local storage and vuex.store, but still the elements don't render on initial login.Please help me with this. I have spend days with solving this. But doesn't find solution
acl.js
import Vue from 'vue'
import { AclInstaller, AclCreate, AclRule } from 'vue-acl'
import router from '#/router'
Vue.use(AclInstaller)
let initialRole = localStorage.getItem('userRole')
console.log(initialRole)
export default new AclCreate({
initial: initialRole,
notfound: '/pages/not-authorized',
router,
acceptLocalRules: true,
globalRules: {
admin: new AclRule('admin').generate(),
editor: new AclRule('editor').generate(),
}
})
VxSidebarItem.vue
<div :class="[{'vs-sidebar-item-active':activeLink}, {'disabled-item pointer-events-none': isDisabled}]" class="vs-sidebar--item" v-if="canSee">
computed: {
canSee() {
this.$acl.check(localStorage.getItem('userRole'));
console.log(localStorage.getItem('userRole'))
if(this.to) {
return this.$acl.check(this.$router.match(this.to).meta.rule)
}
return true
}
},
router.js
{
path: '/',
redirect: '/dashboard/jobs'
},
{
path: '/dashboard/jobs',
name: 'Jobs',
component: () => import('./views/tpo/Jobs.vue'),
meta: {
rule:'admin',
}
},

Angular2 routing: canDeactivate limitations

I've got a form in angular2. If it's dirty (with unsaved changes), I want to restrict the user from navigating away.
Research shows that the canDeactivate route guard is the way to do it.
Google led me to this github file which seems to implement what I want.
import { CanDeactivate } from '#angular/router';
import { FormGroup } from '#angular/forms';
export interface FormComponent {
form: FormGroup;
}
export class PreventUnsavedChangesGuard implements CanDeactivate < FormComponent > {
canDeactivate(component: FormComponent) {
if (component.form.dirty)
return confirm('You have unsaved changes. Are you sure you want to navigate away?');
return true;
}
}
Now, I've put this service in my project, injected it in my form component, added it to my routing module as so...
const routes: Routes = [{
path: '',
loadChildren: 'app/main/main.module#MainModule',
canActivate: [AuthenticationGuard],
}, {
path: 'login',
component: LoginComponent,
canDeactivate: [PreventUnsavedChangesGuard]
}, ]
and included it in the app module's providers array.
Now, it seems to work. In case I have unsaved changes when I click the browser's back button. I get the confirmation dialog. However, when I input a new URL in the address bar, I don't get the confirmation. Also, I'm able to close the tab when I have unsaved changes.
Are these known limitations of canDeactivate, or am I doing something wrong. How do I get the behavior I want? (Confirmation dialog if the user attempts to close tab or navigate away using the address bar?)

RactiveJS decorator init issue

I am using a decorator for some sliders like the following:
content = new Ractive({
el: '.wrapper',
template: templates.wrapper,
partials: templates,
data : { ... },
decorators: {
carousel: function( node )
{
console.log( 'carousel init' );
carousel = $( node ).owlCarousel({
items: 1,
navigation: false
});
return {
teardown: function () {
console.log( 'carousel destroy' );
carousel.trigger('destroy.owl.carousel').removeClass('owl-carousel owl-loaded');
carousel.find('.owl-stage-outer').children().unwrap();
}
}
}
}
}
What happens is that, as you can see in the logs, when swapping between a template which has inited the carousel to another template that has this decorator as well, the first decorator teardown is being triggered after the new template's decorator is initiated, therefore the carousel on the second template gets torn down and not the one in the first template.
Am I doing something wrong ? Thanks !
UPDATE
I have made a jsfiddle for it here : https://jsfiddle.net/05sq8o2k/6/
Make sure to tap load unsafe scripts if you get the warning because ractivejs cdn does not support https as far as I can see so jsfiddle kind of disagrees with it now.
This seems fixed in the next version of Ractive. Update your fiddle to use: https://cdn.ractivejs.org/edge/ractive.min.js
Kind regards
Bob

CK Editor custom plugin to create a button

I have been trying to create a custom plugin to create a 'h1' button for the toolbar. Here is my plugin code -
"use strict";
var pluginName = 'customButtons';
CKEDITOR.plugins.add( 'customButtons', {
icons: 'h1_btn', // If you wish to have an icon...
init: function( editor ) {
// Tagname which you'd like to apply.
var tag = 'h1';
// Note: that we're reusing.
//style = new CKEDITOR.style( editor.config[ 'format_' + tag ] );
var style = new CKEDITOR.style( { element: 'h1' } );
// Creates a command for our plugin, here command will apply style. All the logic is
// inside CKEDITOR.styleCommand#exec function so we don't need to implement anything.
editor.addCommand( pluginName, new CKEDITOR.styleCommand( style ) );
// This part will provide toolbar button highlighting in editor.
editor.attachStyleStateChange( style, function( state ) {
!editor.readOnly && editor.getCommand( pluginName ).setState( state );
} );
// This will add button to the toolbar.
editor.ui.addButton( 'h1', {
label: 'Click to apply format',
command: 'customButtons',
toolbar: 'insert'
} );
}
} );
I added the plugin to config.js as well.
Any idea why this isn't working ?
Never mind. I figured out the answer. But letting the question be, in case some stumbles over with the same problem.
It turned out that ckeditor.editor.php has a bug (wrong directory name for plugin). I changed it back to the directory name in the folder structure and voila, it worked !!

Resources