Multiple instances of same variable - javascript

I'm using an AJAX call to pull filenames from a database which are then used to populate a carousel with images of the same name.
My web app makes use of tabs which when tapped, reload the AJAX and pull from the database a different set of filenames which then repopulate the carousel.
What I'm finding is when the web app initially loads, the carousel works fine, but if I tap any of the tabs, the carousel begins to function incorrectly, i.e. the first time I tap and then use the carousel the carousel moves by two images at at time, a second tap and the images move three at a time, so on and so forth.
If I check console I can see that following the call, when I click either the left or right arrow in the carousel, it's as if there are two instances of the same variable, or as if both AJAX calls are being called in some way. Image attached to show what I mean.
As you can see, following initial load everything is fine, however once any subsequent calls are made it's as if the count from the previous call continues, and a secondary count also starts associated with the new data, or a third or fourth or fifth, dependent on how many calls have been made.
$('.tabs-nav li').on('click', function() {
tabName = $(this).html();
place = 0;
products = getProductDetails(selected); //AJAX call
data = dealWithData(products, place); //Deferred object that works data
});

Sounds like you are having a scoping issue. The easiest way is to have your logic in a closure so your variables get scoped to the particular tab. So instead of something like this:
var place,count
$(".tabs").on('click',function(){/*shares same place & count */});
it would look like this:
$(".tabs").each(function(){
var place,count
$(this).on('click',function(){/*each has their own place,count*/});
});

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
}
});

Interact with a drawing

I created a script that operates some functionality(coping rows, parsing rows and cells, changing format and then inserting into new range) . I assigned the script to a drawing, so when I click a drawing(button) it calls the function.
But the only problem that I am now facing is when a user accidentally or on purpose intensively clicks the button twice or more, a function does not work properly because every calling takes some time (about 5 seconds) and a next call of the function operates the wrong range.
So as i know there is no way to call the function asynchronously, is there?
So I need to somehow interact with the button to either disable button once after it clicked and then enable again when it's finished.
Hope i explained it correctly.
// the function is called by drawind from a spreadsheet
function addNewWeek() {
// here is some logic that copies, parses and inserts cells (takes about 5 seconds)
// need to wait for finish of the function
}
this button calls the function
Class Sheet has the method getImages() that returns all over-the-grid images on the sheet. I think that it could be used to get the drawing, then use assignScript(functionName) to change the assigned function.
Related
Resize all images after an edit in google Spreadsheets
Deleting images in Google sheet via script error

jQuery event triggering multiple times because of multiple javascript inclusions/requires

