AngularJS send updated data to php page via $http.post - javascript

I have just added the functionality to edit a table cell in my angularJS app. What I would like to do now is have the changes reflected in the database by sending the updated data to my PHP script, I'm a little stuck on how to actually resend the updated table.
My Angular Table in question:
<tr ng-repeat="c in resultValue=(data | filter:{'type':typeFilter} | filter:dateFilter | filter:proFilter | filter:cusFilter | filter:taskFilter | filter:nameFilter)">
<td class="jid" ng-hide="viewField">{{c.journal_id}}</td>
<td ng-show="modifyField"><input type="text" class="in1" ng-model="c.journal_id" /></td>
<td class="wda" ng-hide="viewField">{{c.work_date}}</td>
<td ng-show="modifyField"><input type="text" class="in1" ng-model="c.work_date" /></td>
</tr>
<button ng-hide="viewField" ng-click="modify(c)">Modify</button>
<button ng-show="modifyField" ng-click="update(c)">Update</button>
The controller thanks to a SO answer for the edit part:
journal.controller('dbCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.loadData = function () {
$http.get("http://localhost/slick/journalFetch.php").success(function(data){
$scope.data = data;
}).error(function() {
$scope.data = "error in fetching data";
});
}
$scope.modify = function(c){
$scope.modifyField = true;
$scope.viewField = true;
};
$scope.update = function(c){
$scope.modifyField = false;
$scope.viewField = false;
//AM I ABLE TO RESEND THE UPDATED (c) DATA HERE TO THE DATABASE ?
$http({
method: "post",
url: "update.php",
data: {
//if so how to retrieve updated c data here?
}
});
};
$scope.loadData();
}]);

Looks like you are trying to update the entire table with a single Update button click. Your current code is trying to access c outside the tr element which makes c out of scope for the button.
Try passing data variable to the update function.

Related

Angular 1 - Sharing data between parent and child controller - Need advice

