Angular controller loads but ng-repeat doesn't show - angularjs

I'm learning angularJS and I'm having an issue trying to use ng-repeat.I know that the template and controller are loading because I did a console.log(self.post) test that shows the single post that I expect from the demoSuggestions and the template loads the comCtrl.post.title that I expect. But the ng-repeat='comment in comCtrl.post.comments doesn't show anything. Any ideas as to what I'm doing wrong?
HTML
<script type='text/ng-template' id='/suggestions.html'>
<div class='row' ng-controller='commentsController as comCtrl'>
<div class='col-xs-12'>
<div class='commentTitle'>
<h3 class='text-center'>{{comCtrl.post.title}}</h3>
</div><!--End of commentTitle-->
</div><!--End of col-->
</div><!--End of row-->
<div class='row' ng-repeat='comment in comCtrl.post.comments'>
<div class='col-xs-12 col-sm-10 col-sm-offset-1'>
<div class='commentContainer'>
<div class='row'>
<div class='col-xs-3 col-sm-2 col-md-1'>
<div class='thumbsUp'>
<i class="fa fa-thumbs-up" ng-click='comCtrl.upVote($index)'></i>
<span>{{comment.upvotes}}</span>
</div><!--End of thumbsUp-->
</div><!--End of col-->
<div class='col-xs-9 col-sm-10 col-md-11'>
<div class='commentBody'>
<span>{{comment.body}}</span>
</div><!--End of commentBody-->
</div><!--End of col-->
</div><!--End of row-->
</div><!--End of commentContainer-->
</div><!--End of col-->
</div><!--End of row-->
<div class='row'>
<div class='col-xs-12'>
<form id='comment' ng-submit="addComment()" style="margin-top: 50px">
<h3> Submit Your Comment </h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Place comment here" ng-model="body"></input>
</div><!--End of form-group-->
<button type="submit" class="btn btn-danger">Suggest</button>
</form>
</div><!--End of col-->
</div><!--End of row-->
</script>
Module & config
var suggestionApp = angular.module('suggestionBox', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/home.html',
})
.when('/suggestion/:id',{
templateUrl:'/suggestions.html'
})
.otherwise({
redirectTo:'/'
});
}]);
Controller & Service
.controller('commentsController',['$routeParams','suggestions', function($routeParams, suggestions){
var self = this;
var swap = 1;
self.post = suggestions.posts[$routeParams.id];
console.log(self.post)
self.addComment = function() {
self.post.comments.push({
body:self.body,
upvotes:0
});
};
self.upVote=function(index){
if(swap)
{
self.post.comments[index].upvotes += 1;
$('.thumbsUp .fa').eq(index).css('color','red');
swap=0;
}
else
{
self.post.comments[index].upvotes -= 1;
$('.thumbsUp .fa').eq(index).css('color', 'black');
swap=1;
}
};
}])
.factory('suggestions', [function(){
var demoSuggestions = {
posts: [
{
title: 'Term limits on congress',
avatar:'https://upload.wikimedia.org/wikipedia/commons/7/7a/US_Navy_040521-N-9909C-006_Established_by_the_American_Battle_Monuments_Commission,_the_memorial_honors_all_military_veterans_of_World_War_II.jpg',
upvotes: 15,
comments: [
{body:'love the idea',upvotes:0},
{body:'let\'s make this happen', upvotes:0},
]
},
{
title: 'Every two years a popular vote on two issues that passes into law without Congress.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/3/3e/The_Marine_Corps_War_Memorial_in_Arlington,_Va.,_can_be_seen_prior_to_the_Sunset_Parade_June_4,_2013_130604-M-MM982-036.jpg',
upvotes: 9,
comments: [
{body:'Only if the judicial branch still rules on its constitutionality.', upvotes:0},
{body:'Do you really think people would come out to vote?', upvotes:0},
{body:'I\'d be down for this',upvotes:0}
]
},
{
title: 'Create a biometric scanner for all those entering the country.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/e/ea/Washington_Monument_-_01.jpg',
upvotes: 7,
comments:[
{body:'Seriously, not cost effective', upvotes:0},
],
},
{
title: 'Become more isolationist and bring our troops back home.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/3/3b/Bunker_hill_2009.JPG',
upvotes: 3,
comments: [
{body:'sounds a little grim',upvotes:0}
],
}
]
};
return demoSuggestions;
}]);

