Git Product home page Git Product logo

ionic3-multilevelsidemenu's Introduction

Multi-level Side Menu Open Source Love

Ionic 3 demo of a two-level side menu. The component currently supports only two levels of items. If more levels are needed, maybe using tabs layout for the other levels would be a better approach.

The component also supports two different modes: accordion and default.

Accordion Default

Table of contents

Ionic info

Cli packages: (/usr/local/lib/node_modules)

    @ionic/cli-utils  : 1.19.0
    ionic (Ionic CLI) : 3.19.0

Local packages:

    @ionic/app-scripts : 3.1.7
    Ionic Framework    : ionic-angular 3.9.2

Running the demo

Inside of the project folder, run npm install and then to run the demo in the browser ionic serve [-t android/ios]

Using the component in your projects

Just copy the side-menu-content folder (inculding the html, ts and scss files) in your project. Then include the SideMenuContentComponent in the declarations array from your @NgModule.

Features

Items structure

Options and suboptions should be of type SideMenuOption:

export interface SideMenuOption {
    iconName?: string;
    displayText: string;
    badge?: Observable<any>;
    component?: any;
    custom?: any;
    selected?: boolean;
    suboptions?: Array<SideMenuOption>;
}
Property Type Description
iconName string Optional. Name of the Ionic icon to be used for this option/suboption. If it is an option with suboptions and the iconName is null, the default icon will be ios-arrow-down
displayText string Text to be shown in the menu
badge Observable<any>  Optional. Observable that allows the application to dynamically update the value of the badge
component any Optional. Target component or null if it is a special option/suboption (this would mean that it does not change the current page, so it may be related to login/logout options, or to changing the current language, ...)
custom  any Optional. Property to pass whatever we need. That way we can access this property when the user selects this option/suboption and handle login/logout options, changing the language, ...
selected boolean Optional. If true, the option/suboption will be marked as selected by default
suboptions Array<SideMenuOption> Optional. List of suboptions of the option. Each suboption should be of type SideMenuOption

So an option with nested suboptions would look like this:

let menuOption: SideMenuOption = {
    displayText: 'Option Name',
    suboptions: [
        {
            // With icon
            iconName: 'ios-basket',
            displayText: 'Sub Option 1',
            component: 'SomePage'
        },
        {
            // Without icon
            displayText: 'Sub Option 2',
            component: 'SomeOtherPage'
        },
        {
            // Special option with icon
            iconName: 'log-in',
            displayText: 'Login',
            custom: {
                isLogin: true
            }
        },
        {
            // Another special option but without icon
            displayText: 'Spanish',
            custom: {
                shouldChangeLanguage: true,
                targetLanguage: 'ES'
            }
        }
    ]
};

Selecting options

When an option is selected, the SideMenuOption object is returned to the caller by the change event. The SideMenuOption returned object can then be used to check if we need to push/set as root a new page, or if we need to handle that option as a special option.

<side-menu-content [options]="options" (change)="onOptionSelected($event)"></side-menu-content>

And then in the App component code:

@Component({
    templateUrl: 'app.html'
})
export class MyApp {
    // ...

    public onOptionSelected(option: SideMenuOption): void {
        if (option.custom && option.custom.isLogin) {
            // Handle the login...
        } else if (option.custom && option.custom.isLogout) {
            // Handle the logout...
        } else if(option.component) {
            // Push or set as root the option.component page
        }
    }
}

Settings

The component also defines the SideMenuSettings interface, to customize the behaviour of the component.

export interface SideMenuSettings {
    accordionMode?: boolean;
    optionHeight?: {
        ios?: number,
        md?: number,
        wp?: number
    };
    arrowIcon?: string;
    showSelectedOption?: boolean;
    selectedOptionClass?: string;
    indentSubOptionsWithoutIcons?: boolean;
    subOptionIndentation?: {
        ios?: number,
        md?: number,
        wp?: number
    };
}

The settings should be sent to the component using the settings property:

@Component({
    templateUrl: 'app.html'
})
export class MyApp {
	
    //...

    // Settings for the SideMenuContentComponent
    public sideMenuSettings: SideMenuSettings = {
        accordionMode: true,
        showSelectedOption: true,
        selectedOptionClass: 'my-selected-option'
    };

