How to add preloader to long running function - javascript

I develop a custom html page with information about installed certificates on the local machine. The certificate's information I get by crypto provider api, then I filter returned certificates with some restrictions (Issuer, CommonName, etc). This is the work of my function loadCertificates. I show results on button click. But loadCertificates takes some seconds and I want to show preloader before loadCertificates and hide after:
$("#select__cert-btn").click(function () {
showPreloader();
var certificates = loadCertificates(restrictions);
hidePreloader();
showCerificates(certificates);
});
Functions showPreloader and hidePreloader only add/remove div with gif background to the container with certificates info. But when I click on the button my page seems frozen and only after some seconds show results (without appearing my preloader). But in debug mode, before run loadCertificates the preloader is added to html, but it's not visible.
Early I have never the same problem, but it seems like loadCertificates block main thread, but if I'm right why showPreloader not work correclty?
How to solve my problem?

I would try to use a promise so that the loadCertificates runs async without locking the main thread.
Try this:
$("#select__cert-btn").click(function () {
showPreloader();
var certificates = new Promise(function(resolve, reject) {
loadCertificates(restrictions);
resolve();
});
certificates.then(function(result) {
hidePreloader();
showCerificates(certificates);
});
});

if your loadCertificates function call an endpoint via ajax then you can simply add a html region that will be hide/shown with a gif image (loading) :
<!-- Will be called on every ajax call to show the spinner -->
<div class="row" id="ajaxLoading" style="display:none">
<div class="col-md-4 offset-4">
<img src="~/Images/loading.gif" />
</div>
</div>
then add in your scipt file :
var ajaxLoading = $('#ajaxLoading');
//add a spinner to every ajax call
$(document).ajaxStart(function () {
ajaxLoading.show();
});
$(document).ajaxStop(function () {
ajaxLoading.hide();
});

Related

Fully load content before showing it with Angular 2

