Is it possible to use ngChange on <p> property to refresh value - angularjs

I am using 'ngMaterial' module for dialogs. When user clicks edit prompt he can edit review. Everything works fine, except that you don't see that review is updated until you refresh page. Is it possible to make you see changes imediatelly?
This is my prompt function, which redirects user to redirectEdit function which puts changes to database.
These methods are in main.controller.js
$scope.showPrompt = function(ev,index) {
var confirm = $mdDialog.prompt()
.title('Edit your review')
.placeholder('Review')
.initialValue($scope.all[index].review)
.targetEvent(ev)
.ok('Okay!')
.cancel('Cancel');
$mdDialog.show(confirm).then(function(result) {
$scope.redirectEdit(index,result);debugger;
}, function() {
$scope.status = 'You discarded changes.';
});
};
$scope.redirectEdit = function(index,result){debugger;
$scope.all[index].id; console.log($scope.all[index].id);
var JSONObject={
"id":$scope.all[index].id,
"name":$scope.all[index].name,
"surname":$scope.all[index].surname,
"email":$scope.all[index].email,
"review":result
}
var Results = UniversalService.UpdateReview(JSON.stringify(JSONObject));
};
this is my button in main.view.html
<md-button ng-show="storageKey!==null" class="md-raised md-primary" ng-click="showPrompt($event,$index)" >Edit </md-button>
<div class="row comment-table" ng-repeat="item in items ">
<div class="col-md-1">
<img ng-src="http://www.gravatar.com/avatar/{{hash[$index]}}" alt="Description" />
</div>
<div class="col-md-8">
<p>{{item.id}} Review posted by: {{item.name}}</p>
<p>{{item.review}}</p>
<span uib-rating ng-model="rate" max=5 on-leave="overStar = null" titles="['one','two','three']" aria-labelledby="default-rating"></span>
<span class="label" ng-class="{'label-warning': percent<30, 'label-info': percent>=30 && percent<70, 'label-success': percent>=70}" ng-show="overStar && !isReadonly">{{percent}}%</span>
</div>

You should update the review property of the edited element like $scope.all[index].review = result; in your scope.redirectEdit method.

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.

Update facebook page list in to a drop down list

I am working on an angular app which integrates with facebook. I have given the code below,
$scope.getCompanyPages = function () {
fb.login(function (response) {
fb.api('/me/accounts', function (apiresponse) {
if (typeof apiresponse !== 'undefined' && typeof apiresponse.data !== 'undefined') {
$scope.facebookPages = apiresponse.data;
$scope.facebookPages.push({ id: "", name: 'Please select a page' });
$scope.selectedItem = $scope.facebookPages[2];
console.log($scope.facebookPages);
}
});
}, { scope: 'manage_pages' });
};
HTML
<div class="row">
<div class="col-xs-12 col-sm-6 center">
<a href="#" ng-click="shareToMyWall()">
<div class="primary-task">
<i class="fa fa-user fa-3x">
</i>
<h2 class="heading-text fa-bold">Personal Wall</h2>
</div>
</a>
</div>
<div class="col-xs-12 col-sm-6 center">
<a href="#" ng-click="getCompanyPages()">
<div class="primary-task">
<i class="fa fa-building fa-3x">
</i>
<h2 class="heading-text fa-bold">Company Wall</h2>
</div>
</a>
<select ng-if="facebookPages.length > 0" ng-change="shareToFacebookPage(selectedItem.id)" ng-model="selectedItem" ng-options="item.name for item in facebookPages track by item.id"></select>
</div>
</div>
The above method is called in hyperlink click (ng-click) event and the when the response comes back the drop down should update with data. The data does come back but it doesn't update straight away, rather I have to do another click anywhere in the page to update drop down list.
The data in the model is updated when you do the first ng-click. However, AngualrJS probably does not do check so the view still shows the old data. You can force a $digest() check and tell AngualrJS to compare old data and new data and update it if there is any difference. You can use $timeout, $evalAsync, or $apply to trigger $digest() which will update the data immediately.
For example:
$timeout(function () {
$scope.getCompanyPages = function () {...}
//or
$scope.facebookPages = apiresponse.data;
})
Edit: according to Angular JS best coding practice
Always wrap 3rd party API call-backs in to $apply to notify AngularJS
regarding out of environment changes.

PUT request in Angular not sending updated data within XHR Header

