Javascript callback function with one parameter - ajax

I'm trying to get the result of a function (ajaxGetPreference, that contain an ajax call), my code:
highlight_pref = 0;
highlight_pref = ajaxGetPreference('highlight');
console.log(highlight_pref);`
I'm getting always 0. Should I do something like this (see below)? I saw ither similar question, I don't know how to do with the parameter 'highlight'
ajaxGetPreference(function() {
console.log(highlight_pref);
});
Thanks for helping!

Related

CaspserJS assertEval with variables

I'd like to use CasperJS to evaluate a variable equals a certain value.
I simplified my exemple as much as I could that way:
var testDate = "24/03/14";
casper.test.begin('TEST', 1, function suite(test) {
casper.start('http://www.google.com/', function() {
this.test.assertEval(function() {
return testDate == "24/03/14";
}, "testDate is 24/03/14" );
});
casper.run(function() {
this.test.done();
});
});
I don't know why it fails, here is what I get in my console:
Test file: tests.js
#TEST
FAIL testDate is 24/03/14
# type: assertEval
# file: tests.js:7
# code: }, "testDate is 24/03/14" );
# subject: null
# fn: undefined
# params: undefined
FAIL 1 test executed in 2.896s, 0 passed, 1 failed, 0 dubious, 0 skipped.
Details for the 1 failed test:
In tests.js:7
TEST
assertEval: testDate is 24/03/14
Any idea ?
UPDATE
I realised my simplified example was faulty, it didn't represent what I really needed.
Actually, what I want to achieve is to test if a variable from the current page DOM context equals a local variable.
As per manual Asserteval:
Asserts that a code evaluation in remote DOM strictly resolves to a boolean true:
your testdate variable is local to the casperjs script and is not accessible in the remote dom. You would have to inject it to the window like described here.
Ok found the answer myself.
To test if a variable from the current page DOM context equals a local variable, I realised I could use a simple assertEvalEquals():
test.assertEvalEquals(function() {
return variableFromPageDomContext;
}, localVariable);
Likewise, when testing if a variable from the current page DOM context matches a RegExp pattern, we have to use evaluate() to get the variable from the DOM as the first parameter of an assertMatch():
test.assertMatch(this.evaluate(function() {
return variableFromPageDomContext;
}), RegExpPattern);
Hope that can help.
As #Surreal answers its possible to use the assertEvalEquals() passing the function and the expected value.
However the original question wants to pass a variable from casperjs context to assertEval() function, you can simply do it as follows, passing to assertEval() three arguments: the function which receive the value, a message for the assert and the value:
var varPassToEval = 'someValue';
test.assertEval(
function(varFromCasperContext){
return varFromPageDomContext === varFromCasperContext;
},
'Assert Eval to test',
varPassToEval
);
With the above example probably is clear to use assertEvalEquals() however could be useful for more complex cases, for example imagine that you want to check if a text appears in a some <li> inside <ul> in DOM which it's dynamic and can change but you don't know at first where your text is... for this case you can use:
var somePartOfText = 'blue';
test.assertEval(
function(varFromCasperContext){
return document.getElementsByTagName("ul")[0].textContent.indexOf(varFromCasperContext) != -1;
},
'Assert Eval to test',
somePartOfText
);
Hope it helps,

Need assistance with unfamiliar syntax, error - e is undefined - Google Apps Script(GAS)

I'm using a script exactly like the one on the tutorial here, https://developers.google.com/apps-script/reference/ui/file-upload
However, despite using the syntax I keep getting e is undefined in the statement:
var fileBlob = e.parameter.dsrFile;
I think that means my function doPost(e) is probably wrong somehow. Here is my entire script below.
// Create Menu to Locate .CSV
function doGet(e) {
var app = UiApp.createApplication().setTitle("Upload CSV");
var formContent = app.createVerticalPanel();
formContent.add(app.createFileUpload().setName("dsrFile"));
formContent.add(app.createSubmitButton("Start Upload"));
var form = app.createFormPanel();
form.add(formContent);
app.add(form);
return app;
}
// Upload .CSV file
function doPost(e)
{
// data returned is a blob for FileUpload widget
var fileBlob = e.parameter.dsrFile;
var doc = DocsList.createFile(fileBlob);
}
e is undefined because you are not passing anything to doPost. You have to pass the needed object to doPost. Check where you call the function and what parameters do you pass to it if any. Even if you pass a parameter to that function, it holds undefined value. Make sure that you are passing the correct objects to your functions.
Your script should work perfectly. e is defined by Google Apps Script, not need to pass anything in particular is contains the fields of your form, in particular in this case the file you uploaded.
I would suspect you may be falling foul to the dev url vs publish url syndrome, where you are executing an old scrip rather that the code you are currently working on.
Be sure you script end with 'dev' and not 'exec'
https://script.google.com/a/macros/appsscripttesting.com/s/AKfyck...EY7qzA7m6hFCnyKqg/dev
Let me know if you are still getting the error after running it from the /dev url

Code Igniter Passing Variable to Controller Using URL Error

I am creatting a Code Igniter project in which I want to pass a variable through the URL like a get statement, like this:
url: /site/cake/1
controller function: cake($var)
but when the variable is left blank, I receive an error, how can I get code igniter, to ignore this?
In your controller, do this:
function cake($var = null) {
// your other code here
}
When $var isn't present in the URL, it will be set to null and you'll receive no error.
To explain why Colin's answer works:
The issue you had, was that there was no default value for that controller function. In php, creating a default value for a function parameter is done by assigning it a value in the function definition ($var = false). Now when the cake() function is called with no parameter, it will set $var to false by default.

Extract part of HTML document in jQuery

I want to make an AJAX call to an HTML-returning page, extract part of the HTML (using jQuery selectors), and then use that part in my jQuery-based JavaScript.
The AJAX retrieval is pretty simple. This gives me the entire HTML document in the "data" parameter of the callback function.
What I don't understand is how to handle that data in a useful way. I'd like to wrap it in a new jQuery object and then use a selector (via find() I believe) to get just the part I want. Once I have that I'll be passing it off to another JavaScript object for insertion into my document. (This delegation is why I'm not using jQuery.load() in the first place).
The get() examples I see all seem to be variations on this:
$('.result').html(data);
...which, if I understand it correctly, inserts the entire returned document into the selected element. Not only is that suspicious (doesn't this insert the <head> etc?) but it's too coarse for what I want.
Suggestions on alternate ways to do this are most welcome.
You can use your standard selector syntax, and pass in the data as the context for the selector. The second parameter, data in this case, is our context.
$.post("getstuff.php", function(data){
var mainDiv = $("#mainDiv", data); // finds <div id='mainDiv'>...</div>
}, "html");
This is equivalent to doing:
$(data).find("#mainDiv");
Depending on how you're planning on using this, $.load() may be a better route to take, as it allows both a URL and a selector to filter the resulting data, which is passed directly into the element the method was called on:
$("#mylocaldiv").load("getstuff.php #mainDiv");
This would load the contents of <div id='mainDiv'>...</div> in getstuff.php into our local page element <div id='mylocaldiv'>...</div>.
You could create a div and then put the HTML in that, like this…
var div = $("<div>").html(data);
...and then filter the data like this…
var content = $("#content", div.get(0));
…and then use that.
This may look dangerous as you're creating an element and putting arbitrary HTML into it, but it's not: anything dangerous (like a script tag) will only be executed when it's inserted into the document. Here, we insert the data into an element, but that element is never put into the document; only if we insert content into the document would anything be inserted, and even then, only anything in content would be inserted.
You can use load on a new element, and pass that to a function:
function handle(element){
$(element).appendTo('body');
}
$(function(){
var div = $('<div/>');
div.load('/help a', function(){handle(div);});
});
Example: http://jsbin.com/ubeyu/2
You may want to look at the dataFilter() parameter of the $.ajax method. It lets you do operations on the results before they are passed out.
jQuery.ajax
You can do the thing this way
$.get(
url,
{
data : data
},
function (response) {
var page_content = $('.page-content',response).get(0);
console.log(page_content);
}
)
Here in the console.log you will see the inner HTML of the expected/desired portion from the response. Then you can use it as your wish

setAttribute, onClick and cross browser compatibility

I have read a number of posts about this but none with any solid answer. Here is my code:
// button creation
onew = document.createElement('input');
onew.setAttribute("type", "button");
onew.setAttribute("value", "hosts");
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie
onew.setAttribute("onclick", "fnDisplay_Computers('" + alines[i] + "')"); // mozilla
odiv.appendChild(onew);
Now, the setAttribute() method (with the mozilla comment) works fine in mozilla but only if it comes AFTER the line above it. So in other words it seems to just default to whichever gets set last. The .onclick method (with the ie comment) does not work in either case, am I using it incorrectly?
Either way I can't find a way to make this work at all in IE, let alone in both. I did change the function call when using the .onclick method and it worked fine using just a simple call to an alert function which is why I believe my syntax is incorrect.
Long story short, I can't get the onclick parameter to work consistently between IE/Mozilla.
-- Nicholas
onew.setAttribute("type", "button");
Never use setAttribute on HTML documents. IE gets it badly wrong in many cases, and the DOM-HTML properties are shorter, faster and easier to read:
onew.type= 'button';
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie
What is ‘alines’? Why are you converting it to a string and surrounding it with single quotes? It looks like you are trying to do something heinous involving evaluating code in a string (which is what you're doing below in the ‘onew.setAttribute’ version). Evaluating JavaScript code in strings is almost always the Wrong Thing; avoid it like the plague. In the above case, IE should do the same as Firefox: it shouldn't work.
If ‘alines[i]’ is a string, I guess what you're trying to do is make it remember that string by constructing a code string that will evaluate in JavaScript to the original string. But:
"'" + alines[i] + "'"
is insufficient. What happens if ‘alines[i]’ has an apostrophe in, or a backslash?
'O'Reilly'
you've got a syntax error and possible security hole. Now, you could do something laborious and annoying like:
"'" + alines[i].split('\\').join('\\\\').split("'").join("\\'") + "'"
to try to escape the string, but it's ugly and won't work for other datatypes. You could even ask JavaScript to do it for you:
uneval(alines[i])
But not all objects can even be converted to evaluatable JavaScript source strings; basically the entire approach is doomed to failure.
The normal thing to do if you just want to have the onclick callback call a function with a parameter is to write the code in the straightforward way:
onew.onclick= function() {
fnDisplay_Computers(alines[i]);
};
Generally this will work and is what you want. There is, however, a slight wrinkle which you may have hit here, which could be what is confusing you into considering the wacky approach with the strings.
Namely, if ‘i’ in this case is the variable of an enclosing ‘for’ loop, the reference to ‘alines[i]’ won't do what you think it does. The ‘i’ will be accessed by the callback function when the click happens — which is after the loop has finished. At this point the ‘i’ variable will be left with whatever value it had at the end of the loop, so ‘alines[i]’ will always be the last element of ‘alines’, regardless of which ‘onew’ was clicked.
(See eg. How to fix closure problem in ActionScript 3 (AS3) for some discussion of this. It's one of the biggest causes of confusion with closures in both JavaScript and Python, and should really be fixed at a language level some day.)
You can get around the loop problem by encapsulating the closure in its own function, like this:
function callbackWithArgs(f, args) {
return function() { f.apply(window, args); }
}
// ...
onew.onclick= callbackWithArgs(fnDisplay_Computers, [alines[i]]);
And in a later version of JavaScript, you'll be able to say simply:
onew.onclick= fnDisplay_Computers.bind(window, alines[i]);
If you would like to be able to use ‘Function.bind()’ in browsers today, you can get an implementation from the Prototype framework, or just use:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
I usually use something like:
onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')");
this should work both in IE e Firefox.
Use the addEventListener() function with "click" for the type argument for Mozilla-based browsers, and attachEvent() function with "onclick" as the sEvent argument for IE; I find it best to use a try/catch statement, for example:
try {
onew.attachEvent("onclick", //For IE
function(){fnDisplay_Computers("'" + alines[i] + "'"); });
}
catch(e) {
onew.addEventListener("click", //For Mozilla-based browsers
function(){fnDisplay_Computers("'" + alines[i] + "'"); },
false);
}
I think #3 protesteth too much. In a lot of situations I'm building a table dynamically and need to pass parameters to the callback function. It isn't a typesafe issue since my variable parm is an integer index to the table row in question. Here's code with both a variable and fixed parameter that seems to be cross-browser compliant:
for (i = 0; i < arrTableData.length; i++) {
eleTR = objTable.insertRow(i + 1);
cell = eleTR.insertCell(0);
cell.width = "21";
var myElement = document.createElement('img');
myElement.setAttribute('src', 'images/button_down.gif');
myElement.setAttribute('alt', 'Move item down');
myElement.onclick = new Function('moveItem(' + i + ',0)');
cell.appendChild(myElement);
}

Resources