I have a table of info generated by ng-repeat.
I want to add a feature to each row of table which gives user ability to see more detail of that specific record. I added another ng-model which gets the key of that row and asks server for more detail.
But controller cannot read this ng-model. my code is as below:
HTML:
<html ng-app = "myApp">
<head>
...
</head>
<body>
...
<div ng-controller = "AppCtrl">
...
<content>
<div class="general_detail">
<div ng-model = "docParam.docNo"></div>
<div class = "dialog" ng-repeat = 'doc in doclist'>
<table class = "detail">
<tbody>
...
<tr>
...
<td style="text-align: right">
<div ng-model = "docDetail.docNo"></div>
<a href="" ng-click="docDetail.docNo = doc.NO; docDetailP()" >More...</a>
</td>
<td>
<div ng-repeat = 'd in detailView'>
<p>
Rev : {{d.REV_NO}}
</p>
</div>
</td>
</tr>
...
</tbody>
</table>
</div>
</div>
</content>
...
</body>
</html>
Controller:
$scope.docDetailP = function() {
$http.post('/docQuery', $scope.docDetail);
docDetailG();
};
var docDetailG = function() {
$http.get('/docDetails').then(function(response) {
$scope.detailView = response.data;
});
};
Thanks in advance for your solutions.
These are the errors which you made,
<div ng-model = "docParam.docNo"></div>
ng-model will work for form elements
why do you assign docDetail.docNo = doc.NO; and then call the method. Instead you can pass as a parameter
Change the way of posting the value $http.post('/docQuery', $scope.docDetail);.
Have a look at the modified code.
HTML
<content>
<div class="general_detail">
<div ng-model = "docParam.docNo"></div>
<div class = "dialog" ng-repeat = 'doc in doclist'>
<table class = "detail">
<tbody>
...
<tr>
...
<td style="text-align: right">
<div ng-model = ""></div>
<a href="" ng-click="docDetailP(doc.NO)" >More...</a>
</td>
<td>
<div ng-repeat = 'd in detailView'>
<p>
Rev : {{d.REV_NO}}
</p>
</div>
</td>
</tr>
...
</tbody>
</table>
</div>
</div>
</content>
Your controller should be like
$scope.docDetailP=function (number) {
$http({
method: 'POST',
url: '/docQuery',
headers: {
'Content-Type': 'application/json'
},
data: number
})
.success(function (data, status, headers, config) {
successcallback(data);
})
.error(function (data, status, headers, config) {
$log.warn(data, status, headers, config);
})
$scope.docDetailG();
}
Be careful that my solution assumes that the web service endpoint recieves a number.
Related
Using Angularjs I can't do ng-repeat. First ng-repeat is working fine next is not working fine
Html code
<div class="col-xs-12" ng-app="myAns" ng-controller="myCtrl">
<table class="table">
<tr><td ng-repeat="fullname in team1_name">{{fullname}}</td></tr>
<tr><td ng-repeat="strike in team1_strike">{{strike}}</td></tr>
<tr><td ng-repeat="wickets in team1_wickets">{{wickets}}</td></tr>
</table>
</div>
Js code
<script>
var app = angular.module('myAns', []);
app.controller('myCtrl', function($scope, $http, $timeout) {
$timeout(function() {
$http({
url: 'cricketAnswerSuggestionApi.php',
method: "POST",
withCredentials: true,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function (response) {
$scope.team1_name = response.data.team_1.fullname;
$scope.team1_strike = response.data.team_1.strike_rate;
$scope.team1_wickets = response.data.team_1.wickets;
});
});
});
</script>
JSON response link
https://jsfiddle.net/rijo/aapfa0sL/
Kindly anyone help how to print this value using angularjs ... Thanks for all
Because you have some duplicate data
Use track by $index for team1_strike and team1_wickets
Try this,
<div class="col-xs-12" ng-app="myAns" ng-controller="myCtrl">
<table class="table">
<tr>
<td ng-repeat="fullname in team1_name">{{fullname}}</td>
</tr>
<tr>
<td ng-repeat="strike in team1_strike track by $index">{{strike}}</td>
</tr>
<tr>
<td ng-repeat="wickets in team1_wickets track by $index">{{wickets}}</td>
</tr>
</table>
DEMO
My issue is when I load the page first time the angular is working pretty well. but when I try to use same thing when my html is loaded with ajax it is not working at all. nor I can see any relevant error in console.
javascript:
var myApp = angular.module('myApp', ['ngSanitize','ui.utils']);
myApp.controller('CtrlPerformanceByTrack', function($scope, $http) {
$http.get(site_url + 'performance/?method=get_performance_by_track_data').success(function(data, status) {
/*console.log(data.data);
data=[{"title":"title 1","length":"3:02","plays":4,"sales":2,"likes":8},
{"title":"title 1","length":"3:02","plays":4,"sales":2,"likes":8}]
console.log(data);*/
$scope.tracks = data.data;
}).error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
});
html:
<div data-ele="PerformanceByTrackApp" class="track-block" ng-controller="CtrlPerformanceByTrack">
<div class="title">
Performance by track
</div>
<div class="search-block">
<form>
<div class="content fr">
<div class="left-input">
<input type="text" class="form-control" placeholder="Search Track" ng-model="searchTrack">
</div>
<div class="right-icon-block">
<span class="icon-magnifying42 search-icon"></span>
</div>
</div>
</form>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
<div class="table-block">
<table class="table table-striped table-responsive track-table">
<thead class="title">
<th style="width:50%;">Title</th>
<th style="width:13%;">Length</th>
<th style="width:13%;">Plays</th>
<th style="width:13%;">Sales</th>
<th style="width:14%;">Likes</th>
</thead>
<tr ng-repeat="item in tracks | filter:searchTrack">
<td>{{item.title}}</td>
<td>{{item.length}}</td>
<td>{{item.plays}}</td>
<td>{{item.sales}}</td>
<td>{{item.likes}}</td>
</tr>
</table>
</div>
</div>
the sample is at below url:
http://engagev2.ncryptedprojects.com/performance
to call the same page via ajax click performance tab at left.
If you're getting this partial HTML via AJAX, then it should be properly inserted. You have to use angular $compile service. Simplified example below.
...
var template = getTemplate();
var compiledElement = $compile(template)($scope);
element.append(compiledElement);
...
Here is the link https://docs.angularjs.org/api/ng/service/$compile
Caveat: I've just started with client side scripting and Angular JS is the first thing I'm learning and now I feel I should've started with javascript.
PS: I don't wanna use any third party libraries. I wanna learn to code.
Anyway,I have dynamic table which I want to make editable using content-editable=true attribute of HTML.
Problem: How to I get the edited data? whenever I click on submit and pass the this object to the check() function. I doesn't contain edited values. is there a possible way to pass only edited value if it's dirty. It has pagination so If g to the next page the edited values are gone. I know I've give unique Id to every td element with $Index concatenated to it. But I don't know how should I proceed.
Any help or guidance will be appreciated. Controllers and others are defined in my route.
<div>
<form ng-submit="check(this)">
<table class="table table-striped table-hover">
<tbody>
<tr ng-repeat="data in currentItems">
<td contenteditable="true >{{data.EmpNo}}</td>
<td contenteditable="true">{{data.isActive}}</td>
<td contenteditable="true">{{data.balance}}</td>
<td contenteditable="true">{{data.age}}</td>
<td contenteditable="true">{{data.eyeColor}}</td>
<td contenteditable="true">{{data.fname}}</td>
</tr>
</tbody>
<tfoot>
<td>
<div class="pagination pull-right">
<li ng-class="{'disabled': previousPage}">
<a ng-click="previousPage()" >Previous</a>
</li>
<li ng-repeat="page in pageLengthArray track by $index">
<a ng-click="pagination($index)">{{$index+1}} </a>
</li>
<li disabled="disabled">
<a ng-click="nextPage()" ng-class="{'disabled':nextPage}>Next </a>
</li>
</div>
</td>
</tfoot>
</table>
<input type="submit" value="Submit">
</form>
$scope.currentPage=0;
$scope.pageSize=10;
$scope.currentItems;
$scope.tableData;
$http.get('../json/generated.json').then(function(response){
$scope.tableData=response.data;
$scope.pageLength=Math.ceil($scope.tableData.length/$scope.pageSize);
$scope.currentItems=$scope.tableData.slice($scope.currentPage,$scope.pageSize);
$scope.pageLengthArray= new Array($scope.pageLength);
});
$scope.pagination=function(currentPage){ $scope.currentItems=$scope.tableData.slice($scope.pageSize*currentPage,$scope.pageSize*currentPage+$scope.pageSize);
$scope.currentPage=currentPage;
}
$scope.nextPage=function nextPage(argument) {
$scope.currentPage++; $scope.currentItems=$scope.tableData.slice(($scope.pageSize*$scope.currentPage),($scope.pageSize*($scope.currentPage)+$scope.pageSize));
}
$scope.previousPage=function previousPage(argument) {
$scope.currentPage--;
$scope.currentItems=$scope.tableData.slice(($scope.pageSize*$scope.currentPage),($scope.pageSize*($scope.currentPage)+$scope.pageSize));
}
In the usual case, you can not get a change model for contenteditabe because to change the model used ngModel.
But we can create a directive that we have updated the value of the model.
Live example on jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope, $timeout) {
$scope.data = {
EmpNo: "123"
};
})
.directive('contenteditable', function($timeout) {
return {
restrict: "A",
priority: 1000,
scope: {
ngModel: "="
},
link: function(scope, element) {
element.html(scope.ngModel);
element.on('focus blur keyup paste input', function() {
scope.ngModel = element.text();
scope.$apply();
return element;
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<table>
<tr>
<td ng-model="data.EmpNo" contenteditable="true"></td>
</tr>
</table>
<pre>{{data|json}}</pre>
</div>
</div>
I would store any object that gets modified in a seperate array using the ng-keyup directive. When the form is submitted, you will have an array of only elements which have been modified. You may have some UX issues if your pagination is done by server as when you change page and come back, it will show your old data, but hopefully this helps.
$scope.check = function () {
// check modifiedItems
console.log(modifiedItems);
};
// store modified objects in a seperate array
var modifiedItems = [];
$scope.modifyItem = function (data) {
// check if data has already been modified and splice it first
for(var i = 0, j = modifiedItems.length; i < j; i++) {
var currentItem = modifiedItems[i];
if (currentItem.id === data.id) {
modifiedItems.splice(i, 1);
break;
}
}
// add to modified
modifiedItems.push(data);
console.log('modifiedItems: ', modifiedItems);
};
HTML
<form ng-submit="check()">
<table class="table table-striped table-hover">
<tbody>
<tr ng-repeat="data in currentItems">
<td ng-repeat="(key, value) in data" contenteditable="true"
ng-keyup="modifyItem(data)">
{{data[key]}}
</td>
</tr>
</tbody>
<tfoot>
</table>
<input type="submit" value="Submit">
</form>
First of all i'm new to AngularJS and stackoverflow so i'm very open minded. My problem is that i have a table that has 3 items that use the ng-blur directive to call a save function
UI
<div ng-controller="measureController">
<div class="jumbotron">
<h3>RatingYear</h3>
<select ng-model="ratingYear" ng-change="getMeasures()">
<option ng-repeat="year in years" value="{{year}}">{{year}}</option>
</select>
</div>
<!-- this is going to be the container for each measure-->
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Measures for {{ratingYear}}</div>
<table class="table table-bordered table-hover">
<tbody>
<tr>
<th>Code</th>
<th>Name</th>
<th>Action</th>
<th>Active</th>
<th>Order</th>
</tr>
<tr ng-repeat="measure in measureList track by measure.MeasureId">
<td class="col-md-1">{{measure.Code}}</td>
<td class="col-md-5">{{measure.Name}}</td>
<td class="col-md-4"><textarea ng-model="measure.Action" ng-disabled="!measure.Active" ng-blur="save(measure)"></textarea></td>
<td class="col-md-1"><input type="checkbox" ng-checked="measure.Active" ng-model="measure.Active" ng-change="save(measure)" /></td>
<td class="col-md-1"><input class="form-control" ng-model="measure.Order" ng-disabled="!measure.Active" ng-blur="save(measure)" /> </td>
</tr>
</tbody>
</table>
</div>
</div>
Controller
function measureController($scope, $http) {
$scope.years = [2014,2015, 2016 ];
//get Measures Per Year
$scope.getMeasures = function () {
$http.get('/api/measure/' + $scope.ratingYear)
.success(function (data, status, headers, config) {
$scope.measureList = data;
$scope.$apply();
//$scope.loading = false;
})
.error(function () {
$scope.error = "An Error has occured while loading measures!";
$scope.loading = false;
});
};
//Edit Measure
$scope.save = function () {
$scope.loading = true;
var uMeasure = this.measure;
var active = uMeasure.Active ? 1 : 0;
$http.post('/api/measure/' + uMeasure.MeasureId + '/status/' + active, uMeasure)
.success(function (data, status, headers, config) {
$scope.measureList.push(data);
$scope.$digest();
})
.error(function (data,status, headers, config) {
alert("You failed misserably"+data);
});
};
}
I want to be able to refresh the measureList every time save has been called with the new object that has been inserted, that is the modify copy of the existing, right now is creating multiple copies of the same one in the database and i can only see it when i reload the page or change the value in ratingYear.
Thanks in advance
I am using Angularjs and i make a call form server to retrieve data. Data are successfully retrieved but my view is not updated. I don't understand why. Here are the code i use.
Angularjs and html code :
<div class="row custom-margin" ng-controller="ListCtlr" ng-init="initData()">
<form class="form-inline" role="form" id="formId" name="formId">
<div class="form-group">
<label for="searchInput">Data to search</label>
<input ng-model="searchInput" placeholder="Enter term to search">
</div>
<button type="submitSearch" class="btn btn-primary" ng-click="search()">Go</button>
</form>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr class="info">
<th colspan="4" class="centertext">Name</th>
<th colspan="3" class="centertext">Age</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in persons">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Controller code :
function ListCtlr($scope, $http, $location,$filter) {
$scope.formId = {searchInput: ''};
$scope.search = function () {
var url='server/search/'+this.searchInput;
$http.get(url)
.success(function (data) {
$scope.persons = data;
})
.error(function(data){
$scope.error = data;
});
};
}
When i inspect the data retrieved form server i get the following JSON data :
[{"name":"John","age":12},{"name":"Mary","age":25},{"name":"Garry","age":28}]
What's missing please ?
Change
<tr ng:repeat="person in persons">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
to
<tr ng-repeat="person in persons">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
The problem is that your ListCtlr controller is placed on a div that does not contain your ng-repeat.
To solve this, create an outer div, put the ng-controller on that div:
<div ng-controller="ListCtlr">
... (place contents of your html here) ...
</div>
This ensures that ListCtlr's scope includes the ng-repeat.
Note: Be sure to remove the ng-controller="ListCtlr" defined in your inner div.