How to open Angular modal window with selected data from table - javascript

I need to open modal window with selected data from cell of table. Now the modal is opened with data but data in modal belong to all row. I need to chose data from item selected cell. I have a two arrays. One in other. I can selected item from first array (dataTable) but there is exist another array (item.arrValues) in the there. I can't to get the selected data from a second array. How can I to display the data from selected cell?
Example here Plnkr
HTML
<table>
<tbody>
<tr>
<td></td>
<td ng-repeat="i in vm.dataTable[0].arrValues">{{i.DAY}}</td>
</tr>
<tr ng-repeat="item in vm.dataTable">
<td>{{item.time}}</td>
<td ng-click="vm.openEvents(item);" ng-repeat="i in item.arrValues">{{i.Value}}</td>
</tr>
</tbody>
</table>
modalContent.html
<div>
<div class="modal-body" style="overflow: hidden;">
<div ng-bind="selected.item.Country"></div>
<!--<div ng-bind="selected.item.arrValues[0].Value"></div>-->
<div ng-repeat="i in selected.item.arrValues">{{i.Value}}</div>
</div>
</div>
JS
vm.openEvents = function(item){
var modalInstance = $modal.open({
scope: $scope,//
templateUrl: "modalContent.html",
controller: ModalInstanceCtrl,
resolve: {
item: function() {
return item;
},
dataTable: function ($timeout) {
return vm.dataTable
}
}
});
}
var ModalInstanceCtrl = function ($scope, dataTable, item) {
var vm = this;
vm.dataTable = dataTable;
$scope.selected = {
item: item
};
}

Change <td> to pass i to the function (i being the value in the cell in this case):
<td ng-click="vm.openEvents(i);" ng-repeat="i in item.arrValues">{{i.Value}}</td>
Change the modal template to display selected.item.DAY and selected.item.Value.
<div>
<div class="modal-body" style="overflow: hidden;">
<div ng-bind="selected.item.DAY"></div>
<div ng-bind="selected.item.Value"></div>
</div>
</div>
Working PLNKR here.

Related

Issue with removing displayed list of items

