how to populate a html table inside a dynamically loaded DIV - javascript

i have a DIV container inside a HTML page where I am dynamically loading other HTML pages using jquery.load() function . On one of the pages i need to populate a table from the database just after/before that page loads. How do I call a javascript function that executes just after that DIV is loaded with the page.
this is the dynamically loaded "headquarters.html" page:
<div class="row">
<div class="col-md-10" >
<table class="table table-bordered table-hover" id="tbl_hqlist">
<tr>
<th> HQ Code</th>
<th> Headquarter Name</th>
</tr>
</table>
</div>
</div>
i am loading that page using jquery.load() function like below:
function fn_headquarters(){
$('#bodyContent').load("../html/headquarters.html");
headquarterManagement();
return;
}
function headquarterManagement(){
$.ajax({
url:"../bin/manage_hq.php",
data:{ 'procAction': 1},
method: 'POST',
dataType: 'JSON',
success: function(proc_msg){
// get data and populate the table using jquery.each() & jquery.append() functions
},
error: function(xhr){
console.log(xhr.responseText);
}
})
return;
}
this code fails to update "tbl_hqlist".

jQuery load() uses AJAX and is therefore asynchronous, lucky for you, it provides a callback parameter. Adjust like so...
function fn_headquarters(){
$('#bodyContent').load("../html/headquarters.html", function(){
headquarterManagement();
});
return;
}
By doing this, you will make sure the element actually exists before populating it.
?Bonus: This will create table markup from json data:
function makeTableFromArray(arrayOfData){
var html_buffer = [];
html_buffer.push("<table><thead><tr>");
var headerData = arrayOfData[0];
for(var p in headerData)
if(headerData.hasOwnProperty(p))
html_buffer.push("<th>"+p+"</th>");
html_buffer.push("</tr></thead><tbody>");
for(var i=0; i<arrayOfData.length; i++){
html_buffer.push("<tr>");
for(var p in arrayOfData[i])
if(arrayOfData[i].hasOwnProperty(p))
html_buffer.push("<td>"+arrayOfData[i][p]+"</td>");
html_buffer.push("</tr>");
}
html_buffer.push("</table>");
return html_buffer.join("");
}
https://jsfiddle.net/sbctwdLc/

Related

Ajax paging is duplicating _layout page while using pagination to replace page content

I am using x.PagedList to use pagination in my ASP.NET MVC page. The only problem I have with the plugin is , it used a page refresh when I navigate between pages.
To avoid that I am using jQuery calls to replace page contents as explained in this article.
My View and javascript looks like this.
<div id="circuitsContent">
<table class="table">
<tr>
--Header
</tr>
#foreach (var item in Model)
{
<tr>
--Loop through and create content
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
#Html.ActionLink("Details", "Details", new { id = item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
</div>
<div id="circuitContentPager">
#Html.PagedListPager((IPagedList)Model, page => Url.Action("Circuits", new { page }))
</div>
#section scripts
{
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$(document).on("click", "#circuitContentPager a[href]", function () {
$.ajax({
url: $(this).attr("href"),
type: 'GET',
cache: false,
success: function (result) {
$('#circuitsContent').html(result);
}
});
return false;
});
});
</script>
And this is my controller code:
public ActionResult Circuits(int? page)
{
var pageNumber = page ?? 1;
var circuits = _repo.GetAllCircuits().OrderBy(circ=>circ.ID).ToList();
var pagedCircuits = circuits.ToPagedList(pageNumber, 25);
return View(pagedCircuits);
}
What am I missing here?
Your ajax call returns the html from Circuits() method which is the same view you have used to render the page initially, which includes all the initial html, but you only replacing part of of the existing page, so elements such as the paging buttons generated by the #Html.PagedListPager() method are going to be repeated. Your also generating invalid html because of duplicate id attributes (you will have multiple <div id="circuitsContent"> elements
There are 2 ways you could solve this.
Create a separate controller method that returns a partial view of just the <table> and call that method, however you would need to extract the value of the page number for the href attribute of you pager buttons to pass that as well.
Using your current Circuits() method, test if the request is ajax, and if so, return a partial view of just the <table>.
public ActionResult Circuits(int? page)
{
var pageNumber = page ?? 1;
var circuits = _repo.GetAllCircuits().OrderBy(circ=>circ.ID);
var pagedCircuits = circuits.ToPagedList(pageNumber, 25);
if (Request.IsAjaxRequest)
{
return PartialView("_Circuits", pagedCircuits);
}
return View(pagedCircuits);
}
Note: Do not use .ToList() in your query. That is defeating the whole purpose of using server side paging because .ToList() immediately downloads all the records fro the database.
Where _Circuits.cshtml would be
#model IEnumerable<yourModel>
<table class="table">
<thead>
<tr>
// <th> elements
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
.... // Loop through and create content
</tr>
}
</tbody>
</table>
Note that your header elements should be in a <thead> element and the records in a <tbody> element.

