Server handler event info parameters google apps script - events

A simple app:
function doGet() {
return(test());
}
function test(){
var smiley = UiApp.createApplication().setTitle("TT Bomgar Feedback");
var textIn = smiley.createTextBox().setName("text");
var textOut = smiley.createLabel().setId("label").setVisible(false);
var button = smiley.createSubmitButton("Submit");
var handler = smiley.createServerHandler("handler");
button.addClickHandler(handler);
smiley.add(button);
smiley.add(textIn);
smiley.add(textOut);
return(smiley);
}
function handler(e){
app = UiApp.getActiveApplication();
var text = e.parameter.text;
app.getElementById("label").setVisible(true).setText(text);
return(app);
}
In the handler function, var text is always undefined. This means that the following is returned:
So, undefined is printed instead of "some text".
I don't understand why though, because I have correctly set the name of the text box element in the test function ...
Any assistance is greatly appreciated.

You need to add a callBackElemnt to the handler so that its value will get passed to the handler function. In normal practice, we just add the top most element containing all other elements. But you can also add all the elements whose value you want to pass.
modified script
var handler = smiley.createServerHandler("handler");
handler.addCallbackElement(textIn);
button.addClickHandler(handler);

You have to add callback element to your server handler:
...
var handler = smiley.createServerHandler("handler");
handler.addCallbackElement(textIn);
button.addClickHandler(handler);
...
https://developers.google.com/apps-script/class_serverhandler#addCallbackElement

Related

Nightwatch .execute() how to pass parameter to execute function, is it possible?

Please be patient - I am a beginner in programming. Tester for long time but programming is not my domain.
My test is:
from the backend I get some list with some element (e.g. 5 text strings)
I click some element on page which displayed those 5 elements (of course I don't know if listed elements are correct or not)
I need to check if list of elements displayed on ui is the list received from backend
Problem:
I cannot access the elements by Nightwatch api css selector, at least I could not manage (Angular app) to do it with Nightwatch
I found I could do it with .execute()
My code is (failing):
browser
.click(selector.HEADER.APPS_GRID, function () {
for (var app in appsList) {
let appShortName = appsList[app].shortName
let appLongName = appsList[app].longName
let appUrl = appsList[app].url
let appVisibility = appsList[app].visibility
browser.execute(function(app){
var appShortNameDisplayed = document.getElementsByClassName('logo-as-text')[app].innerText
var appLongNameDisplayed = document.getElementsByClassName('app-name')[app].innerText
return [appShortNameDisplayed, appLongNameDisplayed]
}, function(result){
console.log(result.value[0])
})
}
})
It fails in lines:
var appShortNameDisplayed = document.getElementsByClassName('logo-as-text')[app].innerText
var appLongNameDisplayed = document.getElementsByClassName('app-name')[app].innerText
unfortunately I have to make query with [app] - iterating by elements of object. If I skip [app].innerText I get some data like element-6066-11e4-a52e-4f735466cecf instead of text values displayed on page
I get error:
Error while running .executeScript() protocol action: TypeError: document.getElementsByClassName(...)[app] is undefined
Is it possible to pass the "app" param (counter) to the document query?
Or is it the way I have to make one query that will return as many data as necessary and then handle data returned in this block
function(result) {
console.log(result.value[0])
})
The fragment of html page is
<div _ngcontent-c8="" class="ep-app-icon mt-auto mb-auto text-center logo-as-text"> XXX </div>
... and I need to get this "XXX" text.
As your own comment suggests, there is an args argument to .execute that is an array. The array elements will be the arguments in the function passed to execute.
See https://nightwatchjs.org/api/commands/#execute
.executeAsync(function(){
var buttons=document.getElementsByTagName('button');
buttons[2].click();
return buttons;
},[],function(result){
console.log('done')
})
Try Async it works for sure

Jasmine spy doesn't work on a function defined in a constructor