    // ...

} 

And in the view:

<side-menu-content [settings]="sideMenuSettings" [options]="options" (change)="onOptionSelected($event)"></side-menu-content>
Param Description Default value
accordionMode Optional. If true, all options will be collapsed before expanding the new selected option false
optionHeight Optional. Custom height (in pixels) to be used for each option/suboption 50 for all md, ios and wp
arrowIcon Optional. Name of the Ionic icon to be used as the arrow in options that contain suboptions ios-arrow-down
showSelectedOption Optional. If true, the selected option will be highlighted false
selectedOptionClass Optional. Name of the class to be added to the selected option. Only used when showSelectedOption is true selected-option
indentSubOptionsWithoutIcons Optional. If true, suboptions without icons will be vertically aligned based on the parent option false
subOptionIndentation Optional. Left padding (in pixels) to be used on each suboption, so we can indent them if needed 16 for all md, ios and wp

Some other public methods

The component also exposes a collapseAllOptions() method to reset the state of the options when needed (after selecting an option, or when closing the side menu for example):

@Component({
    templateUrl: 'app.html'
})
export class MyApp {
    // Get the instance to call the public methods
    @ViewChild(SideMenuContentComponent) sideMenu: SideMenuContentComponent;

    // ...

    public selectOption(option: SideMenuOption): void {
        this.menuCtrl.close().then(() => {

            // Collapse all the options
            this.sideMenu.collapseAllOptions();
            
            // ...
        
        });
    }
}

Theming

We can use some simple css rules to change the styles of the menu options. If we set the showSelectedOption setting to true, we can also set the styles of the options when they are marked as selected.

Target Class name
Basic option (options without suboptions) option
Option with suboptions header
Suboption sub-option

So for instance, we can use the following css rules (by adding it in the app.scss file) to change the color of the menu items, both when they are selected and when they're not:

side-menu-content {

    // In this example, we have used the following name
    // for the selected option in the settings object:
    // selectedOptionClass: 'active-side-menu-option'

    $active-color: map-get($colors, primary);
    $font-color: #222;
    $background-light-color: #fff;
    $background-dark-color: #eee;

    // Single option
    // ------------------
    ion-item.item.item-block.option {
        background-color: $background-light-color;
        color: $font-color;

        &.active-side-menu-option {
            color: $active-color;
            font-weight: 700;
        }
    }

    // Header
    // ------------------
    ion-item.item.item-block.header {
        background-color: $background-dark-color;
        color: $font-color;

        &.active-side-menu-option {
            color: $active-color;
            font-weight: 700;
        }
    }

    // Sub option
    // ------------------
    ion-item.item.item-block.sub-option {
        background-color: $background-light-color;
        color: $font-color;

        &.active-side-menu-option {
            color: $active-color;
            font-weight: 700;            
        }
    }
}

Navigation outside the side menu

If we set the showSelectedOption setting to true, and then we try to navigate to a given page using a button on the content on the page instead of clicking on that option from the side menu, that page won't be shown as selected in the menu.

In order to avoid this issue we can use:
a) The SideMenuDisplayText decorator.
b) The SideMenuDisplayTextConditions decorator.
c) The SideMenuOptionSelect event sending the SideMenuOptionSelectData.

Important: If we want to use the SideMenuDisplayText or the SideMenuDisplayTextConditions decorators, first we would need to make the injector to be available in the entire module by changing the following line of the app.module.ts file:

export class AppModule { }

and replace it by the following code:

export class AppModule {
  static injector: Injector;
  constructor(injector: Injector) { AppModule.injector = injector; }
}

SideMenuDisplayText

This custom decorator allows each page to define which option from the side menu should be marked as selected when the page is opened.

@SideMenuDisplayText(displayText: string).

The displayText parameter is mandatory and should be equal to the displayText property from the option that should be marked as selected when the user enters to this page. If there are multiple suboptions with the same displayText, "optionDisplayText >> suboptionDisplayText" should be used instead (for example, "With Icons >> Sub Option 1").

So if in the app.component.ts file we created the option like this:

// ...
this.options.push({
    iconName: 'home',
    displayText: 'Home', // <-- The displayText property of this option is 'Home'
    component: 'HomePage',
});
// ....

