DataTables won't work in a modal - javascript

I have a table, where on row click a modal window is opened. Thanks to this:
th:onclick="'javascript:openPoolModal(\''+ ${networkHashrate.id} + '\');'"
openPoolModal.js looks like:
function openPoolModal(id){
$.ajax({
url: "/" + id,
success: function(data){
$("#PoolModalHolder").html(data);
$("#personalModal").modal();
$("#personalModal").modal('show');
}
});
}
PoolModalHolder is just an empty div on my main.html file, where the first table is rendered. personalModal is a fragment of code that opens on a modal dialog.
A modal dialog is then filled with personalModal:
<div class="modal fade" id="personalModal" role="dialog" th:fragment="modalContents">
<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" th:text="'Network Id: ' + ${poolHashrates[0].networkHashrate.id}">Network Id</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table width="100%" class="table table-hover " id="poolTable">
<thead class="thead-inverse">
<tr>
<th class="col-md-2 text-center">Pool name</th>
<th class="col-md-2 text-center">Date from</th>
<th class="col-md-2 text-center">Hashrate</th>
</tr>
</thead>
<tbody>
<tr th:each="poolHashrate : ${poolHashrates}">
<td class="text-center" th:text="${poolHashrate.poolDef.name}"> Sample data</td>
<td class="text-center" th:text="${poolHashrate.poolDef.date_from}">Maven Street 10, Glasgow</td>
<td class="text-center" th:text="${poolHashrate.hashrate}">999-999-999</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
I can't get the DataTables to work on the table inside personalModal window.
The standard DataTables initialization doesn't work and that is:
$(document).ready( function () {
$('#poolTable').DataTable();
} );
I have also tried this, but with same result:
$( "#personalModal" ).focus(function() {
$('#poolTable').DataTable();
});
I have header links added and those are: jQuery, Bootstrap, DataTables.js.
I have also tried with table-responsive example, but again, doesn't work. Data is generated correctly through Spring controller method. I just need to apply sorting & pagination to the table.

Related

Laravel using ajax get records from controller

Am trying to get data from controller and append to "tbody" using Ajax, yet am getting blank page.
Controller:
public function getRecordsMD(){
$filedata = File::where('uploaded_by', '=', auth()->user()->username)->get();
return response()->json([
'filedata'=>$filedata,
]);
}
Route:
Route::get('/manage_document',[utemfilesharing::class, 'getRecordsMD']);
Ajax/Jquery:
$(document).ready(function () {
getRecordsMD();
//Get all records
function getRecordsMD() {
$.ajax({
type:'GET',
url: '/manage_document',
dataType: "json",
success: function(data){
console.log(data.filedata);
$.each(data.filedata, function (key, item) {
$('tbody').append('<tr>\
<td>'+item.id+'</td>\
<td>'+item.name+'</td>\
<td>'+item.faculity_name+'</td>\
<td>'+item.document_type+'</td>\
<td>'+item.subject_name+'</td>\
<td>'+item.description+'</td>\
<td>\
<button type="button" id="editFiles" class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#edit-model" data-id="'+item.id+'"><i class="fas fa-edit"></i></button>\
<button type="button" id="deleteFiles" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#delete-model" data-id="'+item.id+'"><i class="fas fa-trash"></i></button>\
</td>\
</tr>');
});
},
error: function (data) {
console.log('Error:', data);
}
});
}
});
View:
<!-- Manage Document -->
<div class="col-xl-12 col-md-6 mb-4">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div
class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Manage Document</h6>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="alert alert-success" role="alert" id="successMsg" style="display: none" >
File Updated successfully!
</div>
<div class="alert alert-danger" role="alert" id="successDMsg" style="display: none" >
File Delete successfully!
</div>
<table id="manageDocument" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>File Name</th>
<th>Faculity Name</th>
<th>Document Type</th>
<th>Subject Name</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<script src="{{asset('vendor\bootstrap\js\bootstrap5-1-3.bundle.min.js')}}"></script>
<script src="{{asset('vendor\jquery\jquery.min.js')}}"></script>
<script src="{{asset('js\Models.js')}}"></script>
It seems like am missing something I don't know what its. whenever I navigate to /manage_document I get a blank page where it suppose display the table. will be glad if you help.