I am creating a restaurant menu app that a waiter can use to input orders.
I have everything set to where when I select an food item button. That item is added to a list of chosen items for purchase in a list displayed on screen.
I have remove buttons next to each item in case you want to remove one. The remove button works, however it always removes the first item from the list and not the item that had it's particular remove button selected.
I'm not sure why it is doing this. What could I do to get the current item removed that had it's particular remove button selected?
Js code
.controller('orderAddCtrl', ['$scope', '$location', 'dataService', function ($scope, $location, dataService) {
$scope.chosenItems = [];
$scope.totalItemPrices = 0;
$scope.userId = "";
$scope.addOrderToList = function (item) {
$scope.addPricesToTotalItemPrices(item.itemPrice);
$scope.chosenItems.push({'Name': item.itemName, 'Price': item.itemPrice});
};
$scope.addPricesToTotalItemPrices = function (price) {
$scope.totalItemPrices += price ;
};
$scope.removePricesFromTotalItemPrices = function (price) {
$scope.totalItemPrices -= price;
};
$scope.removeFromOrderToList = function (item) {
$scope.removePricesFromTotalItemPrices(item.Price);
$scope.chosenItems.splice(item, 1);
};
Html
<div class="row">
<div class="col-6">
<h2>Food Items</h2>
<div class="row">
<button class="btn btn-success col-3" ng-repeat="item in Items" ng-click="addOrderToList(item)">{{item.itemName}}</button>
</div>
</div>
<div class="col-6">
<table class="table table-bordered">
<thead>
<tr>
<th>Item Name</th>
<th>Item Price</th>
<th>Total Price: ${{totalItemPrices}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="i in chosenItems">
<td>{{i.Name}}</td>
<td>{{i.Price}}</td>
<td>
<button class="btn btn-danger" ng-click="removeFromOrderToList(i)">
Remove
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
This is the splice syntax:
array.splice(startindex, howmany, item1, ....., itemX)
https://www.w3schools.com/jsref/jsref_splice.asp
If you pass a string as a parameter where an integer is expected it will, in the case of splice, first attempt to parse the string as an integer.
When the parse returns NaN it will default to 0, which explains the behavior of your code.

failing to store data in local storage on table data change

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>

How to make dynamic content-editable table using angular JS?

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>

get which are checked in list of checkboxes AngularJS

I would like to get which checkbox are selected by the user, i have this table but it dosen't work. is there any alternative ?
<table class="table table-bordered table-hover" style="max-height: 500px; overflow-y: auto" border="1">
<tr>
<th> Nom Exigence</th>
<th> Verifier</th>
</tr>
<tr data-ng-repeat="item in list" style="background-color: #F5F5F5">
<td>
{{item.Nom}}
</td>
<td>
<input type="checkbox" checklist-model="user.list" />
</td>
</tr>
</table>
verify
Close
when i try to log the $scoepe.user.list it shows me []
this is the modal controller
app.controller('ModalInstanceExigencesCtrl', function ($scope, $modalInstance, list) {
$scope.list = [];
$scope.user = [];
for (var i = 0; i < list.length; i++) {
$scope.list.push(list[i]);
}
console.log($scope.list);
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.verify = function () {
console.log($scope.user);
};
});
this Fiddle should do the job for u: jsfiddle example using checkboxes
Html-Code (pretty similiar to ur code):
<div ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in items">
<label class="checkbox">
<input type="checkbox" ng-model="items[$index].checked" />
{{item.name}}
</label>
</li>
</ul>
<hr class="space clearfix" />
{{items | json}}
JS-Code:
var app = angular.module('angularjs-starter', []);
function MainCtrl( $scope )
{
$scope.items = [
{ name:'foo', checked: true },
{ name:'bar' },
{ name:'baz' }
];
}
I just define one $scope Object called items. In my example each item has a name and optional a value checked, which determines wether a checkbox is checked or not.
Html is pretty forward, we repeat over all items and then bind our checkbox model ng-model="items[$index].checked". $index gives us the number of iteration, for example our first iteration binds to ng-model="items[0].checked"
Hope that helps.
You can try by using this way also
Html-Code:
$scope.collectNumbers = function (contact, index) {
if (contact.IsChecked) {
}
else{
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<tr class="" ng-repeat="contact in Contacts">
<td>
<label>
<input type="checkbox" ng-model="contact.IsChecked" ng-change="collectNumbers(contact,$index)" ng-checked="contact.IsChecked">
</label>
</td>
<td>{{contact.Name}}</a></td>
</tr>

How to dynamically change the content of a table column

Given the following HTML fragment, how can I create the content of the td depending on the column.
<div ng-app="" ng-controller="controller" >
<table>
<tr>
<th ng-repeat="column in columns">
{{ column.header }}
</th>
<tr ng-repeat="row in rows">
<td ng-repeat="column in columns">
<!-- TODO -->
</td>
</tr>
</table>
</div>
Each column can show a different kinds of data. For example, one might just show a string, another might contain a text input field that is bound to a property of the row.
I would like to call a function on the column (column.createCell(row)) that creates that necessary HTML and then put the result in place of <!-- TODO -->.
In WPF, I would just put a ContentPresenter with a DataTemplateSelector, but I don't know what the equivalent is in Angular. I read about something called "ng-bind-html", is that the way to go?
It's not given what kind of custom element you want to build for each column, but for DOM manipulation in AngularJS best practise is to keep it in a directive. Something like this:
in your html:
<body ng-controller="MainCtrl">
<table>
<tr ng-repeat="row in rows">
<td ng-repeat="column in row">
<custom-column="column"></custom-column>
</td>
</tr>
</table>
</body>
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
// whatever you wanted to define here...
$scope.rows = ...
$scope.columns = ...
});
app.directive('customColumn', function() {
return {
scope: {
obj: '=customColumn',
},
link: function(scope, element, attrs) {
var watcher = scope.$watch('obj', function(obj) {
if (!obj) return;
// build custom element
var html = '<div>'+scope.obj.name+'</div>';
element.html(html);
// delete watch if you only need to draw once
watcher();
});
}
}
});

Categories