0

I am trying to create a multi step form in my web app for registration. I am using ui.router to achieve that.

When a user goes to my domain at first for example www.mydomain.com. My node.js server renders the index.ejs page.

app.get('/',function(req, res) {
    res.render('index.ejs'); // load the index.ejs file
});

Now the important thing to know is that index.ejs is also where I am injecting my views in ui-view:

<!doctype html>
<html ng-app="myApp">
<head>
<title>Node Authentication</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/pure/0.6.0/pure-min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.5/angular-animate.min.js"></script>
<link href="./css/side-menu.css" rel="stylesheet" type="text/css">
<script src="./js/mainApp.js"></script>
<script src="./js/controllers/knowledgeBaseCtrl.js"></script>
<script src="./js/services/knowledgeBaseFilter.js"></script>

</head>
<body ng-controller="projectsFilterCtrl">
<div class="container">
    <div>
    <h2>Our multistep form</h2>

        <div id="status-buttons" class="text-center">
            <a ui-sref-active="active" ui-sref="signup.stepOne"><span>1</span> Step One</a>
            <a ui-sref-active="active" ui-sref="signup.stepTwo"><span>1</span> Step Two</a>
            <a ui-sref-active="active" ui-sref="login"><span>2</span> login </a>
        </div>
    </div>
    // INJECT VIEW HERE
    <div ui-view></div>
   </div>

</script>
</body>
</html>

My AngularJs controller:

var knowledgeBaseCtrl = angular.module('knowledgeBaseCtrl', ['ngAnimate','ui.router'])

knowledgeBaseCtrl.config(function($stateProvider, $urlRouterProvider) {

$stateProvider

.state('login', {// this will be the wrapper for our wizard
    url: '/login',
    templateUrl: './login.ejs', 
})

.state('signup', {// this will be the wrapper for our wizard
    url: '/signup',
    templateUrl: './index.ejs',
})

.state('signup.stepOne', {// this will be the wrapper for our wizard
    url: '/stepOne',
    templateUrl: './stepOne.ejs',
})

 .state('signup.stepTwo', {// this will be the wrapper for our wizard
    url: '/stepTwo',
    templateUrl: './stepTwo.ejs',
});

  // catch all route
  // send users to the form page 
     $urlRouterProvider.otherwise('login');
});

Now the issue:

Now when I go to the www.mydomain.com/#/signup/stepOne it loads the content twice as you can see in the image below.

I think its because my node.js server loads index.ejs and then my ui.router again loads index.ejs hence duplicating the page.

The image below shouldn't show the menu and the title twice enter image description here

How can I get around this?

3 Answers 3

1

Don't put your index file in a route - anything you set as a template will be injected in full into ui-view, so you're effectively nesting a second instance of your app inside the view as it stands. Your index.ejs should only contain the content that is identical on every single part of your app.

You should create a signup.ejs template that contains just the content that should be displayed on the signup pages, with another ui-view where you want the child views to be injected.

Sign up to request clarification or add additional context in comments.

4 Comments

An example of why this is an issue - if you go to www.mydomain.com/#/signup as it stands right now, ui-view will load another copy of the app, which is also on the signup view, which mean it loads the app again, which means it loads the view again, etc. Then your browser crashes :p
@JoeClay thank you for the comment. Man this routing is confusing!! Any chance of getting a jsFiddle or a code example? it'll be much appreciated.
I'll try to write something up in my lunch break!
Here's a very basic example of how to do nested views properly: plnkr.co/edit/2DbSX56DDgNfwvgJ9i6O?p=preview. The key takeaway is that you should never have index.html in your route templates. If you have any more questions let me know.
0

Please add controller name in your routes or in your views

$routeProvider .when('/login', { controller: 'stepOneController', templateUrl: './stepOne.ejs' })

Comments

0

this looks like a problem with your router config to me ...

.state('signup', {// this will be the wrapper for our wizard
    url: '/signup',
    templateUrl: './index.ejs',
})

.state('signup.stepOne', {// this will be the wrapper for our wizard
    url: '/stepOne',
    templateUrl: './stepOne.ejs',
})

.state('signup.stepTwo', {// this will be the wrapper for our wizard
    url: '/stepTwo',
    templateUrl: './stepTwo.ejs',
});

if you make signup.stepOne and signup.stepTwo a state in their own right AND NOT child states of their parent "signup" then this will prob fix the issue.

However, if you really want to implement child states then, I believe, the parent state should be an ABSTRACT state.

.state('signup', {// this will be the wrapper for our wizard
    abstract: true
    url: '/signup', // This provides the default URL for children but it can be overriden
    templateUrl: './index.ejs', // This provides the default template for children but it can be overriden
})

hope this helps

See also Joe Clay's answer

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.