DataTables pagination css broken in modal datatables

How do I customize the css of datatables?
My pagination seems broken when I am trying to use datatables function in Modal bootstrap.
Also, how can I limit the pagination number that appear in html when there are so many data ?
For example, in the pagination table it have number
1, 2, 3, 4, 5,...,8
how can I make the pagination into
1, 2 , 3 ,..., 8 ?
The pagination and the row count are just like in a image below.
My datatables script
$('#example').DataTable( {
"ajax": "<?php echo base_url('dashboard/show_karyawan'); ?>",
"columns": [
{
"data": "id",
render: function (data, type, row, meta) {
return meta.row + meta.settings._iDisplayStart + 1;
}
},
{ "data": "NIP" },
{ "data": "nama" },
]
} );
My Modal
<div class="modal fade" id="modalkaryawan" role="dialog" aria-hidden="true" data-backdrop="false">
<div class="modal-dialog modal-lg" style="width: 500px;">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title">
<center><h4>Silahkan Pilih Karyawan</i></h4></center>
</div>
</div>
<div class="modal-body">
<table id="example" class="table table-striped display" cellspacing="0" width="100%">
<thead>
<tr>
<td>No</td>
<td>NIP</td>
<td>Nama Pegawai</td>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td>No</td>
<td>NIP</td>
<td>Nama Pegawai</td>
</tr>
</tfoot>
</table>
</div>
<div class="modal-footer">
<center>
<button type="button" id="savesebab_delete" class="btn btn-primary">Ya</button>
<button type="button" data-dismiss="modal" class="btn btn-danger">Tidak</button>
</center>
</div>
</div>
</div>
For limiting the pagination number add the following code before you initialize the datatable inside the script:
$.fn.DataTable.ext.pager.numbers_length = 5;
This will make sure that you will have 5 page numbers includeing '...'.
I have made a sample demo here: https://codepen.io/Sahero/pen/VzzpvE.

Knockout: Bind template bootstrap modal for many data objects

