How to change Ajax generated HTML-Content - javascript

Hi I have Problems to change HTML content, which is generated by AJAX
This is the code of the page:
#model IEnumerable<WE_SRW_PeerNissen.Models.Reservations>
#{
ViewBag.Title = "List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Übersicht Liste</h2>
<form method="post" action="List">
<div class="input-group">
<div class="input-group-btn">
<input type="text" class="form-control" name="searchbar" placeholder="Search">
<button class="btn btn-default" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
</form>
<table class="table" id="sorttable">
<thead bgcolor="white">
<tr>
<th>
#Html.DisplayNameFor(model => model.BookingNr)
</th>
<th>
#Html.DisplayNameFor(model => model.Arrival)
</th>
<th>
#Html.DisplayNameFor(model => model.Departure)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Appartment)
</th>
<th>
#Html.DisplayNameFor(model => model.Adult)
</th>
<th>
#Html.DisplayNameFor(model => model.Children)
</th>
<th>
#Html.DisplayNameFor(model => model.Total)
</th>
</tr>
</thead>
</table>
<link href="~/Content/DataTables/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="~/Scripts/DataTables/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$('#sorttable').DataTable({
"ajax": {
"url": "/OverView/loaddata",
"type": "GET",
"datatype": "json"
},
"columns": [
{ "data": "BookingNr", "autoWidth": true },
{ "data": "Arrival", "autoWidth": true },
{ "data": "Departure", "autoWidth": true },
{ "data": "Name", "autoWidth": true },
{ "data": "Appartment", "autoWidth": true },
{ "data": "Adult", "autoWidth": true },
{ "data": "Children", "autoWidth": true },
{ "data": "Total", "autoWidth": true },
]
});
});
</script>
An example what is generated:
<div class="dataTables_filter" id="sorttable_filter">
<label>Search:
<input aria-controls="sorttable" type="search" placeholder="">
</label>
</div>
And I think that was my best try:
<script>
$(document).ready(function () {
$(document).on(function () {
$('#sorttable_filter label:eq(1)').text('Suchen:');
});
});
</script>
which I set below the AJAX script, I also tried to put it in the same script-Tag below to make sure, that AJAX is Executed

A few comments...
jQuery on() method binds function to the specific event, like: $(something).on("click", doSomething) and you provide there only a function, thus it does not know what event to bind your function to.
Then, eq(1) is jQuery method, but not a CSS selector, thus you'd like to use "label:first-child" (if you need the first one). It will, however, destroy input field in your example HTML, due to it is inside a label element, so you (probably) would like to have it outside. In the case when you're unable to change that HTML output you can use a dirty hack of "moving" input copy outside of label element... like this
$(document).ready(function() {
var labelEl = document.querySelector("#sorttable_filter label:first-child");
var inputEl = labelEl.querySelector("input");
labelEl.parentNode.appendChild(inputEl);
labelEl.innerText = 'Suchen:';
});
What I don't like is the fact that document.ready() might happen a while before actual element appears, so you'd like to look for result HTML appearance at least...

Related

PHP Datables not showing any rows - Server side