I want to spy on a function used as a click handler. The function is defined within the constructor of a closure.
var viewModel = function(){
var viewModel = function(){
var _this = this;
_this.internalClickHandler = function(){
console.log('I handled a click');
}
}
return viewModel;
}();
var testViewModel = new viewModel();
var theSpy = spyOn(testViewModel, 'internalClickHandler');
Even though Jasmine is happy that 'internalClickHandler' exists and creates the spy, it never gets called. In fact the original function (internalClickHandler) gets call instead.
I've created examples in codepen.io that show the problem. The failing test is the one trying to spy on a function in the constructor.
My event handler needs to be in the constructor as it needs access to instance of the object and I do want to test that the correct handler has been fired not just that the click event was triggered.
Any help would be greatly received. Thanks
You will not be able to execute that test because of the following reasons:
Your clickHandler actually gets reassigned to a different variable
on the DOM Element onClick, see this line
document.getElementById('testLink').addEventListener('click',
_this.internalClickHandler);
When a click trigger gets invoked, it actually executes the function
onClick and NOT internalClickHandler, though they are in actuality(code wise)
the same but they are being referenced by two different variables
i.e onClick & internalClickHandler.
You are better off trying something like this.
it('should spy on a event binding defined in constructor', function() {
var testViewModel = new viewModel();
var tl = document.getElementById('testLink');
var theSpy = spyOn(t1, 'onclick');
//$('#testLink').trigger('click');
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
tl.dispatchEvent(event);
expect(theSpy).toHaveBeenCalled();
tearDown();
});
Hope this helps.
I resolved this by using as the handler an anonymous function wrapping a reference to internalClickHandler. This way the original function still gets called and I'm able to spy on it.
var viewModel = function(){
var viewModel = function(){
var _this = this;
_this.internalClickHandler = function(){
console.log('I handled a click');
}
}
return viewModel;
}();
var theViewModel = new viewModel();
var theSpy = spyOn(testViewModel, 'internalClickHandler');
$('#testLink').on('click',
function(){
theViewModel.internalClickHandler(); //<-- The anonymous function calls internalClickHandler
});

Getting Titanium Mobile label properties inside a function

Problem: How to determine which of the labels is being displayed in the window.
I created labels using Ti.UI.createLabel and there's 6 of them in the window. This is how I initialise them:
var sitCom = Ti.UI.createlabel({
text: 'Door',
top: 10,
left: 5,
visible: false
});
I have the same properties for other variables, the only difference is the text property.
These labels are hidden and they only get displayed on demand, when the button is pressed. I used the setVisible: true to display them. This is working fine.
I then created a function to loop through these variables to check which one is shown. The idea is that, when the user tap a button, the script then searches for the visible ones, hide the not related ones and show the one that the button is calling for.
function whatIsVisible(){
var newArr = new Array();
var newArr[0] = 'sitCom';
var newArr[1] = 'dutyFree';
var newArr[2] = 'Exclusive';
// ...
var i = 0;
for (i=0; i<=6; i++) {
var v = newArr[i].getVisible();
Ti.UI.info(newArr[i]+ ' is '+v);
}
}
The function shows undefined in the console log.
What am I missing here? Do I have to put an if statement inside the for loop to check the each array ?
thanks for your help
This is happening because you don't have label objects in for loop. Remove ' ' from the variables and just pass var name.

Firefox extension:adding a new tab,but addEventListener not working

There is a dialog, and I define a function OnAccept() and call it like this: ondialogaccept:ondialogaccept="OnAccept()".
OnAccept():
function OnAccept() {
var windowManager = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService();
var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator );
var topWindow = windowManagerInterface.getMostRecentWindow( "navigator:browser" );
if(topWindow)
{
var web = topWindow.document.getElementById("content");
web.selectedTab = web.addTab("http://www.google.com");
var newBrowserHandle = web.getBrowserForTab(web.selectedTab);
newBrowserHandle.addEventListener("load", function() { alert("111"); }, true);
}
}
But the addEventListener doesn't work. I don't know why.
There are some issues in your code that are probably just bad copy&paste: ondialogaccept:ondialogaccept="OnAccept()" should be ondialogaccept="OnAccept()" and OnAccept(): should be OnAccept: (without parentheses).
The main issue: the load event listener doesn't get propagated from content to chrome, you would need progress listeners to get that event. You can listen to the DOMContentLoaded event however, that one can be caught on the browser element. This event will fire when only the document content is loaded, not images and such - but maybe that's ok for you.

FBJS...OnClick not being passed. DHTML/setInnerXHtml problem

thanks so much in advance...here is the problem...
I am trying to add dynamic HTML element (EX. [delete]),everytime on a event call using FBJS.I am able to append the element using following code.
var oldFriendHtml = document.getElementById('friend_container');
var numi = document.getElementById('theValue');
var num = (document.getElementById("theValue").getValue()-1)+2;
numi.value = num;
var newElementId = "new"+num;
var newFriendHTML = document.createElement('div');
newFriendHTML.setId(newElementId);
newFriendHTML.setInnerXTML("HTML TO BE ADDED");
oldFriendHtml.appendChild(newFriendHTML);
The problem I am facing is that FBJS parses out the onClick part (event call ) out from the original HTML added .This stops me in the further activity on the added element .It also removes the styling added in the HTML ..
Regarding onclick being parsed out of setInnerXHTML, you can add the event later by using addEventListener.
Here is some sample:
var my_obj = document.getElementById('test');
// add a new event listener for each type of event you needed to capture
my_obj.addEventListener('click',my_click_func); // in your case is onclick
function my_click_func(evnt){
// some action
}
more details see http://developers.facebook.com/docs/fbjs#events

Resources