Angular UI-Router Multiple Navigation (Horizontal Top and Vertical Left Menu)

My website has a top-level menu and left menus that are updated based on the selected top-level menu. When I click on a left menu item, it resets and becomes blank, as shown when clicking on HOME. Currently, only HOME is connected, while Route1 and Route2 are not.

For reference, you can view the Plunker example here: http://plnkr.co/edit/Jwow4VtNsSfMMcpv6qaa?p=preview

How can I prevent the left menu from resetting/reloading on selection? I also want to maintain the highlight on the clicked left menu item.

<!DOCTYPE html>
<html ng-app="myapp">

<head>
    <title>AngularJS: UI-Router Quick Start</title>
    <!-- Bootstrap CSS -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>

<body class="container">

    <div class="navbar">
        <div class="navbar-inner">
            <a class="brand" ui-sref="index">Quick Start</a>
            <ul class="nav">
                <li><a ui-sref="index">Home</a></li>
                <li><a ui-sref="route1">Route 1</a></li>
                <li><a ui-sref="route2">Route 2</a></li>
            </ul>
        </div>
    </div>

    <div class="row">
        <div class="span6">
            <div class="well" ui-view="LeftMenu"></div>
        </div>
        <div class="span6">
            <div class="well" ui-view="Content"></div>
        </div>
    </div>

    <!-- Angular -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
    <!-- UI-Router -->
    <script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>

    <!-- App Script -->
    <script>
    var myapp = angular.module('myapp', ["ui.router"])
    myapp.config(function($stateProvider){
        $stateProvider
            .state('index', {
                url: "",
                views: {
                    "LeftMenu": {
                        template: '<ul><li><a ui-sref="LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
                    },
                    "Content": {
                        template: "LeftMenu index selected"
                    }
                }
            })
             .state('LeftMenuMenu1', {
                 views:{
                 "Content": {
                     template: "LeftMenu.Menu1 selected"
                 }
             }
        })
        .state('LeftMenuMenu2', {
             views: {
                 "Content": {
                     template: "LeftMenu.Menu2 selected"
                 }
             }
         })
         .state('LeftMenuMenu3', {
             url: "",
             views: {
                 "Content": {
                     template: "LeftMenu.Menu3 selected"
                 }
             }
         })
        .state('route1', {
            url: "/route1",
            views: {
                "LeftMenu": {
                    template: '<ul><li><a ui-sref="Route1.Menu1">Route1-Left Menu1</a></li><li><a ui-sref="Route1.Menu2">Route1-Left Menu2</a></li><li><a ui-sref="Route1.Menu3">Route1-Left Menu3</a></li></ul>'
                },
                "viewB": {
                    template: "route1.viewB"
                }
            }
        })
        .state('route2', {
            url: "/route2",
            views: {
                "LeftMenu": {
                    template:'<ul><li><a href="">Route2-Left Menu1</a></li><li><a href="">Route2-Left Menu2</a></li><li><a href="">Route2-Left Menu3</a></li></ul>'
                },
                "viewB": {
                    template: "route2.viewB"
                }
            }
        })
    });
    </script>

</body>

</html>

Answer №1

To optimize your workflow, consider utilizing substates in addition to root states. By setting the left menu options within each root state, you can ensure greater flexibility and organization.

Take for example the following scenario where index serves as the root state that defines the left menu options and specifies where the substates (index.LeftMenuMenu1, index.LeftMenuMenu2, index.LeftMenuMenu3) will be rendered within the view. These substates will be displayed wherever the

<div ui-view="content"></div>
element is placed.

$stateProvider
    //Root state
    .state('index', {
        url: "",
        views: {
            //Set left side bar
            "LeftMenu": {
                template: '<ul><li><a ui-sref="index.LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="index.LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="index.LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
            },
            //Each substate will live here
            "Content": {
                template: "<div ui-view></div>"
            }
        }
    })
    //substates
    .state('index.LeftMenuMenu1', {
        template: "LeftMenu.Menu1 selected"
    })
    .state('index.LeftMenuMenu2', {
        template: "LeftMenu.Menu2 selected"
    })
    .state('index.LeftMenuMenu3', {
        template: "LeftMenu.Menu3 selected"
    })

Extend this pattern to other sections of your page for consistency and efficiency.

$stateProvider
    ...
    //Root state route 1
    .state('route1', {
        url: "/route1",
        views: {
            "LeftMenu": {
                template: 'Route 1 menu options..'
            },
            "Content": {
                template: "<div ui-view></div>"
            }
        }
    })
    .state('route1.LeftMenuMenu1', {
        template: "LeftMenu.Menu1 selected"
    })
    .state('route1.LeftMenuMenu2', {
        template: "LeftMenu.Menu2 selected"
    })
    //Root state route 2
    .state('route2', {
        url: "/route2",
        views: {
            "LeftMenu": {
                template: 'Route 2 menu options..'
            },
            "Content": {
                template: "<div ui-view></div>"
            }
        }
    })
    .state('route2.LeftMenuMenu1', {
        template: "LeftMenu.Menu1 selected"
    })
    .state('route2.LeftMenuMenu2', {
        template: "LeftMenu.Menu2 selected"
    })

View updated plunker

If your left menu only requires changes to links while the view remains consistent, consider implementing a different approach. You could potentially create a menu service to handle menu options and utilize the onEnter property for each root state to update the menu options accordingly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The output of JSTree's data.rslt.obj.text() function is an array of text values, not just the text from the specified node

