I am changing a user list/table I made with Razor and JQuery into AngularJS. One of the features of this table was the ability to show/hide additional user details. The table had two sets of tr with the second one being display:none but would slide down/be visible when its above tr was clicked to show details.
Example (Original) Working Example
I tried to apply the code onto my AngularJS but it does not seem to work for some reason (no errors either)
Original Code (skeleton)
<table>
<tr class="col-xs-12">
<td class="col-xs-2">#Html.DisplayFor(modelItem => item.name)</td>
<td class="col-xs-2">#Html.DisplayFor(modelItem => item.email)</td>
// ect...
</tr>
<tr class="col-xs-12" style="display:none">
<td colspan="12">
<p>
#Html.DisplayFor(other stuff)
</p>
</td>
</tr>
</table>
New AngularJS Code
<table class="table table-striped col-xs-12">
<tbody ng-repeat="actors in Users">
<tr class="col-xs-12">
<td class="col-xs-2">{{actors.name}}</td>
<td class="col-xs-2">{{actors.email}}</td>
// ect...
</tr>
<tr class="col-xs-12" style="display:none">
<td colspan="6">
<p>
{{actors.otherThings}}
</p>
</td>
</tr>
</tbody>
</table>
JQuery (Original had td[colspan=12] instead of td[colspan=6])
<script>
// Toggle Additional Details
$(function () {
$("td[colspan=6]").find("p").hide();
$("td[colspan=6]").addClass("nopadding");
// && !$(e.target).is('span')
$("tr").click(function (e) {
if (!$(e.target).is('button') && !$(e.target).is('input') && !$(e.target).is('select')) {
var $target = $(this);
var $detailsTd = $target.find("td[colspan=6]");
if ($detailsTd.length) {
$detailsTd.find("p").slideUp();
$detailsTd.addClass("nopadding");
} else {
$detailsTd = $target.next().find("td[colspan=6]");
$detailsTd.find("p").slideToggle();
$detailsTd.toggleClass("nopadding");
}
}
});
});
</script>
CSS
/* Removes padding from interactive rows */
.table > tbody > tr > td.nopadding {
padding: 0px;
}
I am still new to AngularJS so maybe I am missing something simple, but I just want to be able to expand show/hide the additional tr. Not sure why it does not work for my Angular code.
AngularJS
var app = angular.module("app", ['ngRoute', 'ngResource']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/pages/home.html',
controller: 'HomeController'
})
.when('/home', {
templateUrl: '/pages/home.html',
controller: 'HomeController'
})
.when('/unknown', {
templateUrl: '/pages/unknown.html',
controller: 'UnknownController'
})
.otherwise({
templateUrl: '/pages/home.html',
controller: 'HomeController'
});
});
app.factory('userService', function ($http) {
var userService = {};
userService.getUsers = function () {
return $http({
url: '/API/APITest',
method: "GET"
})
}
return userService;
});
app.controller('HomeController', function ($scope, userService, $resource, $http) {
$scope.orderByField = 'name';
$scope.reverseSort = false;
$scope.ordering = "(ascending)";
$scope.orderByFieldFunction = function (value) {
$scope.reverseSort = !$scope.reverseSort;
$scope.orderByField = value;
if ($scope.reverseSort === false) {
$scope.ordering = "(ascending)";
} else {
$scope.ordering = "(descending)";
}
}
userService.getUsers().success(function (users) {
$scope.Users = users;
});
});
app.controller('UnknownController', function ($scope, userService, $resource, $http) {
$scope.title = "404 - Does Not Exist";
});
You can add the jQuery in a directive like this, if this is what you're after:
Example: http://jsfiddle.net/58mLfw6z/
AngularJS Directive
app.directive('showmore',function() {
return {
restrict:'A',
link: function(scope,element,attr) {
element.on('click',function() {
element.next('tr').toggle();
});
}
}
});
// or apply a flag to the model with an ng-click on the tr
$scope.more = function(actor) {
if (!actor.more) {
actor.more = true;
}
else {
actor.more = false;
}
};
HTML
<table>
<tbody ng-repeat="actors in Users">
<tr showmore ng-click="more(actors)">
<td class="col-xs-2">{{actors.name}}</td>
<td class="col-xs-2">{{actors.email}}</td>
</tr>
<tr style="display:none;">
<td colspan="2">
<p>
{{actors.otherThings}}
</p>
</td>
</tr>
</tbody>
</table>
I think OP already has found the answer. This post is just to say that ng-repeat has its own scope, an isolated scope.
In this plnkr, http://jsfiddle.net/aanders50/HB7LU/5497/, which OP posted in the comment
<table>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
<tbody ng-repeat="actors in Users">
<tr ng-click="showDetails = ! showDetails">
<td>{{actors.name}}</td>
<td>{{actors.email}}</td>
</tr>
<tr ng-show="showDetails" style="background-color:rgba(0, 255, 255, 0.2)">
<td colspan="2">
<p>birthday: {{actors.birthday}}</p>
</td>
</tr>
</tbody>
</table>
showDetails are bound to each tbody where ng-repeat is defined. Thus, each table has its own $scope.showDetails
Related
Hi I am trying to get all data at a time when I will click on
checkbox, but data not coming but when i click one by one data id
coming. But my problem is how to get all data in checkbox all in
single click.
This is HTML code
<div id="wrapper" class="wrapper">
<div ng-include="'views/partials/navigator.html'"></div>
<div class="page-content-wrapper">
<div ng-include="'views/partials/header.html'"></div>
<div class="row">
<div class="col-md-12">
<h3>Student Information</h3>
<table id="example" class="table">
<tr>
<th>Name</th>
<th>Mobile</th>
<th>Siblling</th>
<th>select all <input type="checkbox" id="slctAllDuplicateStd"/></th>
</tr>
<tr ng-repeat="data in vm.data">
<td>{{data.name}}</td>
<td>{{data.mobileNumber}}</td>
<td>{{data.isMigrated}}</td>
<td><input type="checkbox" ng-model="data.selected" class="duplicateRow" /></td>
</tr>
<tr>
<tr>
<button class ="button" ng-click="vm.process()">Process</button>
</tr>
</table>
<table class="table">
<tr>
<td colspan="4">
<pagination ng-if="renderpagination" page-number='{{vm.pageNumber}}' page-count="{{vm.pageCount}}" total-records="{{vm.totalRecords}}" api-url="duplicate-student"></pagination>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
This is javascript code
(function() {
angular
.module('vidyartha-coordinator')
.controller('StudentDuplicateAccountController', StudentDuplicateAccountController);
StudentDuplicateAccountController.$inject = ['$scope', 'ApiService', '$routeParams', '$http', '$location', '$timeout'];
function StudentDuplicateAccountController($scope, ApiService, $routeParams, $http, $location, $timeout) {
var vm = this;
//console.log($routeParams)
var page = $routeParams.page || 1;
// vm.data = [];
ApiService.getAll('student-duplicate-account?pageCount=5&pageNumber=' + page).then(function(response) {
//console.log("response::"+JSON.stringify(response));
vm.data = response.data.records;
vm.pageNumber = response.data.pageNumber;
vm.totalRecords = response.data.totalRecords;
vm.pageCount = response.data.pageCount;
$scope.renderpagination = true;
});
$("#slctAllDuplicateStd").click(function () {
$(".duplicateRow").prop('checked', $(this).prop('checked'));
// console.log('data:::'+JSON.stringify(data));
});
vm.process = function() {
vm.duplicateArray = [];
angular.forEach(vm.data, function(data){
if (data.selected) {
console.log("true")
vm.duplicateArray.push(data.tenantId);
vm.duplicateArray.push(data.mobileNumber);
vm.duplicateArray.push(data.schoolId);
vm.duplicateArray.push(data.classId);
}
});
console.log(vm.duplicateArray)
}
}
})();
I need all data at a time we i do check and press process button.
So please tell me where i should add some condition.
Am not sure why you are mixing jquery here you can do it as follow
vm.selectAll =function(){
angular.forEach(vm.data, function(data){
data.selected=true;
}
then in your checkbox
<th>select all <input type="checkbox" ng-click="vm.selectAll()"/></th>
New to using Angular local storage and I am unable to store data in local storage after data in the table changes.
I have read their instructions and have got their demo working in my own environment, but that is watching for change when a user types a character into an input field. I need it to watch for change in the <tr>/<td> and then store it in local storage.
When I log the value that is passed to the function it returns `null'. The data that populates the table is dynamic, changing depending on what item a user clicks on. Any idea why the data that is loaded into the table isn't being stored?
UPDATE
Included the service in which I gather the data on ng-click. The id displays in the table cell but:
I have had to use an <input> inside the table cell
No data is binded to the cell at the moment, but it needs to be
When I refresh the page, the table headings are displayed, but the data still disappears
Storing each individual item isn't the most efficient approach
I will label the two html templates I have. First one (list-patents.htm) is the table which displays the items. When a user clicks on an item, a second template (patent-item.htm) below the table loads into ng-view displaying relevant information.
var app = angular.module('myApp', ['ngRoute', 'ui.router', 'LocalStorageModule']);
app.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', 'localStorageServiceProvider', function($stateProvider, $locationProvider, $urlRouterProvider, localStorageServiceProvider) {
localStorageServiceProvider
.setPrefix('demoPrefix')
$urlRouterProvider
.when('', '/patents/list-patents')
.when('/', '/patents/list-patents')
.when('/patents', '/patents/list-patents')
.when('/transactions', '/transactions/current-transactions')
.otherwise('/patents/list-patents');
$stateProvider
.state("patents", {
url: "/patents",
templateUrl: "templates/patents/patent-nav.htm",
controller: "patentListCtrl"
})
.state("patents.list", {
url: "/list-patents",
templateUrl: "templates/patents/list/list-patents.htm",
controller: "patentListCtrl"
})
.state("patents.list.item", {
url: "/patent-item",
templateUrl: "templates/patents/list/patent-item.htm",
params: {
//load of params
},
controller: "patentItemCtrl"
})
}];
app.factory('loadPatentItemService', ['$http', '$timeout', function($http, $timeout) {
var factory = {};
var selectedItem = null;
factory.select = function(item) {
factory.storeSelect = [];
selectedItem = item;
factory.storeSelect.push(selectedItem)
factory.getPatent();
return [selectedItem];
}
}])
app.controller('patentItemCtrl', ['$scope', 'patentTabService', 'patentCheckboxService', 'localStorageService', 'loadPatentItemService', function($scope, patentTabFactory, patentCheckboxService, localStorageService, loadPatentItemService){
var testid = loadPatentItemService.storeSelect[0].id;
$scope.$watch('itemStorage', function(){ //watch for change, value passed to function
localStorageService.set('itemStorage', testid); //set value of property (what user typed in)
$scope.localStorageDemoValue = localStorageService.get('itemStorage');
});
$scope.$watch(function(){
return localStorageService.get('itemStorage');
}, function(){
$scope.itemStorage = testid;
});
}])
list-patents.htm
<div class="row">
<div class="col-md-12">
<table>
<thead>
<tr>
<td class="align-middle">Application No. </td>
<td class="align-middle">Client Ref</td>
<td class="align-middle">Cost now</td>
<td class="align-middle">Cost band end</td>
<td class="align-middle">Cost next</td>
<td class="align-middle">Renewal Date</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in patents">
<td ng-click="select(x)"><a ui-sref="patents.list.item({id: x.id, patentApplicationNumber: x.patentApplicationNumber, clientRef: x.clientRef, renewalStatus: x.renewalStatus, currentRenewalCost: x.currentRenewalCost, costBandEndDate: x.costBandEndDate, renewalCostNextStage: x.renewalCostNextStage, renewalDueDate: x.renewalDueDate, shortTitle: x.shortTitle, primaryApplicantName: x.primaryApplicantName, patentPublicationNumber: x.patentPublicationNumber, title: x.title, filingDate: x.filingDate, epoPatentStatus: x.epoPatentStatus})">{{x.applicationNumber}}</a></td>
<td ng-bind="x.clientRef"></td>
<td ng-bind="x.currentRenewalCost">$</td>
<td ng-bind="x.costBandEndDate"></td>
<td ng-bind="x.renewalCostNextStage"></td>
<td ng-bind="x.renewalDueDate"></td>
</tr>
</tbody>
</table>
<div ui-view></div>
</div>
</div>
patent-item.htm
<div class="col-md-6 text-xs-center" ng-controller="patentItemCtrl">
<h2>Application Number</h2>
<table class="table table-striped">
<thead>
<tr class="font-weight-bold">
<td>applicationNumber</td>
<td>clientRef</td>
<td>renewalStatus</td>
<td>costBandEndDate</td>
<td>renewalCostNextStage</td>
<td>renewalDueDate</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in patentItem">
<td><input type="text" ng-model="itemStorage" placeholder="Start typing..." readonly></td>
<td><input type="text" ng-model="x.clientRef" placeholder="Start typing..." readonly></td>
<td ng-bind="x.renewalStatus"></td>
<td ng-bind="x.costBandEndDate"></td>
<td ng-bind="x.renewalCostNextStage"></td>
<td ng-bind="x.renewalDueDate"></td>
</tr>
</tbody>
</table>
</div>
I have created a directive in which a table html is returned successfully. One of the columns is anchor link <td><a ng-click="showLogDiv()">Show Modified Data</a></td> on whose click i want to show a div containing further data belonging to that row but it doesnot show.
//logdetails.html - the templateUrl proprerty of my directive
<div>
<table class="table table-hover table-responsive">
<thead class="table-thead">
<tr style="background-color:#56a7d6">
<th>AccessLogId</th>
<th>EntityName</th>
<th>EntityId</th>
<th>RequestType</th>
<th>Modified Data</th>
<th>Creation Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="value in viewData.logdata">
<td>{{value.AccessLogId}}</td>
<td>{{value.EntityName}}</td>
<td>{{value.EntityId}}</td>
<td>{{value.RequestType}}</td>
<!--<td><a ng-click="showLogDetails({{value.ModifiedData| json}})">Show Modified Data</a></td>-->
<td><a ng-click="showLogDiv()">Show Modified Data</a></td>
<td>{{value.CreatedDate | date:'medium'}}</td>
</tr>
</tbody>
</table>
<!--<div ng-show="divShow">Hello</div> I want to show {{value.ModifiedData| json}} contents here but even hardcoded Hello value not shown -->
<div ng-show="divShow">Hello</div>
</div>
In controller i have
$scope.divShow = false;
$scope.showLogDiv = function () {
alert($scope.divShow);
$scope.divShow = true;
alert($scope.divShow);
};
My directive
.directive("myActivityLogs", function () {
return {
restrict: 'E',
replace: 'true',
//template: '<div></div>',
//template: '<b>{{viewData.logdata[1].ModifiedData}}</b>'
templateUrl: 'app/modules/appScreen/logdetails.html'
//scope: {
// logsData:'='
//},
//link: function (scope, element, attrs) {
//link: function () {
// alert(viewData.logdata);
//}
};
});
How to hide/show part of html returned by directive and also how can i bind data to that part?
I am new to angularjs and nothing makes sense right now so maybe i am doing things wrong way so please explain in detail it would be very helpful.
One way to do this is to use a directive controller. You can change your directive like this:
.directive("myDirective", function() {
return {
restrict: 'E',
replace: 'true',
templateUrl: './logdetails.html',
scope: {
viewData: '='
},
controller: function($scope) {
$scope.divShow = false;
this.showLogDiv = function() {
$scope.divShow = true;
};
},
controllerAs: 'ctrl'
};
})
And then change your template HTML as the following so that it uses the controller:
<div>
<table class="table table-hover table-responsive">
<thead class="table-thead">
<tr style="background-color:#56a7d6">
<th>AccessLogId</th>
<th>EntityName</th>
<th>EntityId</th>
<th>RequestType</th>
<th>Modified Data</th>
<th>Creation Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="value in viewData.logdata">
<td>{{value.AccessLogId}}</td>
<td>{{value.EntityName}}</td>
<td>{{value.EntityId}}</td>
<td>{{value.RequestType}}</td>
<td><a href ng-click="ctrl.showLogDiv()">Show Modified Data</a></td>
<td>{{value.CreatedDate | date:'medium'}}</td>
</tr>
</tbody>
</table>
<div ng-show="divShow">Hello</div>
</div>
Notice that I've used <a href ng-click="ctrl.showLogDiv()">. You can refer to this working plunker to know more.
What am i doing wrong int the below code. I am not getting any error also I am not getting the results.
1. The alerts are appearing.
2. I tried harding the ceid value still that value si not getting passed to function inside the EVerifyModuleI9Service.
eg : I hard coded EVerifyModuleI9Service.getEmployeeInformation(53) but always 0 is being sent to the function.
Note : LoadViewSelected is to load a view it takes the url of the view and the js file as parameters.
HTML (ListEverify.cshtml):
<div ng-app="EVerifyModule">
<div class="row" ng-controller="EVerifyController as ECtrl">
<table class="table table-bordered table-striped table-hover table-condensed">
<thead>
<tr>
<th ng-click="sortdata('name')"> Employee Name
<span class="glyphicon sort-icon"></span>
</th>
<th ng-click="sortdata('dateHire')">
Hire Date
<span class="glyphicon sort-icon"></span>
</th>
<th ng-click="sortdata('phoneNumber')">
Phone Number
<span class="glyphicon sort-icon"></span>
</th>
<th>
E-Verify
<span class="glyphicon sort-icon"></span>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="emp in Employees" ng-click="storeIds(emp)">
<td>{{emp.name}}</td>
<td>{{emp.dateHire | date:'MM-dd-yyyy'}}</td>
<td>{{emp.phoneNumber}}</td>
<td><a class="btn-sm btn-primary pull-right" href="javascript:void(0)" onclick="LoadViewSelected('/EVerify/EVerify/EVerifySubmit', 'EVerifyModule');">E-Verify</a></td>
</tr>
</tbody>
</table>
</div>
</div>
EVerifyModel.js
var EVerifyModule = angular.module('EVerifyModule', ['angularFileUpload', 'ui.bootstrap', 'angularUtils.directives.dirPagination']);
EVerifyModule.factory('EVerifyModuleService', ['$http', '$window', function($http, $window) {
return {
GetEmployeeList: function(companyId) {
return $http({
url: '/api/EVerify/GetEmployeeList',
method: 'POST',
data: companyId
});
}
};
}]);
EVerifyModule.factory('EVerifyModuleI9Service', ['$http', function($http) {
return {
getEmployeeInformation: function(id) {
return $http({
url: '/api/EVerify/GetEmployeeInfo',
method: 'GET',
params: {
Id: id
}
// data: id
});
}
};
}]);
EVerifyModule.service('DataToPersistService', function(param) {
ceId = param;
});
EVerifyModule.controller('EVerifyController', ['$scope', '$http', '$compile', 'EVerifyModuleService', '$timeout', function($scope, $http, $compile, EVerifyModuleService, $timeout) {
$scope.storeIds = function(emp) {
alert(emp.id);
alert(emp.name);
DataToPersistService.function(emp.id);
}
EVerifyModuleService.GetEmployeeList(61).then(function(response) {
$scope.Employees = response.data.Employees;
});
}]);
EVerifyModule.controller('EVerifyI9Controller', ['$scope', '$http', '$compile', 'EVerifyModuleI9Service', function($scope, $http, $compile, EVerifyModuleI9Service) {
EVerifyModuleI9Service.getEmployeeInformation(ceId).then(function(response) {
if (response != null) {
$scope.employeeInfo = response.data.EmployeeInfo;
}
});
}]);
<a class="btn-sm btn-primary pull-right" href="javascript:void(0)" onclick="LoadViewSelected('/EVerify/EVerify/EVerifySubmit', 'EVerifyModule');">E-Verify</a>
Replace anchor tag with button for simplicity and then replace onclick with ng-click event and make sure that u got LoadViewSelected function attached to ur $scope.
I'm learning AngularJS and I'm stuck on adding new records. I can open and edit/save existing records, but when I open my edit form to create a new record, all the controls are disabled (I can't type in the textboxes or select a value from a DDL). Here is my code:
Index.cshtml:
<script id="ModelList.html" type="text/ng-template">
<table>
<thead>
<tr>
<th>New Rate</th>
<th>Record ID</th>
<th>Company ID</th>
<th>Rate</th>
</tr>
</thead>
<tr ng-repeat="m in models">
<td>Edit</td>
<td><span ng-bind="m.Rid"></span></td>
<td><span ng-bind="m.CompanyId"></span></td>
<td><span ng-bind="m.Rate"></span></td>
</tr>
</table>
</script>
<script id="ModelSave.html" type="text/ng-template">
<form name="myForm">
<div>
<label>Company ID</label>
<select name="CompanyId" ng-model="model.CompanyId">
<option value="101">101</option>
<option value="102">102</option>
<option value="103">103</option>
</select>
</div>
<div>
<label>Rate</label>
<input name="WorkCompRt" ng-model="model.Rate"/>
</div>
<div>
<savebutton text="Save" action="save()"></savebutton>
<cancelbutton></cancelbutton>
</div>
</form>
</script>
.js:
.controller("RecordsListController", function ($scope, $routeParams, $location, State, Services) {
$scope.select = function (item) { State.broadcast(item); };
$scope.addNew = function() { $scope.models.splice(0,0,{ }); };
Services.getRecords().success(function (d) {
$scope.models = d;
});
})
.controller("ViewSaveController", function ($scope, $routeParams, $location, State, Services) {
$scope.select = function (item) { State.broadcast(item); };
$scope.addNew = function () { $scope.models.splice(0, 0, {}); };
Services.getRecord($routeParams.id).success(function (d) {
$scope.model = d;
});
})
.factory("Services", function (Api) {
this.getRecords = function(){
return Api.get("AppApi/GetRecords");
};
this.getRecord = function (rId) {
return Api.get("AppApi/GetRecordById?rId=" + rId);
};
return this;
})
So, I'm using the same form for creating and updating records; however, when rId is 0 (new item), the controls on the form are disabled. Any help is appreciated!
I found that Services.getRecord($routeParams.id) function prevents me from entering values in the controls. I created a separate controller for Adding a record that is the same as "ViewSaveController", except that I removed Services.getRecord($routeParams.id) function. It fixed the problem.