I am having trouble getting Datables to work.
No-matter what I try, I am getting the issue that there is no data.
The message exactly is: "No matching records found".
I am using the correct format found here on the official website but it doesn't seem to want to load.
I am not using MYSQL so haven't include any SPP, but am just returning the array of address's inside an array then encoding it in JSON.
In my frontend file, I am trying to load all address's from a certain router:
<script type="text/javascript">
$(document).ready(function() {
$('#table').DataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": "<?=url('database/addresses');?>",
"dataSrc": "",
},
'columnDefs': [{
'targets': 1,
'checkboxes': {
'selectRow': true
}
}],
'select': {
'style': 'multi',
'selector': 'td:first-child'
},
'order': [[5, 'desc']],
"columns": [
{ "data": "id" },
{ "data": "id" },
{ "data": "input_address" },
{ "data": "destination_address" },
{ "data": "callback_url" },
{ "data": "dateCreated.date" },
{ "data": "id" }
],
'colReorder': true
});
} );
</script>
My html table:
<form method="post" id="deleteMulti" class="ajax-multi" action="<?=url('XhPCrvFtQuE7gPP6/addresses/delete/selected');?>">
<?= csrf() ?>
<div class="row">
<div class="col-xxl-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Addresses [ <?=$count;?> ]</h4>
<div class="right fr">
<button class="btn tooltip" style="display: inline;" name="deleteSelected" title="Delete Selected Addresses"><i class="fa fa-trash" style="color: black;"></i></button>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table id="table" class="display">
<thead>
<tr>
<th>#</th>
<th><input type="checkbox" class="" id="checkAl"></th>
<th>Input Address</th>
<th>Output Address</th>
<th>Callback Url</th>
<th>Created</th>
<th><i class="bi bi-archive-fill"></i></th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
**And in my database/addresses to load the database content:**
// This is used for when we need to load more address's to the admins /addresses page
public function getAddresses() {
define('PAGE_NAME', 'Admin Addresses');
// Skip 100 as we will start from the 100th row
// We set the limit to 100 in Admin page so the page loads 100 much faster
// We will push more and more using this function inside here for when they click load more
$addresses = \r\table('addresses')->orderBy(array('index' => \r\desc('dateCreated')))->skip(100)->limit(100)->run($this->conn);
$addresses = $addresses->toArray();
$count = count($addresses);
$theArr = array();
foreach ($addresses as $address) {
$theArr[] = $address;
}
$final = array(
'draw' => 1,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => array_values($theArr)
);
if($count > 0) {
echo json_encode($final, JSON_FORCE_OBJECT);
} else {
return false;
}
}
My issue is that it keeps showing me:
No matching records found eventhough I do have over 4k records in there.
Take a look at this picture here
Take a look at the format of the json returned from my getAddresses():
here

My Ajax request only sent once

I have an ajax request for getting the purchased list of a user. I thought it was perfectly working because it returns the data that I need. But when I click the other user it seems the ajax request only send a request once. Becuase the data is the same, and when I look at the network tool of chrome, there is no another request was send.
This is my current Ajax request.
var purchased_list;
// $('#student_profile_purchased_item_list_tab').click(function(){
function createTablePurchasedList(id){
console.log("Start, student:"+id);
purchased_list= $('#purchased_item_list_table').DataTable({
// "processing": true,
// "paging": false,
// "ordering": true,
"ajax": {
url:'{{ route("student_item_list") }}?student_id='+id,
cache: true,
dataSrc: "",
},
columnDefs: [
{
className: "dt-center",
targets: [0],
},
],
"columns": [
{
data: "date_purchased"
},
{
data: "product_status_id",
render: function(data, type, row){
switch(data){
case 2:
return 'Purchased';
case 3:
return '<p style="color:red;">Consumed</p>';
case 6:
return '<p style="color:green;">Transferred</p>';
}
}
},
{
data: "name",
render: function(data, type, row){
return data;
}
},
]
});
console.log("End, student:"+id);
}
// });
Tab
<li>Purchased Item List</li>
Datatable
<div class="tab-pane fade in" id="student_profile_purchased_item_list">
<div style="position:relative;">
<div class="other_content_header">
Item List
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table width="100%" class="responsive table table-striped table-bordered table-hover purchase-item-table" id="purchased_item_list_table" style="font-size:12px; text-align:center;">
<thead>
<tr>
<th>Date</th>
<th>Item Status</th>
<th>Product Name</th>
{{-- <th>Quantity</th> --}}
{{-- <th> </th> --}}
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
every time I click a user the console.log result changes, At first I thought the ID is not changing when I click another user. But when I do the console log the result changes.
Hope someone can help me solve my problem.

How to access additional data in JSON requested by Dynatable AJAX call

