I have a large json file almost 5 MB in size with the following array format.
There are about 3000 records.
I am using microsoft mvc 4 and angular + ngTable to display this data in the front end. It needs to be searchable and sortable on all columns.
The server side code does not take any arguments and returns all 3000 records in the format below.
{
"MR": "Inact",
"EncType": null,
"ClientAlias": 111020.0,
"OrgName": "Zic",
"CharacterAlias": null,
"Account#": 30645147.0,
"MRN": null,
"PlanCode": null,
"Address": "PO Box 123456",
"City": "Richmond ",
"St": "VA",
"ZIP": 23298.0,
"ContactName": "Jonny J",
"Fax": "(111) 111-1111",
"PHONE": "pager 111-1111",
"CriticalValueNotification": null,
"ClientPracticeTesting": null,
"Doctor": "John Smith",
"BeginDate": 36395.0,
"medBeginDate": null
}
The javascript file (app.js) contains the following code.
I have a separate files for the views as shown in the angular code below.
For ease of understanding the question, I have put everything in one snippet below.
var flexTable = angular.module("flexTable", ["ngRoute", "ngTable", "ngResource"]);
flexTable.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/about', {
templateUrl: '../../about.html',
controller: 'tableController'
})
.when('/contact', {
templateUrl: '../../contact.html',
controller: 'tableController'
})
.when('/', {
templateUrl: '../../table.html',
controller: 'tableController'
})
.when('/table', {
templateUrl: '../../table.html',
controller: 'tableController'
})
.otherwise({
redirectTo: '/table'
});
}]);
flexTable.controller('tableController',['$scope', '$resource' ,'ngTableParams', function ($scope, $resource,ngTableParams) {
var data = '';
var api = $resource("/Home/GetData")
$scope.tableParams = new ngTableParams({}, {
getData: function (params) {
var varApiGet = api.get(params.url()).$promise.then(function (data) {
params.total(data.inlineCount);
return data.results;
});
return varApiGet;
}
});
}]);
The html page looks as follows
<%# Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html>
<html>
<head runat="server">
<meta name="viewport" content="width=device-width" />
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link href="../../Assets/css/justified-nav.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link href="../../Assets/css/ng-table.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-sanitize.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-resource.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-route.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-animate.js"></script>
<script src="../../Assets/js/lib/ng-table.min.js"></script>
<script src="../../Assets/js/app.js"></script>
</head>
<body>
<div class="container" >
<!-- The justified navigation menu is meant for single line per list item.
Multiple lines will require custom code not provided by Bootstrap. -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>Default</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="jumbotron">
<h1>Instructions stuff!</h1>
<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh,
ut fermentum massa justo sit amet.</p>
<!--<p><a class="btn btn-lg btn-success" href="#" role="button">Get started today</a></p>-->
</div>
<div class="container" ng-controller="tableController">
<div ng-view>
<div class="row">
<table ng-table="tableParams" class="table">
<tr ng-repeat="row in $data track by $index">
<td title="'EncType'">
{{row.EncType}}
</td>
<td title="'ClientAlias'">
{{row.ClientAlias}}
</td>
<td title="'OrgName'">
{{row.OrgName}}
</td>
<td title="'CharacterAlias'">
{{row.CharacterAlias}}
</td>
<td title="'AddressCity'">
{{row.AddressCity}}
</td>
<td title="'St'">
{{row.St}}
</td>
<td title="'ZIP'">
{{row.ZIP}}
</td>
<td title="'ContactName'">
{{row.ContactName}}
</td>
<td title="'Fax'">
{{row.Fax}}
</td>
<td title="'PHONE'">
{{row.PHONE}}
</td>
<td title="'CriticalValueNotification'">
{{row.CriticalValueNotification}}
</td>
<td title="'Doctor'">
{{row.Doctor}}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<footer class="footer">
<p>© 2015 Company, Inc.</p>
</footer>
</div><!--container-->
</body>
</html>
When I have the data hardcoded in the javascript controller function, the table displays fine without the search and sort functionality. When I have the data come in through the ajax call as shown in the code, it displays no data. only the table heading.
I can answer any questions that anyone has about this.
Thanks,
Paras
Any help appreciated.
EDIT
Here is the controller code that worked for me. I also added some extra code for the sorting and the filters.
flexTable.controller('tableController', ['$scope', '$http', 'ngTableParams', '$filter', '$log'
, function ($scope, $http, ngTableParams, $filter, $log) { //
$http.get('/Home/GetData')
.success(function (data, status) {
$scope.data = data;
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
OrganizationName: 'asc' // initial sorting
}
}
, {
total: $scope.data.length, // length of data
getData: function ($defer, params) {
// use build-in angular filter
var filterData = params.filter() ?
$filter('filter')($scope.data, params.filter()) :
$scope.data;
var orderedData = params.sorting() ?
$filter('orderBy')(filterData, params.orderBy()) :
filterData;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
}
);
});
}]);
You could use $http instead of $resource. Your response data will be in the data property of your response. Try the following:
$scope.tableParams = new ngTableParams({}, {
getData: function(params) {
var varApiGet = $http.get(params.url()).then(function(response) {
var data = response.data;
params.total(data.inlineCount);
return data.results;
});
return varApiGet;
}
});
Edit
Here is a working fiddle. I simulated the response as an array with one entry (the one you posted in the question). Make sure that your response data is in the correct format.
Related
I want to display content beneath a table, from a JSON file, relative to to item the user clicked on in the table
Example:
JSON file
{
"patentInfo": [
{
"name": "item1",
"cost": "$33",
"date": "13/06",
},
{
"name": "item2",
"cost": "$29",
"date": "02/02",
}
]
}
View - table
click on item 1 > DISPLAY price:$33, date:13/06
click on item 2 > DISPLAY price:$29, date:02/02
I asked this question last week but didn't get a response as I don't think I made it too clear. I'm using ui-view to display content, and it is the state patents.list.item URL that needs to be relative, dependent on what the user clicked on. Any ideas on how to achieve this?
var app = angular.module('myApp', ['ngRoute', 'angularMoment', 'ui.router', "chart.js"]);
app.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', function($stateProvider, $locationProvider, $urlRouterProvider ) {
$urlRouterProvider
.when('', '/patents/list-patents')
.when('/', '/patents/list-patents')
.when('/patents', '/patents/list-patents')
.when('/transactions', '/transactions/current-transactions')
.otherwise('/patents/list-patents');
$stateProvider
.state("patents", {
url: "/patents",
templateUrl: "templates/patents/patent-nav.htm",
controller: "patentCtrl"
})
.state("patents.list", {
url: "/list-patents",
templateUrl: "templates/patents/list/list-patents.htm",
controller: "patentCtrl"
})
.state("patents.list.item", {
url: "/patent-item",
templateUrl: "templates/patents/list/patent-item.htm",
controller: "patentCtrl"
})
Controller
app.controller('patentCtrl', ['$scope', '$http', 'patentTabFactory', 'loadPatents', '$stateParams', 'patentService', function($scope, $http, patentTabFactory, loadPatents, $stateParams, patentService) {
patentService.items.then(function (patents) {
$scope.items = patents.data;
console.log($scope.patents);
$scope.patents = patents.data[patentService.getPatentItem($scope.items, "aid", $stateParams.id)];
});
$scope.patent={id:null,applicationNumber:'',clientRef:'',costRenew:'',renewalDate:'',basketStatus:'', costEnd: '', nextStage:''};
$scope.patents=[];
$scope.submit = $scope.submit;
$scope.remove = $scope.remove;
$scope.fetchAllPatents = function(){
loadPatents.fetchAllPatents()
.then(
function(d) {
$scope.patents = d;
},
function(errResponse){
console.error('Error while fetching Users');
}
);
}
$scope.fetchAllPatents();
$scope.deletePatent = function(id){
loadPatents.deletePatent(id)
.then(
$scope.fetchAllPatents,
function(errResponse){
console.error('Error while deleting Patent');
}
);
}
$scope.submit = function() {
if($scope.patent.id===null){
console.log('Saving New User', $scope.patent);
loadPatents.createPatent($scope.patent);
}
console.log('User updated with id ', $scope.patent.id);
}
$scope.remove = function(id){
console.log('id to be deleted', id);
if($scope.patent.id === id) {//clean form if the patent to be deleted is shown there.
reset();
}
$scope.deletePatent(id);
}
$scope.tabs = patentTabFactory.tabs;
$scope.currentTab = patentTabFactory.currentTab;
// $scope.isActiveTab = patentTabFactory.isActiveTab();
$scope.onClickTab = function(currentTab) {
patentTabFactory.onClickTab(currentTab);
$scope.currentTab = patentTabFactory.currentTab;
};
$scope.isActiveTab = function(tabUrl) {
return tabUrl == patentTabFactory.currentTab;
}
}]);
list-patents view
<div class="row">
<div class="col-md-12">
<table class="table table-bordered table-striped text-md-center">
<thead class="thead-inverse">
<tr>
<td ng-click="patentAppOrder()" class="align-middle">Application No. </td>
<td class="align-middle">Client Ref</td>
<td class="align-middle">Cost to renew</td>
<td class="align-middle">Basket</td>
<td class="align-middle">Remove</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in patents">
<td><a ui-sref="patents.list.item">{{x.applicationNumber}}</a></td>
<td ng-bind="x.clientRef"></td>
<td ng-bind="x.costToRenew">$</td>
<td ng-bind="x.renewalDueDate"></td>
<td><button type="button" class="btn btn-danger" ng-click="remove(x.id)">Remove</button></td>
</tr>
</tbody>
</table>
<div ui-view></div>
</div>
</div>
<div ui-view></div>
patent item view
<div id="tabs">
<ul>
<li ng-repeat="tab in tabs"
ng-class="{active:isActiveTab(tab.url)}"
ng-click="onClickTab(tab)">{{tab.title}}</li> <!--applies active to the returned tab url -->
</ul>
<div id="mainView">
<div class="row">
<div ng-include="currentTab"></div>
</div>
</div>
</div>
<script type="text/ng-template" id="patent-info.htm">
<div class="col-md-6 text-xs-center">
<h2>Application Number</h2>
<table class="table table-striped">
<tbody>
<table>
<tr ng-repeat="(x, y) in patents">
<td ng-repeat="x.id in patents"></td>
<td>{{y.applicationNumber}}</td>
</tr>
</table>
</tbody>
</table>
</div>
<div class="col-md-6 text-xs-center">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
</p>
</div>
</script>
<script type="text/ng-template" id="cost-analysis.htm">
<div class="col-md-6 text-xs-center" ng-controller="LineCtrl">
<h2>Cost Analysis</h2>
<canvas class="chart chart-line" chart-data="data" chart-labels="labels"
chart-series="series" chart-click="onClick"></canvas>
</div>
</script>
<script type="text/ng-template" id="renewal-history.htm">
<div class="col-md-6 text-xs-center">
<h2>Renewal History</h2>
<p>In pellentesque faucibus vestibulum. Nulla at nulla justo, eget luctus tortor..</p>
</div>
</script>
What you have to do first is to add a dynamic URL parameter to the route which is supposed to display information about a selected patent and give it another controller.
.state("patents.list.item", {
url: "/patent-item/:name",
templateUrl: "templates/patents/list/patent-item.htm",
controller: "patentDetailsCtrl"
})
Then when you are navigating to that patent, you have to include the name (assuming that is a unique identifier) in the link.
<td><a ui-sref="patents.list.item({ name: x.name })">{{x.applicationNumber}}</a></td>
After that in your patentDetailsCtrl, you can fetch information about the patent from the JSON file and display it.
Alternative Solutions
Another solution would be handle it in your patentCtrl without an additional (patents.list.item) route. But I would not recommend that approach.
You could also use components if you are using AngularJS v1.5+. To learn more about components, see the official documentation.
I have two controllers headerController, aboutController.
headerController -> To maintain the navigation and redirection
aboutController -> works when about-us page loads.
My issue is I have to update the headerController variable value when aboutController loads. i.e When about us page loads, the navigation about-us should active, similar to all the pages.
This is my code:
app.service('shareService', function () {
var data;
return {
getProperty: function () {
return data;
},
setProperty: function (value) {
data = value;
}
};
});
app.controller('headerController', function ($scope, shareService) {
$scope.navigation = [
{url: '#!/home', name: 'Home'},
{url: '#!/about-us', name: 'About Us'},
{url: '#!/services', name: 'Services'}
];
var data = shareService.getProperty();
console.log(data);
$scope.selectedIndex = 0;
$scope.itemClicked = function ($index) {
console.log($index);
$scope.selectedIndex = $index;
};
});
app.controller('aboutController', function ($scope, shareService) {
console.log('test');
$scope.selectedIndex = 1;
shareService.setProperty({navigation: $scope.selectedIndex});
});
header.html:
<header ng-controller="headerController">
<div class="header">
<div class="first-half col-md-6">
<div class="row">
<div class="logo">
<img src="assets/img/logo.png" alt=""/>
</div>
</div>
</div>
<div class="second-half col-md-6">
<div class="row">
<div class="social-share">
<ul id="social-share-header">
<li><i class="fa fa-facebook" aria-hidden="true"></i></li>
<li><i class="fa fa-twitter" aria-hidden="true"></i></li>
<li><i class="fa fa-google-plus" aria-hidden="true"></i></li>
</ul>
</div>
</div>
</div>
<nav>
<ul ng-repeat="nav in navigation">
<li class="main-nav" ng-class="{ 'active': $index == selectedIndex }"
ng-click="itemClicked($index)">
{{nav.name}}
</li>
</ul>
</nav>
</div>
</header>
index.html
This is how my template works.
<body ng-app="myApp">
<section class="first-section">
<div ng-include="'views/header.html'"></div>
</section>
<section class="second-section">
<div ng-view></div>
</section>
<section class="last-section">
<div ng-include="'views/footer.html'"></div>
</section>
</body>
Update 1: Added index.html file.
Update 2: Issue explanation: If I run directly to the about us page, then still the home navigation is on active. But it should be About us
What is you are looking for is event based communication between your controllers. This can be easily done using. $rootScope.$on, $rootScope.$emit and $rootScope.$broadcast. Since explaining all three of them in this answer will be overkill. Kindly go through this article
I'm trying to show and hide a div using ng-show. It's a navbar that I want to show only in some views.
I have a controller which "controls" that div. And in other controller I want to edit this ng-show value in order to hide or show the div (navbar).
I tried different things as using a $rootScope, a timeout, an $apply, a factory... but nothing works.
So I'm asking here if anyone could help me.
(Sorry for my English)
This is my html and js codes (last edit code)
<div id="main">
<!-- Aquí inyectamos las vistas -->
<div ng-controller="appCtrl" ng-show="isLogged" class="navbar navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
<a class="navbar-brand" href="#/">Aula Virtual</a> </div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav" style="text-align: right">
<li class="active">Home</li>
<li>Users</li>
<li>Operaciones</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</div>
<div class="connect">
<div class="container">
<p>
Aula Virtual para profesorado y alumnos de la universidad
</p>
</div>
</div>
</div>
<div ui-view></div>
</div>
I tried a (ng-show="isLogged==false") too.
The controller of the div:
.controller('appCtrl', function($scope, $rootScope) {
console.log($scope.isLogged); //---> this shows undefined
});
The controller where I want to edit the isLogged value:
cities2.controller('userCtrl',['rootScope', '$scope', '$state','$http','md5', function($rootScope, $scope, $state, $http, md5) {
$rootScope.$apply(function(){
$rootScope.isLogged = true;
});
Thanks for the help!
It's good practice to use services to share data between controllers.
cities2.controller('appCtrl', ['$scope', 'LoggedStatus', function($scope,LoggedStatus) {
$scope.LoggedStatus = LoggedStatus;
}]);
cities2.controller('userCtrl', ['$scope', 'LoggedStatus', function($scope,LoggedStatus) {
$scope.LoggedStatus = LoggedStatus;
}]);
cities2.service('LoggedStatus', function() {
return {
isLogged: false
}
});
Changing the value of $scope.LoggedStatus.isLogged in either controller will change the value in both.
In your appCtrl controller, do $scope.isLogged=0. If you change this value to 1, the block will be visible else it will be hidden.
app.controller('appCtrl', function($scope) {
$scope.isLogged=0;
})
Refer to the plunker below:
https://plnkr.co/edit/d3q3QwA9k5f6ewXbqZ3M?p=preview
Well, finally I found the solution. I put this if can help someone:
I put a .run in the appCtrl where I initialize the ng-show:
.run(function ($rootScope) {
$rootScope.isLogged = false;
});
and now, when I put a true value in the other controller it works, and the navbar appears.
cities2.controller('userCtrl',['$rootScope', '$scope', '$state','$http','md5','$sessionStorage', function($rootScope, $scope, $state, $http, md5, $sessionStorage) {
$rootScope.isLogged=true;
}]);
I am new to AngularJs, i have seen enough posts for a similar question but haven't found solution for my problem. I am using Angular 1.4.5
app.js (Omitted additional code like Routes and interceptors):
'use strict';
var app = angular.module('app', ['ngRoute', 'authControllers', 'authServices']);
var authControllers = angular.module('authControllers', []);
var authServices = angular.module('authServices', []);
authControllers.js:
authControllers.controller('authCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($scope, $location, $window, UserService, AuthenticationService) {
//Admin User Controller (login, logout)
$scope.logIn = function logIn(username, password) {
if (username !== undefined && password !== undefined) {
UserService.logIn(username, password).success(function(data) {
AuthenticationService.isLogged = true;
$window.sessionStorage.token = data.token;
$location.path("/");
}).error(function(status, data) {
console.log(status);
console.log(data);
});
}
}
$scope.logout = function logout() {
if (AuthenticationService.isLogged) {
AuthenticationService.isLogged = false;
delete $window.sessionStorage.token;
$location.path("/");
}
}
}
]);
authServices.js:
authServices.factory('AuthenticationService',function() {
var auth = {
isLogged: false
}
return auth;
});
Index.html:
<body ng-app="app">
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation" data-ng-controller="authCtrl">
<!-- data-ng-controller="authCtrl" -->
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Angular Restful Auth</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a ng-href="#/">Home</a></li>
<li data-ng-show="token"><a ng-href="#/me">Me</a></li>
<li data-ng-hide="token"><a ng-href="#/signin">Signin</a></li>
<li data-ng-hide="token"><a ng-href="#/signup">Signup</a></li>
<li data-ng-show="token"><a ng-click="logout()">Logout</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container" ng-view="">
</div> <!-- /container -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.1/angular-route.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="/js/app.js"></script>
<script src="/js/authentication/authControllers.js"></script>
<script src="/js/authentication/authServices.js"></script>
</body>
Getting
Uncaught Error: [$injector:unpr]
http://errors.angularjs.org/1.4.5/$injector/unpr?p0=AuthenticationServiceProvider%20%3C-%20AuthenticationService
Please let me know what's the mistake i am doing.
Noting down answer as discussed in comments:
The problem was not including the modular js files in index.html
Example:
<script src="/js/authControllers.js"></script>
<script src="/js/authServices.js"></script>
I am building an email app. It consists of an option to change the default settings. When it is clicked, the following partial view is loaded.
In this view, when the Save changes button is clicked, the values chosen by the user are saved in $localStorage using ngStorage like so:
savePreferenceService.js
(function() {
'use strict';
var savePreferenceService = function ($localStorage) {
this.setPreferences = function (selectedLang, converse, selectedNumber, selectedNumberContact, reply, signature) {
$localStorage.selectedLang = selectedLang;
$localStorage.converse = converse;
$localStorage.selectedNumber = selectedNumber;
$localStorage.selectedNumberContact = selectedNumberContact;
$localStorage.reply = reply;
$localStorage.signature = signature;
console.log($localStorage.selectedLang);
console.log($localStorage.converse);
console.log($localStorage.selectedNumber);
console.log($localStorage.selectedNumberContact);
console.log($localStorage.reply);
console.log($localStorage.signature);
}
};
angular.module('iisEmail')
.service ('savePreferenceService', ['$localStorage', savePreferenceService]);
}());
I have the following questions:
1) Is there a way to store values entered by the user (e.g. selectedLang, converse, selectedNumber) in a JSON file. I have no database.
2) If the user only changes a few preferences (e.g. language preference and number of conversations per page preference), all other preferences (e.g. number of contacts per page and reply) return a value of undefined. Is there a way to return the default values for the preferences that were not changed by the user?. Here is the JSON file that contains the dropdown menu options (e.g. data.languages contains all the languages the user can choose from) and default preferences, data.userPreferences.
settings.json
{
"data": {
"languages": [
"Afrikaans",
"Albanian",
"Arabic",
"Armenian",
"Basque",
"Bengali",
"Catalan",
"Cambodian",
"Chinese (Mandarin)",
"German",
"Greek",
"Gujarati",
"Hebrew",
"Icelandic",
"Maori",
"Marathi",
"Mongolian",
"Serbian",
"Slovak",
"Slovenian",
"Spanish",
"Swahili",
"Swedish",
"Tamil",
"Tatar",
"Telugu"
],
"undoSend": [
5,
10,
20,
30
],
"conversations": [
10,
20,
30,
40,
50,
60,
70,
80,
90,
100
],
"contacts": [
20,
40,
60,
80,
100,
120,
130,
140,
180,
200
],
"userPreferences": {
"selectedLang": "Telugu",
"converse": false,
"selectedNumber": 10,
"selectedNumberContact": 20,
"reply": false,
"signature": "--"
}
}
}
3) My final goal - In the settings page, if the user selects 20 conversations per page, then the next time Inbox is clicked I want to show only 20 emails. Right now, 50 emails are being displayed like so (top-right - It says 1-50 of 277):
Does anyone have ideas regarding these questions?
UPDATE - Question 1
Looks like there is no way to store user entered data in a JSON file, so I am using localStorage to save it on the client-side.
UPDATE - Question 3
Here is a solution for question 3. I bound $scope.conversation property to conversation in the view. The value of $scope.conversation is set to the number selected by the user. This number is saved in localStorage.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Gmail App</title>
<style>
body {
margin: 10px;
padding: 50px;
}
</style>
<link rel="stylesheet" href="Content/css/bootstrap.min.css">
<link rel="stylesheet" href="Content/css/bootstrap-theme.min.css">
<script src="Vendor/jquery-1.11.3.min.js"></script>
<script src="Vendor/bootstrap.min.js"></script>
<script src="Vendor/angular.min.js"></script>
<script src="Vendor/angular-ui-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.6/ngStorage.min.js"></script>
</head>
<body data-ng-app="iisEmail">
<div class="container" data-ng-controller="mainController">
<div class="row">
<div class="col-sm-3 col-md-2">
<div class="btn-group">
<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">
Email <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Mail</li>
<li>Contacts</li>
<li data-ng-click="loadView('settings')">Settings</li>
</ul>
</div>
</div>
<div class="col-sm-9 col-md-10">
<!-- split button -->
<div class="btn-group">
<button type="button" class="btn btn-default">
<div class="checkbox" style="margin: 0;">
<label>
<input type="checkbox"
data-ng-click="selectAllEmail()"
data-ng-model="checkAllEmail">
</label>
</div>
</button>
</div>
<button type="button" class="btn btn-default" data-toggle="tooltip" title="Refresh">
   <span class="glyphicon glyphicon-refresh"></span>  Â