How to get value from html select tag option value using onChange event using jQuery data table?

I am working on jQuery Data table to load few data from mysql database.
Here is the html code :
<table id="employee-grid" cellpadding="0" cellspacing="0" border="0" class="display" width="100%">
<thead>
<tr>
<th>#</th>
<th>User Id</th>
<th>Address</th>
<th>Package Name</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
</table>
From php page I'm loading the data like bellow :
// skipping more code...
$nestedData[] = "
<select class='form-control changeStatus' name='status'>
<option value=''>--Select--</option>
<option value='1|$client_id' $statusMsg1>Active</option>
<option value='2|$client_id' $statusMsg2>Blocked</option>
</select>";
Now the loaded data is look like this :
Now I want to call the an Ajax request when html selected option value is change. It's calling Ajax request successfully by bellow code.
jQuery code for jQuery Data Table and My Ajax Request :
$(document).ready(function() {
var dataTable = $('#employee-grid').DataTable( {
"processing": true,
"serverSide": true,
"ajax":{
url :"server_processing.php", // json datasource
type: "post", // method , by default get
error: function(){ // error handling
$(".employee-grid-error").html("");
$("#employee-grid").append('<tbody class="employee-grid-error"><tr><th colspan="3">No data found in the server</th></tr></tbody>');
$("#employee-grid_processing").css("display","none");
}
}
} );
$("#employee-grid").on('change', function() {
var status = $('.changeStatus').val();
alert(status);
$.ajax({
url : "<?php echo SITE_URL . 'toplevel/update-data'; ?>",
data : {
'statusChange' : status
},
type : 'POST',
});
});
});
but When I select the option then every time it's passing first option value
For e.g. This selected option tag has these value :
<option value='1|11' $statusMsg1>Active</option>
<option value='2|11' $statusMsg2>Blocked</option>
It's always passing 1|11 value !! It's should be pass my selected option value. I don't understand why it's happening :(
Note : I think using jQuery data table custom jquery code should be use in different way.
Well Guys,
I have solved it. I need to use something like that :
$('#employee-grid').on('change', '.changeStatus', function(){
// testing.....
var status = $('.changeStatus').val();
alert(status);
});
The solution is to use event delegation by providing selector for target element as a second argument in on() call.

Update HTML page after jquery.click

I have an onclick function which basically just returns sorted data like following:
$(document).ready(function () {
$(".feedbackClick").click(function () {
$.post("/Analyze/GetSortedByFeedback")
.done(function (data) {
var sellers = $('<table />').append(data).find('#tableSellers').html();
$('#tableSellers').html(sellers);
});
});
});
});
And this is how the table looks like that I'm trying to update after the jquery post:
<table id="tableSellers" class="table table-striped jambo_table bulk_action">
<thead>
<tr class="headings">
<th class="column-title"><h4><i class="fa fa-user" style="text-align:center"></i> <span>Username</span></h4> </th>
<th class="column-title"> <h4><span class="glyphicon glyphicon-tasks salesClick" aria-hidden="true"></span></h4></th>
<th class="column-title"><h4><i class="fa fa-star feedbackClick"></i></h4></th>
</tr>
</thead>
<tbody>
#foreach (var item in ViewBag.rezultati)
{
<tr>
<td>#item.StoreName</td>
<td>
<b>
#item.SaleNumber
</b>
</td>
<td><b>#item.Feedback</b></td>
</tr>
}
</tbody>
</table>
The click would basically just fetch the results and update the table in HTMl...
Can someone help me out?
Edit:
This current method doesn't works... I trigger the event but nothing happens... The code in the Action is called properly, but the results aren't displayed...
Edit 2:
This is the content of the data object after .done:
System.Collections.Generic.List`1[WebApplication2.Controllers.ResultItem]
Edit 3:
This is the action:
public List<ResultItem> GetSortedByFeedback()
{
return lista.OrderByDescending(x => x.Feedback).ToList();
}
Edit4 this is the data after the Alexandru's post:
Array[100]
Now I can do:
data[0].Feedback
And this outputs in console:
61259
Please use this:
public JsonResult GetSortedByFeedback()
{
var list=lista.OrderByDescending(x => x.Feedback).ToList();
return Json(list);
}
If your method is GET please use this:
public JsonResult GetSortedByFeedback()
{
var list=lista.OrderByDescending(x => x.Feedback).ToList();
return Json(list,JsonRequestBehavior.AllowGet);
}
Then please use this:
.done(function (data) {
$('#tableSellers tbody').empty();
$.each(data,function(i,item){
var tr='<tr><td>'+item.StoreName+'</td><td><b>'+item.SaleNumber+'</b></td><td><b>'+item.Feedback+'</b></td></tr>';
$('#tableSellers tbody').append(tr);//append the row
});
});
What you are trying to do is actually appending a JSON data to a HTML element which is of course will not work as expected.
Consider using a template engine like jQuery Templates. You will be able to compile a HTML template and use it to render your data whenever you need. For example:
var markup = "<li><b>${Name}</b> (${ReleaseYear})</li>";
// Compile the markup as a named template
$.template( "movieTemplate", markup );
$.ajax({
dataType: "jsonp",
url: moviesServiceUrl,
jsonp: "$callback",
success: showMovies
});
// Within the callback, use .tmpl() to render the data.
function showMovies( data ) {
// Render the template with the "movies" data and insert
// the rendered HTML under the 'movieList' element
$.tmpl( "movieTemplate", data )
.appendTo( "#movieList" );
}
TRy something like this:
$(document).ready(function () {
$("body").on("click",".feedbackClick",function() {//delegate the click event
$.get("/Analyze/GetSortedByFeedback",function(data) {
var sellers = $(data).find('#tableSellers').html();//find the table and take the html
$('#tableSellers').html(sellers);//append the html
});
});
});
Note: you need to return html (in your case) from the ajaxed page
from #Alexandru partial response you can do the following
public JsonResult GetSortedByFeedback()
{
var list=lista.OrderByDescending(x => x.Feedback).ToList();
return Json(list,JsonRequestBehavior.AllowGet);
}
js:
$(document).ready(function () {
$("body").on("click",".feedbackClick",function() {//delegate the click event
$.get("/Analyze/GetSortedByFeedback",function(data) {
$('#tableSellers tbody').empty();//empty the table body first
$.each(data,function(i,item){//loop each item from the json
$('#tableSellers tbody').append('<tr><td>'+item.StoreName+'</td><td><b>'+item.SaleNumber+'</b></td><td><b>'+item.Feedback+'</b></td></tr>');//build and append the html
});
});
});
});

reload datatable after ajax success

I use JQuery DataTable. I send data to datatable onclick in json file at ajax succes .the first click everything is good,But the next click I get only the right data ANd wrong value of dataTables_info it display always the first value of dataTables_info And paginatio AND row too from the first result.
This is the first display of data in datatable:
ALL the next Click I get only right data:
For this exemple they are one result showing in picture below but everything else(info ,show,pagination) belong to first search showing in the first picture :
In the second Exemple When I click at any page of pagination I get the content of the first page result!!
This is my function ONclick:
$ ( '#ButtonPostJson' ).on('click',function() {
$("tbody").empty();
var forsearch = $("#searchItem").val();
$.ajax({
processing: true,
serverSide: true,
type: 'post',
url: 'searchData.json',
dataType: "json",
data: mysearch,
/* bRetrieve : true,*/
success: function(data) {
$.each(data, function(i, data) {
var body = "<tr>";
body += "<td>" + data.name + "</td>";
..........................
..........................
body += "</tr>";
$('.datatable-ajax-source table').append(body);
})
;
/*DataTables instantiation.*/
$('.datatable-ajax-source table').dataTable();
},
error: function() {
alert('Processus Echoué!');
},
afterSend: function(){
$('.datatable-ajax-source table').dataTable().reload();
/* $('.datatable-ajax-source table').dataTable({bRetrieve : true}).fnDestroy();
$(this).parents().remove();
$('.datatable-ajax-source table').dataTable().clear();*/
}
});
});
I try everything and i dont know what I miss.
I use this jquery for datatable:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
Thanks.
Use like it
$('#product_table').DataTable().ajax.reload();
Get table id first, like:
var table=('#tableid').Datatable();
table.draw();
just put these lines after ajax success function to reload datatable
On a button clik you dont need to empty your table body and make initiate the datatable again with the ajax.
you just have to call your ajax again as you have already initiate on document ready function
just use
$("#Table_id").ajax.reload();
check the below link, you will have better idea.
https://datatables.net/reference/api/ajax.reload()
Let me know if this doesn't help you
I had this same problem. I found a function I wrote on a project that deals with this. Here is a simple 2 column table I made.
<table id="memberships" class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</tfoot>
</table>
This is my script to populate it:
function drawTable(){
var table = $('#memberships').DataTable();
table.destroy();
value = $("#memberName").val();
console.log("member name-->>" + value);
$('#memberships').DataTable({
responsive:true,
pageLength: 50,
ajax:{
"url": `//BACKEND API CALL`,
"type":"get",
"dataSrc": 'members'//my data is in an array called members
},
columns: [
{"data": "name_display" },
{"targets": 0,
"data": "membershipID",
"render": function ( data, type, full, meta ) {
return '<button type="button" class="btn btn-info btn-block"
onclick="editMember(' + data + ')">Edit Member</button><button
type="button" class="btn btn-danger btn-block"
onclick="deleteMember(' + data + ')">Delete</button>';
}
}
]
});
$.fn.dataTable.ext.errMode = 'none';
}
You can ignore my column render function. I needed 2 buttons based on the data returned. The key was the table.destroy in the function. I created the table in a variable called table. I destroy it right in this initialization because it allowed me to use this same function over and over. The first time it destroys an empty table. Each call after that destroys the data and repopulates it from the ajax call.
Hope this helps.
Update: After playing with datatables alot more I found that setting table to a variable in a global scope to your function allows you to use reload.
var table = $('#memberships').DataTable({});
Then
table.ajax.reload();
should work.
I created this simple function:
function refreshTable() {
$('.dataTable').each(function() {
dt = $(this).dataTable();
dt.fnDraw();
})
}
use below code..it perfectly work, it keep your pagination without lose current page
$("#table-example").DataTable().ajax.reload(null, false );
$('.table').DataTable().ajax.reload();
This works for me..
$("#Table_id").ajax.reload(); did not work.
I implemented -
var mytbl = $("#Table_id").datatable();
mytbl.ajax.reload;
.reload() is not working properly untill we pass some parameter
var = $("#example").DataTable() ;
datatbale_name.ajax.reload(null, false );
Try This i hope it will work
$("#datatable_id").DataTable().ajax.reload();

