jQuery Data table reload - datatables

I am using jQuery datatable plugin. I am trying to fetch the record count and based on the count doing some HTML manipulation using jQuery.
So far I have used this code
$('#tb').on('init.dt', function () {
var totalRecords = table.page.info().recordsTotal;
if(totalRecords != 0) {
$('#tb_div').show();
table.columns.adjust().draw();
}else{
$('#tb_div').hide();
$('#no_rec_msg').show();
}
} );
But this init.dt gets executed just once and it doesn't work on table.ajax.reload(); Any API method that would fix this?

Use xhr event instead that will be fired when an Ajax request is completed.
$('#tb').on('xhr.dt', function () {
var totalRecords = table.page.info().recordsTotal;
if(totalRecords != 0) {
$('#tb_div').show();
table.columns.adjust().draw();
} else {
$('#tb_div').hide();
$('#no_rec_msg').show();
}
} );

Related

how to load new data from api using RefreshIndicator

Future<void> _fetchPage(int pageKey) async {
try {
final newItems = await ApiServices.fetchArticleList(pageKey, _pageSize);
final isLastPage = newItems.length < _pageSize;
if (isLastPage) {
_pagingController.appendLastPage(newItems);
} else {
final nextPageKey = pageKey + newItems.length;
_pagingController.appendPage(newItems, nextPageKey);
}
} catch (error) {
print(error);
_pagingController.error = error;
}
}
so, i have method _fetchPage() that loads data from api initially, but on refresh new data are not updated in screen. Any help will be appreciated.
change your onRefresh callback to
onRefresh:()=>_fetchPage(0)
_fetchPage method in your code is expecting a parameter but you are not passing the value. since the onRefresh callback doesn't have any value to pass as parameter to the function

Get JavaScript Array of Objects to bind to .Net Core List of ViewModel

I have a JS Array of Objects which, at time of Post contains three variables per object:
ParticipantId,
Answer,
ScenarioId
During post, there is an Array the size of 8 (at current anyway) which all correctly contain data. When I call post request, the Controller does get hit as the breakpoint triggers, the issue is when I view the List<SurveyResponse> participantScenarios it is shown as having 0 values.
The thing I always struggle to understand is that magic communication and transform between JS and .Net so I am struggling to see where it is going wrong.
My JS Call:
postResponse: function () {
var data = JSON.stringify({ participantScenarios: this.scenarioResponses})
// POST /someUrl
this.$http.post('ScenariosVue/PostScenarioChoices', data).then(response => {
// success callback
}, response => {
// error callback
});
}
My .Net Core Controller
[HttpPost("PostScenarioChoices")]
public async Task<ActionResult> PostScenarioChoices(List<SurveyResponse> participantScenarios)
{
List<ParticipantScenarios> addParticipantScenarios = new List<ParticipantScenarios>();
foreach(var result in participantScenarios)
{
bool temp = false;
if(result.Answer == 1)
{
temp = true;
}
else if (result.Answer == 0)
{
temp = false;
}
else
{
return StatusCode(400);
}
addParticipantScenarios.Add(new ParticipantScenarios
{
ParticipantId = result.ParticipantId,
Answer = temp,
ScenarioId = result.ScenarioId
});
}
try
{
await _context.ParticipantScenarios.AddRangeAsync(addParticipantScenarios);
await _context.SaveChangesAsync();
return StatusCode(201);
}
catch
{
return StatusCode(400);
}
}

Aurelia refresh property dependencies

