Angular JS ng-repeat and modal dialog - angularjs

I am iterating over a list of students and each row has the student name and college and a button. On clicking the button you see a modal dialog which shows student details. For some reason I am unable to get the correct student information. The dialog just shows the 1'st student information only. Here is the pluker
http://plnkr.co/edit/kXB7OZuyOz57qyVMIu8T?p=preview
<div class="table-responsive">
<table class="table table-striped">
<tr ng-repeat = "student in students">
<td>{{student.name}}</td>
<td>{{student.college}}</td>
<td>
<div class="modal-header">
<button type="button" class="btn btn-primary"
data-toggle="modal" data-target="#dialogTestDialog">Options</button>
</div>
<div class="modal fade" id="dialogTestDialog" tabindex="-1" role="dialog" aria-labelledby="executionOptionLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
Student : {{student.name}} <br/> Detail on Student
<div class="modal-body">
<p>{{student.age}}</p>
<p>{{student.address}}</p>
<p>{{student.race}}</p>
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
</div>

The problem is that all your modals have the same id value, so this is not valid html. You need different id values so you can reference the correct one on click. eg: ng-click="showModal($index)"
I would check this out:
How to set the id attribute of a HTML element dynamically with angular js?
Also if you really want to play with bootstrap js and angular, you should use a version specific to angular: http://angular-ui.github.io/bootstrap

Check this version in Plunker: Working Version
To get the ng-repeat index value , you have to use {{ $index }} ng-repeat documentation
and to data-toggle should be the values specified in bootstrap Here

Related

In one jsp page, On button click, load second jsp page as modal in bootstrap

I have a requirement as, Creating a one form and load this form on multiple screen as modal using bootstrap.
Example : Suppose I am having 3 jsp pages i.e. Index.jsp, Request.JSP, Form.jsp
Now I have a link on Index.jsp which will display Form.jsp as Modal and I have button on Request.jsp, on click of button Form.jsp will get displayed as modal.
I have gone through multiple queries but solution was not satisfactory. I dont want to repeat the code and want to use Modal.
Thanks in advance.
i got the solution. I kept the Modal and Modal-dialog class div tags in main JSP like below :
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Cash Request Form</h4>
</div>
<div id="loadModalBody" >
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Then I added the form with modal-body class in second JSP CashRequestForm.jsp :
<div class="modal-body panel">
<div class="panel panel-body" id="panelActTypeAndDate">
<div class="row">
<div class="col-md-8"><font>Activity Type</font></div>
<div class="col-md-3"><font>Select Activity Date</font></div>
</div>
<div id="row1" class="row">
.....
.....
Your code
</div>
</div>
</div>
Then I called .load using jquery as below :
$(".popUp").click(function () {
$("#loadModalBody").load("CashRequestForm.jsp");
});
And it worked for me.

How to pass or reference item from ng-repeat to another element?