Then in the page we will use the SideMenuDisplayText decorator like this:

@IonicPage()
@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})
@SideMenuDisplayText('Home') // <-- We need to set this parameter to 'Home' as well
export class HomePage {
    // ...
}

SideMenuDisplayTextConditions

The previous decorator works properly but only if each page is related to only one option from the side menu (since the decorator is being set per page). But what happens if the same page is related to more than one option from the side menu?

For example, in this demo project we have a EmailsPage page/component that receives a parameter showDeleted: boolean. Based on that parameter, the page shows the inbox or the deleted messages from the user. Both Inbox and Bin are also options being shown in the side menu.

So basically two different options from the side menu are related to the same page. In this scenario, we can use the SideMenuDisplayTextConditions decorator to select the right option from the side menu based on a given condition.

SideMenuDisplayTextConditions(conditions: Array<SideMenuOptionSelectCondition>)

The conditions parameter is mandatory and should be an array of SideMenuOptionSelectCondition entities. Each condition tells the component how to check which option should be marked as selected (if any).

So if in the app.component.ts file we created the options like this:

// ...
this.options.push({
    displayText: 'Same component',
    suboptions: [
        {
            iconName: 'mail',
            displayText: 'Inbox',
            component: 'EmailsPage', // <-- Both options are related the same EmailsPage component
            custom: {
                param: { showDeleted: false }
            }
        },
        {
            iconName: 'trash',
            displayText: 'Bin',
            component: 'EmailsPage', // <-- Both options are related the same EmailsPage component
            custom: {
                param: { showDeleted: true }
            }
        }
    ]
});
// ....

Then in the page we will use the SideMenuDisplayTextConditions decorator like this:

@IonicPage({
    segment: 'emails/:showDeleted'
})
@Component({
    selector: 'page-emails',
    templateUrl: 'emails.html'
})
@SideMenuDisplayTextConditions([ // <-- Here we set an array of conditions!
    { propertyName: 'showDeleted', matcher: Matcher.ToBeFalsy, displayText: 'Inbox' },
    { propertyName: 'showDeleted', matcher: Matcher.ToBeTruthy, displayText: 'Bin' }
])
export class EmailsPage {

    public showDeleted: boolean;

    constructor(private navParams: NavParams) { }

    ionViewWillEnter() {
        // We initialize the showDeleted property so it can be ready
        // to be used in the SideMenuDisplayTextConditions decorator
        this.showDeleted = this.navParams.get('showDeleted');
    }
}

Each condition should be of type SideMenuOptionSelectCondition:

export interface SideMenuOptionSelectCondition {
    propertyName: string;
    value?: any;
    matcher: Matcher;
    displayText: string;
}
Param Description
propertyName Name of a property from the page/component to check its value against the value property
value Optional. Value that the property with name propertyName should have mark this option as selected
matcher Defines how should the value from propertyName be checked to figure out if the condition is satisfied
displayText The displayText of the option/suboption from the side menu that should be marked as selected if the condition is satisfied. If there are multiple suboptions with the same displayText, "optionDisplayText >> suboptionDisplayText" should be used instead (for example, "With Icons >> Sub Option 1").

The Matcher enum includes the following values:

Value Description
ToBe Expects the current value to be == to the expected value
NotToBe Expects the current value to be != to the expected value
ToEqual Expects the current value to be === to the expected value
NotToEqual Expects the current value to be !== to the expected value
ToBeDefined Expects the current value to be defined (not undefined)
ToBeFalsy Expects the current value to be falsy
ToBeGreaterThan Expects the current value to be greater than the expected value
ToBeGreaterThanOrEqual Expects the current value to be greater than or equal to the expected value
ToBeLessThan Expects the current value to be less than the expected value
ToBeLessThanOrEqual Expects the current value to be less than or equal to the expected value
ToBeNull Expects the current value to be null
ToBeTruthy Expects the current value to be truthy
ToBeUndefined Expects the current value to be undefined
ToContain Expects the current value to contain a specific value
ToMatch Expects the current value to match a regular expression

SideMenuOptionSelect with SideMenuOptionSelectData