If you look at the first two divs with the class row, you will notice, that the first div has a ng-controller attached (and displaying your title) and the second one has no controller attached (and displays nothing).
As your ng-repeat is not a child-element of your row with the controller, you cannot use your controller there. You could solve that if you move the ng-controller up one element so it will be on the parent of all your rows.

Related

Angularjs passing id into modal function()

I am using angularjs and spring mvc for my application. At first I am displaying all the placements with one button Placed Candidates. I am doing ng-repeat for displaying all the placements.
Here is my html.
<div class="row" data-ng-repeat="placement in placements">
<div class="col-xs-12 col-sm-12 col-md-12">
<h5>{{placement.companyName}}</h5>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<h6>{{placement.placementDate | date:'dd MMM yyyy'}}</h6>
Company Target (appox):10 Achieved:
</div>
<a href="javascript:void(0);" data-ng-
click="placedcandidatespopup(placement.placementId);">//here i can
get particular placementId but how to pass this id to
savePlacementStudents() method in controller.js???//
PlacedCandidates
</a>
</div>
I am calling one modal popup function. Here is controller.js
$scope.placedcandidatespopup = function()
{
AdminUsersService.getAllUsers().then(function(response)
{
$scope.allusers=response.data;
console.log($scope.allusers);
})
$(".placedcandidates").modal("show");
}
I am calling modal by name "placedcandidates".
Here is the modal
<div class="modal right fade placedcandidates" id="myModal1"
tabindex="-1" role="dialog" aria-labelledby="myModalLabel2">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6" data-ng-
repeat="student in allusers">
<input id="{{student.studentId}}" type="checkbox" value="
{{student.studentId}}" data-ng-
checked="selection.indexOf(student.studentId) >-1"
data-ng-click="toggleSelection(student.studentId)"/>
<label for="{{student.studentId}}"></label>
{{student.firstName}}
</div>
</div>
</div>
<div class="modal-footer" style="position: fixed;">
<input type="button" value="Submit" class="btn" data-ng-
click="savePlacementStudents()">
</div>
</div>
</div>
</div>
After clicking on button popup modal will display with all Students with checkboxes placed beside them.Now I am able to save studentId into database.But I am not able to pass placementId for saving.
Here is my savePlacementStudents method in controller.js.
$scope.selectedStudents = {};
$scope.savePlacementStudents = function(selectedStudents)
{
selectedStudents.selectedList = $scope.selection;
AdminPlacementService.savePlacementStudents(selectedStudents).then
(function(response)
{
if(response.data=="success"){
$window.scrollTo(0,0);
$scope.selectedStudents = {};
$scope.getplacementdetails($scope.currentPageIndex);
$scope.successmessage="Student Selection Saved!;
$timeout(function() {
$scope.successmessage="";
$scope.closeplacedcandidatespopup();
}, 1500);
}
});
}
Can anyone tell how can I pass respective placementId to this saveStudents method() so that I can set that placementId for those students selected.
Here is the solution.
The placementId passed to function placedcandidatespopup can be saved as follows in function placedcandidatespopup
$scope.selectedPlacementId = placementId;
Now the same $scope will have access in Popup also as it is using same controller.js. And now you can use this $scope.selectedPlacementId anywhere in controller.js
So you don't need to pass placementId...!!
Hope that would help you..!!
$scope.placedcandidatespopup = function(id)
{
AdminUsersService.getAllUsers().then(function(response)
{
$scope.allusers=response.data;
console.log($scope.allusers);
})
$scope.inserted = {
placementId:id,
};
var modalInstance = $uibModal.open({
templateUrl: 'views/test/myModal1.html',
controller: 'TestCntrl',
size: "Modelwidth",
resolve: {
items: function () {
return $scope.inserted;
}
}
});
}
In model you have to access using items.placementId and when you savePlacementStudents() method send placementId as well with student info.

Angular Two-Way data-binding not refreshing ng-repeat on $scope change

