AJAX Refresh Blinks Screen - javascript

I have an app that has a status screen that is meant to be displayed at all times in various places around the organization. There are probably 50 different users inputting different pieces of data into it, and the status screen updates every 10 seconds with the new information. It's pretty much a tracking board for widgets flowing through a process.
Currently, I do a refresh every 10 seconds which empties all the divs and then loops through the active widgets and places them where every they should go and color codes based on status and stuff like that. However, there's a fraction of a second of a blink from when the javascript empties the divs and when they repopulate, and it's pretty annoying honestly.
My question is how to best update the status screen where there is no blink and things just empty out and pop in as needed.
My thinking at first is there a way to "freeze" the screen for 2 seconds and let it rewrite in the background then unfreeze so there isn't a blink.
OR, which would be MUCH MUCH MUCH cooler, is that some how I only update pieces that get updated within the 10 second intervals. So if a widget goes from staging area to molding, it fades out of staging and fades into molding and none of the other divs are touched. This would be cool because I could add some animations this way. However, I'm not sure how to "efficiently" do this. Maybe I have an "active array" that stores how everything is, and then the AJAX pulls a new array and executes changes where the two doesn't match?
Anyway, I'd like to know if there's a screen freeze, update in the background answer and if there's an like the second one described.
Sorry for the novel =(

This blink or flashing effect is consequence of the asynchronous behavior of ajax.
what is happening is that your divs are emptying, but your new data is not yet ready to fill them.
the solution is to house your divs' emptying and refilling in a callback that is passed to the successful completion of your ajax request.

I think a lot of your problem comes when you clear all the data out before repopulating it.
You could try two methods for fixing this.
Solution 1
Build a string of html when you get your new results back. Do this in a loop, adding to the string variable each time and then replace the html of a "wrapper" div with the new html. You could make it fancy and do a fade in/fade out too.
var htmlString = '';
for(var i=0; i < jsonReturn.length; i++)
{
htmlString += "<p>" + jsonReturn[i].data + "</p>";
}
$('#wrapper-div").empty().append(htmlString);
Solution 2
Give your html id's that are based on an id value from the data you're repopulating. This will be considerably more complicated but it would let you update single items in your display individually or only if they change.
<p id="data-spot-<?php echo $data['id']; ?>">Some display data</p>
Then in your javascript you would do
for(var i=0; i < jsonReturn.length; i++)
{
$('#data-spot"+jsonReturn.id).empty().append("Some html string or data");
}

Related

Percentage loading indicator that represents function or thread processing state

Problem: When a function is called, google popup says "Running script blahblah" with cancel, dismiss buttons. This green popup gets dismissed after a while(when?), but many cells still show Loading.. state and values are still being populated, meaning the functions are still being run.
Requirement: Need information on some sort of indicator, spinning circle/loading ui or just a simple percentage wise indication of how much processing/function calls have been done, or something that gives the user some indication as to how much loading left, or when it finishes. I realise I'm being vague because I'm unsure if this sort of process monitoring function exists. I visualise it like a thread monitor, that goes green when all processing is complete. But a cell populated with 0-100% value will also do.
Context: When I click on a button, my code executes a lot of functions on a vast range of cells, which require a considerable amount of processing time even with optimisations, during which the state of many cells remain as "Loading..". After all functions have been executed, and all cells have been populated, only then, the user needs to perform some manual inspection/other activities. But there is no indication given to the user that all processing has been completed, other than manual scrolling and searching for absence of "Loading" indicator in all cells, which is tedious.
Alternative Solutions (in case there is no direct processing indicator function):
Callback or return some value for every function, and validate if all of them have arrived (not feasible I feel, coz the number of times a single function has to be executed changes with user specified input ex: user gives 3 inputs, function executes for 300 cells. Also as explained before, the cell population/Loading state happens even after apparent function execution end)
Function to scan the page for cell display value of "Loading.." and if none, indicate that loading has been completed (This function doesn't work as expected, I'm guessing some sync issues) I know this is most feasible option but I was really looking forward to some kind of value/function that automatically tells me that processing is done.
I don't think code snippet is required for this, as I'm basically asking if a particular feature exists or not. If not, alternatives would be appreciated.
The simplest approach is to display a loading-icon after a button is clicked. My recommendation is something like MaterializeCSS.
I assume there are 2 files:
Front-End HTML which contains the View
Back-End Apps Script File which contains Controller
So in your File #1 you would add the following loading bar:
<!-- this is your existing button -->
<button id="yourTriggerButton">Click here</button>
<!-- in your css file, add #loadingBar{display:none} so that is hidden by default -->
<div class="progress" id="loadingBar">
<div class="indeterminate"></div>
</div>
// we can also add some output message here
<div id="outputDiv"></div>
And at the bottom of your front-end file, within a script tag we state that we want to show the loading element wenn the button is clicked (and your back-end script is running) and the hide it once the process is finished:
const triggerButton = document.getElementById("yourTriggerButton");
const loadingElement = document.getElementById("loadingBar");
const outputElement = document.getElementById("outputDiv");
triggerButton.addEventListener( "click", function(e){
// lets show the loading icon when clicked
loadingElement.style.display = "block";
google.script.run
.withSuccessHandler(handleSuccess)
.backEndFunction()
// this is called once backEndFunction is finished / returned
function handleSuccess( returnValueFromBackEnd ){
// lets hide the loading icon
loadingElement.style.display = "none";
// and show the user some feedback
outputElement.innerText = "Done processing…"; // or you can input something that is returned from the back-end function
}
});

JS: temporarily disable page rendering (possible?)

I'm tryin to sort a big html table using JS. It takes a lot of cpu% to rearrange all the rows of this table. I think the big part of this problem is: every time my script moves a pair of rows, the browser starts refreshing the table
So, I'm searching for any way to temporarily tell the browser something like "wait, I'm sorting this table, dont waste CPU for rendering until I'll finish, plz?"
Basically, I need something lke "Memo1.lines.beginupdate / Memo1.lines.endupdate" in delphi >.<
alert(string) stops rendering, and not asyncronous calls, but not loading. You may prompt "too many cells to load, please wait" you may got the desired behavior.
note that, in order to work, string should be a non empty string after trim so a white space is not valid.
You can disable most of the background rendering by disabling displaying of the parent element. Since the parent element is not displayed, client's renderer has nothing to render and also does not recompute sizes. Be aware that when you are updating the content, you will loose focus if it was present wihtin the parent Element.
To achieve something like Memo1.lines.beginupdate and Memo1.lines.endupdate use this:
originalStyleDisplay = myMemo1Div.style.display;
myMemo1Div.style.display = 'none';
try {
mySorting();
} catch() { }
myMemo1Div.style.display = originalStyleDisplay;

Performing a Simple Math Operation in Real Time with Runtime Data in Qualtrics

I have a single slider on a survey in Qualtrics, and need to present the value on the slider from both "ends" (so if the respondent has placed the handle at the value 55, I need to have a box with "55" and "45" shown below the slider, since the maximum value is 100, i.e. 100-55=45).
I've managed to show the value of the slider with the user's input (in the above example, the "55") with this following snippet of HTML in the text question, which places a box somewhere on the page with the slider's value:
<input class="SumInput InputText QID29 QWatchTimer" data-runtime-value="runtime.Choices.1.Value" id="QID29" name="QID29" type="text" value="" />
However, I can't get the other box that displays essentially 100 minus whichever the runtime.Choices.1.Value is to work (the "45"). I've tried simply "100-runtime.Choices.1.Value", "100"-"runtime.Choices.1.Value", the same without any quotations, and just about every possible math function for CSS/HTML. I know that technically HTML only displays and doesn't really do this kind of runtime calculation (I'm a novice so this is as far as I've gleamed), so if there was any Javascript snippet or some other piece of code that would show in real time 100 minus wherever the user has moved the handle on the slider to, that'd be fantastic. I'm assuming some sort of addOnClick function but have no clue how to refer to anything on the slider to do this.
It's such a simple task but for some reason has taken so far quite a bit. Any help is appreciated; thanks!
I've managed to figure this out for the particular example of the slider, though I think the following Javascript should work for presumably many question types, given using the correct getChoiceValue (i.e. changing the "1" to the number corresponding to the element on the page whose answer value you want to obtain):
Qualtrics.SurveyEngine.addOnload(function() {
/*Place your JavaScript here to run when the page loads*/
var result=0;
var otherend= 0;
this.questionclick = function(event,element){
result = this.getChoiceValue(1);
endupdate();
document.getElementById("otherend").innerHTML=otherend;
document.getElementById("result").innerHTML=result;
}
function endupdate() {
otherend=100-result;
}
});
I then added the following in the HTML of the question text, wherever I wanted it to show up (I personally put it in a table so I could center things nicely on the page, along with some explanatory text):
<span id="result">0</span>
<span id="otherend">0</span>
Hope this saves somebody else some time and energy!

Reloading or Refreshing JSON and HTML div load order

I am trying to create some code that will allow me to pull and display stock data for a Smart Mirror Project that I am building.
I have gotten it to display all the information but am not able to update the stock data. I want it to update the information every 5 seconds but when I do this, it basically goes on repeat and continues to output all the stocks over and over, off the page.
How can I get it to reload the data without reloading the entire page and how can I tell that it is working? Is it possible add a css element that flashes the prices yellow whenever the price changes?
Here is my code in fiddle: https://fiddle.jshell.net/Aurum115/2kbpt91z/17/
Edit: To clarify the second part. I basically want to still store the old price and compare it to the new price temporarily and quickly flash the text yellow if it has changed.
The problem you have is that you are appending the new HTML to the existing HTML.
To solve your problem, you need to delete the existing contents of the divs that your are updating. You should add the following code after the setInterval(,,, line:
$("#title").html("");
$("#livePrice").html("");
$("#stockTicker").html("");
$("#livePercent").html("");
$("#liveData").html("");
Unfortunately, it does result in a "flicker" each time you reload. To reduce this, in cases where you have a fixed number of rows, you can label each row 1-X (and use the same number for the cells in each row) and then simply overwrite the contents of each cell on each row as you update...
In my view, if you aren't worried about the order that the stocks appear, you should use a table and give id's to the cells that relate to each stocks price and change (e.g. for Apple the cell ids could be: price_NASDAQ:AAPL, change_NASDAQ:AAPL). You then simply use $("#price_NASDAQ:AAPL").html(...) to update the price and $("#change_NASDAQ:AAPL").html(...) to update the change.
If you want something to happen (like a flash) use $("#price").css("background-color", "...") to change the color and use setInterval(...) to wait for a short time before changing the color back...

Highlight last inserted document in Meteor

I have form and list of objects at the same page. When I insert a new row, it is not very easy to see where the newly inserted row is placed. Therefore, I thought I could color/highlight the newly inserted row (and perhaps remove the highlight after a few seconds).
How can I do this? I think a way to do this could be using a method on the server which returns the inserted id (return Collection.insert(doc);) and on the client use a callback with
Meteor.call('insertDoc', function(err,result) {
// do something with result
});
I think I can use a reactive-var to save the id of the last inserted row and in the loop highlight the row with
{{#each docs}}
<li class="{{isActive}}">{{name}}</li>
{{/each}}
and have a helper to return active if this._id equals the reactive var with the last inserted id.
But is this the best way to do it? How can I remove the color after some seconds? I have seen such behaviour on many pages but I cannot find any tutorials/code snippets to achieve this.
I wrote a package that uses Meteor's UI hooks to fade items in and out of a list as they are added and removed, to help users maintain context as data changes:
https://github.com/mizzao/meteor-animated-each
There is a demo at http://animated-each.meteor.com/. You can see that as items are added and removed, they are faded in and out. If items are inserted off the screen, the visible area does not scroll.
This isn't doing exactly what you want, but you can use the same idea to highlight items as they appear as well, as opposed to the simple fade in.
Note that all of this happens at the UI rendering level - not the template/code level. The UI hooks are also not well documented right now, but they've been around for a while.
I don't know if your method is the best, but that's how I'd go about doing it.
As for the animation, I'd use a CSS3 animation. Plenty to choose from ( https://developer.mozilla.org/en-US/docs/Web/CSS/animation ), and you can easily make them fade to the standard color. The animation would also only be applied to the last inserted item (because of the way you did it, only the last item would have the "active" class)

Categories

Resources