How to Get args from SP.UI.ModalDialog? - javascript

I have tried other online suggestions without success.
So...
My function opening a SharePoint dialog passes agrs into the prescribed option object, like so:
SETTING UP THE DIALOG:
Nothing magical here...
function openEmailDialog() {
var options = SP.UI.$create_DialogOptions(),
url = '../Pages/EmailDocument.aspx';
options.title = "Email Documents";
options.width = 1024;
options.height = 400;
options.allowMaximize = false;
options.url = url;
options.args = { DidYouGetThis: true };
SP.UI.ModalDialog.showModalDialog(options);
};
Next...
Upon opening the target URL, most online examples recommend the following JavaScript to extract the args BACK from the dialog, like so:
GETTING THE ARGS:
Remember, this is JavaScript in a new page which was just opened as a dialog...
$(document).ready(function () {
// This fails because "get_childDialog" doesn't exist
var args = SP.UI.ModalDialog.get_childDialog().get_args();
});
This fails because the SP.UI.ModalDialog object has no get_childDialog function.

Use var args = window.frameElement.dialogArgs;
The article I used for reference.
Live Article.

Here is a tutorial discussing this very concept. - http://www.sharepointdevelopment.me/2011/06/passing-data-to-and-from-sharepoint-modal-dialogs/

Related

Disqus this.callbacks.onNewComment not working

