I'm trying to add a filtering feature to an HTML table. I've seen some HTML filter libraries out there, but since I load the table's content after an AJAX call, these libraries don't seem to update after the table loads the actual values.
I was wondering if you could direct me on either how to implement my own filter, (the list of values to be filtered of the table can be accessed over AJAX too) or how to "delay" a piece of code of HTML and JS so the table and the libraries load together after the data is appended.
Tell me what part of the code you would like to see. Below is the <script> that loads the table. The libraries I tried to use are this and this.
I'm programming this as a favor for my father, so this is just about good-hearted questions. Thanks everyone!
<script>
$(document).ready(function() {
var populateContadorClienteTable = function(r) {
var ClienteTable = $("#ClientesTable tbody");
if(ClienteTable.length == 0) {
return;
} else {
ClienteTable.children().remove();
var r = JSON.parse(r);
var ger, supe, con;
if(r.length > 0) {
for(var i in r) {
if(r[i].Gerente != null) ger = r[i].Gerente; else ger = "";
if(r[i].Supervisor != null) supe = r[i].Supervisor; else supe = "";
if(r[i].Contador != null) con = r[i].Contador; else con = "";
ClienteTable.append(
$("<tr>")
.append($("<td>").text(r[i].ClaveCliente))
.append($("<a>").text(r[i].Nombre)
.css("width", "100%")
.addClass("pure-button")
.attr("href","reasignar.php?ClaveCliente=" + r[i].ClaveCliente + "&Nombre=" + r[i].Nombre))
.append($("<td>").text(ger))
.append($("<td>").text(supe))
.append($("<td>").text(con))
//.append($("<td>").append($("<a>").attr("href","reasignar.php?ClaveCliente=" + r[i].ClaveCliente + "&Nombre=" + r[i].Nombre)
// .text("Editar asignaciones")))
);
}
} else {
alert("No Cliente data retrieved.");
}
}
};
$.ajax({
type: "GET",
url: "/query/ClienteContadoresFull.php",
success: populateContadorClienteTable,
error: function(jqXHR, textStatus, errorThrown) {
alert("Error on retrieval of Cliente: " + textStatus);
}
});
});
</script>
You could try DataTables. It's very feature-rich with a lot of examples.
Specifically you could search an example for AJAX sources.
Related
i want to display these json data into a html table. i am trying to do many things but i cant figure out how can i do it. So anyone can please help me to fix it.
the json data set will appear in the console. but i cant set it to a table.
this is my model
public function displayRecords()
{
$this->db->select('A.*');
$this->db->from('rahu AS A');
$this->db->where('A.status',1);
return $this->db->get()->result_array();
}
this is my controller
public function allrecodes()
{
/*script allow*/
if (!$this->input->is_ajax_request()) {
exit('No direct script access allowed here.');
}
$response= array();
$response['result'] = $this->RahuModel->displayRecords();
echo json_encode($response);
}
this is my js
var get_rec = function(){
//alert("WWW");
$.ajax({
//request ajax
url : "../dashbord/allrecodes",
type : "post",
contentType: "application/json",
dataType : "json",
success: function(dataset) {
//var myobject = JSON.stringify(result);
//alert(myobject[0]);
console.log(dataset);
console.log(dataset.result[0]['id']);
},
error: function() { alert("Invalide!"); }
});
};
the json dataset will appear in console.
And also this get_rec() in js file will called top of the page.
$(document).ready(function() {
//alert("Hello, world!");
get_rec();});
can anyone please help me to fix it.. thank you !!
There is no "simple" way to do it. You will have to loop through the resultset and render the html.
function renderTable(data) {
var result = ['<table>'];
var header = false;
for (var index in data) {
var row = data[index];
if (!header) {
// Create header row.
header = Object.keys(row);
var res = ['<tr>'];
for (var r in header) {
res.push("<th>" + header[r] + "</th>");
}
res.push('</tr>');
result.push(res.join("\n"));
}
// Add data row.
var res = ['<tr>'];
for (var r in header) {
res.push("<td>" + row[header[r]] + "</td>");
}
res.push('</tr>');
result.push(res.join("\n"));
}
result.push('</table>');
return result.join("\n");
}
document.getElementById('output').innerHTML = renderTable(data);
Have a div tag with id output on your HTML
<div id="output"></div>
PHP/HTML:
<ul id="load-more-div"></ul>
<a id="load-more" data-ppp="<?php echo get_option('posts_per_page'); ?>">load more</a>
JavaScripts:
(function($) {
// Grab the load more button, since I only want to run the code if the button is on the page
var loadMoreButton = $("#load-more");
if (loadMoreButton) {
// Get the posts_per_page number set in Reading Options
var ppp = loadMoreButton.data("ppp");
// Initialize function
var loadPosts = function(page) {
var theData, loadMoreContainer, errorStatus, errorMessage;
// The AJAX request
$.ajax({
url: "/wp-json/wp/v2/posts",
dataType: "json",
data: {
// Match the query that was already run on the page
per_page: ppp,
page: page,
type: "post",
orderby: "date"
},
success: function(data) {
// Remove the button if the response returns no items
if (data.length < 1) {
loadMoreButton.remove();
}
// Create a place to store exactly what I need
// Alternatively, the response can be filtered to only return the needed data, which is probably more efficient as the following loop wont be needed
theData = [];
// Get only what I need, and store it
for (i = 0; i < data.length; i++) {
theData[i] = {};
theData[i].id = data[i].id;
theData[i].link = data[i].link;
theData[i].title = data[i].title.rendered;
theData[i].content = data[i].content.rendered;
}
// Grab the container where my data will be inserted
loadMoreContainer = $("#load-more-div");
// For each object in my newly formed array, build a new element to store that data, and insert it into the DOM
$.each(theData, function(i) {
loadMoreContainer.append(
'<li><a href="' +
theData[i].link +
'">' +
theData[i].title +
"</a></li>"
);
});
},
error: function(jqXHR, textStatus, errorThrown) {
errorStatus = jqXHR.status + " " + jqXHR.statusText + "\n";
errorMessage = jqXHR.responseJSON.message;
// Show me what the error was
console.log(errorStatus + errorMessage);
}
});
};
// Since our AJAX query is the same as the original query on the page (page 1), start with page 2
var getPage = 2;
// Actually implement the functionality when the button is clicked
loadMoreButton.on("click", function() {
loadPosts(getPage);
// Increment the page, so on the next click we get the next page of results
getPage++;
});
}
})(jQuery);
This is the trouble part, it doesn't remove the link.
// Remove the button if the response returns no items
if (data.length < 1) {
loadMoreButton.remove();
}
Console errors when click the load more link after reaching the end of posts:
400 Bad Request The page number requested is larger than the number of pages available.
I found two ways to solve it:
###Using data attribute
Get the max number of pages in the template, assign it to a data attribute, and access it in the scripts. Then check current page against total page numbers, and set disabled states to the load more button when it reaches the last page.
PHP/HTML:
<ul id="ajax-content"></ul>
<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>" data-pages="<?php echo $wp_query->max_num_pages; ?>">Show more</button>
JavaScripts:
(function($) {
var loadMoreButton = $('#ajax-button');
var loadMoreContainer = $('#ajax-content');
if (loadMoreButton) {
var endpoint = loadMoreButton.data('endpoint');
var ppp = loadMoreButton.data('ppp');
var pages = loadMoreButton.data('pages');
var loadPosts = function(page) {
var theData, errorStatus, errorMessage;
$.ajax({
url: endpoint,
dataType: 'json',
data: {
per_page: ppp,
page: page,
type: 'post',
orderby: 'date'
},
beforeSend: function() {
loadMoreButton.attr('disabled', true);
},
success: function(data) {
theData = [];
for (i = 0; i < data.length; i++) {
theData[i] = {};
theData[i].id = data[i].id;
theData[i].link = data[i].link;
theData[i].title = data[i].title.rendered;
theData[i].content = data[i].content.rendered;
}
$.each(theData, function(i) {
loadMoreContainer.append('<li>' + theData[i].title + '</li>');
});
loadMoreButton.attr('disabled', false);
if (getPage == pages) {
loadMoreButton.attr('disabled', true);
}
getPage++;
},
error: function(jqXHR) {
errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
errorMessage = jqXHR.responseJSON.message;
console.log(errorStatus + errorMessage);
}
});
};
var getPage = 2;
loadMoreButton.on('click', function() {
loadPosts(getPage);
});
}
})(jQuery);
###Using jQuery complete event
Get the total pages x-wp-totalpages from the HTTP response headers. Then change the button states when reaches last page.
PHP/HTML:
<ul id="ajax-content"></ul>
<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>">Show more</button>
JavaScripts:
(function($) {
var loadMoreButton = $('#ajax-button');
var loadMoreContainer = $('#ajax-content');
if (loadMoreButton) {
var endpoint = loadMoreButton.data('endpoint');
var ppp = loadMoreButton.data('ppp');
var pager = 0;
var loadPosts = function(page) {
var theData, errorStatus, errorMessage;
$.ajax({
url: endpoint,
dataType: 'json',
data: {
per_page: ppp,
page: page,
type: 'post',
orderby: 'date'
},
beforeSend: function() {
loadMoreButton.attr('disabled', true);
},
success: function(data) {
theData = [];
for (i = 0; i < data.length; i++) {
theData[i] = {};
theData[i].id = data[i].id;
theData[i].link = data[i].link;
theData[i].title = data[i].title.rendered;
theData[i].content = data[i].content.rendered;
}
$.each(theData, function(i) {
loadMoreContainer.append('<li>' + theData[i].title + '</li>');
});
loadMoreButton.attr('disabled', false);
},
error: function(jqXHR) {
errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
errorMessage = jqXHR.responseJSON.message;
console.log(errorStatus + errorMessage);
},
complete: function(jqXHR) {
if (pager == 0) {
pager = jqXHR.getResponseHeader('x-wp-totalpages');
}
pager--;
if (pager == 1) {
loadMoreButton.attr('disabled', true);
}
}
});
};
var getPage = 2;
loadMoreButton.on('click', function() {
loadPosts(getPage);
getPage++;
});
}
})(jQuery);
The problem appears to be an invalid query to that endpoint so the success: function() is never being run in this circumstance.
Add to All API Errors
You could add the same functionality for all errors like this...
error: function(jqXHR, textStatus, errorThrown) {
loadMoreButton.remove();
....
}
Though that may not be the desired way of handling of all errors.
Test for Existing Error Message
Another option could be to remove the button if you receive an error with that exact message...
error: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.statusText === 'The page number requested is larger than the number of pages available.') {
loadMoreButton.remove();
}
....
}
but this would be susceptible to breaking with any changes to that error message.
Return Custom Error Code from API
The recommended way to handle it would be to return specific error code (along with HTTP status code 400) to specify the exact situation in a more reliable format...
error: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.statusCode === '215') {
loadMoreButton.remove();
}
....
}
Here's an example on how to configure error handling in an API: Best Practices for API Error Handling
Return 200 HTTP Status Code
The last option would be to change the way your API endpoint handles this type of "error"/situation, by returning a 200 level HTTP status code instead, which would invoke the success: instead of the error: callback instead.
Can anyone help me with this. I need to remember selected item on page reload. My code work, but don`t save selected element. Thank you in advance.
$(function(){function disableElement(element) {};function getSomething(element, id) {if (id != 0) {
$.ajaxSetup ( {
url: 'assets/upgraded/configurator.php',
type: 'POST',
data: {'action':'load', 'id':parseInt(id)}
});
$.ajax ( {
success: function(messages) {
var messages = JSON.parse(messages);
if (messages.length > 0) {
for (var i=0; i < messages.length; i ++) {
$(element).append('<option value="' + messages[i].id + '">' + messages[i].pagetitle+ '</option>');
}
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Ошибка загрузки: ' + xhr.status + ' ' + thrownError);
}
});
$(element).prop('disabled', false); } else {disableElement(element);}}; getSomething('#mark','1');
$('#mark').change(function() {
var id = $(this).val();
getSomething('#model',id);
disableElement('#year');
disableElement('#engine');
});
$('#model').change(function() {
var id = $(this).val();
getSomething('#year',id);
disableElement('#engine');
});
$('#year').change(function() {
var id = $(this).val();
getSomething('#engine',id);
});});
You need to store whatever value you want to use. That can be done in many ways. As #Sushil mentioned, cookie is a choice. HTML5 local storage is another one, and yet, even a database is useful to persist data.
But you can keep your <select> option in browsers cache or something like that.
Tell me if I understood your question properly ;)
you could use cookie to store the selected element value.
I would like to load a twitter popup box in jquery using (ajax?)
Here is my original code, which loads the twitter box in a new window:
function twitter_click() {
var twtTitle = document.title;
var twtUrl = location.href;
var maxLength = 140 - (twtUrl.length + 1);
if (twtTitle.length > maxLength) {
twtTitle = twtTitle.substr(0, (maxLength - 3)) + '...';
}
var twtLink = 'http://twitter.com/home?status=' + encodeURIComponent(twtTitle + ' ' + twtUrl);
window.open(twtLink,'','width=565, height=540');
}
Here is the code for the jquery popup box.
function showUrlInDialog(url, options){
options = options || {};
var tag = $("<div></div>"); //This tag will the hold the dialog content.
$.ajax({
url: url,
type: (options.type || 'GET'),
beforeSend: options.beforeSend,
error: options.error,
complete: options.complete,
success: function(data, textStatus, jqXHR) {
if(typeof data == "object" && data.html) { //response is assumed to be JSON
tag.html(data.html).dialog({modal: options.modal, title: data.title}).dialog('open');
} else { //response is assumed to be HTML
tag.html(data).dialog({modal: options.modal, title: options.title}).dialog('open');
}
$.isFunction(options.success) && (options.success)(data, textStatus, jqXHR);
}
});
}
<img src="twitter_button.jpg>
I don't know anything about coding so if someone can please combine these two scripts so that the twitter content of the first script loads into the jquery popup script that would make my day! Thanks. Pia
Start by changing this:
window.open(twtLink,'','width=565, height=540');
to this:
showUrlInDialog(twtLink, {error: function() { alert('Could not load form') }});
Then to run it, use this:
<img src="twitter_button.jpg>
I've ran into this strange JSON behavior.. I just cant figure out what the hell is going on..
I've got a WebMethod in my asp.net page.. It repetitively calls as page loads through jQuery AJAX.. Everything goes pretty smooth but what strange thing happens is that the data I sens to my jQuery ajax is not the SAME I just sent.. :S
here is not code of page method
[WebMethod()]
public static List<Unister.UnisterCore.Core.Domain.Comment> LoadComments(long objID, int sysID)
{
if (objID == 0)
return null;
UnisterWeb.UserControls.Presenter.CommentsPresenter _presneter;
_presneter = new UnisterWeb.UserControls.Presenter.CommentsPresenter();
List<Unister.UnisterCore.Core.Domain.Comment> comments = new List<Unister.UnisterCore.Core.Domain.Comment>();
comments = _presneter.LoadComments(sysID, objID);
if (comments.Count == 0)
return null;
return comments;
}
Here returning list is what I got from my presenter layer but when I receive that in my js method, its either null or previous value.
Here is my jQuery method..
function LoadComments(SysID, ObjID) {
if (parseInt(SysID) == 0 || parseInt(ObjID) == 0)
return;
var args = 'objID:' + ObjID + ',sysID:' + SysID;
$.ajax({
type: "POST",
url: "/dashboard/default.aspx/LoadComments",
cache: false,
data: '{' + args + '}',
contentType: "application/json",
dataType: "json",
success: function(result) {
if (result.d != null) {
comments = new Array();
$.each(result.d, function(key, val) {
data = new Object();
data.CommentID = val.CommentID;
data.Body = val.Body;
codate = new Date(parseInt(val.CreateDate.replace("/Date(", "").replace(")/", ""), 10));
var fdate = dateFormat(codate, "isoUtcDateTime");
ldate = $.timeago(fdate);
data.CreateDate = ldate;
data.CommentByAccountID = val.CommentByAccountID;
comments.push(data);
});
var boxid = "#commentBox_" + ObjID;
$(boxid).setTemplateURL("../Templates/comments.htm");
$(boxid).processTemplate(comments);
}
}
});
}
Please help me..
I found the solution... :)
First thing we could do is make our request async: false (BUT it'll impact our performance).. Instead, Im sending an ID (in my case SysID) and also bind it with my DIV id like the code below..
<div id ="comment_<%= SysID %>"></div>
In my jQuery function I use
var ID = "#comment_" + val.SysteID;
$(ID).setTemplateURL("../Templates/comments.htm");
$(ID).processTemplate(comments);
Hope it helps you guys too ... :)