How do I call a function with in a function? - javascript

I need to add i3c to my and statements. I don't know the correct syntax. This code is broken. Would an anonymous function be better? So if c0() passes, c4() runs, if c4() passes I need i3c() to run or what is in i3c to run.
function o1(a,b)
{
document.getElementById(a).value=b;
}
function i3()
{
var a=document.forms['f3'].elements,b='f3e';
c0(a,'Please enter both a tile and a url',b)&&c4(a[2],'Please enter a valid url',b)&&d0()&&s0('pi3a.php',is('f3'),s2);
o1(f3aa,'');o1(f3bb,'');
}
function d0()
{
var a=document.getElementById('Bb1c'),
b=document.createElement('a'),
c=document.forms['f3'].elements;
b.href=c[2].value;
b.name="a1";
b.className ="b";
b.innerHTML = c[1].value;
a.appendChild(b);
return 1;
}

The && (logical AND operator) is processed left to right. If any expression returns false, that value is returned. If all but the last one return true, then the value of the last expression is returned (whether it is true or false).
So if i3c is not being called, it is because the return value of one of the preceding calls is falsey, i.e. it type converts to false, so it might be 0, '' (empty string), undefined, NaN, null, ... I've probably left one out.
Edit
As patrick w commented, the line:
c.setAttribute("class","b");
will fail in IE. Don't use setAttribute for standard attributes, use DOM properties instead:
c.href = d[2].value;
c.name = "a1";
c.className = "b";
Faster and less bugy.