If we need to select an option based on a more complex logic, we can still use the SideMenuOptionSelect event to let the side menu component know which option should be marked as selected. This component defines and makes available a SideMenuOptionSelect event and the SideMenuOptionSelectData interface:

export const SideMenuOptionSelect: string = 'sideMenu:optionSelect';
export interface SideMenuOptionSelectData { displayText?: string; }

So in the page we just need to publish that event using Ionic Events:

@Component({
    selector: 'page-demo',
    templateUrl: 'demo.html'
})
export class DemoPage {
    constructor(private eventCtrl: Events, ...) { }

    ionViewWillEnter() {
        const complexResult = this.someComplexMethod();

        if(complexResult % 2 === 0) {
            this.selectOptionByName('Option 2');
        } else {
            this.selectOptionByName('Option 1');
        }
    }

    private someComplexMethod(): number {
        return Math.floor(Math.random() * 10);
    }

    private selectOptionByName(name: string): void {
        const data: SideMenuOptionSelectData = { displayText: name };
        this.eventCtrl.publish(SideMenuOptionSelect, data);
    }
}

Changelog

  • 12/10/2018 Added support for multiple suboptions with the same name. In order to show the proper option as selected the displayText should be "optionDisplayText >> suboptionDisplayText" (in this demo for example, you can see that the suboption Sub Option 1 from the With Icons option uses "With icons >> Sub Option 1" in the custom decorator).

  • 19/04/2018 Added SideMenuDisplayText and SideMenuDisplayTextConditions custom decorators. That way the right option can be selected when refresing the page (see this issue). Created lazy-loaded pages for every option of the demo.

    🔥 ⚠️️️ Breaking changes ⚠️️️ 🔥

    Some interfaces and properties were renamed from the previous version. So if you're updating this demo project from the previous version, please take a look at the breaking changes section.

  • 06/01/2018: Added support for ion-badge in the items/sub-items. The badge option expects an Observable that allows the application to dynamically update the value of the badge (thanks @ralscha!!). Updated Ionic to the 3.9.2 version (thanks @peterennis!!)

  • 04/11/2017: Added option, header and sub-option classes to style the options (see Theming section for more details). Improved overall performance by removing direct access to the DOM.

  • 30/08/2017: Added showSelectedOption and selectedOptionClass to highlight the currently selected option. Added custom subproperty in the SideMenuOption model to allow the user to add any custom property on the items.

  • 16/09/2017: Added indentSubOptionsWithoutIcons and subOptionIndentation settings to allow the user to customize the indentation of the sub items. Improved inner logic so now if the showSelectedOption setting is true and the currently selected option is a sub item, its parent will be shown expanded when opening the side menu.

Roadmap

  • Convert this demo into an npm package
  • Add unit testing
  • Add e2e testing

Contribution

  • Having an issue or looking for support? Open an issue and I'll do my best to help you out.
  • Got a new feature or a bug fix? Fork the repo, make your changes, and submit a pull request.

Support this project

If you find this project useful, please star the repo to let people know that it's reliable. Also, share it with friends and colleagues that might find this useful as well. Thank you! :)

ionic3-multilevelsidemenu's People

Contributors

peterennis avatar ralscha avatar sebaferreras avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ionic3-multilevelsidemenu's Issues

SideMenu Direction

How to change the direction of a side menu?
Currently its left to right, but i want side menu from right to left.
Is there any option available for this?

Remove item from side menu

How can i remove and add items to menu dinamically? For example, when i Logout, i need to remove "Logout" item. I try to splice the options array but nothing happends. Thanks!
My code:

 selectOption(option: MenuOptionModel): void {
    if (option.custom && option.custom.isLogout) {
      this.logout();
      this.options.splice(4,1);
    } else if (option.component) {
      this.goToPage(option.component);
    }
    this.closeMenu();
  }

Property 'injector' does not exist on type 'typeof AppModule'.

Hello,
I am trying to include your multilevelsideMenu into my ionic3 apps and it was running nicely. But all of a sudden it just showing me injector error "Property 'injector' does not exist on type 'typeof AppModule'." in custom-decorators/side-menu-display-text-conditions.decorator.ts file

Open a tab from the Menu

Hello,

I am able to open the first tab page (home) from the side menu, but the second tab page (about) is not working.

here's what I'm doing, can you guide me through it?

