I have trouble calling callback function in popup window in IE9 - javascript

I have this code, that doesn't work in IE 9.
var popup = window.open(url, 'categories','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,copyhistory=no,width=400,height=450,screenX=150,screenY=150,top=150,left=150');
popup.onDone = function(){
var selected = popup.getSelectedIds();
var allready = [];
$("#tab-categories tr input:hidden").each(function(){
if ($.inArray(this.value, selected) != -1) {
allready[allready.length] = this.value;
} else {
$(this).parent().parent().remove();
}
});
for (var i=0, len = selected.length; i<len; i++) {
if ($.inArray(selected[i], allready) != -1) continue;
addCategory(popup.getItemInfo(selected[i]));
}
updateCategoriesCounter();
updateCategoriesMainFlag();
};
Exactly function onDone using as callback function in popup and calls like this:
$("#done").click(function(){
if (window.onDone) window.onDone();
window.close();
return false;
});
but in IE 9 this function looks like undefined.

Related

Make javascript open on page load instead of on link click

I have a script that opens a popunder when any link is clicked. How can I change this to open the popunder when the page loads. Below is the script.
window.onload = function() {
var puURL = 'http://www.example.com';
var puTS = Math.round(+new Date()/1000);
console.log('T.'+localStorage.puTS+'/'+puTS);
if (typeof localStorage.puTS == 'undefined' || parseInt(localStorage.puTS) <= (puTS - 180)) {
var links = document.getElementsByTagName('a');
for(var i = 0, len = links.length; i < len; i++) {
links[i].onclick = function (e) {
var puHref = this.getAttribute("href");
var puTarget = this.getAttribute("target");
if (puHref !== '#' && puHref !== 'javascript:void(0)') {
e.preventDefault();
if (puTarget == '_blank') {
window.open(window.location.href);
}
window.open(puHref);
window.location.href = puURL;
localStorage.puTS = puTS;
}
}
}
}
};
Well, currently you're adding click handlers for all the target elements:
for(var i = 0, len = links.length; i < len; i++) {
links[i].onclick = function (e) { // <--- here
var puHref = this.getAttribute("href");
var puTarget = this.getAttribute("target");
if (puHref !== '#' && puHref !== 'javascript:void(0)') {
e.preventDefault();
if (puTarget == '_blank') {
window.open(window.location.href);
}
window.open(puHref);
window.location.href = puURL;
localStorage.puTS = puTS;
}
}
}
If you don't want to add click handlers but just want to invoke the logic within them right away, just put that logic in the loop without the click handler:
for(var i = 0, len = links.length; i < len; i++) {
var puHref = this.getAttribute("href");
var puTarget = this.getAttribute("target");
if (puHref !== '#' && puHref !== 'javascript:void(0)') {
if (puTarget == '_blank') {
window.open(window.location.href);
}
window.open(puHref);
window.location.href = puURL;
localStorage.puTS = puTS;
}
}
Of course, if this logic includes opening a new page or redirecting the user then that's going to happen immediately upon page load...

Set value of textfield with javascript

I am creating a Safari extension that autofill the email.
I managed to get this working but on some sites, the textfield appears to be filled in by the value, but when the website tries to get that value, it gets nothing.
For clarification, my code works on e.g. Facebook, Github, Stackoverflow,.. . But it doesn't work on e.g. developer.apple.com, www.back4app.com, Microsoft,.. .
I've tried to see what the autofill of keychain in safari does, and this shows met the the email actually get's filled in in the HTML tag. This doesn't happen with my code. But the email is always filled in in the textfield that you see on the webpage.
function handleMessage(event) {
var arguments = event.message;
var emailStr = arguments["Email"];
var nameInputs = document.getElementsByTagName('input');
for (var i = 0; i < nameInputs.length; i++) {
var theFieldName = nameInputs[i].name.toLowerCase();
var theFieldType = nameInputs[i].type.toLowerCase();
if (theFieldName.indexOf("email") !== -1) {
if (!(emailStr === undefined)) {
nameInputs[i].value = emailStr;
filledInEmail = 1;
}
}
else if (theFieldType.indexOf("email") !== -1) {
if (!(emailStr === undefined)) {
nameInputs[i].value = emailStr;
filledInEmail = 1;
}
}
}
}
I'm guessing those sites are listening to the input change event. Try this:
function handleMessage(event) {
var arguments = event.message;
var emailStr = arguments["Email"];
var nameInputs = document.getElementsByTagName('input');
for (var i = 0; i < nameInputs.length; i++) {
var theFieldName = nameInputs[i].name.toLowerCase();
var theFieldType = nameInputs[i].type.toLowerCase();
if (theFieldName.indexOf("email") !== -1) {
if (!(emailStr === undefined)) {
nameInputs[i].value = emailStr;
nameInputs[i].dispatchEvent(new Event('change'));//trigger change event
filledInEmail = 1;
}
}
else if (theFieldType.indexOf("email") !== -1) {
if (!(emailStr === undefined)) {
nameInputs[i].value = emailStr;
nameInputs[i].dispatchEvent(new Event('change'));//trigger change event
filledInEmail = 1;
}
}
}
}

getAttribute() Error