I have a problem here and it's making me mad. I maintain a legacy php system. It's badly organized, no frameworks are used and a lot of other problems, for example, at least 5 different query versions are used in different parts of the system.
So my problem right now is this, I have a search form, when a button is clicked it shows a list of items, lets call this a list of "A" objects. In each A item, there is an expand /toggle button to show the B items that belong to A (this is done using ajax, by setting a specific div's html to the ajax response). Then each B also has an expand/toggle button to show the C items that belong to B.
What is happening: I click to search, all A are shown. I click on the expand to show the B items of one A object, they are shown. I click B to hide it, it hides and then show again. If I click it one more time, it hides, shows and hide. So it is like every ajax request is including the javascript code and running it.
I think this is pretty much an organization problem, I am not knowing how to include/require and insert the js correctly. I've been trying to solve this issue since yesterday and I think I've seen the code so many times that I can't think out of the box.
So here's some of the organization (I changed the names because there are some business rules):
SearchResults.php -> Declares a class that has static methods to print out HTML of each item A, B and C and some other helper methods. To make stuff "work", it has a require "js.php"; otherwise the A expand button does not work because it does not exist at the time the js is executed and no function is bound.
search.php -> the HTML form with all the search options, nothing important.
js.php -> the javascript stuff, why is it in a ".php"? I can't even remember, but I think it is because with the php I can require/include:
<script type="text/javascript" src="../util/js/jquery/1.8.1/jquery.min.js"></script>
<script>
var jQ = jQuery.noConflict(true);
jQ(document).ready(function() {
jQ(".loadBfromA").click( function(e) {
if (div.style.display == 'none')
alert("was hidden, now is showing");
//call ajax_B.php
//response is put into the div using .html(data)
else
alert("was showing, now is hidden");
...
ajax_B.php -> the ajax that access the database and echoes html code that will be put into the A items div. Here I have to require SearchResults.php, because I call some methods of the class.
Why is it including the jQ(document).ready being executed multiple times? How can I fix it? Is there any way I can reorganize the code?
Is the ajax_B.php, when requiring SearchResults.php, including the js again because SearchResults.php requires js.php? Does this gets echoed and then put into the div?
I can't make a fiddle of this because there is ajax included.
Edit:
I have tried unbind("click").bind("click", ()) and it didn't work.
It looks like the event is being bound multiple times on jQ(".loadBfromA")
I know this is not the cleanest solution out there, but you could rewrite the actual binding:
jQ(".loadBfromA").bind('click.loadbfroma', function(e) {
// Do your code
$(this).unbind('click.loadbfroma');
});
That way you can at least be sure that only one event is bound at all times, no matter how many times the code snippet is being included. I know this doesn't really help you with the underlying issue but it's a start.

Index of list item clicked does not reset

On a fresh page load, the code works just fine and will display the correct information, but if you navigate backwards and try again, it displays the information from the first click. First off, here is the code and I will explain what I have...
$(document).on('pageinit', '#months', function(){
$('#listOfHolidays').on('click', 'li', function () {
listIndex = $(this).index();
$.mobile.changePage('#detail');
});
});
$(document).on('pageinit', '#detail', function(){
console.log(listIndex);
$('#ho').text(holidayNames[listIndex]);
$('#hi').text('The index of the list item clicked is: ' + listIndex);
});
I have 2 pages (divs with data-role="page") named #months, which is the one containing my list of items to select from, and #detail which is a page that I want to populate based on the user's choice from the list. The id for my listview is #listOfHolidays and the array which holds the values of each item in the list is called holidayNames. I then display this basic info in the detail page in divs called #hi and #ho (some of this will be changed, I am just trying to test my way out of this problem). I have a back button enabled in the header of detail also.
Like I said, when I load this fresh, the correct holiday name and index number show up in my detail page, but when I use the back button to navigate back and try again, it populates the detail page with the same info from the first click.
I would assume this is because jquery is initializing the detail page in the second $(document).on() function with 'pageinit' and since it is initialized with the first index and holiday name I choose, it just doesn't need to initialize again and draws the data from the first request when I click another list item.
That is my vague understanding of what is going on, so please correct me where I'm wrong and guide me in the right direction!
Thanks!
The 'pageinit' event only fires when the page is introduced to the DOM. Thus the code you have bound to replace the holiday text with the new one, only fires on the original click. The next few clicks do not cause that function to fire.
If you bind to the 'pagebeforeshow' then it will trigger everytime you change pages and you can bind the same function there and it should work correctly.
$(document).on('pagebeforeshow', '#detail', function () {
console.log(listIndex);
$('#ho').text(holidayNames[listIndex]);
$('#hi').text('The index of the list item clicked is: ' + listIndex);
});
I removed some things to simplify the example.
JSFiddle example

How do I store local javascript results from an ajax call to be shown later?

I have an ajax query that returns an array . . I only show the first 20 items in the array right now but i have now added a link for "Show All" after I displayed those first results.
When the user clicks Show All i want to display all of the items in the array.(either inline or in a dialog (but that implementation shouldn't matter)
I want to avoid having to go back to the server to get the full list since I already retrieved the full list from the first ajax call . . where is the best way to locally store this array to be accessed later.
Save the array in a variable, or possibly attached as a data element to something on the DOM. Then, when your "Show All" event fires, read from that array and rebuild your display.
<div id="myArrayDisplay">
</div>
<script>
$(function () {
$.getJSON("backendCode.php", function (jsonData) { // assumes your array arrives as a response from a JSON-based Ajax request to some server code
$("#myArrayDisplay").data("arrayObj", jsonData);
});
});
</script>
Obviously I'm not showing how you would display the contents of the array in the above code, just how I would store it.
I think the easy way you can do is to put the full list data into a hidden input textfield
I don't know about the best way, but the simplest is using a global variable.
Define it here:
$(document).ready(function(){
$.myArray = [];
})
And use it like so:
function myFunction(){
alert($.myArray[0]);
}
More info about $(document).ready.
On the other hand, you could create two separate fields, one with the initial info and one with the rest, making the second one invisible. When the user clicks "Show more" you can show the hidden one.
More information about .show().

Categories

Resources