</button>
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
More <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Mark all as read</li>
<li class="divider"></li>
<li class="text-center"><small class="text-muted">Select messages to see more actions</small></li>
</ul>
</div>
<div class="pull-right" data-ng-controller = "settingsController">
<span class="text-muted"><b>1</b>–<b data-ng-bind = "conversation" data-ng-cloak>{{conversation}}</b> of <b>277</b></span>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-chevron-left"></span>
</button>
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-3 col-md-2">
COMPOSE
<hr/>
<ul class="nav nav-pills nav-stacked">
<li class="" data-ng-repeat="item in leftMenu">
<span class="badge pull-right"> {{item.emailCount}}</span> {{item.name}}
</li>
<!--<li>Starred</li>
<li>Important</li>
<li>Sent Mail</li>
<li>-->
</ul>
</div>
<div class="col-sm-9 col-md-10">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active"><a href="#home" data-toggle="tab"><span class="glyphicon glyphicon-inbox">
</span>Primary</a></li>
<li><a href="#profile" data-toggle="tab"><span class="glyphicon glyphicon-user"></span>
Social</a></li>
<li><a href="#messages" data-toggle="tab"><span class="glyphicon glyphicon-tags"></span>
Promotions</a></li>
<li><a href="#settings" data-toggle="tab"><span class="glyphicon glyphicon-plus no-margin">
</span></a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div ui-view></div>
</div>
</div>
</div>
</div>
<script src="app/main.js"></script>
<!--Services-->
<script src="app/services/commonApiService.js"></script>
<script src="app/services/savePreferenceService.js"></script>
<script src="app/services/fetchDataService.js"></script>
<script src="app/controllers/mainController.js"></script>
<script src="app/controllers/settingsController.js"></script>
<script src="app/controllers/emailViewController.js"></script>
</body>
</html>
savePreferenceService.js
(function() {
'use strict';
var savePreferenceService = function ($localStorage) {
this.setPreferences = function (selectedLang, converse, selectedNumber, selectedNumberContact, reply, signature) {
$localStorage.selectedLang = selectedLang;
$localStorage.converse = converse;
$localStorage.selectedNumber = selectedNumber;
$localStorage.selectedNumberContact = selectedNumberContact;
$localStorage.reply = reply;
$localStorage.signature = signature;
};
};
angular.module('iisEmail')
.service ('savePreferenceService', ['$localStorage', savePreferenceService]);
}());
settingsController.js
(function() {
'use strict';
var settingController = function (fetchDataService, $scope, savePreferenceService, $localStorage) {
$scope.url = 'app/mock/settings.json';
$scope.save = {};
fetchDataService.getContent($scope.url)
.then(function(response){
$scope.contacts = response.data.contacts;
$scope.languages = response.data.languages;
$scope.conversations = response.data.conversations;
$scope.undoSend = response.data.undoSend;
$scope.save = response.data.userPreferences;
});
$scope.setPreference = function () {
savePreferenceService.setPreferences($scope.save.selectedLang, $scope.save.converse, $scope.save.selectedNumber, $scope.save.selectedNumberContact, $scope.save.reply, $scope.save.signature);
};
$scope.conversation = $localStorage.selectedNumber;
};
angular.module('iisEmail')
.controller ('settingsController',
['fetchDataService', '$scope', 'savePreferenceService', '$localStorage', settingController]);
}());