Why is e.parameter.source undefined? - google-apps-script

I am trying to find out where a callback function came from, but e.parameter.source has been undefined.
The code I'me using to create the callback event is:
var temp_handler = app.createServerHandler("do_things");
container.add(app.createButton(s_list[i][2]).setId("goto_"+s_list[i][1]).addClickHandler(temp_handler));
container.add(app.createLabel("goto_"+s_list[i][1]));
where container is later added to the app.
The first part of the function that gets called is:
function do_things (e)
{
var app = UiApp.getActiveApplication();
Logger.log(e.parameter);
var src = e.parameter.source;
From this, I have been able to tell that e.parameter is:
{clientY=61, clientX=38, button=1, alt=false, eventType=click, screenY=278, ctrl=false, screenX=493, y=11, shift=false, meta=false, x=34}
This does not include source. I find this peculiar because as far as I can tell, other callback functions in the same file have been able to access and use e.parameter.source without issue.
Does anyone know what I am doing wrong in this callback such that the source parameter is inaccessible?

The other answers do not make much sense to me.
First, because the source parameter is filled by the element id that generated the event, not its name.
Also it's filled automatically, there's no need to addCallbackElement, which is required for accessing widgets contents by their name. And last, set a name for a label is only useful when you're setting a tag on it, as there's no "content" for a label.
All that said, the only problem I can imagine is if you're setting the same id on another widget and it's messing with your original one (the button). But I haven't tested that to be sure.

You simply forgot to give a name to your Label widget. The value returned by the e.parameter is assigned to a widget by its name.
The ID is used to access the widget from outside the UiApp creation function when you need to modify it.

In addition to what Serge answered, you might want to supply a callback element on the handler using
ServerHandler.addCallbackElement()

Related

Polymer two-way data binding and Facebook callback

I am very new to JavaScript and Polymer. I do like the PWA concept but now hit some roadblocks.
I tried to use polymerfire <firebase-auth> and was able to do google provider logins. But got blocked as I don't know how to do Facebook provider login and didn't find anywhere on how to use the tag as I wish to provide Facebook login too in JavaScript. If someone guides me to a source that works I will then not need part 2 of the question.
So, I tried facebook login via Graph API FB.login(). FB.login() has callback and I was not able to extract the response.name, public_profile and set it to Polymer attribute say {{user}} like
var userName = response.name; and then this.user = {displayName : userName};
I noticed that as soon as I exit FB.login() callback on successful login, I lose the changes done in assignment in callback to 'this.user ' object.
My question is - I am not able to make two way binding work in polymer. How can I change the object in child element and then it propagates to all the pages / polymer elements?
How can I change the object in child element and then it propagates to all the pages / polymer elements?
Well really that depends on how you set up all the pages. If you're in the parent, you can pass functions, variables, and objects to the child element by passing it in the component.
<ChildElement details={{_details}}/> // If you want to pass a details object to the child
<ChildElement sqft={{square(size)}}/> // This will call the square function inside your ChildElement and pass in the parameter size
Use the latter to call a function in your child and that function will have access to all the elements within that scope.
If you're in the child and you want to change something in the parent, you can do a callback with this.fire(someFunction()), and then create a function in your parent that with the same name. It's not too bad when you're just passing from parent to child or vice versa but if you're passing it everywhere, then you might want to look into some sort of state management. Passing things from one place to everywhere else will get ugly real fast.

AngularJS - Dynamically change class and load JSON - two things, really

I'm facing an issue (or probably two) that is frustrating the swearwords out of me; keep in mind, I'm a fairly beginner coder, so there's a good chance I'm missing something obvious.
One: I've got a page that has a sidebar that is hidden via a class containing margin-left: -90%. When the class is removed, the bar slides in to fill the whole screen. I can handle this really easily with jQuery, but I'd rather stick as much as possible in Angular - to this end, I've given it the following code:
<div id="detail_box" ng-class="{d_hide: dVis}">
<div tw-detail></div>
</div>
Which, as you can see, has a class that refers to a variable in a controller, and a link that has an ng-click connected to a function. The controller in question is stupidly simple, and relies on $rootScope variables. I'm only using rootScope because in total, over my whole page, I have two variables that will need to change dynamically, but be the same, for every controller and directive I've made. The connecting scope and controller are here:
app.run(function($rootScope) {
$rootScope.currentUrl = 'visual/design/1/';
$rootScope.detail_hide = true;
});
app.controller('navController', ['$scope', '$rootScope',
function ($scope, $rootScope) {
$scope.dVis = $rootScope.detail_hide;
$scope.hide = function(){
$rootScope.detail_hide = false;
}
}]);
Now, I've used console.log from my ng-click to see that it is picking up clicks, and I've used console.log to make sure that the detail_hide part of rootScope is changing. If I change true to false by hand in my app.js, the detail page hides itself just fine... but that ng-click doesn't actually do what I'm trying when I test it on the page. It's painful and I can't understand why changing the variable via a function (which I know changes the actual variable in rootScope, thanks to extensive testing) isn't telling my detail box to just go away.
Secondly, and it's connected to the first; dynamically changing the currentUrl in rootScope similarly doesn't change the actual AJAX content I've got stuck inside my twDetail directive, even though, again, the ng-click functions I've written do change the variable. Changing it manually works fine (although images in the second URL aren't loading but that's probably an entirely different problem) but just... what the heck am I doing wrong here?
The following code is only being run once, when the controller is being setup
$scope.dVis = $rootScope.detail_hide
Make sure you change the $scope.dVis in the hide function, like this
$scope.hide = function(){
$rootScope.detail_hide = false;
$scope.dVis = $rootScope.detail_hide;
}
I need more info on the twDetail directive to be able to solve that problem

apps-script: how do I read back the contents of a text widget?

I'm sure this is a really dumb question, but I've spent an hour googling, with no luck.
I'm storing spreadsheet data (some text, some dates) in various widgets. At some point, a click handler has to read back the text or the date from the widget, and write it out to another spreadsheet. Currently, I've got the data in a FlexTable (or in a Label widget in the FlexTable). I've now found out (I think) that there's no way to read back this data.
Any ideas how I'm meant to handle this? I just need a widget that will let me store data, display it, and later read it back.
Thanks.
EDIT
I don't think the answers have actually got me any further forward. I appreciate that I can read the value of some widgets if they're passed to the handler as a callback. However, this appears to be restricted to ones with a setName method - is this just TextBox and ListBox? If so, that's no use, because TextBox is for user entry.
So, is there a widget that will let me (the script, not the user) store data, and later read it back? Or am I just being thick?
You haven't search very well, there are plenty of examples around here... just one posted today : Date AND Time picker Google App Script
and the documentation, look at the (near) end of the page...
You can actually read the text from a Label widget if you set the text in it's tag as well...
// Get Label text and set it to another label
function doGet() {
var app = UiApp.createApplication();
var panel = app.createVerticalPanel();
var label1 = app.createLabel('hello').setTag('hello').setId('label1');
Logger.log(label1.getTag()); // works
var label2 = app.createLabel('').setId('label2');
var handler = app.createServerHandler('myFunction').addCallbackElement(panel);
var btn = app.createButton('Get tag', handler);
panel.add(label1).add(label2).add(btn);
app.add(panel);
return app;
}
function myFunction(e) {
var app = UiApp.getActiveApplication();
Logger.log(app.getElementById('label1').getTag()) // doesn't work
var tag = e.parameter.label1_tag; // works
Logger.log(tag);
app.getElementById('label2').setText(tag); // Sets label2 text as label1 tag
return app;
}
There's no .setName() that you specify with a Label, but it looks like one gets automatically created.
In your case, storing text inside of invisible Text Boxes that coincide with the Labels would be another option.
Have a look at https://developers.google.com/apps-script/uiapp#ServerHandlers
Values of widgets are passed to server handler in e.parameter. Don't forget to give widget Name and Id. If you want to get values of widgets that are not the one triggering the event handled then you need to pass the data using the widget tag value

Global Variables in Chrome Extensions

Is there a simple way where I can access a global javascript variable through content-scripts in chrome extensions?
Accessing global object from content script in chrome extension
I followed the steps mentioned in the above link, but it did not work out for me. Any help would be much appreciated.
Thanks,
Shankar
I managed to complete it. Thanks for the help. I used simple message passing to retrieve the value from the extension script to the content script. The place where I had missed was, the listener at the extension script needs to be at the background page (I think so). Once I changed that, it worked.
For those from the future looking for an answer to this question, here's how I do it:
function getVariable(v) {
var c = document.createElement("div");
c.id = 'var-data';
c.style.display = 'none';
document.body.appendChild(c);
var s = document.createElement('script');
s.innerHTML = 'document.getElementById("var-data").innerText=JSON.stringify('+v+');';
document.head.appendChild(s);
var data = JSON.parse(c.innerText);
c.remove();
s.remove();
return data;
}
And basic usage:
getVariable('globalVarIWantToAccess');
All this script goes in the content-script, not the code for the main webpage, which means that no co-operation is needed from the webpage itself. Basically, the getVariable function creates a script element which is injected into the main page. This script tag retrieves the requested global variable and puts the data into a new div. The function then gets this data from the new div, deletes the new div, deletes the new script element and returns the data.

MooTools return undefined object

I have predefine MooTools.js and some another javascript called moomenu for dropdown...
However i could test the code and i come to know that "typeof(MooTool)" return undefined...
I am new to MooTool so will any body please tell me what happens there???
It's because your calling it "MooTool" instead of "MooTools"; however, if you look at the source, var MooTools only refers to an object with the version and build information. If you're trying to select an element, you want to look at the $ and $$ functions of the Element object:
http://mootools.net/docs/core/Element/Element