In an angular component I'm generating an image from a service http call, which then I want to display on the site. However it's taking longer for the image to generate than it takes the site to load.
Thus I'm forced to refresh a few extra times to see/display the actual image when it finally loads.
How can i make ngOnit wait for everything to be generated and loaded before displaying the page?
this.someService.generateImage().subscribe(x => {
console.log('Image is now in folder')}
I want the page to be displayed after this call.
Any hints for this?
You can do like this:
Markup:
<div *ngIf="!isLoading">
// do not show till loading
</div>
Component:
isLoading = true;
this.someService.generateImage().subscribe((x) => {
console.log('Image is now in folder')
this.isLoading = false;
})
On your ngOnInit use :
ngOnInit() {
this.someService.generateImage().subscribe(x => {
//load page content functions.
console.log('Image is now in folder')
});
}
This is a work around since ngOnInit() on itself doesn't wait for async calls
Why stop the ngOnInit execution instead let it load all the dependency just don't show it,
The hack you can apply is hiding the contents of the complete page by a blocking loader with a loader service and show the content of the page when the image is generated. Something like this.
ngOnInit() {
loaderService.show();
this.someService.generateImage().subscribe(x => {
loaderService.hide();
console.log('Image is now in folder')
}
[Extra dependencies stuff .....]
}
You can use ngAfterViewInit() It get executed after dom loaded fully

Laravel routing behavior with PJAX not as expected

I'm building my first lavavel website from scratch and I've run into a behavioral issue with a few routes.
Here is the relevant code for my routes file:
Route::get('work', 'PageController#work');
Route::get('work/{item}', 'PageController#workitem');
And here are the relevant methods:
public function work() {
return view('pages.work');
}
public function workitem($item) {
$v = 'work.'.$item;
if(view()->exists($v)) {
return view($v);
} else {
return view('errors.noitem');
}
}
And here is the relevant part of my view:
#extends('layout')
#section('content')
...
<div class="workflex">
<a class="workitem" href="/work/test"></a>
<a class="workitem" href="/work/test2"></a>
</div>
<div id="loadContent" class="loadContent">
#yield('insert')
</div>
...
#stop
It is worth mentioning that I intend to load the individual workitem pages with PJAX. I have views that the PJAX loads into the the "insert" section based on the URL:
$(document).pjax('a.workitem', '#loadContent');
The user loads the initial work page at the /work subdirectory, and clicks a button to load /work/item pages with PJAX. As the routes suggest, I also want the user to be able to enter a workitem into the URL and be directed to the work page already loaded with that item. This whole system behaves as intended... until I added the following jquery to work.blade.php:
$(document).ready(function() {
$('#loadContent').load("/work/init", function() {
myFade('#loadContent > *', 1); //ignore this function, it's an animation irrelevant to my problem
});
});
This is here as an attempt to load a initial message inside the PJAX loading div #loadContent to tell the user to select a workitem. However, a side effect of this is that now whenever I browser to a /work/item directly (PJAX still loads the pages correctly) the document triggers this jquery and the message overrides the page content.
I was brainstorming ways to allow the work() method in my controller to trigger something that loads this script or passes just the work/init view into the "insert" section.
What do you think would be the best way to solve this? Your answers are greatly appreciated.
I was able to answer my own question. I forgot about the route optional parameters. I changed/added these things:
Route::get('work/{item?}', 'PageController#work');
and in my controller:
public function work($item = 'init') {
$v = 'work.'.$item;
if(view()->exists($v)) {
return view($v);
} else {
return view('errors.noitem');
}
}
Works perfectly now!

Function won't run on page load

I have changed the a function to load on page load but it will not do it.
The original code which runs with a link:
function updateBannerText(text) {
smartsupp('banner:set', 'bubble');
smartsupp('banner:update', { text: text });
});
Welcome,
This chat is awesome
My code which should run on page load:
function updateBannerText(text) {
smartsupp('banner:set', 'bubble');
smartsupp('banner:update', { text: "{$Artikel->cName}" });
}
window.onload = updateBannerText;
I have changed updateBannerText(text) to updateBannerText() but it was not possible to run it.
The problem is that the Smartsupp widget itself only starts to load on the page load, so your window.onload function runs before the widget is properly initialized and thus has no effect. You can test this by delaying the banner update, which should have an effect:
window.onload = function () { setTimeout(updateBannerText, 5000) }
To get around this, you should attach your startup code to an appropriate Smartsupp widget event, say, the rendered event for updating the banner:
smartsupp('on', 'rendered', function() {
updateBannerText('whatnot')
})

jQuery load dynamic content and make it accessible with a url

I have little time studying JavaScript and jQuery and would like to learn how to load dynamic content in a div of the site by a button and the loaded content create a new url to be indexable and could share with friends social networks, etc.
I created a function that is called with the onclick event of a button. The function takes two parameters, the div where to load the content and the path where the content to be loaded is stored:
function contentLoad(nameDiv, url)
{
$(name).load(url, function() {
});
}
button:
Moon
I do not know if I'll be doing well. The code still being very simple and charge me works perfectly content. But I'd like to load content would generate a new url that was accessible and that the link could be shared. How could I get it?
I think we need to store data loaded into a content with jQuery url when attempting to access, mount everything automatically and show visitors the web with dynamic content already loaded.
See if you can guide me in the process and that steps need to get it. Thanks to all.
You can use "client routes", using the hash tag in your url, and than some js lib which can handle this routes, for instance you can use director js, here is an example:
$(function() {
var author = function () {
// Load your content using AJAX
$("#content").html("author");
};
var viewBook = function (bookId) {
$("#content").html("viewBook: bookId is populated: " + bookId);
};
var routes = {
'/author': author,
'/books/view/:bookId': viewBook
};
var router = Router(routes);
router.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Director/1.2.8/director.js"></script>
<div id="content"></div>
<ul>
<li>#/author</li>
<li>#/books/view/1</li>
</ul>

Loading data ajax style

I jsut started learning angular.js. Can you guys show me the right way to make a page that initially presents an ajax loader element saying 'Loading data' or something like that. Then after data's been fetched it would update the view and hide the element. I can put stuff in page load event using jquery, but how do you do that using pure angular? So far I figured out how to put that in click event:
<div ng-app="VideoStatus" ng-controller="VideoStatusCtrl">
<button ng-click="getVideos()">get videos</button>
</div>
<script type="text/javascript">
angular.module('VideoStatus', ['ngResource']).run(function(){
// I guess somehow I can start fetching data from the server here,
// but I don't know how to call Controller methods passing the right scope
});
function VideoStatusCtrl($scope, $resource) {
$scope.videoStatus = $resource('/Videos/GetStatuses', { callback: 'JSON_CALLBACK' });
$scope.getVideos = function () {
$scope.videoResult = $scope.videoStatus.get();
console.log('videos fetched');
};
};
</script>
Kudos to Adam Webber & Peter Bacon Darwin
Here is the working plunker
Here is my version plunker that make loading as a directive with modal popup feature
Here is the tutorial to use my version
you only need loading.js and modal.js and reference jQuery and twitterbootstrap css.
in your code,
Only 2 steps you need to do with your code.
Add the following code to HTML
< div data-loading> < /div>
Add LoadingModule module to your application module.
angular.module('YourApp', ['LoadingModule'])

Categories

Resources