I'm learning how to use Angularjs with ROR through this tutorial https://thinkster.io/angulartutorial/angular-rails/
I've come to a point where when I'm adding a new function for a service which is supposed to get all posts we have in the db. However When I run the code the page does not load anymore. Or at least the html is not rendered. There is no indication of errors in the elements inspections. However I'm not sure it has to do with the placing of the function in the js file. I'm totally new to js and I still struggle to read the sintax and spot errors in the code. Rubymine has given a clue with and Unreacheble code warning for the o.getAll. If someone could have a look at it and give me any hints it would be great.
Apologies to all the code in one file both html and js. I'm having some issues with the assets pipeline that I mean to get fixed soon.
app.js
Blockquote
angular.module('flapperNews', ['ui.router'])
//Provider
.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
})
$urlRouterProvider.otherwise('home');
}])
//Posts service
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
return o;
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
}])
//Main Controller
.controller('MainCtrl', [
'$scope',
'posts',
function($scope, posts){
$scope.posts = posts.posts;
$scope.addPost = function(){
if(!$scope.title || $scope.title == '') { return; }
$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0,
comments: [
{author: 'Joe', body: 'Cool post!', upvotes: 0},
{author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0}
]
});
$scope.title = '';
$scope.link = '';
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}])
//Posts Controller
.controller('PostsCtrl', [
'$scope',
'$stateParams',
'posts',
function($scope, $stateParams, posts){
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function(){
if($scope.body === '') { return; }
$scope.post.comments.push({
body: $scope.body,
author: 'user',
upvotes: 0
});
$scope.body = '';
};}]);
>
and following the application.html.erb
> Blockquote
<html>
<head>
<title>FlapperNews</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="javascripts/app.js"></script>
<script src="javascripts/application.js"></script>
<%= csrf_meta_tags %>
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(post)"></span>
{{post.upvotes}}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Title"
ng-model="title">
</div>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Link"
ng-model="link">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
<div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">
{{comment.body}}
</span>
</div>
<form ng-submit="addComment()"
style="margin-top:30px;">
<h3>Add a new comment</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Comment"
ng-model="body">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
</body>
</html>
From factory you are returning o before the getAll function so it is unreachable
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
//removed return
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
return o; //at the added return
}])
Related
I have a form in one tab and list of applications submitted in another tab.
If I click edit on a form, I should load the data from database and go to the other tab. On ng-click , I am able to retrieve the data but not able to change the tab.
Here are the relevant files:
navbar.html
<nav class="navbar navbar-default navbar-cls-top " role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-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="index.html"></a>
</div>
<div class="header-right">
<i class="fa fa-sign-out fa-2x"></i>
</div>
</nav>
<!-- /. NAV TOP -->
<nav class="navbar-default navbar-side" role="navigation" style="width:200px">
<div class="sidebar-collapse">
<ul class="nav" id="main-menu">
<li>
<div class="inner-text">
{{user.name}}
<br />
<small> </small>
</div>
</div>
</li>
<li>
<a id="page1" ng-class='{"active-menu": selectedMenu == "dashboard"}' ui-sref="secured.dashboard" ng-click='selectedMenu = "dashboard"'><i class="fa fa-dashboard "></i>Dashboard</a>
</li>
<li>
<a id="page2" ng-class='{"active-menu": selectedMenu == "applicationForm"}' ui-sref="secured.applicationForm" ng-click='selectedMenu = "applicationForm"'><i class="fa fa-handshake-o "></i>Application Forms</a>
</li>
<li>
<a ng-class='{"active-menu": selectedMenu == "logout"}' href="" ng-click="logout()" ng-click='selectedMenu = "logout"'><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>
</ul>
</div>
</nav>
dashboard.html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard For Applications</title>
</head>
<body>
<div id="wrapper">
<div id="page-wrapper">
<div id="page-inner">
<div class="row">
<div class="col-md-12">
<h1 class="page-head-line">
<div class="alert alert-danger">
DASHBOARD
</div>
</h1>
<h1 class="page-subhead-line">
<div class="alert alert-info">
Welcome! Here is the list of applications you have saved or submitted. <br><br>
</div>
</h1>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3>Applications List</h3>
</div>
<div class="panel-body">
<table ng-if="applicationList" st-table="applicationTable" class="table table-striped">
<tr>
<th>Application Number</th>
<th>Project Title</th>
<th>Project Description</th>
<!-- <th>DataSet Available</th> -->
<!-- <th>Impact</th> -->
<th>Number of Interns</th>
<th>Expected SkillSet</th>
<th>Software Licenses Needed</th>
<th>Hardware Requirements</th>
<th></th>
<th></th>
</tr>
<tbody>
<tr ng-repeat="application in applicationList">
<td class="col-md-2">{{application.number}}</td>
<td class="col-md-2">{{application.title}}</td>
<td class="col-md-2">{{application.description}}</td>
<!-- <td><span ng-repeat='area in idt.areas'>{{area}}, </span></td> -->
<!-- <td class="col-md-2">{{application.technical}}, {{application.business}}</td> -->
<td class="col-md-2">{{application.numberOfInterns}}</td>
<td class="col-md-2">{{application.skillSet}}</td>
<td class="col-md-2">{{application.software}}</td>
<td class="col-md-2">{{application.hardware}}</td>
<td><button class="btn btn-danger" ng-click="remove(application._id)" ng-show="application.state=='saved'">Delete</button></td>
<td><button class="btn btn-warning" ng-click="selectedMenu='applicationForm'; edit(application._id)" ng-show="application.state=='saved'">Edit</button></td>
<!-- <td><button class="btn btn-warning" ng-click="selectedMenu='dashboard'; edit(application._id)" ng-show="application.state=='saved'">Edit</button></td> -->
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- /. ROW -->
<hr />
</div>
<!--/.ROW-->
</div>
<!-- /. PAGE INNER -->
</div>
<!-- /. PAGE WRAPPER -->
</div>
<!-- /. WRAPPER -->
</body>
</html>
dashboard.js :
(function() {
var app = angular.module('dashboard', []);
app.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('secured.dashboard', {
url: '/dashboard',
controller: 'DashboardController',
templateUrl: '/views/dashboard.html'
});
}]);
app.controller('DashboardController', ['$scope', 'AuthService', 'user', '$state', '$http', function($scope, AuthService, user, $state, $http) {
$scope.user = user;
AuthService.setUser(user);
$scope.logout = function() {
AuthService.logout().then(function() {
$scope.user = null;
$state.go('unsecured');
})
}
var refresh = function(){
$http.get('/application/applicationList').then(function(response){
console.log("I got the applications I requested");
$scope.applicationList = response.data;
console.log($scope.applicationList);
$scope.pagination = {};
// $scope.totalItems = 200;
$scope.pagination.currentPage = 0;
$scope.numPerPage = 10;
});
};
refresh();
$scope.remove = function(id){
var del = false;
swal({
title: 'Are you sure?',
text: "You won't be able to revert this!",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
focusCancel: true,
allowEscapeKey: true,
allowEnterKey: true,
allowOutsideClick: true,
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'No, cancel!',
confirmButtonClass: 'btn btn-success',
cancelButtonClass: 'btn btn-danger',
buttonsStyling: false
}).then(function () {
$http.delete('/application/applicationlist/'+id).then(function(response){
clear();
refresh();
});
swal(
'Deleted!',
'Your Application has been deleted.',
'success'
)
}, function (dismiss) {
// dismiss can be 'cancel', 'overlay',
// 'close', and 'timer'
if (dismiss === 'cancel') {
swal(
'Cancelled',
'Your Application is safe :)',
'error'
)
}
})
};
$scope.edit = function(id){
console.log(id);
console.log("Edit function called");
$http.get('/application/applicationList/'+id).then(function(response){
$scope.application = response.data;
console.log($scope.application);
//refresh();
$scope.changeTab(event, 'page1');
});
};
var clear = function(){
$scope.application = {
technical: false,
business: false
};
};
}]);
})();
applicationForm.js:
(function() {
var app = angular.module('applicationForm', []);
app.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('secured.applicationForm', {
url: '/applicationForm',
controller: 'applicationFormController',
templateUrl: '/views/applicationForm.html'
});
}]);
app.controller('applicationFormController', ['$http', '$scope', '$state', '$uibModal', function($http, $scope, $state, $uibModal) {
$scope.application = {
technical: false,
business: false
};
var refresh = function(){
$http.get('/application/applicationList').then(function(response){
console.log("I got the applications I requested");
$scope.applicationList = response.data;
console.log($scope.applicationList);
$scope.pagination = {};
// $scope.totalItems = 200;
$scope.pagination.currentPage = 0;
$scope.numPerPage = 10;
});
};
refresh();
$scope.saveApplication = function(){
console.log($scope.application);
console.log($scope.applicationList);
var check = 0;
$scope.application.state = "saved";
$scope.application.userEmail = $scope.user.email;
for (var i=0, len=$scope.applicationList.length; i < len; i++) {
if ($scope.applicationList[i]._id == $scope.application._id) {
check = 1;
console.log("matched");
break;
}
}
if(check == 1){
$http.put('/application/applicationlist/' + $scope.application._id, $scope.application).then(function(response){
//$scope.contact = response.data;
refresh();
});
}
else{
$http.post('/application/applicationList', $scope.application).then(function(response){
console.log(response);
refresh();
});
}
swal({
title: "Great!",
text: "We have saved your application",
type: "success",
timer: 3000,
confirmButtonText: "Wohoo!"
});
clear();
};
$scope.submitApplication = function(){
console.log("Submit called");
console.log($scope.application.title);
console.log($scope.user.email);
$scope.application.userEmail = $scope.user.email;
$scope.application.state = "submit";
var check = 0;
for (var i=0, len=$scope.applicationList.length; i < len; i++) {
if ($scope.applicationList[i]._id == $scope.application._id) {
check = 1;
console.log("matched");
break;
}
}
if(check == 1){
$http.put('/applicationlist/' + $scope.application._id, $scope.application).then(function(response){
refresh();
});
}
else{
$http.post('/application/applicationList', $scope.application).then(function(response){
console.log("Successfully submitted");
refresh();
});
}
swal({
title: "Great!",
text: "We have received your request",
type: "success",
timer: 3000,
confirmButtonText: "Wohoo!"
});
clear();
};
var clear = function(){
$scope.application = {
technical: false,
business: false
};
};
//Universities
$scope.application.selectname1={id:100,name: 'None'};
$scope.application.selectname2={id:100,name: 'None'};
$scope.application.selectname3={id:100,name: 'None'};
$scope.filter1 = function(item){
return (!($scope.application.selectname1&&$scope.application.selectname1.id)||item.id !=$scope.application.selectname1.id||item.id==100);
};
$scope.filter2 = function(item){
return (!($scope.application.selectname2&&$scope.application.selectname2.id)||item.id!=$scope.application.selectname2.id||item.id==100);
};
$scope.filter3 = function(item){
return (!($scope.application.selectname3&&$scope.application.selectname3.id)||item.id !=$scope.application.selectname3.id||item.id==100);
};
$scope.universities = [
{
id:1,
name: 'IITs'
},
{
id:2,
name: 'IIITs'
},
{
id:3,
name: 'BITS'
},
{
id:4,
name: 'IISc'
},
{
id:100,
name: 'None'
}
];
//Degrees
$scope.application.selectdegree1={id:100,name: 'None'};
$scope.application.selectdegree2={id:100,name: 'None'};
$scope.application.selectdegree3={id:100,name: 'None'};
$scope.filterDegree1 = function(item){
return (!($scope.application.selectdegree1&&$scope.application.selectdegree1.id)||item.id !=$scope.application.selectdegree1.id||item.id==100);
};
$scope.filterDegree2 = function(item){
return (!($scope.application.selectdegree2&&$scope.application.selectdegree2.id)||item.id!=$scope.application.selectdegree2.id||item.id==100);
};
$scope.filterDegree3 = function(item){
return (!($scope.application.selectdegree3&&$scope.application.selectdegree3.id)||item.id !=$scope.application.selectdegree3.id||item.id==100);
};
$scope.degrees = [
{
id:1,
name: 'PhD'
},
{
id:2,
name: 'Masters'
},
{
id:3,
name: 'BTech'
},
{
id:100,
name: 'None'
}
];
$scope.pageChanged = function() {
//alert('Page changed to: ' + $scope.pagination.currentPage);
//$scope.pagination.currentPage = page;
var begin = (($scope.pagination.currentPage - 1) * $scope.numPerPage);
//var end = begin + $scope.numPerPage;
$scope.getPatents(begin)
};
}]);
})();
#Tarun exactly like you said, your structures are the problem, you should have your navbar navigation in a parent/abstract state, the dashboard and other pages in sub states, so in the app.html would be the navbar and remember to include a <div ui-view></div> tag for the contents of dashboard.html to be displayed nested in the app.html parent state once you navigate to /dashboard:
$stateProvider
.state('login', {
url: "/login",
templateUrl: 'pages/login.html',
controller: 'LoginController',
data: {
requireLogin: false
}
})
.state('app', {
abstract: true,
url: '/app',
templateUrl: 'views/app.html',
data: {
requireLogin: true
}
})
.state('app.dashboard', {
url: '/dashboard',
controller: 'DashboardCtrl',
templateUrl: 'pages/map.html',
data: {
requireLogin: true
}
});
I have added angular.min.js, angular-route.min.js
The issue is when the login button is clicked the url changes to '/home' but the page home.html is not displaying. I've tried adding controller under templateUrl but it's not working
<main class="container" ng-app="Myapp">
<div class="row">
<div class="login-page" ng-controller="loginCtrl">
<div class="form">
<form class="login-form">
<input type="text" placeholder="username" ng-model="username"/>
<input type="password" placeholder="password" ng-model="password"/>
<button type="submit" ng-click="submit()">login</button>
<p class="message">Not registered? Create an account</p>
</form>
</div>
</div>
</div>
var app = angular.module('Myapp', ['ngRoute']);
app.config(function ($routeProvider, $locationProvider){
$locationProvider.hashPrefix('');
$routeProvider
.when('/', {
templateUrl: 'index.html'
})
.when('/home', {
templateUrl: 'home.html'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('loginCtrl', function($scope, $location){
$scope.submit = function(){
var username = $scope.username;
var password = $scope.password;
if($scope.username =='admin' && $scope.password == 'pwd'){
$location.path('/home');
}
else {
alert("Invalid Credentials");
}
});
You need to abstract your application and put it in different files and include the reference to these files in your index.html
index.html
<main class="container" ng-app="Myapp">
<div class="row" ng-controller="mainCtrl">
<div ng-view></div>
</div>
</main>
login.html
<div class="login-page">
<div class="form">
<form class="login-form">
<input type="text" placeholder="username" ng-model="username"/>
<input type="password" placeholder="password" ng-model="password"/>
<button type="submit" ng-click="submit()">login</button>
<p class="message">Not registered? Create an account</p>
</form>
</div>
</div>
Config file
var app = angular.module('Myapp', ['ngRoute']);
app.config(function ($routeProvider, $locationProvider){
$locationProvider.hashPrefix('');
$routeProvider
.when('/', {
templateUrl: 'login.html',
controller:'loginCtrl'
})
.when('/home', {
templateUrl: 'home.html',
controller: 'homeCtrl'
})
.otherwise({
redirectTo: '/'
});
});
Main Controller
app.controller('mainCtrl', function($scope, $location){
});
Home Controller
app.controller('homeCtrl', function($scope, $location){
});
Login Controller
app.controller('loginCtrl', function($scope, $location){
$scope.submit = function(){
var username = $scope.username;
var password = $scope.password;
if($scope.username =='admin' && $scope.password == 'pwd'){
$location.path('/home');
}
else {
alert("Invalid Credentials");
}
});
You need a "ui-view elment" to wrap dynamic contents. then home.html will be loaded/compiled within this "ui-view" element.
If the index.html has ng-app="Myapp" delete it from home.html and add ng-view to to the right place in index.html . So angular route will replace ng-view with your home.html
This is my main HTML file.
<div ng-controller="filterController">
<div class="quick-view" id="quickview" data-toggle="modal" data-target="#modal-bar"
ng-click="quickView(quickview)"><i class="fa fa-eye">
</i><span>Quick View</span></div>
</div>
This is my controller.js file
angular.module('myApp',[]).controller('filterController', function($scope) {
$scope.quickView = function quickView(id){
$.ajax({
type: 'GET',
url: 'assets/external/_modal.html',
data: id,
success: function (data) {
// Create HTML element with loaded data
$('body').append(data);
console.log('body append');
},
error:function(jqXHR,textStatus,exception){console.log('Exception:'+exception);}
});
}
$scope.venue = "India";
}
This is _modal.html
<div ng-controller="filterController">
<p>Hi. I live in {{venue}}</p>
</div>
How can I pass the controller scope to the external file _modal.html so that "I live in India" gets displayed instead of "I live in {{venue}}"?
Try angularjs way. Use uib modal. https://angular-ui.github.io/bootstrap
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope,$uibModal, $log, $document) {
$scope.animationsEnabled = true;
$scope.Venue = "India"; // declare venue
$scope.open = function (size, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
appendTo: parentElem,
resolve: {
values: function () {
return $scope.Venue; //we are passing venue as values
}
}
});
modalInstance.result.then(function () {
$scope.msg = "Submitted";
$scope.suc = true;
}, function(error) {
$scope.msg = 'Cancelled';
$scope.suc = false;
});
};
});
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope,$uibModalInstance, values) { // inject that resolved values
$scope.Venue= values; // we are getting & initialize venue from values
$scope.ok = function () {
$uibModalInstance.close('ok');
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl" class="modal-demo">
<br>
<form name="form" novalidate>
Type your venue : <input type="text" style="width:200px" class="form-control" name="name" ng-model="Venue" required><br>
<button type="button" ng-disabled="form.$invalid" class="btn btn-default" ng-click="form.$valid && open()">See Venue</button>
</form><br>
<p ng-hide="!msg" class="alert" ng-class="{'alert-success':suc, 'alert-danger':!suc}">{{msg}}</p>
</div>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title" id="modal-title">Your Details</h3>
</div>
<div class="modal-body" id="modal-body">
<p>The venue is <b>{{Venue }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">Submit</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
</body>
</html>
I am making a test app on MEAN stack and whenever I try to update information in my database regarding the fields, Google chrome throws Connection refused to the Url where I am posting the stuff.
Code for the controller:
(function() {
angular.module('TimeSuck')
.controller('EditProfileController',['Upload','$scope','$state', '$http', function(Upload, $scope, $state, $http) {
$scope.user = localStorage['Userdata'] || undefined
$scope.$watch(function(){
return $scope.file
},function(){
$scope.upload($scope.file);
});
$scope.upload = function(file) {
if(file){
Upload.upload({
url:'api/profile/editPhoto',
method: 'POST',
data: {userId: $scope.user._id},
file: file
}).progress(function(event){
console.log("Uploaded");
}).success(function(data){
}).error(function(error){
console.log(error);
})
}
};
$scope.updateUsername = function() {
var request = {
userId: $scope.user[0]._id,
username: $scope.username
}
$http.post('api/profile/updateUsername', request).success(function(){
console.log("success");
}).error(function(error){
console.log(error);
})
}
$scope.updateBio = function() {
var request = {
userId: $scope.user[0]._id,
bio: $scope.bio
}
$http.post('api/profile/updateBio', request).success(function(){
console.log("success");
}).error(function(error){
console.log(error);
});
}
$scope.post = function() {
console.log("successfully Posted.");
}
and the code for the html is here:
<div class="jumbotron">
<div class="col-sm-8 col-sm-offset-2">
<div class="row"> <div class="button" ngf-select ng-model="file" name="file" ngf-pattern="'image/*'"
ngf-accept="'image/*'" >Select</div> </div>
<div class="row">
<input class="form-control" ng-model="username" ng-blur="updateUsername()">
</div>
<div class="row">
<textarea class="form-control" ng-model="Bio" ng-blur="updateBio()"> </textarea>
<button type="submit" ng-click="post()"> Post </button>
</div>
</div>
</div>
I have spent the last few days monkeying with my app, trying to figure out how best to keep track of an editing state within a given controller. Of course, the problem is, multiple of these ObjectControllers exist at one time, and only one can be editing at a given moment. Below is the important code:
App.js:
var App = Ember.Application.create();
//ROUTES
App.Router.map(function() {
this.resource('tasks', function() {
this.resource('task', {path: ':task_id'});
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('tasks');
}
});
App.TasksRoute = Ember.Route.extend({
model: function() {
return App.Task.find();
}
});
App.TaskRoute = Ember.Route.extend({});
//CONTROLLERS
App.TasksController = Ember.ArrayController.extend({
isEditing: null,
editing: false,
newTask: function() {
console.log('new task');
},
toggleEdit: function(id) {
this.set('isEditing', id);
if ($('#collapse' + this.get('isEditing')).hasClass('in')) {
this.set('editing', false);
this.set('isEditing', null);
$('.in').collapse('hide');
} else {
this.set('editing', true);
$('.in').collapse('hide');
$('#' + 'collapse' + this.get('isEditing')).collapse('toggle');
}
}
});
App.TaskController = Ember.ObjectController.extend({
needs: 'tasks',
collapseId: function() {
return "collapse" + this.get('id');
}.property('id'),
collapseHref: function() {
return "#collapse" + this.get('id');
}.property('id'),
});
//VIEWS
App.ApplicationView = Ember.View.extend({
didInsertElement: function() {
var self = this;
Ember.run.schedule('afterRender', function() {
self.$('.navbar').affix({offset: -1000});
});
}
});
//HANDLEBARS HELPERS
//STORE DEFINITION
App.Store = DS.Store.extend({
revision: 11,
adapter: 'DS.FixtureAdapter'
/*DS.RESTAdapter.extend({
url: 'http://localhost:3000'
})*/
});
//MODELS
App.Task = DS.Model.extend({
summary: DS.attr('string'),
description: DS.attr('string'),
start: DS.attr('string'),
end: DS.attr('string'),
recurrence: DS.attr('string')
});
//FIXTURE DATA
App.Task.FIXTURES = [{
id: "q5ji9chrh1hcu05dohvrf4aumc",
summary: "Test",
description: null,
start: "2013-04-01T10:00:00-07:00",
end: "2013-04-01T11:00:00-07:00",
recurrence: "FREQ=WEEKLY;BYDAY=MO,WE,TH,FR"
}, {
id: "mm4m3pq6icbgbl6m49jpdhi8j0",
summary: "Test 2",
description: "absafdaerwer",
start: "2013-04-01",
end: "2013-04-02",
recurrence: null
}];
Home.HTML:
<!--TEMPLATES-->
<script type="text/x-handlebars">
<div class="navbar" data-spy="affix">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
</div>
</div>
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" id="tasks">
<div class="row-fluid span8 offset2 task-list">
<div class="space-top"><div>
<div class="accordion" id="accordion">
{{partial 'tasks/newTask'}}
{{#each task in controller}}
<div class="accordion-group">
{{render 'task' task}}
</div>
{{/each}}
</div>
</div>
</script>
<script type="text/x-handlebars" id="tasks/_newTask">
<div class="accordion-group">
<div class="new-task-header accordion-heading" {{action newTask on="click"}}>
<span class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapseNew">New Task...</span>
</div>
<div id="collapseNew" class="accordion-body collapse">
<div class="new-task accdion-inner">
{{#if task.description}}
<p>{{task.description}}</p>
{{else}}
<p>No description</p>
{{/if}}
</div>
</div>
</div>
</script>
<script type="text/x-handlebars" id="task">
<div class="task">
{{#linkTo 'task' task}}
<div class="accordion-heading" {{action toggleEdit task.id on="click"}}>
<span class="accordion-toggle" data-toggle="collapse" data-parent="#accordion">
{{#if controllers.tasks.editing}}
editing {{task.summary}}
{{else}}
{{task.summary}}
{{/if}}
</span>
</div>
{{/linkTo}}
</div>
<div {{bindAttr id="collapseId"}} class="accordion-body collapse">
<div class="edit-task accdion-inner">
{{#if task.description}}
<p>{{task.description}}</p>
{{else}}
<p>No description</p>
{{/if}}
</div>
</div>
</script>
In this code, there are not multiple TaskControllers being created, I believe. Try setting itemController: 'task' on the ArrayController. (Discussed here, and if you're using 1.0.0-rc.2 see mention here.) That way you can set an editing property on that particular task (and reference tasks if needed). Does that clear anything up?