MEAN Stack : Real-time polls application II
Angular uses partial HTML templates to render data from the controllers. It allows us to use placeholders and expressions to include data and perform operations such as conditionals and iterators. We will create three partials for our app in public/partials/. The first partial (list.html) will display the list of polls available, and we will use Angular to filter this list by a search field.
<div class="page-header"> <h1>Poll List</h1> </div> <div class="row"> <div class="col-xs-5"> <a href="#/new" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> New Poll</a> </div> <div class="col-xs-7"> <input type="text" class="form-control" ng-model="query" placeholder="Search for a poll"> </div> </div> <div class="row"><div class="col-xs-12"> <hr></div></div> <div class="row" ng-switch on="polls.length"> <ul ng-switch-when="0"> <li><em>No polls in database. Would you like to <a href="#/new">create one</a>?</li> </ul> <ul ng-switch-default> <li ng-repeat="poll in polls | filter:query"> <a href="#/poll/{{poll._id}}">{{poll.question}}</a> </li> </ul> </div> <p> </p>
We also want to provide poll view to the user. This second partial (item.html) uses the Angular switch directive to determine whether the user has voted. Based on the result, it will display either a form to vote on the poll, or a chart with the poll results.
<div class="page-header"> <h1>View Poll</h1> </div> <div class="well well-lg"> <strong>Question</strong><br>{{poll.question}} </div> <div ng-hide="poll.userVoted"> <p class="lead">Please select one of the following options.</p> <form role="form" ng-submit="vote()"> <div ng-repeat="choice in poll.choices" class="radio"> <label> <input type="radio" name="choice" ng-model="poll.userVote" value="{{choice._id}}"> {{choice.text}} </label> </div> <p><hr></p> <div class="row"> <div class="col-xs-6"> <a href="#/polls" class="btn btn-default" role="button"><span class="glyphicon glyphicon-arrow-left"></span> Back to Poll </div> <div class="col-xs-6"> <button class="btn btn-primary pull-right" type="submit"> Vote »</button> </div> </div> </form> </div> <div ng-show="poll.userVoted"> <table class="result-table"> <tbody> <tr ng-repeat="choice in poll.choices"> <td>{{choice.text}}</td> <td> <table style="width: {{choice.votes.length /poll.totalVotes*100}}%;"> <tr><td>{{choice.votes.length}}</td></tr> </table> </td> </tr> </tbody> </table> <p><em>{{poll.totalVotes}} votes counted so far. <span ng-show="poll.userChoice">You voted for <strong>{{poll.userChoice.text}} </strong>.</span></em></p> <p><hr></p> <p><a href="#/polls" class="btn btn-default" role="button"> <span class="glyphicon glyphicon-arrow-left"></span> Back to Poll List</a></p> </div> <p> </p>
The third partial (new.html) has the form which allows the user to create new polls. The user will be asked to enter a question and three choices. A button is provided to allow additional choices to be added.
<div class="page-header"> <h1>Create New Poll</h1> </div> <form role="form" ng-submit="createPoll()"> <div class="form-group"> <label for="pollQuestion">Question</label> <input type="text" ng-model="poll.question" class="form-control" id="pollQuestion" placeholder="Enter poll question"> </div> <div class="form-group"> <label>Choices</label> <div ng-repeat="choice in poll.choices"> <input type="text" ng-model="choice.text" class="form-control" placeholder="Enter choice {{$index+1}} text"><br> </div> </div> <div class="row"> <div class="col-xs-12"> <button type="button" class="btn btn-default" ng-click= "addChoice()"><span class="glyphicon glyphicon-plus"> </span> Add another</button> </div> </div> <p><hr></p> <div class="row"> <div class="col-xs-6"> <a href="#/polls" class="btn btn-default" role="button"> <span class="glyphicon glyphicon-arrow-left"></span> Back to Poll List</a> </div> <div class="col-xs-6"> <button class="btn btn-primary pull-right" type="submit"> Create Poll »</button> </div> </div> <p> </p> </form>
The last thing is to display the results. We want to add a few CSS declarations to our public/stylesheets/style.css file:
body { padding-top: 50px; font: 24px "Lucida Grande", Helvetica, Arial, sans-serif; } .result-table { margin: 20px 0; width: 100%; border-collapse: collapse; } .result-table td { padding: 8px; } .result-table > tbody > tr > td:first-child { width: 25%; max-width: 300px; text-align: right; } .result-table td table { background-color: lightblue; text-align: right; }
Node.JS
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization