I am working on a Health & Monitoring application which has several dashboards. Working on showing on all dashboards one by one as a slideshow. So that we know the health of the system without manual intervention.
This is what I did. Developed a view for slideshow Slideshow.cshtml and which has jquery code to connect to controllers and those controllers return partial views and partial views has code to connect to the server and display the data. So partial views are different dashboards. Tried to put it as simple as possible with the code. Sorry for the lengthy code.
I see dashboards are not displaying any data after sometime. I am looking for the suggestions and best practices and how to do it in a better way. are there any open source plug-ins we can use?
Slideshow.cshtml
<div id="partialContainer"></div>
$(function () {
getData();
setInterval(getData, 60000); // Iterate all pages 20 sec each page
});
function getData() {
getData1();
setTimeout(getData2, 20000); //20 Sec
setTimeout(getData3, 40000); //20 Sec
}
function getData1() {
$.ajax({
url: "#Url.Action("GetData1", "Dashboard")",
dataType: 'html',
success: function (data) {
$('#partialContainer').html(data);
}
});
}
function getData2() {
$.ajax({
url: "#Url.Action("GetData2", "Dashboard")",
dataType: 'html',
success: function (data) {
$('#partialContainer').html(data);
}
});
}
function getData3() {
$.ajax({
url: "#Url.Action("GetData3", "Dashboard")",
dataType: 'html',
success: function (data) {
$('#partialContainer').html(data);
}
});
}
****Controller:****
public class DashboardController : Controller
{
public ActionResult GetData1()
{
return PartialView("_Data1");
}
public ActionResult GetData2()
{
return PartialView("_Data2");
}
public ActionResult GetData3()
{
return PartialView("_Data3");
}
}
****One of the Dashboards(partial view): _Data1.cshtml****
<script>
$.ajaxSetup({
// Disable caching of AJAX responses */
cache: false
});
getDataP1();
function getDataP1() {
$("#tblErrors > tbody").html("");
$.ajax({
url: '#Url.Action("GetSummary", "Dashboard")',
data: {},
type: 'GET',
error: function () {
},
success: function (res) {
for (i = 0; i < res.Errors.length; i++) {
var data = res.Errors[i];
var rowClass = 'alt';
if (i % 2 == 0)
rowClass = '';
var row = "<tr class='" + rowClass + "'>";
//Appn Name
row = row + "<td>" + data.AppnName + "</td>";
//Application Type
row = row + "<td>" + data.ApplicationType + "</td>";
//Status
row = row + "<td>" + data.Status + "</td>";
row = row + "</tr>";
$("#tblErrors").append(row);
}
$("label[for='refreshTime']").html(res.LastRefreshTime);
}
});
}
</script>
Related
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.
Trying to figure out how to change the selected item of a select2 box after the page loads for the first time (and after it has loaded data from a ajax api call)
I tried using the below, but I cant get them to call after the ajax data has loaded?
$series2.val('2');
$series2.trigger('change');
The documentation says that it cannot be done using the val function (see here https://select2.org/programmatic-control/add-select-clear-items) and I do not want to do this with a custom API call that provides a "selected" value - as this does not work with templating.
This is NOT a duplicate of Select2 auto trigger event change
var $make2 = $(".make2");
var $series2 = $(".series2");
$make2.select2().on('change', function() {
$series2.empty();
if ($make2.val() !== null) {
$.ajax({
url: "{{ url('/') }}" + "/api/series/" + $make2.val(),
type: 'GET',
dataType: 'json',
async: true,
success: function(data) {
$series2.select2({
data: data,
templateSelection: function(result) {
return result['text'];
},
templateResult: function(result) {
if (!result['id']) {
return result['text'];
};
var final =
'<div>' +
'<strong>' + result['text'] + '</strong>' +
'<ul class="list-unstyled">' +
'<li><em>' + result['make'] + '</em></li>' +
'<li><em>' + result['category'] + '</em></li>' +
'</ul>' +
'</div>';
return final;
},
escapeMarkup: function(result) {
return result;
},
});
}
});
}
}).trigger('change');
});
I am using Asp.net MVC, I am trying to make post and comment mechanism,I can comment and post and I add them to database in different tables, I can also take comment from database to Index.cshtml page with Ajax request via jQuery. I have try to take post and post's comment simultaneously, I have created Paralel() function which is given below but I do not have any idea how to take comment and post simultaneously in that function. Could you help me? Thanks.
getPosts():
function getPosts() {
var toSend = new Object();
if (timestamOfLastPost == null) {
toSend.timestampFrom = 4294967295;//MAX_INT
}
else {
toSend.timestampFrom = timestamOfLastPost;
}
toSend.numberOfPosts = 2;
$.ajax({
url: '/Home/GetPosts',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(toSend),
dataType: "json",
async:true,
success:function (data) {
$.each(data.postList, function (i, post) {
postsHtml += getMessageHtml(post.title, post.message, post.ID, "", "");
});
$("#posts").html(postsHtml);
timestamOfLastPost = data.timestamp;
},
error: function (jqXHR, exception) {
alert('Error message.');
}
});
}
getComment():
function getComment()
{
if (timestamOfLastComment == null) {
//toSend.timestampFrom = Date.now() / 1000 | 0;
toSend.timestampFrom = 4294967295;//MAX_INT
}
else {
toSend.timestampFrom = timestamOfLastPost;
}
$.ajax({
url: '/Home/getComment',
type: 'POST',
async:true,
contentType: 'application/json',
data: JSON.stringify(toSend),
dataType: "json",
success: function (data) {
$.each(data.comment, function (i) {
comment += getComment(comment.message,comment.author_Id,comment.Post_ID)
});
}
});
}
Paralel:
function Paralel()
{
$.when($.ajax("/Home/GetPosts"), $.ajax("/Home/Comment")).done(function(a1, a2)
{
///To take post and comment
});
}
getCommentHtml():
function getCommentHtml(message, author_Id, Post_ID)
{
var result = '';
result += "<label>";
result += message;
result += "</label>";
}
getMessageHtml():
function getMessageHtml(title, message,ID,comment_ID,comment_message) {
var result = '';
result += "<div class=\"row col-md-8\">";
result += "<div class=\"row\">";
result += "<h2>" + title + "</h2>";
result += "</div>\n";
result += "<div class=\"row\">";
result += message;
result += "</div>\n";
result += "<hr width='%100'>";
result += "<div style='margin-left:100px' class=\"row\">";
result += "<hr width='%100'>";
result += "<form action='#' method='post'>";
result += "\n<textarea id='comment";
result += ID
result += "'></textarea>\n";
result += "\n<input type='submit' class='btn btn-default' OnClick='doComment("
result += ")' value='Comment' />";
result += "</div>\n";
return result;
}
If you change your Paralel fucntion to this will work:
function Paralel() {
getPosts();
getComment()
}
Your code with run in "parallel" because $.ajax is asynchronous.
In your example, your are trying to use promises to do something $.when the promises (getPosts, getComment) where resolved.
The $.ajax are prepared to be promised but your functions (getPosts, getComment) not. You have to use jQuery promises (https://learn.jquery.com/code-organization/deferreds/examples/)
Guys I have a html table in my ASP.net MVC home view. Now the table is being filled initially through the data present in model. Now upon clicking certain buttons on the homepage, I want to update the data present in the table i.e. clear the data present in the table and update it with the one from ajax call.
This is my table from view :
<article class="scrlable">
<table>
<tr>
<td>#</td>
<td>Name</td>
<td>Status</td>
<td>Since</td>
</tr>
#{
int srno = 1;
foreach (var pendingResponseModel in Model.hrPendingResponseList)
{
<tr>
<td>#srno</td>
<td>#pendingResponseModel.CandidateName</td>
<td>#pendingResponseModel.CandidateLifeCycleStatusName</td>
#if (pendingResponseModel.DayDifference == "1")
{
<td>#(pendingResponseModel.DayDifference) day</td>
}
else
{
<td>#(pendingResponseModel.DayDifference) days</td>
}
</tr>
srno++;
}
}
</table>
</article>
And this is my ajax call :
function GetStatusWise(control, departCode) {
$.ajax(
{
type: "GET",
url: "...URL..." + departCode,
dataType: "json",
crossDomain: true,
async: true,
cache: false,
success: function (data) {
$.each(data.data, function (index, value) {
// UPDATE TABLE HERE...
});
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
}
}
);
}
The data returned from ajax call is in JSON. It has Name, Status and Since elements. They can be viewed by using value.CandidateName, value.Status etc
Now I want to update the values of above table with the values I am getting through AJAX call. How would I go about doing that? Is it possible to replace the whole article ?
Note : I am getting multiple values through ajax call so that is why I put a loop on the function.
I have solved my problem by the following code
function GetStatusWise(control, departCode) {
$.ajax(
{
type: "GET",
url: WebApiURL + ".....URL...." + departCode,
dataType: "json",
crossDomain: true,
async: true,
cache: false,
success: function (data) {
var srno = 1;
$('#tblPendingHrResponse').find($('.trTblPendingHrResponse')).remove();
$.each(data.data, function (index, value) {
random(value, srno);
srno++;
});
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
}
}
);
}
.
function random(values, srno) {
var daydifference = values.DayDifference == 1 ? '<td>' + values.DayDifference + ' day </td>' : '<td>' + values.DayDifference + ' days </td>';
var tr = '<tr class="trTblPendingHrResponse">' +
'<td>' + srno + '</td>' +
'<td>' + values.CandidateName + '</td>' +
'<td>' + values.CandidateLifeCycleStatusName + '</td>' +
daydifference + '</tr>' + srno++;
$('#tblPendingHrResponse').append(tr);
}
You can use jQuery append.
success: function (data) {
$.each(data.data, function (index, value) {
$("table").html("Your HTML to updated");
});
},
Have your controller method return a partial which contains your table or article.
[HttpPost]
public virtual ActionResult GetTable(ArticleViewModel viewModel)
{
// do stuff
return PartialView("_ArticleTable", viewModel);
}
Then update the table or article in jQuery:
ou can use jQuery append.
success: function (data) {
$("table").html(data);
},
I have to use a AJAX call to get Json data after clicking next and previous buttons. Json data should contain blog content displayed after clicking next or previous. Any suggestions how my function should look like? So far I have only:
function getPrev() {
$.ajax({
type: "GET",
url: "../Content/test.txt",
dataType: "json"
}).success(function (data) {
$.each(data, function (key, val) {
$('#blogcont').append(key+ val);
});
return false;
});
}
And my Json file is only a test file:
{"one":"test1", "two":"test2", "three":"test3" }
Sorry I am a beginner!!!!
Thanks
Your $.ajax() syntax is incorrect
function getPrev() {
$.ajax({
type: "GET",
url: "../Content/test.txt",
dataType: "json",
success: function(data) {
var content = "";
$.each(data, function(key, val) {
content += "<p>" + key + ":" + val + "</p>";
});
$('#blogcont').html(content);
}
});
return false;
}
or
function getPrev() {
$.ajax({
type: "GET",
url: "../Content/test.txt",
dataType: "json"
}).done(function(data) {
var content = "";
$.each(data, function(key, val) {
content += "<p>" + key + ":" + val + "</p>";
});
$('#blogcont').html(content);
});
return false;
}
Try this
function getPrev() {
$.ajax({
type: "GET",
url: "../Content/test.txt",
dataType: "json"
}).done(function(data) {
var content = "";
$.each(data, function(key, val) {
content += '<p>' + key + ':' + val + '</p>';
});
$('#blogcont').html(content)
.find('p')
.hide()
.first().show();
$('button.next').click(function() {
$('#blogcont').find('p:visible')
.hide()
.next('p').show();
});
});
return false;
}
How about storing the JSON data as a variable, which you can then access using an index on click?
var jsonData;
$.ajax({
type: "GET",
url: "../Content/test.txt",
dataType: "json",
success: function (data) {
jsonData= data;
}
});
var clickIndex = 0;
$('.prev').click(function() {
if(clickIndex > 0) {
clickIndex -= 1;
}
get(clickIndex);
});
$('.next').click(function() {
clickIndex++;
get(clickIndex);
});
Your get function would then accept the index and find the JSON property:
function get(i) {
var item = jsonData[i];
}
Note that you would need to add an if statement to check whether you have reached the index limit on click of .next. Also, this is fine for a test JSON file, but a better solution would be to be able to request just one relevant item from a web service returning the JSON.