I somehow cannot get the Disqus this.callbacks.onNewComment to work. What could be wrong? Im trying to alert('hey!') once a new comment is posted. Source
<script>
var disqus_config = function () {
this.page.url = PAGE_URL;
this.page.identifier = PAGE_IDENTIFIER;
this.callbacks.onNewComment = [function(comment) {
alert(comment.id);
alert(comment.text);
alert('hey!');
}];
};
(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = 'https://example.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
PAGE_URL and PAGE_IDENTIFIER need to be specific to your site
This callback is for detecting a new post by this browser window. Not new posts arriving from other users (or even your own user in another browser windows)
That 2nd one threw me as I thought it was to indicate new post had arrived

XPathEvaluator in Firefox addon

I am attempting to follow this article to evaluate an XPath expression. My code is copy/pasted from the article:
// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator();
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement);
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}
However, I'm getting this error:
Message: ReferenceError: XPathEvaluator is not defined
Is Mozilla's article out of date, perhaps? Is there a more up-to-date article available on parsing XML in an SDK add-on?
Edit. When I tried it this way:
var {Cc, Ci} = require("chrome");
var domXPathEvaluator = Cc["#mozilla.org/dom/xpath-evaluator;1"].createInstance(Ci.nsIDOMXPathEvaluator);
I got a long error message:
- message = Component returned failure code: 0x80570019 (NS_ERROR_XPC_CANT_CREATE_WN) [nsIJSCID.createInstance]
- fileName = undefined
- lineNumber = 14
- stack = #undefined:14:undefined|#resource://helloworld-addon/index.js:14:25|run#resource://gre/modules/commonjs/sdk/addon/runner.js:145:19|startup/</<#resource://gre/modules/commonjs/sdk/addon/runner.js:86:7|Handler.prototype.process#resource://gre/modules/Promise-backend.js:920:23|this.PromiseWalker.walkerLoop#resource://gre/modules/Promise-backend.js:799:7|this.PromiseWalker.scheduleWalkerLoop/<#resource://gre/modules/Promise-backend.js:738:39|Promise*this.PromiseWalker.scheduleWalkerLoop#resource://gre/modules/Promise-backend.js:738:7|this.PromiseWalker.schedulePromise#resource://gre/modules/Promise-backend.js:762:7|this.PromiseWalker.completePromise#resource://gre/modules/Promise-backend.js:705:7|handler#resource://gre/modules/commonjs/sdk/addon/window.js:56:3|
- toString = function () /* use strict */ toString
edit 2. Here, I'll just post my whole code, because it's clear something stranger than I thought is going on. I've created a hello-world addon using the Mozilla tutorials including this one to display a popup. I've modified that further so that it will append text to a file, and modified that further to, I hope, parse and modify XML. So the resulting add-on is supposed to take text entered in the popup and append it to an XML file.
var data = require("sdk/self").data;
var text_entry = require("sdk/panel").Panel({
contentURL: data.url("text-entry.html"),
contentScriptFile: data.url("get-text.js")
});
const fooFile = "/Users/sabrina/Documents/addon/foo.xml";
var {Cc, Ci} = require("chrome");
var parser = Cc["#mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
//var domXPathEvaluator = Cc["#mozilla.org/dom/xpath-evaluator;1"].createInstance(Ci.nsIDOMXPathEvaluator);
var foo = parser.parseFromString(readTextFromFile(fooFile), "application/xml");
// Create a button
require("sdk/ui/button/action").ActionButton({
id: "show-panel",
label: "Show Panel",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: handleClick
});
// Show the panel when the user clicks the button.
function handleClick(state) {
text_entry.show();
}
text_entry.on("show", function() {
text_entry.port.emit("show");
});
text_entry.port.on("text-entered", function (text) {
console.log(text);
// appendTextToFile(text, "/Users/sabrina/Documents/addon/output.txt");
appendFoo(text);
text_entry.hide();
});
function appendFoo(text) {
var newNode = foo.createElement("blah");
newNode.innerHTML = text;
var mainFoo = evaluateXPath(foo, '/foo')[0];
mainFoo.appendChild(newNode);
foo.save(fooFile);
}
function evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator();
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement);
//var result = domXPathEvaluator.evaluate(aExpr, aNode, null,
// domXPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}
function readTextFromFile(filename) {
var fileIO = require("sdk/io/file");
var text = null;
if (fileIO.exists(filename)) {
var TextReader = fileIO.open(filename, "r");
if (!TextReader.closed) {
text = TextReader.read();
TextReader.close();
}
}
console.log(arguments.callee.name + ": have read " + text + " from " + filename);
return text;
}
function writeTextToFile(text, filename) {
var fileIO = require("sdk/io/file");
var TextWriter = fileIO.open(filename, "w");
if (!TextWriter.closed) {
TextWriter.write(text + "\n");
console.log(arguments.callee.name + ": have written " + text + " to " + filename);
TextWriter.close();
}
function appendTextToFile(text, filename) {
var textplus = readTextFromFile(filename) + text;
writeTextToFile(textplus, filename);
}
I run at the command line using jpm run which opens Firefox Developer Edition. I click the addon button, the popup comes up, I enter text, I hit return, and I see this in the console:
JPM undefined Starting jpm run on Sabrina's Helloworld Addon
Creating XPI
JPM undefined XPI created at /var/folders/gg/r_hp4hzs0gdfy70f__l18fmr0000gn/T/#helloworld-addon-0.0.1.xpi (46ms)
Created XPI at /var/folders/gg/r_hp4hzs0gdfy70f__l18fmr0000gn/T/#helloworld-addon-0.0.1.xpi
JPM undefined Creating a new profile
console.log: helloworld-addon: readTextFromFile: have read <?xml version="1.0" encoding="UTF-8"?>
<foo><blah>eek</blah><foo>
from /Users/sabrina/Documents/addon/foo.xml
console.log: helloworld-addon: ook
console.error: helloworld-addon:
JPM undefined Message: ReferenceError: XPathEvaluator is not defined
Stack:
evaluateXPath#resource://gre/modules/commonjs/toolkit/loader.js -> resource://helloworld-addon/index.js:63:9
appendFoo#resource://gre/modules/commonjs/toolkit/loader.js -> resource://helloworld-addon/index.js:57:19
#resource://gre/modules/commonjs/toolkit/loader.js -> resource://helloworld-addon/index.js:50:2
emitOnObject#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:112:9
emit#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:89:38
portEmit#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/content/sandbox.js:343:7
emitOnObject#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:112:9
emit#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:89:38
onContentEvent/<#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/content/sandbox.js:384:5
delay/<#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/lang/functional/concurrent.js:38:20
notify#resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/timers.js:40:9
Non-authoritative, speculative answer
In a different question, Wladimir Palant (author of Adblock Plus, presumably he has good knowledge of firefox) said:
Yes, a lot of global classes available in the window context aren't there in SDK modules which are sandboxes.
Source: https://stackoverflow.com/a/10522459/3512867
This could explain why XPathEvaluator is not defined in the SDK addon.
The logical conclusion would be to use Firefox's Components object to access the nsIDOMXPathEvaluator interface. Which brings up the following error:
NS_ERROR_XPC_CANT_CREATE_WN
Looking into it takes us to this, from mozillazine's forums user "lithopsian":
That means it can't create a wrapper for a non-javascript interface.
Source: http://forums.mozillazine.org/viewtopic.php?f=19&t=2854793
I am unable to judge the credibility of that statement and while the linked bug reports seem to be relevant, I can not attest they actually are:
https://bugzilla.mozilla.org/show_bug.cgi?id=994964
https://bugzilla.mozilla.org/show_bug.cgi?id=1027095
https://bugzilla.mozilla.org/show_bug.cgi?id=1029104
Unless those informations are confirmed (or dispelled) by people with a deeper knowledge of Firefox's internal workings, I can only hesitantly conclude that the nsIDOMXPathEvaluator interface can simply not work in an SDK addon.

Node.js - how to use external library (VersionOne JS SDK)?

I'm trying to use VersionOne JS SDK in Node.js (https://github.com/versionone/VersionOne.SDK.JavaScript). I'm simply downloading whole library, placing it alongside with my js file:
var v1 = require('./v1sdk/v1sdk.js');
var V1Server = v1.V1Server;
console.log(v1);
console.log(V1Server);
Unfortunately something seems wrong, the output I get after calling
node app.js
is:
{}
undefined
Can somebody point me what I'm doing wrong or check whether the sdk is valid.
Thanks!
You can see in the source where V1Server is defined, that it's a class with a constructor. So you need to use the new keyword and pass the arguments for your environment.
https://github.com/versionone/VersionOne.SDK.JavaScript/blob/master/client.coffee#L37
var server = new V1Server('cloud'); //and more if you need
Can you try the sample.js script that I just updated from here:
https://github.com/versionone/VersionOne.SDK.JavaScript/blob/master/sample.js
It pulls in the two modules like this:
var V1Meta = require('./v1meta').V1Meta;
var V1Server = require('./client').V1Server;
var hostname = "www14.v1host.com";
var instance = "v1sdktesting";
var username = "api";
var password = "api";
var port = "443";
var protocol = "https";
var server = new V1Server(hostname, instance, username, password, port, protocol);
var v1 = new V1Meta(server);
v1.query({
from: "Member",
where: {
IsSelf: 'true'
},
select: ['Email', 'Username', 'ID'],
success: function(result) {
console.log(result.Email);
console.log(result.Username);
console.log(result.ID);
},
error: function(err) { // NOTE: this is not working correctly yet, not called...
console.log(err);
}
});
You might have to get the latest and build the JS from CoffeeScript.
I think I was trying out "browserify" last year and that's how the "v1sdk.js" file got generated. But I'm not sure if that's the best approach if you're using node. It's probably better just to do it the way the sample.js file is doing it.
However, I did also check in a change to v1sdk.coffee which property exports the two other modules, just as a convenience. With that, you can look at sample2.js. The only different part there is this, which is more like you were trying to do with your example:
var v1sdk = require('./v1sdk');
var hostname = "www14.v1host.com";
var instance = "v1sdktesting";
var username = "api";
var password = "api";
var port = "443";
var protocol = "https";
var server = new v1sdk.V1Server(hostname, instance, username, password, port, protocol);
var v1 = new v1sdk.V1Meta(server);

How do I change the flashvars using the ContentScript of a Chrome Extension?

I want to create a chrome extension to help me debug my swf, and I'd like the extension to be able to change some of the flashvars while keeping others untouched.
I can't imagine this is a new or unique problem, so before I reinvent the wheel, I'm asking if anyone here has examples of it being done, or how to do it.
I've tried searching, but my googlefu seems to be off.
My use case is as follows. I have a Google Chrome extension which has a few drop down menus with possible flash var values. I want the change the values in the drop down, and then reload the swf with these new flashvars, but without changing flashvars which are not in my drop down menus.
I'm able to easily inject a new swf on the page with the values from my dropdown menus, however I'd like to be able to reload, rather than recreate, the swf.
I have tried using Jquery to pull all the flash vars like this:
var flashVars = $("param[name=flashvars]", gameSwfContainer).val();
However, I'm having a hard time changing or replacing just a couple of the values, and then injecting them back into the object. (Regex might be helpful here unless there is a better way?)
Thanks for your help.
Currently, I am trying to do the following, but I'm not sure if it's the right direction.
ContentScript.js
//Setup
var swfVersionStr = "10.1.0";
var xiSwfUrlStr = "playerProductInstall.swf";
var params = {};
params.quality = "high";
params.bgcolor = "#000000";
params.allowscriptaccess = "always";
params.allowfullscreen = "true";
var attributes = {};
attributes.id = "game_swf_con";
attributes.name = "game_swf_con";
attributes.class = "game_swf_con";
attributes.align = "middle";
var InjectedFlashvars = {
"run_locally": "true",
//.. some other flash vars that I won't be changing with my extension
"swf_object_name":"game_swf"
};
// Injection code called when correct page and div detected;
var injectScriptText = function(text)
{
loopThroughLocalStorage();
swfobject.embedSWF(
swfName, "game_swf_con",
"760", "625",
swfVersionStr, xiSwfUrlStr,
InjectedFlashvars, params, attributes);
swfobject.createCSS("#game_swf_con", "display:block;text-align:left;");
};
function loopThroughLocalStorage()
{
for(key in localStorage){
try{
var optionArray = JSON.parse(localStorage[key]);
var option = returnSelectedFlashVar(optionArray);
var value = option.value ? option.value : "";
InjectedFlashvars[key] = value;
} catch(err){}
}
}
function returnSelectedFlashVar(optionArray){
for(var i= 0; i < optionArray.length;i++)
{
if(optionArray[i].selected == true)
{
return optionArray[i];
}
}
}
Overall, I currently have contentscript.js, background.js, options.js, options.html, popup.html and popup.js The code above so far only exists in contentscript.js
Had a little trouble deciding what you actually wanted.
But if its manipulating the values in the flashvar maybe this will help...
queryToObject = function(queryString) {
var jsonObj = {};
var e, a = /\+/g,
r = /([^&=]+)=?([^&]*)/g,
d = function(s) {
return decodeURIComponent(s.replace(a, " "));
};
while(e = r.exec(queryString)) {
jsonObj[d(e[1])] = d(e[2]);
}
return jsonObj;
}
objectToQuery = function(object) {
var keys = Object.keys(object),
key;
var value, query = '';
for(var i = 0; i < keys.length; i++) {
key = keys[i];
value = object[key];
query += (query.length > 0 ? '&' : '') + key + '=' + encodeURIComponent(value);
}
return query;
}
// this is what a flashvar value looks like according to this page...http://www.mediacollege.com/adobe/flash/actionscript/flashvars.html
var testQuery = 'myvar1=value1&myvar2=value2&myvar3=a+space';
var testObject = queryToObject(testQuery);
console.debug(testObject);
testQuery = objectToQuery(testObject);
console.debug(testQuery);
testObject.myvar0 = 'bleh';
delete testObject.myvar2;
console.debug(objectToQuery(testObject));
And if your using localStorage in a content script then be aware that the storage will be held in the context of the page.
Try looking at chrome.storage instead.
EDIT : Answer to comments
This looks correct, but how do I "reload" the object so that those new flashvars are the ones that are used by the swf?
Ive never used swfObject (havent done any flash stuff in like 5 years) but had a look and it looks like you can just rerun the swfobject.embedSWF with the new flashVars and it will replace the old object with the new one. Which is fine if your replacing one that you added yourself as you can supply all of the details, if your replacing something put there by someone else you could clone the object, change some stuff and replace the original with the clone. Cloning will not clone any events attached to the element but I dont think thats a problem in your case. Here's an example (which I couldnt test as I couldnt find any simple sample swf that just prints the flashvars)....
var target = document.querySelector('#game_swf_con');
// Cloning the element will not clone any event listners attached to this element, but I dont think that's a prob for you
var clone = target.cloneNode(true);
var flashvarsAttribute = clone.querySelector('param[name=FlashVars]');
if (flashvarsAttribute) {
var flashvars = flashvarsAttribute.value;
flashvars = queryToObject(flashvars);
// add a new value
flashvars.newValue = "something";
// update the clone with the new FlashVars
flashvarsAttribute.value = objectToQuery(flashvars);
// replace the original object with the clone
target.parentNode.replaceChild(clone, target);
}​
Sources:
a) Content Scripts
b) Background Pages
c) Message Passing
d) tabs
e) Browser Action
f) API()'s
Assuming a html page containing following code
<embed src="uploadify.swf" quality="high" bgcolor="#ffffff" width="550"
height="400" name="myFlashMovie" FlashVars="myVariable=Hello%20World&mySecondVariable=Goodbye"
align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflash" />
I try to get following get height of embed object and change it.
Sample Demonstration
manifest.json
{
"name":"Flash Vars",
"description":"This demonstrates Flash Vars",
"manifest_version":2,
"version":"1",
"permissions":["<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["myscript.js"]
}
]
}
myscript.js
// Fetches Current Width
width = document.querySelector("embed[flashvars]:not([flashvars=''])").width;
console.log("Width is " + width);
// Passing width to background.js
chrome.extension.sendMessage(width);
//Performing some trivial calcualtions
width = width + 10;
//Modifying parameters
document.querySelector("embed[flashvars]:not([flashvars=''])").width = width;
background.js
//Event Handler for catching messages from content script(s)
chrome.extension.onMessage.addListener(
function (message, sender, sendResponse) {
console.log("Width recieved is " + message);
});
Let me know if you need more information.