function i3() {
var e = 'f3e';
if ( !(c0(a,'Please enter both a tile and a url',e)) ) { return flase; }
if ( !(c4(a[2],'Please enter a valid url',b)) ) { return flase; }
(function() {
var doc = document,
a = doc.forms.f3.elements,
b = doc.getElementById('Bb1c'),
c = doc.createElement('a'),
d = doc.forms.f3.elements;
c.href = d[2].value;
c.name = "a1";
c.className = "b";
c.innerHTML = d[1].value;
b.appendChild(c);
// which a you need here ???
//var a = is('f3');
var someOtherA = is('f3');
//------------------------
s0('pi3a.php', a, s2);
// if these are part of the form you use in this function
// use
// document.forms[<name>].elements[<name>].value
doc.getElementById('f3aa').value = '';
doc.getElementById('f3bb').value = '';
})();
}
This may work, I suppose c0 and c4 return true/false. This way they are easier to read. If they return true, continue with the next one and don`t return.
In the i3c function you declare a twice!
Look at the comments for more details.

Related

Javascript if statement in function overwriting global variable?

Am attempting to create a static navigation panel which becomes absolute at the bottom before the footer when reaching the end of the page content.
As I am developing for wordpress the page could be of varying height so I have attempted to trigger the absolute positioning when the nav panel “collides” with the footer.
So far I have used this code I found here
function collision($archive, $footer){
var archivexPos = $archive.offset().left;
var archiveyPos = $archive.offset().top;
var archiveHeight = $archive.outerHeight(true);
var archiveWidth = $archive.outerWidth(true);
var archiveb = archiveyPos + archiveHeight;
var archiver = archivexPos + archiveWidth;
var footerxPos = $footer.offset().left;
var footeryPos = $footer.offset().top;
var footerHeight = $footer.outerHeight(true);
var footerWidth = $footer.outerWidth(true);
var footerb = footeryPos + footerHeight;
var footerr = footerxPos + footerWidth;
if (archiveb < footeryPos || archiveyPos > footerb || archiver < footerxPos || archivexPos > footer) return Boolean = false;
return Boolean = true;
And used a global variable of Boolean to pass to this function
$(window).on('scroll', function() {
var scrollmath = Math.round($(window).scrollTop());
var archiveValue = scrollmath + 48;
var archiveBottom = archiveValue + 'px';
console.log('collision boolean', Boolean)
if (Boolean = false) {
$('#archive').css('position', 'fixed');
$('#archive').css('top', '48px');
} else {
$('#archive').css('position', 'absolute');
$('#archive').css('top', archiveBottom);
}
My problem is the if statement seems to be creating another Boolean variable? As when I comment it out I can see that the console reports the Boolean variable as expected. However when I leave it in and they collide this happens
Whats happened here?
The primary thing that's happening is that you're using = for comparison. JavaScript uses == (or ===), not =. = is always assignment.
But when testing the value of a boolean, you don't want == or != anyway, just use the boolean directly:
if (flag) {
// It was true
} else {
// It was false
}
Or if you're just testing for false:
if (!flag) {
// flag was false
}
(Note that because JavaScript does type coercion, that will also work with variables containing values other than booleans: Any truthy value coerces to true, any falsy value coerces to false. The falsy values are 0, "", NaN, null, undefined, and of course, false; all other values are truthy.)
Separately: Boolean is not a good choice for a variable name, as it's part of the JavaScript standard library (a function).
Also, your current collision function does two things:
It sets Boolean to true or false
It returns the value it set
In general, all other things being equal, it's best if a function doesn't have side-effects like that. If the caller wants to set Boolean to the return value of the function, he/she can, there's no need for the function to do it — it's already returning the value.
And finally: Global variables are, in general something to avoid. The global namespace on browsers is incredibly crowded and it's easy to get conflicts (for instance, a global called name may well not work as expected, because there's already a name global [it's the name of the window]).
no, your real Problem is, that you overwrite the constructor for the Boolean Type.
1st. stick to coding conventions: Only classes start with an uppercase-letter.
2nd. local vars have to be declared with the var-Keyword (or let for block-scoped vars, or const).
otherwise you reference a var from a surrounding scope; and in the end, the global scope.
3rd. the equal-sign:
=== means typesafe comprison
3 === 3 //=> true
3 === '3' //=>false
== means simple comparison
3 == '3' //=> also true now
= means assignment, not comparison
var foo = 3;
if it inside of some other code like
var bar = 42 + (foo = 3);
//it works basically like
var bar = 42 + (function(){
foo = 3;
return 3; //NOT FOO!!! not even foo after the assignment
})();
//the same way, that this:
var bar = 42 + foo++;
//works basically like this:
var bar = 42 + (function(){
var result = foo;
foo = foo+1;
return result;
})();

While operator undefined

I want to make a small calculator in javascript.
I got the html code looking like this (for all the numbers)
<button type="button" onclick="calcNum(1)">1</button>
<button type="button" onclick="operator('+')">+</button>
var myNumbers = [];
The calcnumber function like this:
function calcNum(i) {
myNumbers.push(i);
var x = document.getElementById("screen").innerHTML = myNumbers.join("");
}
and the operator function like this:
function operator(op) {
var operator = op;
var y = document.getElementById("screen").innerHTML = operator;
}
My goal is to make it like this:
If I press 1,2,3 I want the screen element to display "123" (which it does) if I press "+" I want "+" to be displayed (which it does) however when the operator is pressed, and then a new number is pressed I want it to start on a new number, right now if I press "123" and then + and then "456" I get:
123456, instead I want it to display "456", hence starting on a new number. Hope it's all clear.
I figured I could add this to the calcNum function:
while(op == "undefined") {
keep pushing numbers // but this does not work
}
In the end I want to construct a calc function which takes all the numbers up to a operator is pressed as the FIRST number, then concatanate with the operator and the second number and adding them together.
I see several issues in your code but I don't know if it is due to the fact that you didn't copy all your code in your question.
First, the operator function is incorrect : you give a local variable the samename than the function. If you want the function return a value, use the returnkeyword.
I figured I could add this to the calcNum function:
while(op == "undefined") { keep pushing numbers // but this does
not work }
Where is opdefined? The only op I see is a local variable of the operatorfunction. It will always be undefined in calcNum.
Note also that if you want to test if a variable is undefined, you should not test
if (myVar == "undefined")
but
if(typeof myVar == "undefined")
Finally I'd change your code this way (should be tested though):
var currentNumber= "";
var entries = []
function calcNum(i) {
currentNumber +=i;
document.getElementById("screen").innerHTML = currentNumber;
}
function operator(op) {
var y = document.getElementById("screen").innerHTML = op;
//Note that you could already process the entered operations as if you clicked on '='
//and display the result instead of displaying the operation...
if(currentNumber != ""){//there must be a number entered before you click on an operator
entries .push(currentNumber);
entries .push(op);
currentNumber= "";
}
}
And you still need of course to implement what you do when you click on =...
Change your functions like this
var numbers = "";
function calcNum(i) {
myNumbers.push(i);
numbers +=i;
var x = document.getElementById("screen").innerHTML = numbers;
}
and
function operator(op) {
var operator = op;
var y = document.getElementById("screen").innerHTML = operator;
myNumbers.push(op);
numbers = "";
}
Declare above:
var leftOperand = null;
var lastOperator = null;
In calcNum:
if(lastOperator !== null) {
document.getElementById("screen").innerHTML = '';
leftOperand = myNumbers.join('');
myNumbers = [];
lastOperator = null;
}
// rest of the function
In operator:
lastOperator = op;
// rest of the function

Javascript "with" operator removal

I recently ran into some issues with a plugin and outlined the issue in this post: With operator & dashes in object keys and wanted to know if the modifications I've made below cover the scenarios that the with scope blocks would have covered.
I've modified some code to remove the with operator and I'm wondering if I've replicated everything properly in doing so.
Here is the original code:
var test = new Function('$f','$c','with($f){with($c){return{'+ declarations +'}}}'));
Where $f and $c are passed objects (From what I could tell, $f shouldn't ever have a property of $c). The declarations variable is a string that has a colon in it (EX: "value:color") and available within the scope.
Here is my modified code:
var test = function($f, $c, declarations) {
var result = {};
var value = "";
var split = declarations.split(":");
if (split.length < 2) {
throw new Error("Declaration is in an invalid format");
}
if ($f[$c] !== undefined && $f[$c][split[1]]) {
value = $f[$c][split[1]];
}
else if ($c[split[1]]) {
value = $c[split[1]];
}
else if ($f[split[1]]) {
value = $f[split[1]];
}
else {
value = "" + split[1];
}
var key = split[0];
result[key] = value;
return result;
};
Everything appears to work as it did previously, but this modification now handles the use case where the declarations variable could have a dash in it (EX: "value:background-color"). Additionally the declarations variable is passed into the function, to ensure it's defined.

JavaScript Throws Undefined Error

What it is supposed to do -
Example
url1(pages,"ALT") returns "www.xyz.ac.uk"
url1(pages,"xyz") returns ""
The error - TypeError: Cannot call method 'toUpperCase' of undefined
This is just for some coursework, Im stuck with these errors. Any help would be much appreciated
function index(string,pattern,caseSensitive) {
if(caseSensitive == false) {
var v = string.toUpperCase();
} else {
var v = string;
}
return indexNumber = v.indexOf(pattern);
}
var pages = [ "|www.lboro.ac.uk|Loughborough University offers degree programmes and world class research.", "!www.xyz.ac.uk!An alternative University" , "%www%Yet another University"];
alert(url1(pages, "ALT"));
function url1(pages,pattern) {
var siteContent = [];
for(i=0;i<pages.length;i++) {
var seperator = pages[i].charAt(0);
if(pages[i].indexOf(seperator)>0){
siteContent = pages[i].split(pages[i].indexOf(seperator));
}
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}else{
return "";
}
}
}
if(pages[i].indexOf(seperator)>0){
siteContent = pages[i].split(pages[i].indexOf(seperator));
}
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}else{
return "";
}
If pages[i].indexOf(seperator)<=0, siteContent is still whatever it was from the last iteration. If that happens on the first iteration, siteContent is still [], and siteContent[2] is undefined.
Another problem: the expression pages[i].indexOf(seperator) returns a number, and pages[i].split expects a delimiting string as an argument. Since the number doesn't appear in your input, you'll always get a single-element array, and siteContent[2] will always be undefined. Get rid of .indexOf(seperator), change it to siteContent = pages[i].split(seperator).
One more: get rid of the else { return ""; }. Add a return ""; after the for loop.
Finally, in the first if statement condition, change .indexOf(seperator) > 0 to .indexOf(seperator, 1) !== -1. Since you're getting seperator from the first character of the string, it will be found at 0. You want the second occurrence, so start the search at 1. In addition, .indexOf returns -1 if it doesn't find the substring. You'll need to account for this in both if conditions.
Side note, as this is not causing your problem: never use == false. JS will coerce stuff like 0 and "" to == false. If that's what you want, just use the ! operator, because the expression has nothing to do with the value false.
My final answer is http://jsfiddle.net/QF237/
Right here:
alert(url1(pages, ALT)); // ALT ISN'T DEFINED
I believe you forgot to quote it:
alert(url1(pages, "ALT"));
You should split the string passing the separator character itself. Your function then will look like:
function url1(pages,pattern) {
var siteContent = [];
for(i=0;i<pages.length;i++) {
var seperator = pages[i].charAt(0);
console.log(seperator);
if(pages[i].indexOf(seperator)>=0){
siteContent = pages[i].split(seperator); //fixed here
}
console.log(siteContent);
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}else{
return "";
}
}
}
Tell us if it worked, please.
EDIT: It seeems your index() also has a little problem. Please try the function below.
function index(string,pattern,caseSensitive) {
var v;
if(caseSensitive == false) {
v = string.toUpperCase();
pattern = pattern.toUpperCase(); //to clarify: pattern should be uppercased also if caseSensitiveness is false
} else {
v = string;
}
return v.indexOf(pattern);
}
EDIT 2:
And url1() is finally like this:
function url1(pages,pattern) {
var siteContent = [];
for(i=0;i<pages.length;i++) {
var seperator = pages[i].charAt(0);
if(pages[i].indexOf(seperator)>=0){
siteContent = pages[i].split(seperator);
}
if( index(siteContent[2],pattern,false)>=0){
return siteContent[1];
}
}
return "";
}
In this case, the first occurrence of pattern in all pages will be returned.

breaking main loop - jstree

I am using jstree library to display a tree.
In the code below, I am looping through the selected nodes in the tree and based on some conditions, I am assigning a variable 'allow_edit' a boolean value.
I would like to break the main loop if 'allow_edit = false'.
I tried using label and breaking the loop but this does not seem to work. I am getting undefined label.
loop1:
$j.each($j("#demo2").jstree("get_selected"), function(index, element) {
var selected_node_depth = parseInt($j(element).attr('node_depth'));
var allow_edit = false;
var array_first_filter = $j.grep(array_first, function(v) { return v[1] != "not detected";})
var array_second_filter = $j.grep(array_first_filter, function(v) { return v[3] > selected_node_depth;})
if (array_second_filter.length === 0 || array_second_filter.length == null)
{
allow_edit = true;
}
else{
alert("Confliction exists in your selected terms.");
allow_edit = false;
//break loop1; /** not working, getting undefined label **/
}
}
Any suggestions on how to break the main loop if 'allow_edit = false'? Thanks a lot
If the function you pass to .each() returns false, the iteration will stop.
else {
allow_edit = false; // pointless since you're about to return ...
return false;
}
Also, as a programming style note, any construction of the form:
if (something) {
flag = true;
}
else {
flag = false;
}
can be better written as simply:
flag = something;
In JavaScript, to force flag to be boolean (true or false), you can do this:
flag = !!(something);
The two ! (logical "not") operators force the expression ("something") to be evaluated as a boolean by the same rules as are used when that expression is the test clause of an if statement.

Categories