I am facing an issue with the jstree where it is returning a concatenated list of node names when I try to rename a node, instead of just the text for the node I am renaming. The jstree is set up to load on demand. How can I ensure that only the text for ...

Please optimize this method to decrease its Cognitive Complexity from 21 to the maximum allowed limit of 15. What are some strategies for refactoring and simplifying the

How can I simplify this code to reduce its complexity? Sonarqube is flagging the error---> Refactor this method to reduce its Cognitive Complexity from 21 to the allowed 15. this.deviceDetails = this.data && {...this.data.deviceInfo} || {}; if (th ...

"Encountering an error retrieving weather forecast API in JavaScript - issue with

I've been attempting to fetch the weather forecast API JSON in a similar manner to how I accessed the current weather API, but unfortunately, it doesn't seem to be working no matter what approach I take. let inOneDay = { fetchWeather: functio ...

Is it possible to incorporate click methods within vuex?

Recently, I've been delving into learning Vue and Vuex. One thing I noticed is that I have repetitive code in different components. To streamline this, I decided to utilize Vuex to store my data in index.js, which has proven to be quite beneficial. No ...

The error message indicates that the Dbschema, which is a Mongoose Schema, cannot be called

I am attempting to design a basic registration form using MEAN_Stack with mongoose. Here is my models/dbSchema.js var mongoose = require('mongoose'); var Schema = mongoose.Schema; var User = new mongoose.Schema({ FirstName: String, La ...

JavaScript nested function "invalid function"

Recently, I've encountered an issue with a JavaScript file that I'm including on my page. Here's a summary of the situation: var PageTransitions = (function() { function setCurrent(currentSet) { alert(currentSet); } fu ...

The function Firebase.database() is unavailable in the Sails Service

I have developed a service named Firebase.js, and I am attempting to utilize it from my Controllers by using Firebase.database. However, I am encountering an error stating that Firebase.database() is not a function services/Firebase.js var admin = requir ...

ngRepeat momentarily displays duplicate items in the list

There is a modal that appears when a button is clicked. Inside the modal, there is a list of items that is populated by data from a GET request response stored in the controller. The issue arises when the modal is opened multiple times, causing the list t ...

The scrolling speed of the mousewheel in Firefox is notably slower compared to that of Google Chrome

Kindly review this sample link: When I test the above example in Chrome and scroll using the mouse wheel, the page moves up by 100px each time. The Y position is displayed as well. However, if I try the same page in Firefox 26.0 and scroll with the mouse ...

Is there a way to create a JavaScript-driven search filter that updates automatically?

My website showcases a lineup of League of Legends champion icons, with one example shown below: <div class = "champion"> <p>Aatrox <img class = "face_left" src = "images/small/Aatrox.png"> <div class = "name" onmouseover="if(cha ...

What is the best way to convert a string to an integer in JavaScript while still maintaining compatibility with Internet Explorer 11?

Here is the code snippet that I am working with: setCol (param) { // missing forEach on NodeList for IE11 if (window.NodeList && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } const a ...

Button component in React JS fails to appear on iPhones

After building a website using reactjs, I encountered an issue where the landing page's begin button is not displaying correctly on iPhones. The website works fine on all other devices, but on iPhones, the button is barely visible - with only a faint ...

What are some methods for resolving the problem of CORS policy blocking access to retrieve data from Yahoo Finance?

Currently, I am attempting to retrieve the price of a stock within my pure React App by utilizing fetch. When I try to fetch without any options or configurations, using fetch(url), I encounter the following error: Access to fetch at 'https://quer ...

Sending a batch of items through an ajax request

I am faced with a challenge where I have a collection of data stored within multiple objects. Within each object, there is an ID and a status, while the main object contains a type and form id. The issue arises when trying to post the result via ajax as ...

Display a text box upon clicking an item

I've been curious about how to create the effect of a text box or div that appears when clicked on, similar to what you see in this. Scroll down and click on "show patchnotes"; I've been puzzled by this for a while but haven't come across a ...

How can you ensure seamless synchronization while logging in a user with ReactJS and retrieving data from the API?

Is there a way to synchronize and run these two functions in succession before calling console.log(user) and setLogin()? The goal is to ensure that all the information retrieved from the API is available in the user context before activating the setLogin() ...

Can you increase all px measurements in Notepad++ by a factor of X?

Looking for help with a large HTML image map that contains over 3000 lines of images with specific top/left pixel positions. I'd like to replace these images with larger ones, which would require increasing all the pixel references by a certain amount ...

Repeatedly triggering the Jquery Dialog Event

When I open a calendar plugin in jquery dialog, I encounter a recurring issue. Every time I close and reopen the dialog, my calendar event onDayClick triggers multiple times – twice, thrice, and so on. <div id="show_calendar"> <div class="c ...

I have the ability to utilize local storage within NextJS with the integration of redux-thunk

Issue with using local Storage in file Store.js An error occurred during page generation. Any console logs will be displayed in the terminal window. In Store.js import { createStore, combineReducers, applyMiddleware } from "redux"; import thunk from " ...

Having trouble with Angular's ui-router resolve feature not functioning as expected

I need to implement a get service JSON function in the main state resolve function so that I can save the data to a scope variable. The account JSON information is crucial because all subordinate pages rely on this data. -- Although the code below is pa ...