i have the following tabs:
tabs.html

<ion-tabs [selectedIndex]="mySelectedIndex">
  <ion-tab [root]="tab1Root" tabIcon="home" tabUrlPath="home"></ion-tab>
  <ion-tab [root]="tab2Root" tabIcon="information" tabUrlPath="about"></ion-tab>
</ion-tabs>

tabs.ts

tab1Root: any = 'HomePage';
tab2Root: any = 'AboutPage';

the SideMenuOption

// Load simple menu options
  // ------------------------------------------
  this.options.push({
    iconName: 'home',
    displayText: 'Home',
    component: 'TabsPage',
  });

  this.options.push({
    iconName: 'information',
    displayText: 'About Us',
    component: 'TabsPage',
    custom: {
      param: { tabComponent: 'AboutPage' }
    }
  });

Restricting Side Menu From Collapsing.

Hi,
I just wanted to know how can I restrict the side menu from closing when I navigate to another page...
Basically what I want is if anyone opens side-menu and then navigates to another page and when presses the back button I want the side-menu to be open as it was...
So how can I achieve this??
Thanks!

Page refresh loses selected option and sets default Home as selected option

Hello,

First of all thanks a lot for such a nice implementation.

You have explained very nice how to set the selected option when we navigate with a button to an option.

I have a one question. When I refresh the page then gets selected option automatically default page, in this case Home.

For example I have a menu structure: Home - Users - Products.

I chose the Users menu then the URL is http://localhost:8100/#/user-list and Users menu is selected, so far so good.

