modal inside an ng-repeat directive causes crash - javascript

i am trying to put inside a table abutton that will open a modal.
but no matter which button i click it seems that it tries to open it many times.
i have put the openModal and closeModal inside the main controller.
i believe the problem might be because i am using it inside an ng-repeat?
but in any case i do not know what is going wrong. what am i doing wrong?
i am using this modal:
http://angular-ui.github.io/bootstrap/#/modal
the html code:
<div class="row">
<div class="span4" ng-repeat="court in courts">
<table class="table table-condensed table-bordered table-hover">
<caption><h4>court {{court.records[0].id}}<h4></caption>
<tr>
<th style='text-align:center'>Hour</th>
<th style='text-align:center'>Player 1</th>
<th style='text-align:center'>Player 2</th>
<th></th>
</tr>
<tr ng-repeat="record in court.records">
<td width="50" >{{record.hour}}</td>
<td ng-style="user1Payed(record)" style='text-align:center'>{{record.u1_first}} {{record.u1_last}}</td>
<td ng-style="user2Payed(record)" style='text-align:center'>{{record.u2_first}} {{record.u2_last}}</td>
<td> <!-- options button -->
<button class="btn" ng-click="openModal()">Open me!</button>
<div modal="shouldBeOpen" close="closeModal()" options="opts">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-warning cancel" ng-click="closeModal()">Cancel</button>
</div>
</div>
</td> <!-- options button end -->
</tr>
</table>
</div>
</div>
and the controller code:
function CourtsController($scope, $window, $http, CourtsService, $timeout) {
$scope.openModal = function () {
$scope.shouldBeOpen = true;
};
$scope.closeModal = function () {
$scope.closeMsg = 'I was closed at: ' + new Date();
$scope.shouldBeOpen = false;
};
$scope.items = [
"Guest Payment",
"Member Payment",
"League (no payment)",
"no Payment"
];
$scope.opts = {
backdropFade: true,
dialogFade:true
};

Move you modal div of the ng-repeat and set $scope variable according your openModal().

Related

Accessing HTML Element after Adding with innerHtml

I am adding the data received as a result of a request to my page as follows.
showMovieInfo(movies) {
this.tableDiv.innerHTML = "";
movies.forEach(movie => {
this.tableDiv.innerHTML +=
`
<table class="table align-middle mb-0 bg-white">
<thead class="bg-light">
<tr>
<th>Movie Name</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center">
<img src="${movie.image}"
alt="" style="width: 120px; height: 120px" class="rounded-circle" />
<div class="ms-3">
<p class="fw-bold mb-1">${movie.title}</p>
<p class="text-muted mb-0">${movie.description}</p>
</div>
</div>
</td>
<td>
<button type="button" id="showonmap" class="btn btn-link btn-sm btn-rounded">
Show on map
</button>
</td>
</tr>
</tbody>
</table>`
});
}
then i want to add addEventListener to buttons with id="showonmap".But I am getting an error and when I click the buttons, any function does not work.
To support the comment made above regarding the delegated event listener I quickly rattled up this simple demo that slightly rewrites your original class method as a standalone function so that you can see the effect in action. As the event handler is assigned to a parent element within the DOM which does exist when the page is loaded you can use the event to identify which button ( or other element ) was clicked and from there do whatever operations are required.
const movies = [{
image: 'http://t1.gstatic.com/images?q=tbn:ANd9GcQsJW_I8KPZiq4mXcpRCd8uKBsUMR4Gz691k6gwEiLqVOoTl8pf',
title: 'The Life of Brian',
description: 'this is a great movie'
},
{
image: 'https://m.media-amazon.com/images/M/MV5BOTI4MDdjMmUtOTZhOS00MTYwLWEyZTUtYTdhMTQxNGM1YTUxXkEyXkFqcGdeQXVyMzg1ODEwNQ##._V1_UX140_CR0,0,140,209_AL_.jpg',
title: 'The Wasp Woman',
description: 'this is a terrible movie'
}
];
// slightly re-written as no longer part of a class/object
showMovieInfo = (movies) => {
// exlicitly define this.tableDiv here rather than in constructor earlier ( & not shown )
this.tableDiv = document.getElementById('movies');
this.tableDiv.innerHTML = "";
movies.forEach(movie => {
this.tableDiv.innerHTML +=
`
<table class="table align-middle mb-0 bg-white">
<thead class="bg-light">
<tr>
<th>Movie Name</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center">
<img src="${movie.image}"
alt="" style="width: 120px; height: 120px" class="rounded-circle" />
<div class="ms-3">
<p class="fw-bold mb-1">${movie.title}</p>
<p class="text-muted mb-0">${movie.description}</p>
</div>
</div>
</td>
<td><!-- modified id to data-id and added data-title for demo -->
<button type="button" data-id="showonmap" data-title="${movie.title}" class="btn btn-link btn-sm btn-rounded">
Show on map
</button>
</td>
</tr>
</tbody>
</table>`;
});
this.tableDiv.addEventListener('click', function(e) {
if (e.target != e.currentTarget && e.target.tagName == 'BUTTON' && e.target.hasAttribute('data-id')) {
alert(e.target.dataset.title);
// ... here you would do other operations to actually "view on map"
// ... etc
}
})
}
showMovieInfo(movies);
<div id='movies'></div>

Thymeleaf pass data from html id to thymeleaf variable

I've a problem with below code. I need to pass a variable from html id to thymeleaf variable.
<table class="responsive-table highlight bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Surname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr th:each="worker: ${workersList}">
<td th:text="${worker.id}"></td>
<td th:text="${worker.name}"></td>
<td th:text="${worker.surname}"></td>
<td th:text="${worker.email}"></td>
<td>
<a href="#deleteModal" class="btn tooltipped modal-trigger" th:attr="data-id=${worker.id}, data-name=${worker.name +' '+ worker.surname}"
data-position="top" data-delay="50" data-tooltip="Delete"><i class="material-icons">delete</i></a>
</td>
</tr>
<!-- Delete Modal -->
<div id="deleteModal" class="modal modal-fixed-footer">
<div class="modal-content">
<p id="modal-name"></p>
<p id="modal-id"></p>
</div>
<div class="modal-footer">
<a th:href="#{'/delete/'+${modal-id} }" class="modal-action modal-close waves-effect waves-red btn-flat">Yes</a>
</div>
</div>
</tbody>
</table>
<script th:inline="javascript">
$('#deleteModal').modal({
ready: function(modal, trigger) {
var button = $(trigger);
var id = button.data('id');
$('#modal-id').html(id);
}
});
</script>
It won't work. I've to pass it using js because this id's are changeable depends on worker I click. This works, but It can't pass an id to th:href Thanks for help!
They way you have it done, you need to use Javascript to update the ID, as your modal is outside the loop. I would do something like this:
<div class="modal-footer">
<a id="idModalLink" href="#" class="modal-action modal-close waves-effect waves-red btn-flat">Yes</a>
</div>
And in your javascript code:
$('#deleteModal').modal({
ready: function(modal, trigger) {
var button = $(trigger);
var id = button.data('id');
$('#modal-id').html(id);
$('#idModalLink').attr("href", "/delete/" + id);
}
});

Include template in angular-datatables not rendering

I am using angular-datatables plugin to add datatables to my project. In this, I have a column Actions where I want to add some buttons. For this, I am using ng-template which is defined on the same page. The problem is that the template does not always render. It sometimes shows the button, and sometimes it does not. It never shows the buttons after I make a search.
controller
$scope.dtOptions = DTOptionsBuilder.newOptions().withOption('ajax', {
url: '/api/department',
type: 'GET'
})
.withDataProp('data')
.withOption('processing', true)
.withOption('serverSide', true)
.withPaginationType('full_numbers')
.withOption('createdRow', function (row, data, dataIndex) {
// Recompiling so we can bind Angular directive to the DT
$compile(angular.element(row).contents())($scope);
})
.withBootstrap();
$scope.dtColumns = [
DTColumnBuilder.newColumn('id').withTitle('ID'),
DTColumnBuilder.newColumn('name').withTitle('Name'),
DTColumnBuilder.newColumn('actions').withTitle('Actions').withOption("searchable", false)
];
view
<script type="text/ng-template" id="actions.html">
<button class="btn btn-primary btn-xs" ng-click="edit()"><i class="fa fa-edit"></i> Edit</button>
<button class="btn btn-danger btn-xs" ng-click="delete()"><i class="fa fa-trash"></i> Delete</button>
</script>
<div class="hbox hbox-auto-xs hbox-auto-sm" ng-controller="DepartmentsController">
<div class="bg-light lter b-b wrapper-md">
<h1 class="m-n font-thin h3">Departments</h1>
</div>
<div class="wrapper-md">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-xs-6">
<button class="btn m-b-md btn-md btn-primary " ui-sref="manager.departments.create">
<i class="fa fa-plus"></i> <span class="hidden-sm hidden-xs">Add Department</span></button>
</div>
</div>
<div class="row">
<div class="col-sm-12 m-b-xs">
<table datatable="" dt-options="dtOptions" dt-columns="dtColumns" class="table table-striped b-t b-b">
<thead>
<tr>
<th style="width:20%">ID</th>
<th style="width:60%">Name</th>
<th style="width:20%">Actions</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
controller on server side in Laravel
public function index() {
$departments = Department::company($this->company->id)
->select("departments.id", "departments.name");
return \Datatables::of($departments)
->add_column("actions", function($row) {
return '<div ng-include src="\'actions.html\'"></div>';
})
->make(true);
}
I belive this is some syncronization issue. But, I am not getting anywhere.
Do you really get any successfully inserted templates? The only way I can get $compile(angular.element(row).contents())($scope) to work is when the <table> is prebuilt or rendered by ng-repeat.
Here delayed injected HTML from a jQuery AJAX needs to be replaced with a ng-template including bindings, I think $scope.$apply() is the only way around :
.withOption('createdRow', function (row, data, dataIndex) {
$scope.$apply($compile(angular.element(row).contents())($scope))
})
Works for me -> http://plnkr.co/edit/UqZKhpgMx7aHCXdaNkiN?p=preview
Silly me. The same can be done in a simple $timeout.
$timeout(function() {
$compile(angular.element(row).contents())($scope)
})
http://plnkr.co/edit/5OTeHHUgkIurd6Z3DCkP?p=preview

Bootstrap table responsive grey line

I have grey line under my responsive table. I don't know from where it comes. How it gets created. Here a pic:
My html code:
<div class="container">
<div class="row">
<div ng-app="appGenerator" ng-controller="MainCtrl">
<div ng-repeat="table in tablenames">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
</thead>
<tbody>
<tr ng-repeat="ttable in table.table" ng-click="setSelect(ttable)">
<td>{{ttable}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
My js code:
var app = angular.module('appGenerator', ['ngRoute']).controller('MainCtrl', function ($scope, $http) {
$http.get('GeneratedFiles/RelationsBC.bbTable').success(function (tableResponse) {
$scope.tablenames = tableResponse.table;
});
$scope.setSelect = function (ttable) {
alert(ttable);
}
});

Cannot populate record to bootstrap modal when a link is clicked

Please I need some help, I have been working so hard to populate a record to bootstrap modal when a link is clicked so that user can edit and update the record. The link is not in form, its in a table.
Below are my nonworking codes:
The HTML
<div class="widget-content">
<form action="#" method="GET">
<table class="table table-striped table-bordered table-hover table-checkable datatable">
<thead>
<tr>
<th class="checkbox-column">
<input type="checkbox" class="uniform">
</th>
<th>Actions</th>
<th>Code</th>
<th>Full Name</th>
<th>Company Name</th>
<th>Business Location</th>
<th>Telephone</th>
<th>Credit Limit</th>
</tr>
</thead>
<tbody>
<?php
$query="select * from customer_vendor";
$result = mysqli_query($link,$query);
while($row = mysqli_fetch_array($result, MYSQL_ASSOC) ){
$firstname = $row['first_name'];
$lastname = $row['last_name'];
$fullname = $firstname.' '.$lastname;
$climit = number_format($row['credit_limit'],2);
echo
"<tr>
<td class=\"checkbox-column\">
<input type=\"checkbox\" class=\"uniform\" >
<input type=\"hidden\" >
</td>
<td>
<ul class=\"table-controls\">
<li><a class=\"bs-tooltip\" id=\"updateit\" name=\"update_cv\" data-class=\"{$row['customer_vendor_id']}\" data-toggle=\"modal\" href=\"#update_customer_vendor\" title=\"Edit\"><i class=\"icon-pencil\"></i></a> </li>
<li><a class=\"bs-tooltip\" data-toggle=\"modal\" href=\"#delete_customer_vendor\" title=\"Delete\"><i class=\"icon-trash\"></i></a> </li>
</ul>
</td>
<td>{$row['customer_vendor_id']}</td>
<td>$fullname</td>
<td>{$row['company_name']}</td>
<td>{$row['business_location']}</td>
<td>{$row['telephone']}</td>
<td>$climit</td>
</tr>";
}
?>
</tbody>
</table>
</form>
<button class="btn btn-primary"><i class="fa fa-plus"> New</i></button>
</div>
The modal:
<div class="modal modal-wide fade" id="update_customer_vendor">
<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">Updating customer - Vendor</h4>
</div>
<form action="#" method="POST">
<div class="modal-body" id="update_modal">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" ><i class="fa fa-save"> Update</i></button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
The script:
<script type="text/javascript">
$(document).ready(function(){
$("#updateit").click(function(){
var studentClass =$("#updateit").val();
$.ajax({
type:"GET",
url:"update_cust_vend.php",
data:"updateit="+studentClass,
success:function(data){
$("#update_modal").html(data);
}
});
});
});
</script>
try following. i think that should fix it.
<li><a class=\"bs-tooltip\" id=\"updateit\" name=\"update_cv\" data-class="studentclass" data-toggle=\"modal\" href=\"#update_customer_vendor\" title=\"Edit\"><i class=\"icon-pencil\"></i></a> </li>
link must contain studentClass somewhere it's not a input field so can't use val() .
i.e data-class="studentclass" in above link.
$(document).ready(function(){
$("#updateit").on('click', function(e){
e.preventDefault();
var studentClass =$(this).data('class'); // get studentclass form link.
$.ajax({
type:"GET",
url:"update_cust_vend.php",
data:"updateit="+studentClass,
success:function(data){
$("#update_modal").html(data);
$("#update_customer_vendor").modal();
}
});
});
});
First of all add the following to your click event to prevent the default behaviour of the hyperlink:
$("#updateit").click(function(event){
event.preventDefault();
});
After that I am confused, you are taking the value of your hyperlink here:
var studentClass =$("#updateit").val();
Is this not a mistake? Because your hyperlink doesn't have a value...
You can store a value in a custom made attribute. To do so you must define your attribute with the data- prefix. So for example data-value.
So your hyper link would be:
<li><a class=\"bs-tooltip\" id=\"updateit\" ... data-value="1"><i class=\"icon-pencil\"></i></a></li>
To get the value use:
var studentClass = $(this).attr('data-value');
Where $(this) refers to your clicked hyperlink.
And in your success handler after populating the html you don't show the modal, add this:
$('#update_customer_vendor').modal('show');

Categories

Resources