I am using the dynatable.com plugin to create a table of of schools that are stored in our database. The table can be filtered so does not always show the total number of schools. We do not display a 'number of pupils' column but are trying to show a 'total number of pupils' summary at the bottom of the table.
html on the page is as follows:
<table id="dynatable">
<thead>
<tr>
<th data-dynatable-column="id">ID</th>
<th data-dynatable-column="schoolName">School Name</th>
<th data-dynatable-column="contactName">Contact Name</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="3"><span id="numPupils"></span> Pupils</td>
</tr>
</tfoot>
</table>
Followed by the JS:
<script>
$('#dynatable').dynatable({
dataset: {
ajax: true,
ajaxUrl: '/my/json/page.json',
ajaxOnLoad: true,
records: []
}
});
</script>
And a sample of the JSON retrieved (note the additional totalNumPupils field at the bottom):
{
"records": [
{
"id": "1",
"schoolName": "ABC School",
"contactName": "Terry"
},
{
"id": "17",
"schoolName": "DEF School",
"contactName": "Claire"
},
{
"id": "45",
"schoolName": "GHI School",
"contactName": "Barry"
}
],
"queryRecordCount": 3,
"totalRecordCount": 450,
"totalNumPupils": 794
}
I am trying to establish if there is a way to access the responseJSON.totalNumPupils that is requested by dynatable's ajax call or whether I would have to perform my own ajax call, ascertain the number of pupils, then pass in the JSON to the dynatable function afterwards?
Please see the code snippet. You can use normal AJAX to get the JSON payload, then populate the dynatable with the data from the AJAX response, while simultaneously accessing the unique totalNumPupils property.
$('#dynatable').dynatable({
dataset: {
ajax: true,
ajaxUrl: 'https://api.myjson.com/bins/1ezw8l',
ajaxOnLoad: true,
records: []
}
});
$.ajax({
url: 'https://api.myjson.com/bins/1ezw8l',
success: function(data) {
$('#dynatable').dynatable({
dataset: {
ajax: false,
records: data
}
});
$('#numPupils').text("Total Pupils: " + data.totalNumPupils);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Dynatable/0.3.1/jquery.dynatable.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Dynatable/0.3.1/jquery.dynatable.css" rel="stylesheet" />
<table id="dynatable">
<thead>
<tr>
<th data-dynatable-column="id">ID</th>
<th data-dynatable-column="schoolName">School Name</th>
<th data-dynatable-column="contactName">Contact Name</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="3"><span id="numPupils"></span> Pupils</td>
</tr>
</tfoot>
</table>

Click event on dynamic button in table

I have a datatables element on my page with a hidden first column, and an empty column at the end to contain a button.
I'm trying to get the click event of that button to:
Hide the button,
Show a 'loading' icon - fontawesome icon already in the column
Retrieve the value of the hidden columns corresponding row
Show a success/fail icon - to be added but will be a fontawesome icon
CSHTML:
<div class="row">
<div class="col-sm-12">
<table class="table table-striped table-hover" id="SignOffTable">
<thead>
<tr>
<th>DATA_ID</th>
<th>KPI Name</th>
<th>Value 1</th>
<th>Value 2</th>
<th>Value 3</th>
<th>Date For</th>
<th>Value Type</th>
<th>Added By</th>
<th>Added On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td>
#item.DATAID
</td>
<td>
#item.KPIHead
</td>
<td>
#item.Value1
</td>
<td>
#item.Value2
</td>
<td>
#item.Value3
</td>
<td>
#item.FromDate.ToString("dd/MM/yyyy")
</td>
<td>
#item.Type
</td>
<td>
#item.AddedBy
</td>
<td>
#item.AddedOn.ToString("dd/MM/yyyy")
</td>
<td id="ActionCol">
<button id="TableSignOff" class="btn btn-outline-success btn-sm" data-interaction="#item.DATAID">Sign Off</button>
<div id="Loader"><span id="Loading" class="fa fa-spinner fa-pulse fa-fw"></span></div>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
Script:
<script>
$(document).ready(function () {
$("div#Loader").hide();
var table = $('#SignOffTable').DataTable({
paging: true,
searching: false,
ordering: false,
pagingType: "simple_numbers",
lengthChange: false,
bfilter: true,
info: true,
"columnDefs": [
{ "visible": false, "targets": 0 }
]
});
});
$("#SignOffTable button").click(function () {
$(this).hide();
$('div#Loader').show();
var trElem = $(this).closest("tr");
var firstTd = $(trElem).children("td")[0];
alert($(firstTd).text())
})
</script>
However I can't seem to access the hidden column's data, or successfully hide the button/show the loading spinner. The spinner icon is hidden upon page load, and the button click will hide that button but will then show all the spinners in the column, rather than just that specific one.
You are creating duplicate IDs for your elements. This is invalid HTML and will cause your code to be confused about which elements it's trying to access.
Something more like this should help, using classes rather than IDs:
<td>
<button class="TableSignOff btn btn-outline-success btn-sm" data-interaction="#item.DATAID">Sign Off</button>
<div class="Loader" hidden>
<span class="fa fa-spinner fa-pulse fa-fw" ></span>
</div>
</td>
And
<script>
$(document).ready(function () {
var table = $('#SignOffTable').DataTable({
paging: true,
searching: false,
ordering: false,
pagingType: "simple_numbers",
lengthChange: false,
bfilter: true,
info: true,
"columnDefs": [
{ "visible": false, "targets": 0 }
]
});
});
$("#SignOffTable .TableSignOff").click(function () {
var btn = $(this);
btn.hide(); //hide the button
btn.parent().find(".Loader").show(); //show the loader within the button's parent td
alert(btn.data("interaction")); //output the DATAID
})
Also note that the loaders are hidden at the start by markup rather than code, so you don't get any momentary showing of the loaders before the code runs.

jQuery DataTables plugin with JSON data source taking multiple POST requests on global search

Friends,
I'm using jQuery DataTables plugin. I'm doing the Server Side Processing with JSON datasource to fill the DataTable as showing in the example
Here's my code
HTML
<Table class="projectGrid DataTable display" id="tblList" width="100%">
<thead>
<tr>
<th align="center">
Created
</th>
<th align="center">
Assigned
</th>
<th align="center">
Stage
</th>
<th align="center">
Priority
</th>
<th align="center">
Status
</th>
</tr>
</thead>
<tfoot>
<tr>
<th align="center">
Created
</th>
<th align="center">
Assigned
</th>
<th align="center">
Stage
</th>
<th align="center">
Priority
</th>
<th align="center">
Status
</th>
</tr>
</tfoot>
<tbody>
<asp:Repeater ID="reptList" runat="server">
<ItemTemplate>
<tr>
<td align="center">
<%#Eval("CreatedBy")%>
</td>
<td align="center">
<%#Eval("AssignedTo")%>
</td>
<td align="center">
<%#Eval("Stage")%>
</td>
<td align="center">
<%#Eval("Priority")%>
</td>
<td align="center">
<%#Eval("Status")%>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
JavaScript
<script type="text/javascript">
var data =
{
datatableConfig: {
"aaSorting": [],
"processing": true,
"serverSide": true,
"ajax": {
url: "~/IssueData.asmx/GetIssueList",
type: "POST"
},
"columns": [
{ "data": "0" },
{ "data": "1" },
{ "data": "2" },
{ "data": "3" },
{ "data": "4" }
]
}
}
$(data.datatable + ' tfoot th').each(function () {
var title = $(this).text();
if (!$(this).hasClass('hidden')) {
$(this).html('<input type="text" class="footerInput" style="width:' + ($(this).width() - 10) + 'px" placeholder="Filter ' + $.trim(title) + '" />');
}
});
// Apply Datatable
if ($(options.datatable).length) {
table = $(options.datatable).DataTable(options.datatableConfig);
}
// Apply the search
table.columns().every(function () {
var that = this;
$('input.footerInput', this.footer()).on('change', function () {
if (that.search() !== this.value) {
that.search(this.value).draw();
}
});
});
</script>
Everything is working fine, except Search. When I enter single letter in a Search, It raises 3-4 Ajax POST Requests. Any Idea why it processes more POST requets on single keypress event?
You can use below code to apply search so when user press 'enter' key ajax request is made to search :
// Apply the search
table.columns().every(function () {
var that = this;
$('input.footerInput', this.footer()).on('keyup', function (e) {
if (e.keyCode == 13 && $.trim(this.value) !== '') {
that.search(this.value).draw();
}
});
});

Categories