I am relatively new in Javascript and Knockout JS and I am facing the problem below:
I load data from a Ajax request and map it into my object:
function ActivityModel(obj) {
if (typeof (obj) != 'undefined') {
this.ShowTable = ko.observable(true);
this.Name = ko.observable(obj.nomVessel);
this.NumRecords = ko.observable(obj.data.length);
this.DataRecords = ko.observableArray([]);
var aux = [];
//When add new items, mark they as changed, so the update css style will be loaded
$.each(obj.data, function (index, value) {
aux.push({ hasChanged: ko.observable(true), record: value });
});
this.DataRecords.push(aux);
}
}
I store all objects into an observable Array named DataTables.
Then, based on the data, I render a 'gadget', that is composed by a div with some buttons, and a table that loads my data records:
<!-- ko foreach: DataTables -->
<div class="col-sm-6">
<div class="box gadget">
<div class="box-header clearfix">
<i class="glyphicon glyphicon-remove"></i>
<i class="glyphicon glyphicon-chevron-up"></i>
<h1><strong><span data-bind="text: $data.Name"></span></strong> - Activities</h1>
<div class="icons pull-right">
<i class="glyphicon glyphicon-cog"></i>
</div>
</div>
<div class="box-body">
<div class="table-responsive">
<table class="table table-bordered table-hover text-left density-medium">
<thead>
<tr>
<th>Start Date</th>
<th>Start Time</th>
<th>End Date</th>
<th>End Time</th>
<th>Details</th>
</tr>
</thead>
<tbody data-bind="foreach: $data.DataRecords">
<tr class="tooltipstered" data-bind="tooltipster: 'bottom-right'">
<td data-bind="text: $data.record.startDate"></td>
<td data-bind="text: $data.record.endDate"></td>
<td data-bind ="text: $data.record.details"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- /ko -->
Particularly, I have a button to open a bootstrap modal inside each gadget:
<div class="icons pull-right">
<i class="glyphicon glyphicon-cog"></i>
</div>
The code of the modal
<div id="modal-configure-gadget" class="modal fade modal-configure-gadget" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header shadow">
<button type="button" class="close" data-dismiss="modal">×</button>
<i class="icon-arrow-down-circle"></i><span class="h2">Configure <strong>gadget</strong></span>
</div>
<div class="modal-body">
<form action="" class="form-horizontal" role="form">
<div class="row">
<div class="col-sm-6">
<span class="h2">Set <strong>size</strong></span>
<div class="box box-filter">
<div class="form-group row">
<label for="linhas" class="control-label col-sm-4">Rows:</label>
<div class="add-remove-button col-sm-8">
<span class="btn btn-mini btn-navbar decrease-button">
<i class="glyphicon glyphicon-minus"></i>
</span>
<input id="linhas" type="text" class="form-control" value="1">
<span class="btn btn-mini btn-navbar increase-button">
<i class="glyphicon glyphicon-plus"></i>
</span>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer shadow">
<button class="btn btn-success">Ok</button>
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
</div>
</div>
</div>
My problem is: For each 'gadget' created, I would like to bind the button I've shown to open the modal. Moreover the input 'linhas' inside the modal should be bound to the observable NumRecords of my object. When I tried to bind using a simple click binding I have an unexpected behaviour that I changed the value of the input for one object (thus updating a single observable NumRecords) and the call was somehow broadcasted to the other gadgets on the screen.
I also tried using a custom binding:
ko.bindingHandlers.UpdateActivityCount = {
init:function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$('#modal-configure-gadget').on('show.bs.modal', function(e) {
$('#linhasActivity').val(bindingContext.$data.NumActivities());
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$('#modal-configure-gadget .btn-success').on('click', function(e) {
var confirm_button = $(e.target).is("#btnConfirmActivitiesChange");
if (confirm_button === true) {
//Update Value
self.UpdateObservableValue(data.NumRecords, $('#linhasActivity'), 'int', data, event);
}
});
}
};
but the unexpected behaviour remained.
I suspect this behaviour is occurring because the id of the modal and its elements are the same of every gadget created (Instead having one modal for each gadget, I have just one modal for all of them and it is generanting a conflict).
However, I do not know how to generate multiple modals with different ids (and different ids for the components such as buttons and inputs). I had a look at the component binding, but could not realise how it works and whether it would be useful to solve my problem.
Anyone has a suggestion?
Thanks.
Some suggestions
at
<tbody data-bind="foreach: $data.DataRecords">
<tr class="tooltipstered" data-bind="tooltipster: 'bottom-right'">
<td data-bind="text: $data.record.startDate"></td>
<td data-bind="text: $data.record.endDate"></td>
<td data-bind ="text: $data.record.details"></td>
</tr>
</tbody>
you dont need to use the $data variable, since you are already inside a foreach context. You can replace it with
<tbody data-bind="foreach: DataRecords">
<tr class="tooltipstered" data-bind="tooltipster: 'bottom-right'">
<td data-bind="text: record.startDate"></td>
<td data-bind="text: record.endDate"></td>
<td data-bind ="text: record.details"></td>
</tr>
</tbody>
Also for modal dialog, you can have one dialog to show details of different objects. Something like
<!-- ko with: currentDialogDetails -->
<input id="linhas" type="text" class="form-control" data-bind="textInput: NumRecords" />
<!-- /ko -->
and the have a click binding for opening up the dialog like
<div class="icons pull-right">
</i>
</div>
and in your view model, add an observable and another click handler as
this.currentDialogDetails = ko.observable(null);
this.setCurrentDialogDetails = function(details){
this.currentDialogDetails(details);
}

Create a reusable modal using JQuery

I know writing an IF-ELSEIF-ELSE statement in the loop below would work, however I want to avoid having to write multiple modals. Instead I am looking for a JQuery modal to pop up when the image icon (basically a info image) is clicked. I want to be able to pass in the error into the function, which will then display in the modal.
Example:
Say I have a 400 Error and 500 Error, when I click the info icon, the definition should appear.
CODE BELOW:
index.gsp
<html>
<%-- Some code (saving space for body) --%>
<body>
<div id="content">
<div id="content-header">
<h1>Error Checking</h1>
</div> <!-- #content-header -->
<div id="content-container">
<div class="portlet">
<div class="portlet-content">
<div class="table-responsive">
<table
class="table table-striped table-bordered table-hover table-highlight table-checkable"
data-provide="datatable"
data-display-rows="25"
data-info="true"
data-search="true"
data-length-change="true"
data-paginate="true">
<thead>
<tr>
<th data-filterable="true" data-sortable="true" data-direction="desc">User ID</th>
<th data-filterable="true" data-sortable="true" data-direction="desc">Task ID</th>
<th data-filterable="true" data-sortable="true" data-direction="desc">Error Message</th>
</tr>
</thead>
<tbody>
<g:each in="${lists}" var="list">
<tr>
<td>${list.userId}</td>
<td>${list.taskId}</td>
<td>
**%{--WANT TO PLACE MODAL CALL HERE--}%**
**<i class="fa fa-exclamation-triangle ui-popover pull-left" style="color:#f0ad4e;"></i>
${list.errorMsg}**
</td>
</tr>
</g:each>
</tbody>
</table>
</div> <!-- /.table-responsive -->
</div> <!-- /.portlet-content -->
</div> <!-- /.portlet -->
</div> <!-- /#content-container -->
</div> <!-- #content -->
The MODAL I want to pop up:
<div id="styledFreqLargerModal" class="modal modal-styled fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title">Issue</h3>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-tertiary" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
You can generate dynamic id's using your list item's id. Then you can place your modal at the place you have mentioned. The following is a code example:
<div id="styledFreqLargerModal${list.id}" class="modal modal-styled fade">
[..]
</div><!-- /.modal -->
If you are using jQuery-UI
<a class="openDialog" href="#styledFreqLargerModal${list.id}"><i class="fa fa-exclamation-triangle ui-popover pull-left" style="color:#f0ad4e;"></i></a>
In your javascript do:
$(document).on("click", "a.openDialog", function() {
$($(this).attr("href")).dialog();
}
If you are using bootstrap
<a data-toggle="modal" href="#styledFreqLargerModal${list.id}"><i class="fa fa-exclamation-triangle ui-popover pull-left" style="color:#f0ad4e;"></i></a>
Solved the problem... Used Jquery modal. This prevented me from having to create multiple modals. In the modal I have a "click" method that determines which item got clicked, then outputs that specific message. See code below.
index.gsp
<html>
<%-- Some code (saving space for body) --%>
<body>
<div id="content">
<div id="content-header">
<h1>Error Checking</h1>
</div> <!-- #content-header -->
<div id="content-container">
<div class="portlet">
<div class="portlet-content">
<div class="table-responsive">
<table
class="table table-striped table-bordered table-hover table-highlight table-checkable"
data-provide="datatable"
data-display-rows="25"
data-info="true"
data-search="true"
data-length-change="true"
data-paginate="true">
<thead>
<tr>
<th data-filterable="true" data-sortable="true" data-direction="desc">User ID</th>
<th data-filterable="true" data-sortable="true" data-direction="desc">Task ID</th>
<th data-filterable="true" data-sortable="true" data-direction="desc">Error Message</th>
</tr>
</thead>
<tbody>
<g:each in="${lists}" var="list">
<tr>
<td>${list.userId}</td>
<td>${list.taskId}</td>
<td>
<g:if test="${(list.errorMsg).contains("400")}">
<a id="modalAlert-${list.taskId}" class="modal-alert-null" ><i class="fa fa-exclamation-triangle ui-popover pull-left" style="color:#f0ad4e;"></i></a>
${list.errorMsg}
</g:if>
<g:elseif test="${(list.errorMsg).contains("500")}">
<a id="modalAlert-${list.taskId}" class="modal-alert-outOfBounds" ><i class="fa fa-exclamation-triangle ui-popover pull-left" style="color:#f0ad4e;"></i></a>
${list.errorMsg}
</g:elseif>
</td>
</tr>
</g:each>
</tbody>
</table>
</div> <!-- /.table-responsive -->
</div> <!-- /.portlet-content -->
</div> <!-- /.portlet -->
</div> <!-- /#content-container -->
</div> <!-- #content -->
<r:require modules="jquery"/>
<script type="text/javascript">
$(document).ready(function() {
// Null pointer exception
$(".modal-alert-null").click(function() {
modalAlert("400 error message");
});
// outOfBoundsException
$(".modal-alert-outOfBounds").click(function() {
modalAlert("500 error message");
});
});
function modalAlert(description)
{
$("body").append(buildAlertModal());
$("#alert-modal .modal-description").html(description);
$("#alert-modal").modal("show");
}
function buildAlertModal() {
return "<div id='alert-modal' class='modal modal-styled fade'>" +
" <div class='modal-dialog'>" +
" <div class='modal-content'>" +
" <div class='modal-header'>" +
" <button type='button' class='close' data-dismiss='modal' aria-hidden='true'>×</button>" +
" <h3 class='modal-titl'>Exception Info</h3>" +
" </div>" +
" <div class='modal-body'>" +
" <p class='modal-description'></p>" +
" </div>" +
" <div class='modal-footer'>" +
" <button type='button' class='btn btn-tertiary' data-dismiss='modal'>Close</button>" +
" </div>" +
" </div>" +
" </div>" +
"</div>";
}
function closeModalAlert() {
$("#alert-modal").modal("hide");
}
</script>

ng-repeat won't work in modal

So I'm trying to get a modal to ng-repeat an array of objects and it won't show up at all.
I'm not quite sure what I'm doing wrong but hoping for help as to getting the ng-repeat to work!
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"> × </button>
<h4>Transfer Funds</h4>
</div>
<br />
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<table class="table">
<thead>
<tr>
<th class="text-center">
eGift Cards
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="trans in gctrans.Items | filter: cardSearch">
<td class="text-center">
<strong>{{getCustomerName(trans)}}</strong>
<strong>{{getCustomerCardNumber(trans)}}</strong>
<small>{{getCustomerPhone(trans) | tel}}<br /></small>
<small> {{getCustomerEmail(trans)}}<br /></small>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<br />
<div class="modal-footer">
<button class="btn btn-primary" ng-click="confirmTransfer(trans)">Next</button>
</div>
</div>
the two most likely things that would be causing this are model not existing in scope and filter causing unexpected behavior. The first to try would be seeing if the gctrans.Items is available in the scope of the modal. Try adding {{gctrans}} in the modal and see if any data is there, like:
<div class="col-md-12">
raw data: {{gctrans}}
<table class="table">
second, if there is data try removing the filter:
<tr ng-repeat="trans in gctrans.Items">
and one more thing to try, if the data is good and the filter is not unexpectedly removing items, you might not be selecting anything inside of the repeat. Try just outputting the item
<tr ng-repeat="trans in gctrans.Items">
<td class="text-center">
<strong>{{trans}}</strong>
</td>
</tr>
thanks so much for the input. I figured out what I had done wrong in the controller (hadn't declared gctrans in the modal function).
Make sure all your stuff is declared in functions as well if you're using modals and ng-repeat!

Categories