My functionality is very simple, and I have to imagine very common. I have a page that lists a collection of 'age groups', and provides functionality to add an 'age group'. I simply would like to have the page immediately reflect the change when a new 'age group' is added.
In early versions, I had simply used the $rootScope in my service to put all 'age groups' in the $rootScope when the $http request was completed. On this latest refactoring I am removing all use of $rootScope in my app, and it is becoming problematic.
The code for the HTML view is as follows: [NOTE: all code considered extraneous has been removed from all code snippets]
<div id="tabContent" class="tab-pane fade in active" ng-show="subIsSelected(1)">
<div class="row">
<div class="col-xs-12">
<form class="form-inline">
<button type="button" class="btn btn-success" ng-click="openAddAgeGroup()">Add Age Group</button>
</form>
</div>
</div>
<hr />
<div class="row row-content">
<div class="col-xs-12">
<h4 ng-show="!areAgeGroups()">No current age groups.</h4>
<ul class="media-list" ng-show="areAgeGroups()">
<li class="media" ng-repeat="ageGroup in ageGroups" style="padding:10px; background: lightGray;">
<div class="media-left media-top" >
<img class="media-object img-thumbnail" style="width: 75px;" ng-src="./images/trfc.png" alt="club logo">
</div>
<div class="media-body">
<h3 class="media-heading" style="padding-top: 20px;">{{ageGroup.name}}</h3>
<button type="button" class="btn btn-xs btn-primary" style="width: 50px;" ng-click="openEditAgeGroup(ageGroup)">Edit</button>
<button type="button" class="btn btn-xs btn-danger" style="width: 50px;" ng-click="deleteAgeGroup(ageGroup)">Delete</button>
</div>
</li>
</ul>
</div>
</div>
</div>
when first loaded, the page correctly shows all 'age groups' that are in the $scope.ageGroups array.
On clicking the button to add an 'age group', an ng-dialog is created as follows:
$scope.openAddAgeGroup = function() {
console.log("\n\nOpening dialog to add age group");
ngDialog.open({ template: 'views/addAgeGroup.html', scope: $scope, className: 'ngdialog-theme-default', controller:"HomeController" });
};
and that dialog is populated as such:
<div class="ngdialog-message">
<div class="">
<h3>Add a New Age Group</h3>
</div>
<div> </div>
<div>
<form ng-submit="addAgeGroup()">
<div class="form-group">
<label class="sr-only" for="name">Age Group Display Name</label>
<input type="text" class="form-control" id="name" placeholder="age group name" ng-model="ageGroupForm.name">
</div>
<div class="form-group">
<label class="sr-only" for="birthyear">Birth Year</label>
<input type="text" class="form-control" id="birthyear" placeholder="birth year" ng-model="ageGroupForm.birthyear">
</div>
<div class="form-group">
<label class="sr-only" for="socceryear">Soccer Year</label>
<div class="input-group">
<div class="input-group-addon">U</div>
<input type="text" class="form-control" id="socceryear" placeholder="soccer year" ng-model="ageGroupForm.socceryear">
</div>
</div>
<button type="submit" class="btn btn-info">Add</button>
<button type="button" class="btn btn-default" ng-click=closeThisDialog("Cancel")>Cancel</button>
</form>
</div>
</div>
When the form is submitted, the 'age group' is added to the database, from the controller:
'use strict';
angular.module('ma-app')
.controller('HomeController', ['$scope', 'ngDialog', '$state', 'authService', 'coreDataService', 'userService', '$rootScope', 'clubService', 'schedulingService', function($scope, ngDialog, $state, authService, coreDataService, userService, $rootScope, clubService, schedulingService) {
...
$scope.addAgeGroup = function() {
coreDataService.addAgeGroup($scope.ageGroupForm)
.then(function(response) {
coreDataService.refreshAgeGroups()
.then(function(response) {
coreDataService.setAgeGroups(response.data);
$scope.ageGroups = coreDataService.getAgeGroups();
console.log("\n\n\nretrieved age groups and put them in scope");
console.log($scope.ageGroups);
ngDialog.close();
});
}, function(errResponse) {
console.log("Failed on attempt to add age group:");
console.log(errResponse);
});
};
The coreDataService is defined as follows:
'use strict';
angular.module('ma-app')
.service('coreDataService', ['$http', 'baseURL', 'googleGeolocateBaseURL', 'googleGeocodeKey', 'googleMapsBaseURL', function($http, baseURL, googleGeolocateBaseURL, googleGeocodeKey, googleMapsBaseURL) {
var ageGroups = {};
var ageGroupsLoaded = false;
this.getAgeGroups = function() {
return ageGroups;
};
this.setAgeGroups = function(newAgeGroups) {
ageGroups = newAgeGroups;
ageGroupsLoaded = true;
};
this.addAgeGroup = function(formData) {
//post age group:
var postString = '{ "birth_year": "' + formData.birthyear + '", "soccer_year": "U' + formData.socceryear + '", "name": "' + formData.name + '" }';
console.log("Posting age group with string: " + postString);
return $http({
url: baseURL + 'age_groups/',
method: 'POST',
headers: {
'content-type': 'application/json'
},
data: postString
});
};
}]);
So, when an 'age group' is added, console logging indicates that the new 'age group' is in the collection now stored in the $scope.ageGroups array, but the HTML's ng-repeat does not reflect the new 'age group'. Only when I navigate to another tab in the interface, and then return to the tab containing the 'age groups' is the newly added 'age group' displayed.
Updated:
After you update your value you need to tell angular that its been updated. If you wrap your code in a $timeout. On the next digest cycle the view will get updated. See here for more information.
...
$timeout(function() {
$scope.ageGroups = coreDataService.getAgeGroups();
// anything you want can go here and will safely be run on the next digest.
})
...
The $timeout basically runs on the next $digest cycle thus updating your value in the view.
I would suggest wrapping your ng-repeat part in a directive, fire an event on add method and listen to it from the directive:
this.addAgeGroup = function(formData) {
// do stuff
$scope.$broadcast('itemadded');
}
Inside your directive link function:
$scope.$on('itemadded', function() {
$scope.ageGroups = coreDataService.getAgeGroups();
});
I would recommend using the ControllerAs syntax which will refresh the ng-repeat, if the array to which it is bound to gets updated.
Refer the answer given here - ng-repeat not updating on update of array

Angular Wiring up two controllers from Model to auto fill form

I've got an angular app I'm working on where I'm trying to auto fill a pop up modal based on a user's selection.
I thought I could use my model service to keep track of what the user selected and 'wire' the controller for the <select> list and it's edit button to the model but that doesn't seem to work.
Adding to the complexity I'm using angular-route and my <select> list is buried in a view. I was trying to keep my pop up modals in a separate controller outside the view because they've got their own templates and I had problems when I nested them into the view...
I've seen a few examples of wiring up angular apps and thought I understood them but I can't figure out what I'm doing wrong.
EDIT (thanks Pankaj Parkar for pointed out my mistakes in the plunker):
I have a plunker here:
https://plnkr.co/edit/6f9FZmV8Ul6LZDm9rcg9?p=preview
Below is the snipped in a single HTML page with CDN links :).
Am I just completely misunderstanding how angularjs is suppose to work?
<html ng-app="myApp">
<head>
<title>Bootstrap 3</title>
</head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<div ng-view></div>
<script id="editables.html" type="text/ng-template">
<div class="container">
<div class="jumbotron">
<form>
<div class="form-group">
<select class="form-control" id="mapsSelect" size="10" multiple ng-model="model.selected">
<option ng-repeat="n in editables">{{n}}</option>
<select>
</div>
<a href="#editModal" class = "btn btn-info" data-toggle="modal" ng-click="edit()" >Edit</a>
</form>
</div>
</div><!--end container div-->
</script>
<div ng-controller="modalsController">
<div id="editModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<form class="form-horizontal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4>New Map</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="name" class="col-lg-3 control-label">Name</label>
<div class="col-lg-9">
<input type="text" class="form-control" id="name" ng-model="formModel.name"></input>
</div>
</div>
<div class="form-group">
<label for="desc" class="col-lg-3 control-label">Description</label>
<div class="col-lg-9">
<input type="text" class="form-control" id="desc" ng-model="formModel.desc"></input>
</div>
</div>
<div class="modal-footer">
<pre> {{ formModel | json }}<br><br>Working: {{ workingMap }}</pre>
Cancel
Continue
</div>
</form>
</div>
</div>
</div><!-- end modal -->
</div>
</body>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-route.min.js"></script>
<script src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- <script src = "js/script.js"></script> -->
<script>
var app = angular.module('myApp', ['ngRoute']);
var modelService = function ($log){
var moduleHello = function(myMessage){
console.log("Module hellow from myService " + myMessage);
}
var moduleNames = {
"First" : {desc: "First's Description"},
"Second" : {desc: "Second's Description"},
"Third" : {desc: "Third's Description"}
};
var moduleWorkingName = {};
return {
hello: moduleHello,
editables: moduleNames,
workingName: moduleWorkingName
}
}//end modelService
app.factory("modelService", ["$log", modelService]);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/editables', {
controller: "editablesController",
templateUrl: "editables.html"
}).
otherwise({
redirectTo: "/editables"
});
}]);
app.controller('editablesController', ['$scope', '$log','modelService', function($scope,$log, $modelService) {
$scope.model = {};
//console.log( JSON.stringify( $modelService.editables ) );
$scope.editables = [];
for ( name in $modelService.editables){
$scope.editables.push( name );
}
$scope.edit = function(){
if ( typeof $modelService.editables [$scope.model.selected] != 'undefined'){
$modelService.workingName = $modelService.editables [$scope.model.selected];
console.log ("Setting my working name to " + JSON.stringify( $modelService.workingName ) );
}else{
console.log ("Nothing Selected");
}
}
}]);
app.controller('modalsController', ['$scope','modelService', function($scope,$modelService) {
$scope.formModel = {};
$scope.formModel.name = "Hard coding works of course";
$scope.formModel.desc = $modelService.workingName.desc; //But I can't seem to get this to update. I thought pointing it at an object in the Model would be enough.
console.log("Firing up modalsController");
}]);
</script>
</html>
I spent the last two days mulling over this in my head and I think I figured it out. For starters, here's the (working) plunker:
https://plnkr.co/edit/Kt3rebPtvGTt0WMXkQW4?p=preview
Now, the explanation. I was trying to keep a separate 'formModel' object that kept track of the controller's state. But that's both silly and pointless.
Instead what you're supposed to do is:
a. Create an object in your service to hold all your data (I just called this 'model')
b. For each controller that needs to share data create a variable on the $scope of the controller and point it to your 'model' variable from your service.
c. after that use the variables from your model in your html.
So in both my controllers you'll find this line:
$scope.model = $modelService.model;
and in my HTML you'll find stuff like this:
<input type="text" class="form-control" id="name" ng-model="model.workingName.name"></input>
notice how I'm using "model.workingName.name"? This references $scope.model.workingName.name, which thanks to the line $scope.model = $modelService.model from my JavaScript now points directly to my model.
And that is how you "wire up" Angular.
By the way, experienced Angular folks have probably noticed that this part:
$scope.editables = [];
for ( name in $modelService.model.names){
$scope.editables.push( name );
}
probably belongs in a directive instead of a controller because I'm editing the DOM.
Stuff like that's what makes it so hard to learn AngularJS. There's so many concepts to get the hang of.