Accessing variable outside on load function

Hi I am working Android application development using titanium studio.I have developed small application.my problem is that I can not access variable which is define inside the xhr.on load.I used following code:
xhr.onload = function()
{
var json = this.responseText;
var to_array = JSON.parse(json);
var to_count = to_array.length;
};
I want to access to_count and to_array outside onload function and pass it to another child window.For that I used following code:
var feedWin = Titanium.UI.createWindow({
url:'home/feed.js'
});//alert(to_count);
feedwin.to_array = to_array;
feedwin.to_count = to_count;
The XHR client is asychronous by default, which means that code will continue to execute while the XHR is running. If you have code that is dependent on your XHR being finished, then you will need to either call that code from within the onload function, or force the XHR to be synchronous by adding "false" as a third parameter to xhr.send() (I've found the first option to be the more reliable one, and more in line with what Titanium expects/feels is best practice, just FYI).
The best way to accomplish this is to initialize your feedWin in the onload. So, one of the following two snippets should work:
xhr.onload = function()
{
var json = this.responseText,
feedWin = Titanium.UI.createWindow({
url:'home/feed.js'
});//alert(to_count);
feedWin.to_array = JSON.parse(json);
feedWinto_count = to_array.length;
};
or
var feedWin = Titanium.UI.createWindow({
url:'home/feed.js'
});
xhr.onload = function()
{
var json = this.responseText,
feedWin.to_array = JSON.parse(json);
feedWinto_count = to_array.length;
};
I'm not familiar with Titanium, so I don't know particulars, but that is my best guess.
I am not very familiar with Titanium, but wrt to scope of declaration, I think this is what you need to do to use them outside the function.
var to_array;
var to_count;
xhr.onload = function()
{
var json = this.responseText;
to_array = JSON.parse(json);
to_count = to_array.length;
};

Categories

Resources