i got a got a little embedded system that can be controlled via a webinterface.
the page looks like:
...
foo
...
is there a way to call this function just by http? like
http://<the-devices-ip>:80/javascipt:foo(bar) //wrong
thank you
You can do so by passing a querystring or a hash into the URL and execute a piece of JS which checks it during onload.
var query = window.location.search; // Gets '?foo=bar' from http://example.com/page.html?foo=bar
var hash = window.location.hash; // Gets '#foo' from http://example.com/page.html#foo
You only have to parse it further yourself or by using a 3rd party JS framework with plugin capabilities, like jQuery.
page1.html:
foo
page2.html:
<script type="text/javascript">
if(window.location.hash)
eval(window.location.hash)
</script>
I'm not saying it's a good idea. It might be helpful to document why you think you need to do this, there are probably better ways to accomplish whatever the actual goal is.
Note that doing this will not allow you to pass variables around. You need to have only static values in the javascript code executed on page2.html, or generate the href in page1.html dynamically.
Caveat: this will potentially open up your code to HTML and/or script injections. Filter rigorously.
I recently had to do something similar for a project that I was contracted out on. Like others, I used the hash portion of the URL to pass in JavaScript functions and parameters. However, the main difference was that I didn't do a simple eval of the entire string. I established a specific format to 1) narrow the amount of functions that could be executed, and 2) sanitize any input that the method required
The format, in full, is as follows:
http://somedomain.tld/path/?query=blah#specific.controller.object/method/['array', 'of', {json: 'arguments'}]
So, basically, you end up with the following string:
specific.controller.object/method/['array', 'of', {json: 'arguments'}]
I then wrote a parser to handle this string. Restrictions where exacted over what objects could be called by prepending with a sort of "namespace" object, in other words, calling it as part of a member of an existing, predetermined static object. For example, specific.controller.object, would be called as new com.project.specific.controller.object();. Here's something similar to my parser:
var data = location.hash.substr(1).split('/'),
controller = ("my.namespace." + data[0]).split("."),
// You can provide a default method if you want, my framework used `show`
method = data[1] || "show",
// must be an array for use with `apply`
params = data[2] || "[]";
// Parse the controller to find the appropriate object to instantiate.
// All objects are in reference to the global window object. Break
// them apart by their dot composition and step down through the object
// tree starting at window.
var composition = window;
for ( var i=0; i<controller.length; i++ ) {
composition = composition[ controller[i] ];
}
var obj = new composition;
// Handle the parameters. It may be the case that there "/" is present
// in the last argument. If so, add anything that was left out.
if ( data.length > 3 ) {
for ( var i=3; i<data.length; i++ ) {
params += '/' + data[i];
}
}
// Convert params from a string to an array.
// ***Possible injection point here***
params = dojo.fromJson(params);
// Make sure that the method runs in the proper context and
// pass it all of the parameters
obj[method].apply(obj, params);
Because the way the parser works, you required to provide parameters if none are needed, and in some cases, if you choose to allow default methods as I have, you don't have to specify which member on the object to call, which simplifies that construction of these URL's greatly.
Instead of using a static namespace object to restrict what objects could be instantiated, it would be trivial to use a white list of safe objects and methods.
foo represents the calling of a function, not the call to a url. There is no direct mapping between a url and a JavaScript function.
Related
In an application I am working on I need to get a list of the names of all applicationScope variable then I need to cycle through them and filter out the ones starting with a know string say $xyx. I thought that the applicationScope.keySet().
I'm using this code for starter:
var col = applicationScope.keySet();
var itr:java.util.Iterator = col.iterator();
if (itr.hasNext()){
var str:String = itr.next();
dBar.info(str,"Value = ");
}
if I put the variable col in a viewScope it shows a list of all the keys. but when I run the script the values displayed in the dBar info are not the keys but some other information that I'm not sure where it comes from.
I should just be able to iterat through the list of keys, am I missing something?
This code is in the before page loads event
After some poking around and experimenting I got this to work:
var col = applicationScope.keySet();
var itr:java.util.Iterator = col.iterator();
while (itr.hasNext()){
var str:Map.Entry = itr.next();
if (str.substring(0,9) == "$wfsLock_"){
//do stuff
}
}
so I'm now a happy camper.
Although your code works in SSJS, it is not correct (and that's why I don't like SSJS...).
The applicationScope is an implementation of the java.util.Map interface and the keySet() method returns a Set containing the keys in that Map. Every entry is (probably) a String (other data types like integers are actually also valid). The line
var str:Map.Entry = itr.next();
doesn't cast it to a Map.Entry: it doesn't really do anything: str remains a string.
The Map interface also has an entrySet() method that returns the entries (Map.Entry). You can use that to retrieve the key as well as the value:
var it = applicationScope.entrySet().iterator();
while (it.hasNext()) {
var entry = it.next();
print( entry.getKey() + " = " + entry.getValue() );
}
(in this code the print() line will use the toString() method of the key as well as the value to send information to the console)
I see from your code that you've installed my XPages Debug Toolbar. You can also use that to quickly check what's in the scopes and what the actual datatype is.
I have a JSON string which includes a function I need to call.
My JSON looks like this:
{
"type":"listview",
// the function I would like to call
"content":"dynoData.getRetailers()",
"custom_classes":["","nMT pickList","",""],
"lib":"static_listview.html",
"tmp":"tmp_listview_inset",
"lang":"locale_search",
...
I'm using this to assemble a jQuery Mobile listview on the client. To get the dynamic data, I need to call dynoData.getRetailers().
However I'm struggling to make the call :-)
This is what I'm trying:
var dyn = $.parseJSON( passed_JSON_string ),
content = dyn.content;
I had hoped calling it would trigger the function but it just returns the function name as a string.
Question:
How can trigger the actual function?
Thanks!
EDIT:
I'm putting the JSON string on the HTML element on the actual page, which I will replace with the element I'm building. Here is the HTML:
<ul data-template="true" data-config='{
"type":"listview",
"content":"dynoData.getRetailers()",
"custom_classes":["","nMT pickList","",""],
"lib":"static_listview.html",
"tmp":"tmp_listview_inset",
"lang":"locale_search",
"theme":"c",
"filter":"true"
}'></ul>
I could put all of these into data- attributes, but that would be messy...
Solution:
This worked:
1) change JSON to:
..."method":"getRetailers", ...
2) call from Javascript:
content = dynoData[ dyn.method ]();
Thanks everyone!
Assuming the function is always part of the dyn object you can use notation like following to call a function:
dyn['dynoData']['getRetailers']();
So if you are able to adjust json you could send back something like:
"content":{ "mainObject": "dynoData" , "method" :"getRetailers"}
And translate it to your dynamic function using variables:
dyn[content.mainObject][content.method]();
As an example using jQuery try using the following :
$('div')['hide']();
Which is the same as :
$('div').hide()
As charlietfl pointed out you can use object notation to call functions. For your case you have to get rid off () and split it, then call it like this;
jQuery(function($) {
var temp = $('ul').data('config').content.replace(/\(\)/g, '').split('.');
window[temp[0]][temp[1]]();
});
However this could solve your problem, if you think about future, you have to extend it a little bit. This way even you don't know the depth, you can call it anyway;
jQuery(function($) {
var temp = $('ul').data('config').content.replace(/\(\)/g, '').split('.'), func, i, il = temp.length;
for(i = 0; i < il; i++) {
if(func == null) {
func = window[temp[i]];
continue;
}
func = func[temp[i]];
}
func();
});
Try ConversationJS. It makes dynamic calls pretty easy and its a great way to decouple your codebase: https://github.com/rhyneandrew/Conversation.JS
JSON is purely data notation to be passed around so it is easily read and parsed, therefore it has no concept of functions. However, there are other ways of dealing with this and if you are starting to think that that is the only way to deal with your dilemma, then take a step back and examine your design. Instead of using this:
eval(yourCode);
Try this
var tempFun = new Function(yourCode);
tempFun();
I have an Object and I'm trying to use jquery to quickly change the parameter values, but the parameters keep coming back null. code brings back the list of parameters but I can't seem to change anything. Even if I put it at it's base of parameters to change everything - it still comes back as null.
Other than that it works, but if u look closely you will see some api error messages in black at the top left. I added a pastebin so you can see what I'm doing.
http://jsfiddle.net/f4qMe/
and below is the javascript I'm running to try and change the objects parameters. The object is called (id) twitchTV.
function test(){
var data = "http://www.twitch.tv/widgets/live_embed_player.swf?channel=day9tv";
var src = "hostname=www.twitch.tv&auto_play=true&start_volume=25&channel=day9tv";
var code = $("#twitchTV").html();
var newcode = $("param", code).attr("value", src).html();
$("#twitchTV").html(newcode);
$("#twitchTV").attr("data", data);
}
Your problem is probably here:
var code = $("#twitchTV").html();
var newcode = $("param", code).attr("value", src).html();
html() returns a string so code is a string and you're using it as context in newcode which expects an DOM element or jquery object instead.
I am customizing Denis Gritcyuk's Popup date picker.
This pop-up script uses inline Javascript in a href link, to set the selected date into the input field, in the parent window, that is was called for. An example URL looks like:
<a href="javascript:window.opener.document.formname.field.value='03-10-2011';
window.close();">3</a>
The input field name, (e.g. document.formname.field), is passed to the script as a string parameter.
I would like to add things done when that link is clicked (e.g. change background color of field, set flag, etc.). So while this DOES work, it's getting ugly fast.
<a href="javascript:window.opener.document.formname.field.value='03-10-2011';
window.opener.document.formname.field.style.backgroundColor='#FFB6C1';
window.close();">3</a>
How would I move these inline commands into a JS function? This would give me much cleaner URLs and code. The URL would now look something like
3
with a function like (this example obviously does NOT work):
function updateField (str_target, str_datetime) {
var fieldName = "window.opener" + str_target;
[fieldName].value = str_datetime;
[fieldName].style.backgroundColor = '#FFB6C1';
// Set flag, etc.
window.close();
}
So any suggestions on how this can be done, please?
I'd prefer to hide the dom path tracing back from the current window back to the opener. It's appropriate to bake that into the function since the function will always be used in the context of that child popup. Then your function call is cleaner and more readable. Obviously, replace "myField" with the ID of the field you're intending to update.
3
function updateField ( str_date, str_fieldname ) {
var fieldToUpdate = document.getElementById( str_fieldname );
fieldToUpdate.value = str_date;
fieldToUpdate.style.backgroundColor = '#FFB6C1';
// Set flag, etc.
window.close();
}
You're acessing the property incorrectly. Try:
function updateField (str_target, str_datetime) {
var fieldName = window.opener;
str_target = str_target.split('.');
for (var i = 0; i < str_target.length; i++)
fieldName = fieldName[str_target[i]];
fieldName.value = str_datetime;
fieldName.style.backgroundColor = '#FFB6C1';
// Set flag, etc.
window.close();
}
The bracket notation ([]) is only used for properties of objects, not objects themselves. If you found my post helpful, please vote for it.
You can build a string and evaluate it as code using the eval function, but I would recommend against it.
There are a couple of things wrong with your code:
You cannot use the [] operator in a global context, you have to suffix it on an object, so you can say window["opener"] and this will be equivalent to window.opener, but there is no such thing as simply ["window"]
When navigating nested properties, as in window.opener.document you cannot navigate multiple levels using the [] operator. I.e. window["opener.document"] is not allowed. You must use window["opener"]["document"] instead.
i want to get hash parameters value in my java script
for example my url should be like that
www.example.com/#!mydata=data&myopt=option
i want to get mydata in variable which will be "data" as value,
and myopt "option"
iam trying to implement google ajax cowling like here
Google Code
and i have tried to implement jquery address
but with big fail so help me either by solving 1st part or give me simple walk through tutorial to implement jquery address to my ajax requests ,thank you
This piece of code will convert any well formed (i.e. properly url-encoded) request string into an object literal with values parsed.
var s = "#!mydata=data&myopt=option";
var o = {};
$.each(s.substr(2).split('&'), function(i, elem) {
var parts = elem.split('=');
o[parts[0]] = parts[1];
});
Then you can access values like o.myopt
UPDATE
Of course, to get the value from browser's address, you should use
var s = window.location.hash;