I am a beginner and new to AngularJS. I am trying to build an Edit/Update function.
The edit function doesn't do much, it just copies the model data to the Form inputs:
// Edit post
$scope.editPost = function(post){
$scope.title = post.title;
$scope.link = post.link;
};
The Update function should (after clicking the Update Button) take the edited data of the inputs, to update the post model:
// Update post
$scope.updatePost = function(post){
posts.update(post, {
title: $scope.title,
link: $scope.link
}).success(function() {
ToastService.show('Post updated');
});
};
The Edit Part works, when I edit the title input and click the Submit Button of the Edit Form, it sends a PUT request, but it seems to doesn't send the updated data within the PUT - it just sends a request with the original data.
The posts.js service:
angular.module('bidrp')
.factory('posts', [
'$http',
function($http){
var o = {
posts: [{title:"hey", upvotes:123}]
};
o.update = function(post) {
return $http.put('/posts/' + post.id, post).success(function(data){
o.posts.push(data);
});
};
Template where Post is displayed and editPost is triggered:
<div ng-repeat="post in posts | orderBy: '-upvotes'">
<md-button class="md-icon-button md-accent" aria-label="Vote-Up" ng-click="incrementUpvotes(post)">
<i class="material-icons">thumb_up</i>
</md-button>
{{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>
posted by <a ng-href="#/users/{{post.user.username}}">{{post.user.username}}</a>
</span>
<span>
Comments
Edit
Delete
</span><br>
<div ng-show="showEditForm" ng-include="'home/_edit-post.html'"></div>
</div>
<div ng-include="'home/_add-post.html'"></div>
_edit-post.html partial:
<form ng-submit="updatePost(post)">
<h3>Edit post</h3>
<div ng-include="'home/_form-post.html'"></div>
</form>
_form-post.html partial:
<md-input-container>
<label>Title</label>
<input required type="text" ng-model="title">
</md-input-container>
<md-input-container>
<label>Link</label>
<input type="text" ng-model="link">
</md-input-container>
<md-button type="submit" class="md-raised md-primary">Submit</md-button>
What am I doing wrong, how can I send the edited form data within the PUT request?
This is happening because, your, are just passing the original post object generated by ngRepeat to the update function not the $scope.post. When using ng-model="post" this will be attached to the $scope object.
You do not need the editPost function, the new data are already passed to $scope.title/$scope.title by ngModel directive (doing this will re-update the $scope.tile, $scope.link with the old values):
// Edit post
$scope.editPost = function(post){
$scope.title = post.title;
$scope.link = post.link;
};

AngularJs how to reload a template page after selecting a charater

I am using http.get and i need to reload a template after selecting a character so that my template gives the answer according to what I selected
The code of the template
<div class="container-fluid" ng-controller="CriterioCtrl">
<div id="result"></div>
<div>
Selected Items:
<div ng-repeat="id in selection">
{{id}}
</div>
</div>
<div ng-repeat-start="crit in data" class="row">
<h2 align="center">{{crit.name}}</h2>
<div ng-repeat="caracter in crit.characters" class="col-md-4">
<div type="checkbox" value="{{caracter.id}}" ng-checked="selection.indexOf(caracter.id) > -1" ng-click="clickSelection(caracter.id)">
<a href="#crit" class="thumbnail" ng-click="clickCriterios(caracter.id)">
<h4 align="center">{{caracter.name}}</h4>
<img ng-src="http://skaphandrus.com/{{caracter.image_url}}"/>
</a>
</div>
</div>
</div>
<div ng-repeat-end>
</div>
<!--<button class="btn" ng-click="toggle()">Toggle</button>
<p ng-show="visible">Hello World!</p> codigo de um botao -->
</div>
This code is for the selection
$scope.selection=[];
$scope.clickSelection = function clickSelection(caracterId) {
var idx = $scope.selection.indexOf(caracterId);
// is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// is newly selected
else {
$scope.selection.push(caracterId);
}
var selectedId = $scope.selection;
console.log(selectedId);
// Check browser support
if (typeof(Storage) != "undefined") {
// Store
localStorage.setItem("idSelect", selectedId);
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("idSelect");
}
};
This code is the http part in another controller
MyApp.controller('EspeciesCtrl', function ($scope, $http) {
$http({
url: 'someurl',
method: "post",
params: {module_id: localStorage.getItem("idMod"),"characters[]": [localStorage.getItem("idSelect")]}
})
.then(function(res){
$scope.data = res.data;
});
});
This is the code of the template that have to change after the selection
<div class="container-fluid" ng-controller="EspeciesCtrl">
<div class="row">
<div ng-repeat="esp in data" class="col-md-6">
<a href="#infEsp" class="thumbnail" ng-click="clickEspecie(esp.id)">
<h4 align="center">{{esp.name}}</h4>
<img ng-src="{{esp.image_src}}"/>
</a>
</div>
</div>
</div>
How can i do that?
edit 1
If I've correctly understood, you may need to use ng-show (https://docs.angularjs.org/api/ng/directive/ngShow) whose boolean value checks if the user selected anything and show the extra bit of code you need, instead of trying to have another http request.
Also, it seems like you are using $scope.data for both the esp and the crit, so you will end up with the errors.
You probably don't need to reload the template.
You may want to use the data in $scope.data inside the template in order to let Angular manage the update on the view. As soon as the $scope.data changes, the rendered HTML changes too.
I can't comment but it would be helpful if you could share the template you are using and be more specific in your request :)

Angular Material - Dynamically add tab and change to that tab

Currently working on a chat app here https://playwithfire.firebaseapp.com/ and whenever a user adds a new room I want the new room tab to be entered. Currently you can add a room but need to click it afterwards to enter that room and display its content.
I tried changing the attribute md-selected="selectedIndex" but that makes no tab active so no content appears.
Is it possible to do what I'm asking for? What I've got so far:
index.html
<div layout="column" ng-controller="RoomController">
<!-- Tabs Container -->
<md-tabs md-stretch-tabs md-selected="selectedIndex">
<!-- Individual Tab -->
<md-tab ng-repeat="room in roomList"
label="{{room.roomName}}">
<div ng-controller="ChatController">
<!-- Display messages -->
<md-list>
<md-item ng-repeat="msg in messages">
<md-item-content>
<div class="md-tile-content">
<div class="bubble">
<strong>{{msg.from}}</strong><br>
{{msg.body}}
</div>
</div>
</md-item-content>
</md-item>
</md-list><!--/DisplayMessages-->
<!-- Chat controls -->
<div layout="row" layout-margin layout-wrap>
<div flex="33">
<!-- Assign username -->
<label for="nameInput">Username</label>
<input ng-model="name" type="text" id="nameInput" placeholder="Enter a username...">
</div>
<div flex="95">
<!-- Post a message -->
<label>Message</label>
<textarea class="form-control"
ng-model="msg"
ng-keydown="addMessage($event)"
id="messageInput"
placeholder="Type a message...">
</textarea>
</div>
<div layout="row" layout-sm="column" layout-margin layout-fill layout-align="start end">
<!-- Click to send message -->
<div flex>
<md-button class="md-raised md-primary pull-left" ng-click="sendMessage()">Send</md-button>
</div>
<!-- Modal to add or join room -->
<div flex ng-controller="ModalController">
<md-button class="md-raised md-primary pull-left" ng-click="open()">Add or Join Room</md-button>
</div>
<!-- Opens helper -->
<div flex ng-controller="HelpController">
<md-button class="pull-right" ng-click="open()" ng-href="">Need help?</md-button>
</div>
</div>
</div><!--/ChatController-->
</md-tab>
</md-tabs><!--/tabs container-->
</div><!--/RoomController-->
room.js
angular.module('myApp')
.controller('RoomController', function($scope, ShareFactory) {
$scope.roomList = ShareFactory.roomList;
// use this to default to index 0 in roomList
$scope.selectedIndex = 0;
$scope.$on('RoomChange', function(event, data) {
$scope.selectedIndex = data;
console.log('Heard the change!');
console.log('The data is: ' + data);
});
});
modal.js
angular.module('myApp')
.controller('ModalController', function($rootScope, $scope, $modal, ChatFactory, ShareFactory) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'views/modal.html',
controller: 'ModalInstanceController'
});
modalInstance.result.then(function (name) {
var found = false;
var length = ShareFactory.roomList.length;
var index = 0;
for(var i = 0; i < length; ++i) {
if(ShareFactory.roomList[i].roomName === name) {
found = true;
index = i;
console.log('index ' + index);
}
}
if(!found) {
ShareFactory.roomList.push({ roomName : name});
index = ShareFactory.roomList.length - 1;
}
else {
// don't care about disabled, not a feature i want to use
//ShareFactory.roomList[index].disabled = false;
}
// Broadcast event to all children of rootScope
// namely want RoomController to listen for this change
$rootScope.$broadcast('RoomChange', index);
}, function () {
console.log('cancel');
});
};
});
Ya know, this definitely came up in a Github issue a while ago, but it may have been kicked to the backlog due to other high priority issues.
I just added this feature to master:
https://github.com/angular/material/commit/8285e2d0bb6efbc72e311ee85b619cbbe8437072
And it should be viewable shortly on our site in the second demo:
https://material.angularjs.org/HEAD/#/demo/material.components.tabs
In the meantime, you should be able to solve this by adding the following code:
if(!found) {
ShareFactory.roomList.push({ roomName : name});
index = ShareFactory.roomList.length - 1;
$timeout(function () {
ShareFactory.selectedIndex = index;
});
}
The $timeout is necessary because you must wait until after the render is finished before you can update the selected index to the new one - otherwise, it will think that the valid is out of range.
Hope this helps!

Resources