Refreshing list after ajax call with Knockout JS

I have a list of attachments on a page which is generated using a jQuery $.ajax call and Knockout JS.
My HTML looks like (this is stripped back):
<tbody data-bind="foreach: attachments">
<tr>
<td data-bind="text: Filename" />
</tr>
</tbody>
I have a function that gets the list of attachments which is returned as a JSON response:
$(function () {
getFormAttachments();
});
function getAttachments() {
var request = $.ajax({
type: "GET",
datatype: "json",
url: "/Attachment/GetAttachments"
});
request.done(function (response) {
ko.applyBindings(new vm(response));
});
}
My view model looks like:
function vm(response) {
this.attachments = ko.observableArray(response);
};
There is a refresh button that the use can click to refresh this list because over time attachments may have been added/removed:
$(function () {
$("#refresh").on("click", getAttachments);
});
The initial rendering of the list of attachments is fine, however when I call getAttachments again via the refresh button click the list is added to (in fact each item is duplicated several times).
I've created a jsFiddle to demonstrate this problem here:
http://jsfiddle.net/CpdbJ/137
What am I doing wrong?
Here is a fiddle that fixes your sample. Your biggest issue was that you were calling 'applyBindings' multiple times. In general you will call applyBindings on page load and then the page will interact with the View Model to cause Knockout to refresh portions of your page.
http://jsfiddle.net/CpdbJ/136
html
<table>
<thead>
<tr><th>File Name</th></tr>
</thead>
<tbody data-bind="foreach: attachments">
<tr><td data-bind="text: Filename" /></tr>
</tbody>
</table>
<button data-bind="click: refresh">Refresh</button>
javascript
$(function () {
var ViewModel = function() {
var self = this;
self.count = 0;
self.getAttachments = function() {
var data = [{ Filename: "f"+(self.count*2+1)+".doc" },
{ Filename: "f"+(self.count*2+2)+".doc"}];
self.count = self.count + 1;
return data;
}
self.attachments = ko.observableArray(self.getAttachments());
self.refresh = function() {
self.attachments(self.getAttachments());
}
};
ko.applyBindings(new ViewModel());
});
--
You may also want to look at the mapping plugin - http://knockoutjs.com/documentation/plugins-mapping.html. It can help you transform JSON into View Models. Additionally it is able to assign a property to be the "key" for an object... this will be used to determine old vs new objects on subsequent mappings.
Here is a fiddle I wrote a while back to demonstrate a similar idea:
http://jsfiddle.net/wgZ59/276
NOTE: I use 'update' as part of my mapping rules, but ONLY so I can log to the console. You would only need to add this if you wanted to customize how the mapping plugin updated objects.

Categories

Resources