I want to pass a single item/object ('ca') from a repeater to another element (in this case a modal) within the same controller context:
<div data-ng-controller="ContactActionCtrl" data-ng-app="myApp" runat="server">
<div class="row">
<div class="col-sm-12">
<h2>Tasks</h2>
<table class="table">
<thead>
<tr>
<th>Created</th>
<th>Due</th>
<th>Completed</th>
<th>Created By</th>
<th>Assigned</th>
<th>Description</th>
</tr>
</thead>
<tbody data-ng-repeat="ca in contactactions | filter:{ObjectType:'Task'}">
<tr data-actionid="{{ca.Id}}" data-toggle="modal" data-target="#actionDetail">
<td>{{ca.CreationDate | date:"MM/dd/yyyy"}}</td>
<td>{{ca.ActionDate | date:"MM/dd/yyyy 'at' h:mma"}}</td>
<td>{{ca.CompletionDate | date:"MM/dd/yyyy"}}</td>
<td>{{ca.CreatedByUsername}}</td>
<td>{{ca.UserIDUsername}}</td>
<td><label data-ng-if="ca.ActionType">{{ca.ActionType}} - </label><label>{{ca.ActionDescription}}</label><br>{{ca.CreationNotes | limitTo:270}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="actionDetail" class="modal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">{{ca.ActionDescription}}</h4>
</div>
<div class="modal-body">
//more details from ca here
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Everything is working, including popping up the bootstrap modal div from a row click, except for actually populating it from outside of the repeater. Since the full object is still in memory, I was hoping to avoid fetching a singular item from the db again (with a different service call) in order to fill the modal. Even though I'm showing a modal, I think this question might apply to any element / set of elements that lie outside the repeater.
I think the most straight forward way for you would be to have the modal display a different single variable e.g. 'ca.selectedItem' then when you click on an item populate selectedItem with that object. I'll see if I can whip up an example.
Controller:
$scope.contactActions = [{name:"Action 1"},{name:"Action 2"},{name:"Action 3"}]
$scope.selectedAction = {name:""};
$scope.rowClick = function(event, selected) {
$scope.selectedAction = selected;
};
Markup:
<tr data-actionid="{{ca.Id}}" ng-click="ca.rowClick($event, i)" data-toggle="modal" data-target="#actionDetail">
Here's a plunk.
P.S. You can use bootstrap with Angular but it uses non-angular javascript (i.e. jquery) which bypasses Angular to do things like DOM manipulation. This often results in Angular not updating it's bindings properly, so you end up doing stuff like $scope.apply() to manually tell Angular to update all it's bindings. One alternative to this would be to use UI Bootstrap which uses the same css but the javascript has been re-implemented in Angular.

dirpagination is working but not able to see controls

The dirpagination works because it gives 10 items per row but I am not able to see the controls at the bottom of table to navigate.
//Creating tabs and table
<div ng-controller="MyController" class="my-controller">
<div class="container">
<h2>Legislaotrs</h2>
<ul class="nav nav-tabs">
<li>By State</li>
<li>House</li>
<li>Senate</li></ul>
</div>
<form class="form-inline">
<div class="form-group">
<label >Search</label>
<input type="text" ng-model="search" class="form-control" placeholder="Search">
</div>
</form>
<table class="table table-striped table-hover">
<thead>
<tr>
 <th>Party</th>
<th>Name</th>
<th>Chamber</th>
<th>District</th>
<th>State</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="user in users|filter:search|itemsPerPage:10">
<td> <img src="{{user.party_name}}" style="max-height: 10%;max-width: 10%;"/> </td>
<td>{{user.fullname}}</td>
<td > <img src="{{user.chamber_type}}" style="max-height: 8%;max-width: 7%;"/>{{user.chamber_name}} </td>
<td>{{user.district_name}}</td>
<td>{{user.state_name}}</td>
<td> <button type="button" class="btn btn-primary">View Details</button></td>
</tr>
</tbody>
</table>
//setting pagination controls
<div id="paginate">
<dir-pagination-controls
max-size="5"
direction-links="true"
boundary-links="true">
</dir-pagination-controls></div>
</div>
First you need to include the module in your project:
angular.module('myApp', ['angularUtils.directives.dirPagination']);
Then create the paginated content:
<dir-pagination-controls
[max-size=""]
[direction-links=""]
[boundary-links=""]
[on-page-change=""]
[pagination-id=""]
[template-url=""]>
</dir-pagination-controls>
here is working plunker

Mobile Angular UI modal not able to update

Seems like modals in Angular UI is difficult to update, previously in Bootstrap I could update via jQuery but in Angular UI, not able to do even a simple update.
I have <span id="spnApproveSelectedCount">0</span> inside my modal-body, and I update it using jQuery $('#spnApproveSelectedCount').text(selectedCount); like this. It was working in Bootstrap but not in Angular UI.
Even update from $scope is not working if that variable is inside the modal. But if I moved them outside of modal it is working. I suspect it is because the modal is not display yet?
Updated:
I have a repeat in which the each item is clickable. When user clicked on it, it's supposed to open up the modal with further info. Below are my codes.
<div class="list-group">
<div ng-repeat="approval in approvals" class="list-group-item">
<div class="row">
<div class="selectable" style="float: left; width: 95%" ui-turn-on="detailsModal" ng-click="SetDetails(approval)">
<p class="list-group-item-text"><b>Ref</b> <span>{{ approval.ref }}</span></p>
<p class="list-group-item-text"><b>Pay To</b> <span>{{ approval.payTo }}</span></p>
<p class="list-group-item-text"><b>From</b> <span>{{ approval.from }}</span></p>
</div>
</div>
</div>
</div>
Notice that I have the ng-click on the row and below are my codes at controller.
$scope.SetDetails = function(current)
{
$scope.details = current;
}
And also partial of my modal code..
<div class="modal" ui-if="detailsModal" ui-state='detailsModal'>
<div class="modal-backdrop in"></div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" ui-turn-off="detailsModal">×</button>
<h4 class="modal-title">Transaction Details</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-5">
Type
</div>
<div class="col-sm-7">
<b>{{ details.category }}</b>
</div>
</div>
<br />
<div class="row">
<div class="col-sm-5">
Submitted By
</div>
<div class="col-sm-7">
<b>{{ details.submittedBy }}</b>
</div>
</div>
Before everything, in fact in my controller I have a line of code to pre-set the details variable to take the first element (before it is passed to ng-repeat), this works and when the modal open, it is showing the first element value and that's it, the value stays there even if I click on row 2, 3 ...
$scope.details = $scope.approvals[0];

AngularJS/Bootstrap - Select row and open details in modal with button

I'm using AngularJS, Bootstrap, and data-toggle to open a modal. I want to click on a row in a table, get the index number and store it, and click a button to open a modal that displays more details for that row using the stored index.
My code right now can get the index of the clicked row and my button opens a modal, but they're not connected so that the button grabs the row index and shows those details in the modal. My modal shows all row data instead of the details for the one clicked row. How can I connect the clicked row to the button and how do I get my modal to show details for one app instead of all apps? Any help would be much appreciated!
Here is my JS Fiddle.
Here is the code snippet for the click functions:
$scope.selectedRow = null;
$scope.clickRow = function(index) {
$scope.selectedRow = index;
console.log(index);
};
$scope.getDetails = function(index) {
$scope.selectedRow = index;
console.log(index);
};
And here is the code for my table and modal that call the click functions:
<div id="tableDiv">
<table id="myTable" class="table display">
<thead>
<tr>
<th ng-repeat="(i, th) in head" value="{{th.id}}" class="{{th.class}}"><span>{{th.name}}</span></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="app in apps | filter:search" ng-click="clickRow($index)" ng-class="{selected: $index === selectedRow}">
<td>{{app.appName}}</td>
<td>{{app.dateCreated}}</td>
<td>{{app.dateUpdated}}</td>
<td>{{app.payload}}</td>
<td>{{app.status.name}}</td>
<td>{{app.errorCode.name}}</td>
<td>{{app.errorDesc}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th ng-repeat="(i, th) in head" value="{{th.id}}"><span>{{th.name}}</span></th>
</tr>
</tfoot>
</table>
</div>
<div id="details">
<button class="btn btn-default" data-toggle="modal" data-target="#myModal" ng-click="getDetails($index)">Launch</button>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Details</h4>
</div>
<div class="modal-body">
<table class="table display">
<thead>
<tr>
<th ng-repeat="(i, th) in details" value="{{th.id}}"
class="{{th.class}}"><span>{{th.name}}</span></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="app in apps">
<td>{{app.appName}}</td>
<td>{{app.errorDesc}}</td>
<td>{{app.recordCount}}</td>
<td>{{app.recordFail}}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
The first thing I'll point out is that you're not actually using angular-ui-bootstrap, you're using the jQuery version without angular directives, and by doing so making life harder for yourself. If you're going to do much more with this or making more modals I recommend switching.
You can still make this work though.
Instead of passing the $index in clickRow($index), pass the app itself clickRow(app) and assign that to your scope property.
It's a variable created in your ng-repeat loop that can be accessed by other expressions in the loop.
$scope.clickRow = function(app) {
$scope.selectedApp = app
};
Then, in your modal's html, you can bind to the properties of selectedApp. It should only show you the data for that one app.

Resources