Im working on 2 apps that will simply display all active incidents and then all closed incidents. The 2 apps share similar logic when it comes to create, modify, save and delete.
So im trying to figure the best aproach to share the CRUD logic between the 2 applications. I tought maybe it would be best to set a parent - child controller setup like so:
Common_CRUD_file.js:
var Common_Application = .module('Common_Application ',[app, app1, app2, app3])
Parent_controller.controller('Parent_controller'), function ($scope, $http, $filter, $timeout) {
//all my CRUD logic goes in here
$scope.edit = function(data) { //edit logic goes here }
$scope.save = function(data) { //save logic goes here }
$scope.cancel = function(data) { //cancel logic goes here }
$scope.delete = function(data) { //delete logic goes here }
}
Child_Show_closed_incidents.js:
var Common_Application = angular.module('Common_Application');
Child_controller.controller('Child_controller'), function ($scope, $http, $filter, $timeout) {
//All of the app logic goes here
$scope.get_data = function(data) { //store fetched ajax data in $scope.All_closed_incidents }
}
Quick excerpt of the HTML file:
<div ng-app="Common_Application" ng-controller="Parent_controller">
<div ng-controller="Child_controller">
<table directive_for_angular_app_here>
<tr>
<td></td>
<td>Description</td>
<td>Status</td>
</tr>
<tr ng-repeat="incident in All_closed_incidents">
<td><button type="button" ng-click="edit(incident)">Edit</button></td>
<td>{{incident.Description}}</td>
<td>{{incident.Status}}</td>
</tr>
</div>
</div>
So this setup is able to load my table but the edit function dosent seem to fire at all when I click on the button. No errors in the console either. Seems to ignoring my Parent functions all together when I was expecting it to share all of its scopes. Would anyone have a better aproch to this?
I would discard the parent/child setup you have. Turn the parent into a service with functions:
//all my CRUD logic goes in here
$scope.edit = function(data) { //edit logic goes here }
$scope.save = function(data) { //save logic goes here }
$scope.cancel = function(data) { //cancel logic goes here }
$scope.delete = function(data) { //delete logic goes here }
then inject that service into the child controller and call the functions. Reduces complexity and enhances reusability.

AngularJS: ng-hide not working

I am trying to hide a column in my table using ng-hide. Before the user logins the column should not been shown to the user. After they login the hidden column should be shown. But now after i used the ng-hide property the whole table is hidden if the user isnt login into the system. Can i know how to solve this problem.
This is my partial html code:
<table class="table table-hover table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th ng-show="noteEnabled">Note</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="movie in movies | pagination: currentPage * entryLimit | limitTo: entryLimit" data-ng-class="{'selected':selectedFilm.film_id===movie.film_id}" >
<td>
{{movie.title}}
</td>
<td>
{{movie.description}}
</td>
<td data-ng-click="selectFilmDetails($event,movie)" ng-show="movie.noteEnabled" >
{{movie.comment}}
</td>
</tr>
</tbody>
</table>
This is my controller.js code:
.controller('AllMovieController',
[
'$scope',
'dataService',
'$location',
function ($scope, dataService, $location){
$scope.noteEnabled = false;
$scope.movies = [ ];
$scope.movieCount = 0;
$scope.currentPage = 0; //current page
$scope.entryLimit = 20; //max no of items to display in a page
var getAllMovie = function () {
dataService.getAllMovie().then(
function (response) {
var userName=dataService.getSessionService('user');
$scope.movieCount = response.rowCount + ' movies';
if(userName){
$scope.movies = response.data;
$scope.userLogin = dataService.getSessionService('user');
$scope.userLoginEmail = dataService.getSessionService('userEmail');
$scope.showSuccessMessage = true;
$scope.successMessage = "All movie Success";
$scope.noteEnabled = true;
}
},
function (err){
$scope.status = 'Unable to load data ' + err;
}
); // end of getStudents().then
};
$scope.numberOfPages = function(){
return Math.ceil($scope.movies.length / $scope.entryLimit);
};
//------------------
$scope.selectFilmDetails = {};
$scope.selectFilmDetails = function ($event,movie) {
$scope.selectFilmDetails = movie;
$location.path('/filmDetails/' + movie.film_id);
}
getAllMovie();
}
]
)
At first i set the noteEnabled to false and check with the session if the user is logged in then the noteEnabled will become true. Thanks in advance.
Use ng-hide="$parent.noteEnabled" instead of ng-hide="noteEnabled".
To access $scope variable from the loop (ng-repeat) use $parent
Here is a good example of how to use ng-show and ng-hide and here is the official documentation as well . Hope it helps !
In your case you have use ng-show/ ng-hide only to tag in of the column you want to show/hide. So on any scenario whole table will not be hide unless there is no data so you may is it as hidden.
Anyway as per you code, seems you have misused ng-show/hide. On controller initially you set noteEnabled to false and after you check the logging you set noteEnabled to true. as you have used ng-show/hide as follows
<td data-ng-click="selectFilmDetails($event,movie)" ng-hide="noteEnabled" >
{{movie.comment}}
</td>
the result will be; initially column will be shown and after your dataService receive userName it will hide the column. The opposite of what you want!!!. So change the directive you use from ng-hide to ng-show or change the value set to noteEnabled.
The real cause behind problem is, ng-repeat does create child scope which is prototypically inherited from parent scope, while rendering each iteration element where ng-repeat directive has placed.
And the you have used noteEnabled variable as primitive datatype, so when you use noteEnabled variable inside a ng-repeat div it does gets added inside that ng-repeat div scope.
noteEnabled property to be maintained on each element level of movies collection. Then do toggle, whenever you want.
ng-show="movie.noteEnabled"
By default it will be hidden & toggle it whenever you want to show it.
Even better approach is to follow controllerAs pattern where you don't need to care about prototypal inheritance. While dealing with such a variable access thing on UI.
I solved the problem by myself. Here is the solution for it.
$scope.noteEnabled = false;
$scope.movies = [ ];
$scope.movieCount = 0;
$scope.currentPage = 0; //current page
var getAllMovie = function () {
dataService.getAllMovie().then(
function (response) {
var userName=dataService.getSessionService('user');
$scope.movieCount = response.rowCount + ' movies';
if(userName){
$scope.movies = response.data;
$scope.userLogin = dataService.getSessionService('user');
$scope.userLoginEmail = dataService.getSessionService('userEmail');
$scope.showSuccessMessage = true;
$scope.successMessage = "All movie Success";
$scope.noteEnabled = true;
}else{
$scope.movies = response.data;
$scope.noteEnabled = false;
}

http returns data but doesn't update view

I have this input field in my html:
<input type="text" spellcheck="false" id="widgetu1049_input"
name="custom_U1049" tabindex="3" placeholder="Search..." ng-model="searchText"
ng-change="getPostHttp()" ng-trim="false"/>
and i'm calling http post in a scope function:
$scope.getPageItems = function(callback){//TODO add county and state moudles
var search = {'searchText':$scope.searchText,'state' : $scope.currentState,'county' : ''};
var params = {'action':'getPageItems', 'currentPage':$scope.currentPage, 'pageSize':$scope.pageSize, 'search':search };
$http.post(EndPoint, params).then(function(response) {
var page=response.data;
console.log(page);
callback(page);
});
}
I'm calling the above function from this function:
$scope.getPostHttp = function(){
$scope.getPageItems(function(data) {
$scope.items = data;
});
}
I've got this approach from this question Angular $http returns data but doesn't apply to scope
And although it shows the items on an ng-init call I made, it does not update on the ng-change call above.
Any ideas?
EDIT: I'm adding the view of the ng-repeat call:
<tr style=" background-color: #BFBFBF;" ng-model="items" ng-class="{marked: isExists(item.id) == true}" ng-click="view(item.id)"
data-toggle="modal" data-target="#smallModal" ng-repeat="item in items" ng-animate="'animate'">
<td ng-show="id">{{item.id}}</td>
<td ng-show="fname">{{item.fname}}</td>
</tr>

How to keep track of Array index in angularJS?

Very new to Angularjs. So I have some JSON files that I am reading into my webpage that contain and array of objects that are cars. What I am trying to do is have my "button" when pressed alert me to the data specific to that button.
The ng-repeat is running 8 times so that is the length of the array, but in angularJs i'm not sure how to basically store the array index for each time the ng-repeat passes in my button function.
This is my a snippet of my .html:
<div class="carTable table-responsive text-center" ng-controller="ButtonController" >
<table class="table specTable">
<thead>
<tr>
<th>Make</th>
<th>Model</th>
<th>Year</th>
<th>Color</th>
<th>Milage</th>
<th>Doors</th>
<th class="reserve">Horsepower</th>
<th>Price</th>
<th class="reserve"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="cars in car | orderBy:'year'">
<td>{{cars.year}}</td>
<td>{{cars.model}}</td>
<td>{{cars.make}}</td>
<td>{{cars.color}}</td>
<td>{{cars.mileage | number}}</td>
<td>{{cars.doors}}</td>
<td>{{cars.horsepower}}</td>
<td>{{cars.price | number}}</td>
<td><div class="panel panel-default">Reserve</div></td>
</tr>
</tbody>
</table>
</div>
The portion in question is at the bottom where I have a Reserve "button"
I'm leaving out my JSON files, works properly there. I'm just not sure how to keep track of the array index as the ng-repeat does its thing.
Here is the angular:
(function(){
var app = angular.module("myReserveApp", []);
app.controller("ButtonController", ["$scope", "$window", function($scope, $window){
$scope.buttonPress = function(){
$window.alert(JSON.stringify($scope.car[0]));
}
}]);
var MainController = function($scope, $http, $window){
var onGatherBoatData = function(response){
$scope.boat = response.data;
};
var onError = function(reason){
$scope.error = "Could not fetch Boat Data";
};
var onGatherCarData = function(response){
$scope.car = response.data;
};
var onError = function(reason){
$scope.error = "Could not fetch Car Data";
};
var onGatherTruckData = function(response){
$scope.truck = response.data;
};
var onError = function(reason){
$scope.error = "Could not fetch Truck Data";
};
$scope.message = "Hello, Angular Here!";
};
app.controller("MainController", ["$scope", "$http", "$window", MainController]);
}());
Currently in the top portion of the code I just have it alerting object[0] but I want it to be specific to which button is pressed. Any help is appreciated, thank you.
$index refers to the index in ng-repeat. So if you want to pass your function the index in array on the button click, change buttonPress() to buttonPress($index)
you'll have to change your controller to something like the following:
$scope.buttonPress = function(index){
$window.alert(JSON.stringify($scope.car[index]));
}
To do the following, you can just pass the current data in the ngRepeat. Moreover,if you want the current index, the ngRepeat directive provide specials properties, as the $index, which is an iterator.
$scope.buttonPress = function(car, index){
//Retrieve current data of the ngRepeat loop
console.log(car);
//Current index of your data into the array
console.log(index);
}
Then you can call your function like this :
Reserve
First, thank you both for the quick responses. Both of these answers work. I found another way to do it as well before reading your posts.
<div class="panel panel-default">
Reserve:{{car.indexOf(cars)}}
</div>
Using (car.indexOf(cars)) gives me the same result
$scope.buttonPress = function(index){
$window.alert(JSON.stringify(index));
}
Now when I click on the "button" it sends me back the array index, so now I should be able to play with that data. Thank you again both, for your help.

Javascript Assign New Field to object

I have a snippet of code here running in a node application
for( i=0; i < Equipment.length; i += 1 ) {
Equipment[i].NumberForSearch = Equipment[i].ClassPrefix + "-" + Equipment[i].UnitNumber;
console.log(Equipment[i].NumberForSearch);
}
console.log(Equipment[0]);
Equipment is an array of objects and I am trying to add a property to each object in that array called "NumberForSearch".
In my application the way we want to display unit numbers for equipment is "ClasssPrefix"-"UnitNumber". The reason I am wanting to join them here into one variable is that inside my angular application, I want the user to be able to type 12345-12345 inside of a search field which then filters out the Equipment. This doesnt work if I have {{ClassPrefix}}-{{UnitNumber}} for obvious reasons, angular doesnt know that the - even exists.
The problem is that inside my for loop everything is checking out fine. Its logging just as its supposed to, so I figured it worked. When I checked the front end and changed it to display "NumberForSearch", nothing showed up.
I then added the logging statement outside the for loop to check just one of my objects to see if the field even existed and it doesnt. So my question is, why is this snippet not adding the "NumberForSearch" field in my object?
You have to make object with this field before setting to $scope's parameter.
Have a look at init() function.
After adding NumberForSearch field we defined array of objects to parameter in scope.
Of course ng-repeat will loop through it and render elements.
So we will add "| filter:query" to show only needed
<div ng-controller="EquipmentController">
<input type="text" ng-model="query.NumberForSearch" placeholder="search">
<ul>
<li ng-repeat="Item in Equipment | filter:query">{{Item.ClassPrefix}}-{{Item.UnitNumber}}</li>
</ul>
</div>
js part:
var App = angular.module('App', []);
App.controller('EquipmentController', function ($rootScope, $scope, $http, $filter) {
$scope.Equipment = [];
$scope.init = function() {
var request = $http({
method: 'get',
url: '/path/to/equipment/resource'
});
request.success(function (response) {
var Equipment = response.Equipment;
for(var i in Equipment) {
Equipment[i].NumberForSearch = Equipment[i].ClassPrefix + "-" + Equipment[i].UnitNumber;
}
$scope.Equipment = Equipment;
$scope.$apply();
});
}
$scope.init();
});
another way of filtering is to send search field to route, in another word we send query to server and it filters response on serverside.
<div ng-controller="EquipmentController">
<input type="text" ng-model="queryNumber" ng-change="searchByNumber()" placeholder="search">
<ul>
<li ng-repeat="Item in Equipment">{{Item.ClassPrefix}}-{{Item.UnitNumber}}</li>
</ul>
</div>
js part:
var App = angular.module('App', []);
App.controller('EquipmentController', function ($rootScope, $scope, $http, $filter) {
$scope.Equipment = [];
$scope.all = function() {
var request = $http({
method: 'get',
url: '/path/to/equipment/resource'
});
request.success(function (response) {
$scope.Equipment = response.Equipment;
$scope.$apply();
});
}
$scope.all();
$scope.searchByNumber = function() {
var request = $http({
method: 'get',
url: '/path/to/equipment/resource?number='+$scope.queryNumber
});
request.success(function (response) {
$scope.Equipment = response.Equipment;
$scope.$apply();
});
}
});

Categories

Resources