GWT - changing anchor title dynamically - javascript

We have a link in a table cell. When the user hover overs the link, an async RPC call is made and the hover text (the title attribute) is updated. We are seeing wildly inconsistent results with the hover text changing while the user is still hovered over the element. On some machines it works fine, on others not at all.
We cache the results so if the user triggers the hover again, the tooltip text is correctly displayed.
Is there a trick to updating the anchor's title attribute while the user is still hovered over the anchor?
When the RPC call succesfully returns, we just call
link.setTitle(text);
which calls
/**
* Sets the title associated with this object. The title is the 'tool-tip'
* displayed to users when they hover over the object.
*
* #param title the object's new title
*/
public void setTitle(String title) {
if (title == null || title.length() == 0) {
DOM.removeElementAttribute(getElement(), "title");
} else {
DOM.setElementAttribute(getElement(), "title", title);
}
}

Your code here doesn say much about the problem. setTitle works wthout any issues no doubt. But firing an async call on mousehover is not so desirable as the issue you are facing here purely looks like originating because of time taken by the async call to complete.
I would strongly suggest to prefetch the data that you need to show on mouseover, during the page load itself and set that text directly instead of an async call.

When a user moves a mouse over a link, the browser displays the title attribute as a tooltip. In your case, there is no tooltip at all if the title is not set. When your RPC call returns and you set the title, nothing will happen in the browser until the user moves a mouse away from the link and then back over the link. So some tooltips will not show up, others (already set on the previous mouse-over) will show up: this UI pattern will really confuse your users.
You may have to rethink your design. A better approach is to show a small popup panel next to your link. You have complete control over when this panel shows and hides. Create a popup panel. Add a MouseOverHandler to your links. When a MouseOverEvent fires, dispatch your RPC call. When the call returns, populate the popup panel and show it next to the link. When a user moves away, hide the popup panel.
It can obviously be optimized if you have a large number of links in a table: you can use a single MouseOverHandler for the table and then check which element is the source of the event.

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

Selenium doesn't click on the top-most element

Consider the following Selenium automation:
Its goal is to go to a financial chart from the website Barchart, click on the custom calendar icon (at the top right corner over the chart), input a custom range in the form that pops up over it, and validated it using the apply button.
driver = webdriver.Chrome()
url = 'https://www.barchart.com/stocks/quotes/AAPL/interactive-chart'
driver.get(url)
driver.find_element_by_css_selector('.calendar-icon').click()
driver.find_element_by_css_selector('option[label="Intraday"]').click()
driver.find_element_by_css_selector('[data-ng-model="selectedAggregation.range.from"]').send_keys('11/01/2019')
driver.find_element_by_css_selector('[data-ng model="selectedAggregation.range.to"]').send_keys('11/01/2019')
driver.find_element_by_css_selector('[data-ng-model="selectedAggregation.range.to"]').send_keys(Keys.ENTER)
driver.find_element_by_css_selector('[data-ng-click="modalConfirm()"]').click()
It works fine for the most part, until I try to validate, which never works. I then realised that sometime this last action would lead me to a promotional page whose link is located exactly beneath the Apply button. Which seems to indicate that selenium 'click through' the form onto the link below.
I have tried other selector for the apply button, which all give the same result.
I also try to use the submit() method from selenium, which returns an error. Lastly, I also try to implement the execute_script method from selenium, but I did not manage to understand what exactly is the javascript call being executed on clicking apply.
Note : this is because i need to get the cookie and xsrf token that is generated by that call, not because i need to collect the actual financial data ( I know that the financial data can be collected using 'https://www.barchart.com/proxies/timeseries/queryminutes.ashx?' + data), where data are the query string parameters.
Any help greatly appreciated.
I had a look for you, the below should accept the changes for you, I've checked this and it works for me.
javascript = 'document.querySelector("body > div.reveal-modal.fade.interactive-chart-modal-aggregation.in > div > div > div > button.bc-button.light-blue").click()'
driver.execute_script(javascript)

How to attach events on control buttons of SAPUI5's Network Graphs?

I am creating a Network Graph based on this official code sample https://sapui5.hana.ondemand.com/#/entity/sap.suite.ui.commons.networkgraph.Graph/sample/sap.suite.ui.commons.sample.NetworkGraphDimensions
I would like to disable search field (make it invisible) by default and enable it only after switching to Full Screen Mode.
Disabling search field by default is easy:
var oNetworkGraph = this.getView().byId("myGraphId");
if (oNetworkGraph.isFullScreen() === false) {
oNetworkGraph._searchField.setVisible(false);
}
The problem is that our search field and other buttons (zoom in/out, toggle legend button, etc) are not defined inside XML view neither inside controllers. I guess it's a part of either sap.suite.ui.commons.networkgraph or sap.suite.ui.commons.networkgraph.layout and being inserted on init.
Because of this issue I can't add a listener on my Full Screen Toggle Button.
You could attach yourself similarly to your search field modifications.
I've checked the code and the button is available under the class variable _oFullScreenButton. That means by oNetworkGraph._oFullScreenButton.attachPress(function() {}); You could run code when button is pressed.
Note that accessing these private APIs might break in future versions.

Display loading icon when transitioning between divs

I have a form, that when the "Next" button is clicked, a new div appears in place of the old one with this code:
function showDiv() {
document.getElementById('2').style.display="block";
document.getElementById('1').style.display="none";
}
I am then, once the form is submitted, sending my data to a server so that it is emailed to me. The problem is that the previous action, the transition between divs after the button click, is being performed far too quickly. People have told me that it would look a lot better with some sort of transition or a quick loading icon, and that it doesn't look authentic.
Is there any way to have my second div "slide" into the position of the new one? Or some sort of transition? Keep in mind, this is just switching two divs out for one another. No actual data is being processed yet, and no new page is being loaded. Or is there any way to create a loading icon on this action to last for 1second?
Thank you for your help.
Try this
// send data
// show loading gif
setTimeout(function () {
// hide loading gif
// show other div
}, 2000);
You get a 2 second delay this way. Hope it helps.
I assume you're open to using jQuery based on your tags. jQuery offers a number of ways to animate changes to divs. .animate() provides a way to do custom animations, or your can use one of the provided options. In your case, perhaps something like .fadeToggle() would work?
Detailed information here: https://api.jquery.com/category/effects/

Javascript is done, but browser do not reflect these changes (ASYNC?)

I am using CEF and CefSharp.
I have one c# class that its purpose is to know if JS function call is done and then call call JS again on curent element xPath in
class test {
//array of Xpaths of elements
elementsXpaths
public IsDone(){
LoadNext()
}
LoadNext(){
call = string.Format("click('{0}')", elemenentsXpath[next])
browser.ExecuteScriptAsync(call)
}
}
Then JS something like this
function click(xpath){
elementFoundedByXPath.click()
elementFoundedByXPath.style.backgroundColor = "#FF0000"
test.isDone();
}
My problem is, that background color is not changed right after click().
So for example I have one element, clicking on this element reveal some other elements (fe I click on show login button and login and password input are shown after this click) and then click do not fails, but I cant see that login and password input. Very odd. I would guess that this will fail, because element is not founded (I am checking this in JS).
I am also checking this in debug, when I have breakpoint on LoadNext I can see that LoadNext is called and backgroundColor of previous element is not changed.
I assumed that if I do click on that element I can be sure that actual click was performed.
Is this problem with async calling of JS? Will EvaluateScriptAsync() help me ? In that case somebody show me some easy example and difference between these two functions ? Or is problem most likely somewhere else ?

Categories

Resources