Validate if checkbox should be displayed in html page:
get canPerformCommand() {
let r = false;
let valids = ['Success', 'Error'];
if (this.requests.length == 0) return false;
if (valids.indexOf(this.myresult[0].requestStatus) > 0) {
r = true;
}
return r;
}
Html page:
<span if.bind="canPerformCommand" class="panel-heading-buttons">
<button click.trigger="confirm()">Confirm</button>
</span>
Search:
return this.myService.getRequests()
.then(data => {
this.requests = data
//Somehow refresh canPerformCommand here?
});
this.requests will be empty on first page load, resulting in canPerformCommand = false.
I want to refresh canPerformCommand when using the search function.
Currently canPerformCommand will not refresh itself after a search has been done.
How do I refresh canPerformCommand after search using Property Dependencies?
Solution:
The easiest and most logical solution would be to change canPerformCommand into two separate entities -- a flag variable and a function. Make the flag variable be canPerformCommand and keep the if.bind=canPerformCommand but change the name of your function to updateCanPerformCommand() so that you can easily call this function from your return this.myService.getRequests() .then function.
Details:
Set up your view-model like this:
export class App { // <-- (or whatever yours is called)
canPerformCommnad = false;
constructor() {
// ...
}
updateCanPerformCommand() {
let r = false;
let valids = ['Success', 'Error'];
if (this.requests.length == 0) {
this.canPerformCommand = false;
} else if (valids.indexOf(this.myresult[0].requestStatus) > 0) {
this.canPerformCommand = true;
}
}
}
I believe you need to change myresult to requests in the canPerformCommand getter:
get canPerformCommand() {
let r = false;
let valids = ['Success', 'Error'];
if (this.requests.length == 0) return false;
if (valids.indexOf(this.requests[0].requestStatus) > 0) {
r = true;
}
return r;
}
Since this getter will be dirty checked by Aurelia, it will be called every 200ms. To avoid that, you can add a computedFrom decorator:
import {computedFrom} from 'aurelia-framework';
export class MyClass {
....
#computedFrom('requests')
get canPerformCommand() { ....
I replaced:
if (valids.indexOf(this.myresult[0].requestStatus) > 0) {
r = true;
}
With
if (valids.includes(this.requests[0].requestStatus)) {
r = true;
}
And now it works. I was using the indexOf function on other pages aswell, and strangely enough it worked on most of them. Must have been something wrong in my model.
Also, I agree that it would be better to use computedFrom.

Worklight JsonStore advanced find

How to use advanced find in worklight JSONStore using QueryPart?
I have tried the following code but its not working properly, I doubt if I am calling advancedFind correctly.
var query = WL.JSONStore.QueryPart().equal('age', 35);
var collectionName = "people";
WL.JSONStore.get(collectionName).find(query).then(function(arrayResults) {
// if data not present , get the data from DB
if (arrayResults.length == 0) {
} else {
}
}).fail(function(errorObject) {
alert("fail" + errorObject);
// handle failure
});
You are calling the find() method. The one you want to call is advancedFind(). Also, advancedFind receives an array of query parts, not just one query part. Your code should look like this:
var queryPart = WL.JSONStore.QueryPart().equal('age', 35);
var collectionName = "people";
WL.JSONStore.get(collectionName).advancedFind([queryPart]).then(function(arrayResults) {
// if data not present , get the data from DB
if (arrayResults.length == 0) {
} else {
}
}).fail(function(errorObject) {
alert("fail" + errorObject);
// handle failure
});
For future reference, here is the API and some examples on how to use the Javascript JSONStore API.

Creating a pdf from a Knockout JS view & viewModel

Scenario: In our application a user can create a invoice by filling in certain fields on a Knockout view. This invoice can be previewed, via another Knockout page. I want to use the preview url within our PDF creator (EVOPdf), so we can provide the user with a PDF from this invoice.
To preview the invoice we load the data (on document ready) via an ajax-request:
var InvoiceView = function(){
function _start() {
$.get("invoice/GetInitialData", function (response) {
var viewModel = new ViewModel(response.Data);
ko.applyBindings(viewModel, $("#contentData").get(0));
});
};
return{
Start: _start
};
}();
My problem is within the data-binding when the PDF creator is requesting the url: the viewModel is empty. This makes sense because the GetInitialData action is not called when the PDF creator is doing the request. Calling this _start function from the preview page directly at the end of the page does not help either.
<script type="text/javascript">
$(document).ready(function() {
InvoiceView.Start();
});
</script>
Looking at the documentation of EvoPdf, JavaScript should be executed, as the JavaScriptEnabled is true by default: http://www.evopdf.com/api/index.aspx
How could I solve this, or what is the best approach to create an pdf from a knockout view?
Controller action code:
public FileResult PdfDownload(string url)
{
var pdfConverter = new PdfConverter();
// add the Forms Authentication cookie to request
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
pdfConverter.HttpRequestCookies.Add(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
}
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(url);
return new FileContentResult(pdfBytes, "application/pdf");
}
Javascript:
var model = this;
model.invoiceToEdit = ko.observable(null);
model.downloadInvoice = function (invoice) {
model.invoiceToEdit(invoice);
var url = '/invoice/preview';
window.location.href = '/invoice/pdfDownload?url=' + url;
};
The comment of xdumaine prompted me to think into another direction, thank you for that!
It did take some time for the Ajax request to load, but I also discovered some JavaScript (e.g. knockout binding) errors along the way after I put a ConversionDelay on the pdf creator object
pdfConverter.ConversionDelay = 5; //time in seconds
So here is my solution for this moment, which works for me now:
To start the process a bound click event:
model.downloadInvoice = function (invoice) {
var url = '/invoice/preview/' + invoice.Id() + '?isDownload=true';
window.open('/invoice/pdfDownload?url=' + url);
};
which result in a GET resquest on the controller action
public FileResult PdfDownload(string url)
{
var pdfConverter = new PdfConverter { JavaScriptEnabled = true };
// add the Forms Authentication cookie to request
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
pdfConverter.HttpRequestCookies.Add(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
}
pdfConverter.ConversionDelay = 5;
var absolutUrl = ToAbsulte(url);
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(absolutUrl);
return new FileContentResult(pdfBytes, "application/pdf");
}
The Pdf creator is requesting this action on the controller, with isDownload = true (see bound click event):
public ActionResult Preview(string id, bool isDownload = false)
{
return PartialView("PdfInvoice", new InvoiceViewModel
{
IsDownload = isDownload,
InvoiceId = id
});
}
Which returns this partial view:
PartialView:
// the actual div with bindings etc.
#if (Model.IsDownload)
{
//Include your javascript and css here if needed
#Html.Hidden("invoiceId", Model.InvoiceId);
<script>
$(document).ready(function () {
var invoiceId = $("#invoiceId").val();
DownloadInvoiceView.Start(invoiceId);
});
</script>
}
JavaScript for getting the invoice and apply the knockout bindings:
DownloadInvoiceView = function() {
function _start(invoiceId) {
$.get("invoice/GetInvoice/" + invoiceId, function(response) {
var viewModel = new DownloadInvoiceView.ViewModel(response.Data);
ko.applyBindings(viewModel, $("#invoiceDiv").get(0));
});
};
return {
Start: _start
};
}();
DownloadInvoiceView.ViewModel = function (data) {
var model = this;
var invoice = new Invoice(data); //Invoice is a Knockout model
return model;
};