I am getting an error in firefox about getAttribute not being a function. Below is my code with the error line marked.
var nodeList = document.getElementsByTagName("input");
for(item in nodeList){
try{
if(nodeList[item].getAttribute("type") == "file"){
//ERROR HERE///->var id = nodeList[item].getAttribute("id");
var fileSelector = document.getElementById(id);
document.getElementById(id).addEventListener("change",function(e){
if(e){
e.preventDefault();
}
if (fileSelector.files) {
window.file = fileSelector.files[0];
} else {
window.file = fileSelector.value;
}
readData();
});
}
}catch(e){}
}
Try like this :
var nodeList = document.getElementsByTagName("input");
var max = nodeList.length;
for(var i=0; i<max ; i++){
try{
if(nodeList[i].getAttribute("type") == "file"){
//ERROR HERE///->var id = nodeList[item].getAttribute("id");
var fileSelector = document.getElementById(id);
document.getElementById(id).addEventListener("change",function(e){
if(e){
e.preventDefault();
}
if (fileSelector.files) {
window.file = fileSelector.files[0];
} else {
window.file = fileSelector.value;
}
readData();
});
}
}catch(e){}
}
Probably nodeList[item] is not a Node. Use a for loop instead of for..in:
var i, len = nodeList.length;
for(i=0; i<len; i += 1){
try {
if(nodeList[i].getAttribute("type") == "file"){
// ...
See JSFiddle for an explanation
for (item in nodeList)
gives 0, 1 and 2 as the array indices, which is ok.
But then it delivers more properties length, item and namedItem, which aren't DOM elements and don't have a getAttribute() function.
So, as others have already suggested, use a normal for loop.

Disable ajax form button on key press

I have a button on an Ajax form that when pressed, indicates to the user that it is "searching" kind of a small "throbber" to keep the user occupied while the DB is being queried.
When the submit button is clicked it goes to a function. That function will disable the button, gather up what is filled out on the form, perform the Ajax call (non-asynchronous - meaning the script is to WAIT on the call to complete before moving on to the next line of code) and then re-enable the button.
Like so:
function CheckForm()
{
disableButton(document.getElementById("save"));
....... lots of instructions in here ........
....... Loops through every form el .........
//Ajax called
CallAjax(sUrls, sParams);
enableButton(document.getElementById("save"));
}
function disableButton(element)
{
try
{
disabledEl = element.id
disabledElOrigTxt = element.value;
element.value = ' Loading...'
addClass(element, "pleaseWait");
addClass(document.myForm.reset, "resetWait");
element.disabled = true;
document.myForm.reset.disabled = true;
//return true;
}
catch(e)
{
////SHHHHHH
}
}
function enableButton(element, timer)
{
try
{
if(element.value == ' Loading...')
element.value = disabledElOrigTxt;
removeClass(element, "pleaseWait");
removeClass(document.myForm.reset, "resetWait");
element.disabled = false;
document.myForm.reset.disabled = false;
clearTimeout(timer);
return true;
}
catch(e)
{
////SHHHHHH
}
}
function hasClass(element, className)
{
var classes = element.className.split(' ');
var len = classes.length;
for (var i=0; i<len; i++)
{
if (classes[i] == className)
return true;
}
return false;
}
function addClass(element, className)
{
if (!hasClass(element, className))
element.className = (element.className == '' ? className : element.className + ' ' + className);
}
function removeClass(element, className)
{
var newValue = '';
var classes = element.className.split(' ');
var len = classes.length;
for (var i=0; i<len; i++)
{
if (classes[i] != className)
newValue += newValue.length ? ' ' + classes[i] : classes[i];
}
element.className = newValue;
}
This works in Mozilla, IE, but NOT CHROME. Anyone have any idea why?
If I modify disableButton() and make it alert("hi") on the last line of the try, in Chrome I can observe the button change.... but ONLY if I throw an alert in there to stop the script. Obviously that is not what I want to do.
Maybe your CallAjax() function works asynchronously in Chrome?
Another possibility, maybe Chrome processes it so fast you don't notice the changes?

javascript abstract console logging

I want to make a function, like this.
For example:
function Logger() {
this.log = function(msg) {
console.log(msg);
}
}
And I want to use it in functions/modules etc, and that all works fine.
But the default console in my browser normally give the fileName + lineNumber.
Now when I abstract this functionality, the fileName and lineNumber is not where I put my instance.log(). Because it will say from where the console.log is being called, not the function itself.
So my question:
How can I get the correct information from where I want to use my logger?
Or give me, please, any tips to improve this functionality.
function Logger() {
this.log = console.log.bind(console);
}
I asked about this some time ago: Create shortcut to console.log() in Chrome.
Try using backtrace function like this one :
function printStackTrace() {
var callstack = [];
var isCallstackPopulated = false;
try {
i.dont.exist += 0; //doesn't exist- that's the point
} catch (e) {
if (e.stack) { //Firefox
var lines = e.stack.split('\n');
for (var i = 0, len = lines.length; i & lt; len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
callstack.push(lines[i]);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
else if (window.opera & amp; & amp; e.message) { //Opera
var lines = e.message.split('\n');
for (var i = 0, len = lines.length; i & lt; len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
var entry = lines[i];
//Append next line also since it has the file info
if (lines[i + 1]) {
entry += ' at ' + lines[i + 1];
i++;
}
callstack.push(entry);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
}
if (!isCallstackPopulated) { //IE and Safari
var currentFunction = arguments.callee.caller;
while (currentFunction) {
var fn = currentFunction.toString();
var fname = fn.substring(fn.indexOf( & amp; quot;
function & amp; quot;) + 8, fn.indexOf('')) || 'anonymous';
callstack.push(fname);
currentFunction = currentFunction.caller;
}
}
output(callstack);
}
function output(arr) {
//Optput however you want
alert(arr.join('\n\n'));
}
Try assigning the function:
(function () {
window.log = (console && console.log
? console.log
: function () {
// Alternative log
});
})();
Later just call log('Message') in your code.

Categories

Resources