MEAN stack editing a post

So I am working on my very first MEAN stack app and I am using using type script.
I have my post working just fine, but my edit post is not working. Since this is my first app I am not quite sure why. The error says that my parameters for my post are undefined. I hope one of you lovely people can help me out. I've avoided asking for help for a long time because I am sure its a stupid error.
controllers.ts
http://pastebin.com/bhXT5bLz
app.ts
state('jobPost', {
url: '/jobPost',
templateUrl: "/templates/jobPost.html",
controller: MyApp.Controllers.jobPostController,
controllerAs: 'jobPost'
})
.state('editjobPost', {
url: '/editjobPost',
templateUrl: "/templates/jobPost.html",
controller: MyApp.Controllers.jobPostController,
controllerAs: 'jobPost'
})
route.ts:
router.get('/jobPostData', function (req, res) {
console.log('getting jobPost data');
JobPost.find({}, function(err, jobposts) {
res.json(jobposts);
});
});
router.put('/jobPost', function (req, res, next) {
console.log('editing jobPost');
let jobPost = new JobPost({
jobTitle: req.body.jobTitle,
jobLocation: req.body.jobLocation,
jobDescription: req.body.jobDescription,
created_at: req.body.created_at
});
console.log(jobPost);
jobPost.save(function(err, jobPost) {
if (err) return next(err);
console.log('edited post');
res.send(jobPost);
});
});
jobPost.html:
<link rel="stylesheet" href="/css/jobPost.css" media="screen" title="no title" charset="utf-8">
<br><br><br><br><br><br><br>
<div class="container-fluid">
<div class="container">
<div class="row">
<div ng-show="jobPost.newForm" class="col-md-12" id="background">
<h1 class="headers">Post a Job</h1>
<form ng-submit="jobPost.newJobPost()" class="new_job_form" name="new_job_form">
<input ng-model="jobPost.jobPost.title" id="jobTitle" type="text" name="jobTitle" placeholder="job title"> <br><br>
<input ng-model="jobPost.jobPost.location" id="jobLocation" type="text" name="jobLocation" placeholder="job location"> <br><br>
<textarea ng-model="jobPost.jobPost.description" rows="8" cols="50"class="input-block-level" id="jobDescription" name="jobDescription" placeholder="Enter Description" ></textarea><br>
<input class="submit-btn" type="submit" name="submit" value="Submit">
</form>
<!-- <h2>{{jobPost.message}}</h2> -->
</div>
<div ng-show="jobPost.editForm" class="col-md-12" id="background">
<h1 class="headers">Edit a Job</h1>
<form ng-submit="jobPost.editJobPost()" class="edit_job_form" name="edit_job_form">
<input ng-model="jobPost.jobPost.title" type="text" name="jobTitle" value="{{editJobPost.editTitle}}"> <br><br>
<input ng-model="jobPost.jobPost.location" type="text" name="jobLocation" value="{{editJobPost.editLocation}}"> <br><br>
<textarea ng-model="jobPost.jobPost.description" rows="8" cols="50"class="input-block-level" name="jobDescription" value="{{editJobPost.editDescription}}" ></textarea><br>
<input class="submit-btn" type="submit" name="submit" value="Submit">
</form>
</div>
</div
</div>
</div>
</div>
<br><br>
<div class="container-fluid">
<div class="container">
<h1 class="headers">Your Jobs</h1>
<div class="row" ng-repeat="job in jobPost.jobPosts.slice(((jobPost.currentPage-1)*jobPost.itemsPerPage),((jobPost.currentPage)*jobPost.itemsPerPage)) | orderBy : 'created_at' ">
<h1></h1>
<div class="col-md-12 jobPosting panel-title">
<h2>{{job.jobTitle}}<a class="pull-right" ui-sref="editjobPost"><span ng-click="jobPost.editJobPost()" class="glyphicon glyphicon-cog"></a></h2>
<h3>{{job.jobLocation}}</h3>
<h3>{{job.jobDescription}}</h3>
</div>
</div>
<!-- <pagination total-items="jobPost.totalItems" ng-model="jobPost.currentPage" ng-change="jobPost.pageChanged()" class="pagination-sm" items-per-page="jobPost.itemsPerPage"></pagination> -->
<ul uib-pagination total-items="jobPost.totalItems" items-per-page="jobPost.itemsPerPage" ng-model="jobPost.currentPage" ng-change="jobPost.pageChanged()"></ul>
<!-- <ul uib-pagination total-items="totalItems" ng-model="JobPost" ng-change="pageChanged()"></ul> -->
<!-- <h4>Default</h4>
<h5>totalItems: {{jobPost.totalItems}}</h5>
<ul uib-pagination total-items="jobPost.totalItems" ng-model="jobPost.currentPage" ng-change="jobPost.pageChanged()"></ul> -->
<!-- <ul uib-pagination boundary-links="true" total-items="jobPost.totalItems" ng-model="jobPost.currentPage" class="pagination-sm" previous-text="‹" next-text="›" first-text="«" last-text="»"></ul>
<ul uib-pagination direction-links="false" boundary-links="true" total-items="jobPost.totalItems" ng-model="jobPost.currentPage"></ul>
<ul uib-pagination direction-links="false" total-items="jobPost.totalItems" ng-model="jobPost.currentPage" num-pages="smallnumPages"></ul>
<pre>The selected page no: {{jobPost.currentPage}}</pre>
<button type="button" class="btn btn-info" ng-click="jobPost.setPage(3)">Set current page to: 3</button> -->
<hr />
</div>
</div>
<script src="/js/jobForm.js" charset="utf-8"></script>
jobForm.ts:
$(document).ready(function() {
$('.new_job_form').on('submit', function(e){
e.preventDefault();
var jobTitle = $('#jobTitle').val();
var jobLocation = $('#jobLocation').val();
var jobDescription = $('#jobDescription').val();
$('#jobTitle').val('');
$('#jobLocation').val('');
$('#jobDescription').val('');
var data = {
jobTitle: jobTitle,
jobLocation: jobLocation,
jobDescription: jobDescription,
};
console.log(data);
$.ajax({
url: '/jobPost',
dataType: "json",
method: "POST",
data: data,
success: function(data, textStatus, jqXHR){
console.log("Successfully saved to database",data);
// var resultString = "<h4>"+data.jobTitle+"</h4><h4>"+data.jobLocation+"</h4><h4>"+data.jobDescription+"</h4>";
// $('.postResult').html(resultString);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
});
});
angular.module('MyApp').controller('jobPostController', function ($scope, $log) {
$scope.totalItems = 64;
$scope.currentPage = 1;
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
};
$scope.pageChanged = function() {
$log.log('Page changed to: ' + $scope.currentPage);
};
$scope.maxSize = 5;
$scope.bigTotalItems = 175;
$scope.bigCurrentPage = 1;
});
});
****EDIT to reflect answering stack overflow checklist
I have tried messing with the ui-sref and ng-click for the editJobPost section in the JobPost.html thinking maybe it was a routing error.
I then changed the editJobPost method in controller.js from the JobPost variable to JobPosts variable. Now that it runs and compiles (it didn't before) it throws this in the console:
HITTING EDIT
controllers.js:241 undefined
controllers.js:242 undefined
controllers.js:245 undefined
controllers.js:249 Title: undefined
controllers.js:250 Location: undefined
controllers.js:251 Description: undefined
angular.js:11881 PUT http://127.0.0.1:3000/jobPost/%7B%7Bjob._id%7D%7D 404 (Not Found)
I know that it means my declared variables are undefined, I just don't know where to start. what is wrong and why.

I can't scope anything onto my angular dialog(reviewForm) from the DialogController?

Below I have a button that is attached to each venue list item. So each list item has its own button. Also, each list item is a object. So when I click one of buttons I need to somehow grab the ID from that specific list item and be able to use it in my dialogcontroller.
<div class="results">
<div class="searchbox col-md-6 form-group">
<input type="text" placeholder="search venues" class="form-control" ng-model="filterTerm">
<ul class="list-unstyled">
<li class="well" ng-repeat="venues in venues | filter: filterTerm">
<h3>{{venues.name}}</h3>
<p>{{venues.info}}</p>
<md-button class="md-primary md-raised" ng-click="showAdvanced($event, venues)" flex-sm="100" flex-md="100" flex-gt-md="auto">Add a Review</md-button>
<button>See Reviews</button>
</li>
</ul>
</div>
My get call to my JSON file. Also, This is my ng-click function that is using mdDialog (which opens a popup window with a reviewForm.html as its content.
$http.get('/getMarkers').success(function(response) {
$scope.venues = response;
console.log($scope.venues);
});
$scope.showAdvanced = function(ev, venues){
$mdDialog.show({
controller: DialogController(ev,venues),
templateUrl: 'views/reviewForm.html',
parent:angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true
})
};
This is my DialogController which is handling the content(reviewForm.html) that is being rendered in my mdDialog window.
function DialogController($scope, venues, $mdDialog) {
console.log(venues);
$scope.rate = 0;
$scope.max = 5;
$scope.hoveringStaff = function (value) {
$scope.overStar = value;
$scope.percent = 100 * (value / $scope.max);
console.log($scope.overStar);
};
}
This is the html that is going into the dialog
<md-dialog aria-label="Review Form">
{{something}}
<md-toolbar>
{{venues}}
<div class="md-toolbar-tools">
<h2>Review Form</h2>
<span flex></span>
</div>
</md-toolbar>
<md-dialog-content>
{{$scope.something}}
<label>{{something}}Show Attended: </label><input type="text" ng-model="show"><br/>
<label>Date: </label><input type="date" ng-model="date"><br/>
<label>Staff Friendliest: </label><uib-rating ng-model="rate" max="max" on-hover="hoveringStaff(value)" on-leave="overStar = null" titles="['one','two','three']" aria-labelledby="default-rating"></uib-rating><br/>
<label>Sound Quality: </label><input type="text" ng-model="sound"><br/>
<label>Favorite Drink/Cocktail: </label><input type="text" ng-model="drink"><br/>
<label>Nearby Bar/Food Recommendations: </label><input type="text" ng-model="nearby"><br/>
<label>Comments: </label><input type="text" ng-model="comments"><br/>
<label>Venue Rating: </label><br/>
<md-button class="md-raised md-primary" ng-click="sendReview()">Primary</md-button>
</md-dialog-content>
I need the ID because I am going to posting a form to the database and need to add the form content to the selected list item. Sorry if this is confusing, let me know if you have any questions. Thanks!
I think you might need to use locals or resolve to pass objects to the new controllers, because of angular's dependency injection, passing objects to the controller will not work (i.e MyController($scope, a, b)).
ex:
$mdDialog.show({
locals: {
venue: venue
}
});
or with resolve
$mdDialog.show({
resolve: {
venue: function(){return venue;}
}
});
Another issue which I think is a typo, is in the ng-repeat directive venues in venues which should be venue in venues.
Reference the view values to venue object(i.e venue.drink, venue.date, ...ect) instead of $scope, will make it easier to pass it back to the parent controller.
function MainCtrl($http, $scope, $mdDialog) {
/*
$http.get('/getMarkers').success(function(response) {
$scope.venues = response;
console.log($scope.venues);
});
*/
$scope.venues = [{
name: 'Venue #1',
info: 'Info',
date: new Date(),
drink: 'A drink'
}];
$scope.showAdvanced = function(ev, venue) {
$mdDialog.show({
controller: 'DialogController',
template: '<md-dialog aria-label="Review Form">\
{{venue.name}}\
<md-toolbar>\
{{venue}}\
<div class="md-toolbar-tools">\
<h2>Review Form</h2>\
<span flex></span>\
</div>\
</md-toolbar>\
<md-dialog-content>\
{{venue.name}}\
<label>{{venue.name}}Show Attended: </label><input type="text" ng-model="venue.show"><br/>\
<label>Date: </label><input type="date" ng-model="venue.date"><br/>\
<label>Staff Friendliest: </label><uib-rating ng-model="venue.rate" max="max" on-hover="hoveringStaff(value)" on-leave="overStar = null" titles="[\'one\',\'two\',\'three\']" aria-labelledby="default-rating"></uib-rating><br/>\
<label>Sound Quality: </label><input type="text" ng-model="venue.sound"><br/>\
<label>Favorite Drink/Cocktail: </label><input type="text" ng-model="venue.drink"><br/>\
<label>Nearby Bar/Food Recommendations: </label><input type="text" ng-model="venue.nearby"><br/>\
<label>Comments: </label><input type="text" ng-model="venue.comments"><br/>\
<label>Venue Rating: </label><br/>\
<md-button class="md-raised md-primary" ng-click="sendReview()">Primary</md-button>\
</md-dialog-content>',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
locals: {
venue: venue
}
})
};
}
function DialogController($scope, venue, $mdDialog) {
$scope.venue = venue;
console.log(venue);
$scope.rate = 0;
$scope.max = 5;
$scope.hoveringStaff = function(value) {
$scope.overStar = value;
$scope.percent = 100 * (value / $scope.max);
console.log($scope.overStar);
};
}
angular.module('MyApp', ['ngAria', 'ngAnimate', 'ngMaterial'])
.controller('MainCtrl', MainCtrl)
.controller('DialogController', DialogController);
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-aria.min.js"></script>
</head>
<body ng-app="MyApp" ng-controller="MainCtrl">
<div class="results">
<div class="searchbox col-md-6 form-group">
<input type="text" placeholder="search venues" class="form-control" ng-model="filterTerm">
<ul class="list-unstyled">
<li class="well" ng-repeat="venue in venues | filter: filterTerm">
<h3>{{venue.name}}</h3>
<p>{{venue.info}}</p>
<md-button class="md-primary md-raised" ng-click="showAdvanced($event, venue)" flex-sm="100" flex-md="100" flex-gt-md="auto">Add a Review</md-button>
<button>See Reviews</button>
</li>
</ul>
</div>
</div>
</body>
</html>

Resources