When I refresh the page (http://localhost:8100/#/user-list) then Home will be automatically selected, not the Users menu.

For sure I can send the event to the menu option on user.list.component.ts but think that I have 20 more components and 20 menus. Then I have to implement in every page. Is there a way in one place to configure selected menu with page refresh?

Custom component error

I created a shared component and when I load it to my page i get:
ERROR Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded RangeError: Maximum call stack size exceeded
and when I remove component import from my_page.module.ts everything is normal again....

accordion.ts:
accordion ts

components.module.ts:
components module

my_page.module.ts:
page module

Error:
error

not highlighted selected menu and submenu

on click of side menu current menu or item not showing selected and same case with submenu . and another issue with this side menu is it is showing highlighted submenus parent item bydefault. I dont want to show it highlighted bydefault.
untitled

How can I set the menu heading color and font color?

I would like to be able to have a different color for the selected menu background.
Also a secondary color for the actual selected menu would be nice.
If it exists and is documented it must be in my blind spot :(

capture222

Add new id property to SideMenuOption interface

Even though it's easy to use the displayText to decide which option/suboption should be marked as selected, it'd be better if the component allow users to add an id to each option/suboption and then use that id instead of the displayText.

For example:

public enum SideMenuPage {
    AdminDetails,
    UserDetails
}

// ...

const options: Array<SideMenuOption>  = [
    {
        displayText: 'Admin',
        suboptions: [
            {
                id: SideMenuPage.AdminDetails,
                displayText: 'Details',
                component: 'DetailsPage',
                // ...   
            },
            // ...
        ]
    },
    {
        displayText: 'User',
        suboptions: [
            {
                id: SideMenuPage.UserDetails,
                displayText: 'Details',
                component: 'DetailsPage',
                // ...
            },
            // ...
        ]
    }
]

And then:

@Component({
    selector: 'page-details',
    templateUrl: 'details.html'
})
@SideMenuDisplayTextConditions([
    { propertyName: 'userType', matcher: Matcher.ToEqual, value: UserType.Admin, optionId: SideMenuPage.AdminDetails },
    { propertyName: 'userType', matcher: Matcher.ToEqual, value: UserType.User, optionId: SideMenuPage.UserDetails }
])

Support @ngx-translate for displayText

I'd like to suggest changing displayText from string to BehaviorSubject<string> to support dynamic change of display text and @ngx-translate, the HTML markup will become like, e.g.

<span *ngIf="option.displayText | async as menuText">{{ menuText | translate }}</span>

Side Menu background image

Unable to apply a background image in side menu..., and If I apply then it changes the background of the pages to which I navigate thru it..( I was using scroll-content to set an image on app.scss ) Any solution??

adding the component to project

Hi,

My scenario is

  1. Login to application
  2. Homapage should display the MultiLevelSideMenu in the Home Page.

I tried

  1. copied the shared component folder into my project.

  2. copied the app.component.ts to my project.

  3. copied the below code into my home.html
    <ion-menu persistent="true" [content]="content" (ionClose)="collapseMenuOptions()">


    {{ (sideMenuSettings.accordionMode ? 'Accordion' : 'Default') + ' menu' }}

     <!-- Side Menu -->
     <side-menu-content [settings]="sideMenuSettings" [options]="options" (selectOption)="selectOption($event)"></side-menu-content>
    

<ion-nav [root]="rootPage" #content swipeBackEnabled="false">

Getting error below
Error: Uncaught (in promise): Error: Template parse errors:
Can't bind to 'settings' since it isn't a known property of 'side-menu-content'.

  1. If 'side-menu-content' is an Angular component and it has 'settings' input, then verify that it is part of this module.

  2. If 'side-menu-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

  3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("

     <!-- Side Menu -->
     <side-menu-content [ERROR ->][settings]="sideMenuSettings" [options]="options" (selectOption)="selectOption($event)"></side-menu-c"): ng:///HomePageModule/HomePage.html@67:21
    

Can't bind to 'options' since it isn't a known property of 'side-menu-content'.

  1. If 'side-menu-content' is an Angular component and it has 'options' input, then verify that it is part of this module.

  2. If 'side-menu-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

  3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("

     <!-- Side Menu -->
     <side-menu-content [settings]="sideMenuSettings" [ERROR ->][options]="options" (selectOption)="selectOption($event)"></side-menu-content>
    

"): ng:///HomePageModule/HomePage.html@67:51
'side-menu-content' is not a known element:

  1. If 'side-menu-content' is an Angular component, then verify that it is part of this module.

  2. If 'side-menu-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("

     <!-- Side Menu -->
     [ERROR ->]<side-menu-content [settings]="sideMenuSettings" [options]="options" (selectOption)="selectOption($ev"): ng:///HomePageModule/HomePage.html@67:2
    

Error: Template parse errors:
Can't bind to 'settings' since it isn't a known property of 'side-menu-content'.

  1. If 'side-menu-content' is an Angular component and it has 'settings' input, then verify that it is part of this module.

  2. If 'side-menu-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

  3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("

     <!-- Side Menu -->
     <side-menu-content [ERROR ->][settings]="sideMenuSettings" [options]="options" (selectOption)="selectOption($event)"></side-menu-c"): ng:///HomePageModule/HomePage.html@67:21
    

Can't bind to 'options' since it isn't a known property of 'side-menu-content'.

  1. If 'side-menu-content' is an Angular component and it has 'options' input, then verify that it is part of this module.

  2. If 'side-menu-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

  3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("

     <!-- Side Menu -->
     <side-menu-content [settings]="sideMenuSettings" [ERROR ->][options]="options" (selectOption)="selectOption($event)"></side-menu-content>
    

"): ng:///HomePageModule/HomePage.html@67:51
'side-menu-content' is not a known element:

  1. If 'side-menu-content' is an Angular component, then verify that it is part of this module.

  2. If 'side-menu-content' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("

     <!-- Side Menu -->
     [ERROR ->]<side-menu-content [settings]="sideMenuSettings" [options]="options" (selectOption)="selectOption($ev"): ng:///HomePageModule/HomePage.html@67:2
    

    at syntaxError (http://localhost:8101/build/vendor.js:80553:34)
    at TemplateParser.parse (http://localhost:8101/build/vendor.js:91791:19)
    at JitCompiler._compileTemplate (http://localhost:8101/build/vendor.js:105985:39)
    at http://localhost:8101/build/vendor.js:105904:62
    at Set.forEach ()
    at JitCompiler._compileComponents (http://localhost:8101/build/vendor.js:105904:19)
    at http://localhost:8101/build/vendor.js:105791:19
    at Object.then (http://localhost:8101/build/vendor.js:80542:143)
    at JitCompiler._compileModuleAndComponents (http://localhost:8101/build/vendor.js:105790:26)
    at JitCompiler.compileModuleAsync (http://localhost:8101/build/vendor.js:105719:37)
    at c (http://localhost:8101/build/polyfills.js:3:19132)
    at Object.reject (http://localhost:8101/build/polyfills.js:3:18554)
    at NavControllerBase._fireError (http://localhost:8101/build/vendor.js:44355:16)
    at NavControllerBase._failed (http://localhost:8101/build/vendor.js:44343:14)
    at http://localhost:8101/build/vendor.js:44398:59
    at t.invoke (http://localhost:8101/build/polyfills.js:3:14356)
    at Object.onInvoke (http://localhost:8101/build/vendor.js:4247:33)
    at t.invoke (http://localhost:8101/build/polyfills.js:3:14296)
    at r.run (http://localhost:8101/build/polyfills.js:3:9523)
    at http://localhost:8101/build/polyfills.js:3:19622
    Ionic Framework: 3.7.1
    Ionic App Scripts: 3.0.0
    Angular Core: 4.4.3
    Angular Compiler CLI: 4.4.3
    Node: 8.1.2
    OS Platform: Windows 7
    Navigator Platform: Win32
    User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64)

Please can you help me how to use the component in my scenario.

CSS

I'd like to suggest changing the CSS as follows so it will not affect other ion-items in the app:

// ------------------------------------ //
// Simple items                         //
// ------------------------------------ //
side-menu-content {
    ion-item.item-ios,
    ion-item.item-md,
    ion-item.item-wp {

        padding-left: 16px;
        padding-right: 16px;
        min-height: 50px;

        &.item.item-block {
            border-bottom: 1px solid $item-color-bg;
        }
        
        & [item-left], 
        & [item-right] {
            margin-left: 0;
        }

        & ion-icon[item-left] + .item-inner, 
        & ion-icon[item-left] + .item-input {
        margin-left: 8px;
        }
    }
}

menu icon does not appear

Hi,
I wanted to use this, but when I added the stuff to my project, the menu toggle button would not be visible in page components. What do I need to make that happen? I already have a button in the toolbar with menuToggle. Please help me.

Lazy loading??

Converting it to lazy loading is a nightmare! I have been trying for (almost) a month now without any progress.... Any help is more than welcome.

Don't collapse menu when selected sub item

I don't want to collapse my sub menu on select of sub menus. I am trying ti use this multilevel side menus on split pane .I want to show on my desktop.When i click on sub menu it should be open till we are on that page.

Side menu always visible

Hello, very good work.
Is possible to mantain alwais visible the side menu?
Thank you for your great contribution.

npm WARN [email protected] requires a peer of [email protected] but none is installed

I have an update running using Angular 6 here:
https://test.adaept.com/
with this repo:
https://github.com/peterennis/test-side-menu-content

However, I cannot seem to update your code as the tsickle WARN does
not allow TypeScript to be updated.

State of my fork is here: https://github.com/peterennis/Ionic3-MultiLevelSideMenu

tsickle relates to Closure, but I have no idea if you are using that or how.

Purpose

Update prep for testing Ionic 4.

I removed ionic-native stuff as it will probably be using Capacitor.

Another repo will be needed for Ionic 4. Are you interested to
move forward on that?

I have some tests running:
https://aetabs.adaept.com
https://aeion4.adaept.com

This one:
https://aeicons.adaept.com/
Is using Ionic 3.9.2 with Angular 6

Active item

Is it possible to set a style for the currently active/selected page in the menu

Permisos a items y subitems

Hola Sebastián,
Me gustaría saber como podria agregarle un nuevo atributo a los items del menu, para que sean agregados o no dependiendo de un booleano correspondiente a si el usuario tiene o no permiso para acceder a una page en especifico. Yo ya tengo algo hecho te muestro codigo

{ iconName: 'basket', displayName: 'Mis empresas', component: 'PgBusinessPage', permission: permissions.business.business, },

eso corresponde a un subitem,

Por otro lado he modificado el método set del archivo side-menu-content:

` @input('options')
set options(value: Array) {
console.log("SET OPTIONS SIDE MENU")
console.log(value)
if (value) {
this.menuOptions = value;
console.log(value)
if (!this.menuSettings || this.menuSettings.showSelectedOption) {
this.selectedOption = this.menuOptions.find(option => option.selected);

    this.parents = new Map<string, MenuOptionModel>();

    this.menuOptions.forEach(option => {
      if (option.subItems) {
        option.subItems.forEach(subItem => {
          console.log("tiene permiso:", subItem.displayName, subItem.permission)
          if (subItem.permission) {
            console.log("agrego el item porque tiene permiso")
            console.log(option)
            this.parents.set(subItem.displayName.toLowerCase(), option);
          }else{
            console.log("no agrego porque no tiene permiso")
          }
        });
      }
    });
  }
}

}`

pensando que la linea:

this.parents.set(subItem.displayName.toLowerCase(), option);

me agregaría o no el subitem pero no es así

espero que me puedas ayudar

Quedo atento

Matías Álvarez Sabaté

Add options dynamically

Hi. First of all thank you for this wonderful plugin and for sharing!!.

I'm trying to create a menu from which I first know the main elements, but one of them is a submenu with elements that come from a web service ...

The fact is that once I have added the structure to the SideMenuOption, I can not find a way to modify or add more elements... even if I load some data in the option array after a timeout (as a test) these do not appear anymore!

The only way I have found is to retain the initialization of the application until the web service has answered, using the angular APP_INITIALIZER token, and then create the menu ... but that causes the screen to go blank for a while. :(

Is there a way to reset or reinitialize the menu once I have the necessary data?

TX.

Help

Hi i new, can anyone tell me, where i have to copy this (side-menu-content) folder, in my pages folder?

Side menu transparency

Hi guys
I noticed that even though this is supposed to be a standalone component,
it's still bound to some generic app settings( https://github.com/sebaferreras/Ionic3-MultiLevelSideMenu/blob/master/src/app/app.scss )
and I was wondering how to make it more isolated in this terms - my goal is to achieve transparent black background - but I am confused where should this change be done (and how ... to not break current isolation), can you enlighten me?

thank you in advance for any hints
L
(oh and kudos for this code, it's really nice!)

Selected option when reusing displayText

First of all, I want to thank you for this awesome component!

I have a menu structure like this:

  • admin
    • config
    • doc
    • log
    • status
  • user
    • doc
    • status
  • dev
    • doc

As you can see, I'm reusing some of the displayTexts (doc and status). They direct to the same component passing different custom properties. While the page is displayed according to the properties, the menu displays (highlights) always the last occurence of the display name (e.g. dev/doc when selecting admin/doc).

Is there a way to avoid this or does the displayText have to be unique? If the latter is the case, could you unbind the selection from the displayText and add an additional property to the SideMenuOption used for getting the correct selection?

Back button on android to go home page

Hi Seba, it's me again. I have a problem when I want to back to the home page pressing the back button of an a android phone, the problem occurs when I enter in a view and open a modal, then I close the modal but the back button do nothing, the idea when i press the is back button go to the home page, can you help me? Thanks for your time!

Alejandro.

Example on how to use it step by step?

Hi, i'm new to ionic and i want to use your Multilevelsidemenu. but i dont know how to implement it. can someone provide me some links on how to use it?

What if I want subItems of subItems and so on..??

I want 4 level side menu

I tried to push option as mention bellow but it is not working.
also played with side-menu-content.component.html but didn't get what to do,
Can you please guide where else I have to make changes.

Thank you for your great contribution.

this.options.push({ displayName: 'Nayan', subItems: [ { iconName: 'basket', displayName: 'Sub Option 1', subItems: [ { iconName: 'basket', displayName: 'Sub Option 1', component: 'HomePage' }, { iconName: 'bookmark', displayName: 'Sub Option 2', component: 'HomePage' } ] }, { iconName: 'bookmark', displayName: 'Sub Option 2', component: 'HomePage' } ] });

how to set a display name in menu using a variable....

Thanks for your support all the way..I am trying to set a display name to menu using a variable...I am using ng2-translate ...as per selected language i want to set a display name.I am quiet confused or if i may using it in wrong way..but when i set the variable to display name it show nothing in side menu..please correct me ...its urgent.....thanks in advance
This is my code
capture 1

this code give me following output
capture 2

Ionic 4 version

Hello,
Can you please make an Ionic 4 version of this MultiLevelSideMenu?

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.