If statement and .click function - javascript

I have been making a videogame with javascript. However, there is just one thing that I don't understand.
if (!user.hasOwnProperty('firstName')) {
$('#inputSubmit').click(function () {
user.firstName = getInput();
addText_1("Good, now type your character's last name");
});
};
this statement will keep executing. Basically the condition is that the user does't have a first name property and the function will add the first name on the click of submit. However, you can keep pressing the submit button and it will keep adding the text.
$('#inputSubmit').click(function() {
if(!user.hasOwnProperty('firstName')) {
user.firstName = getInput();
addText_1('hello');
};
});
However, this works. It only does it once. Could someone explain the principle that I am not understanding?
Thank you very much!

You attach a click event to #inputSubmit. This callback ignores the surrounding if statement. In your second sample code, if is inside the callback function.

in first code "hasOwnProperty" checked in outer scope of function() but in second code the condition checked in scope of function

Related

Javascript: JSON request works only for the first time

I have a script which registers a click event to a button.
The function which should be executed when the button is clicked, should make a JSON request to a Quotes API and give my Quote element the random quote.
$("document").ready(function() {
$("#new-quote").on("click", newQuote());
});
function newQuote() {
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
$("#quote-paragraph").html(a[0].content);
$("#footer").html(a[0].title);
});
}
This is how my code should look like, but I already tried different solutions and to find my error. I added an alert() statement at the end of my function to see if the function gets executed, which it does. Well sometimes. I tried it a couple times and got different results each time I tried it. I am working with codepen.io . Thanks for your help!
On the second line
$("#new-quote").on("click", newQuote());
You're executing the function and assigning its result to the onclick event instead of assigning the function itself. That's why your function executes once, when you do the assignment, and not again, because you didn't actually assign it. Do this:
$("#new-quote").on("click", newQuote);

Passing code as function argument in Javascript and that code uses variable defined in the function

I have following javascript code. I am trying to achieve a hide/display generic function on change in select form field. Lets take an example. Suppose I have a select field where values are "none", "auth", "other" and if user selects "auth" then display another form field. I may have such situation many places in the form for different select fields. Hence I have written this function below profile_field_toggler
function escapeJquerySelectorStr(str) {
if (str) {
return str.replace(/([ #;?&,.+*~\':"!^$[\]()=>|\/#])/g,'\\$1');
}
return str;
}
function profile_field_toggler (cotroller_id, reciever_id, block_code) {
parsed_controller_id = "#"+escapeJquerySelectorStr(cotroller_id);
parsed_reciever_id = "#"+escapeJquerySelectorStr(reciever_id);
selected = jQuery(parsed_controller_id + " option:selected").val();
if(block_code()) {
jQuery(parsed_reciever_id).removeClass("hide");
} else {
jQuery(parsed_reciever_id).addClass("hide");
}
}
Here I make call to the generic function i.e profile_field_toggler. Last argument of the generic function accepts conditional code, so I am passing it in the call below selected == "auth" . BUT selected has no scope in this call hence it will not work (as I want to refer the selected variable in the generic function). So how can I solve this problem? Please note, I must want to keep the condition such as selected == "auth" or selected != "xyz" or selected == "undefined" in the caller only, because they may vary.
jQuery(document).ready(function() {
profile_field_toggler("base[remove_option]", "general_passwordassword_block", function() {selected == "auth"});
});
Any idea how to solve this problem?
A closure can only access variables in its own scope, but definitely will not (and can not) have any knowledge of the scope of the function that eventually calls it.
In this particular example - perhaps "block_code" should take selected as an argument.
It looks weird, but I found the solution. It seems you can pass selected in the call from caller only and even if it is defined in the generic function, it will work. Check this out. I just added return so that condition can be evaluated. and it worked. I tested with all different conditions and it is working ..sweet, but weird.
jQuery(document).ready(function() {
profile_field_toggler("base[remove_option]", "general_passwordassword_block", function() {return(selected == "auth")});
});

Javascript function breaking/variables being forgotten

It's hard to describe the issue within the title, but basically, I have a function that, when a button is clicked, checks a bunch of attributes on the element in order to display/hide associated content.
It all works great, except when I tried to add an extra feature that hides a panel when a certain tab is selected. It's a simple if statement I thought I'd have no trouble with, but it has the strangest reaction I've ever seen.
There are 3 main tabs, and one of those tabs with a value of 'mirror' closes a group of tabs relating to patterns for a controller designer I am working on. When 'mirror' is clicked, the variable 'dependingvar' is set fine, however - it will only be used once. Here is the code of the if statement:
if (dependingvar !== undefined) {
jQuery('.' + dependingvar).children('.cdesign-toggle').first().trigger('click');
jQuery('.' + dependingvar).hide();
lastdepend = dependingvar;
} else {
jQuery('.' + lastdepend).show();
}
Only the very first line that triggers a click will run. The second one that hides the group does not run. If I swap these around, the block will hide, but the trigger wont run. I've checked the debug console, and the variable is literally getting unassigned as soon as it's ran the first one. I have no idea what is happening with it.
Here is the full code:
http://pastebin.com/6QncXf6c
I can't really do a JSFiddle due to the dependancies, but here's the HTML as a pastebin:
http://pastebin.com/nePQbtjE
I really just have no idea why this is happening. An important note, as well:
If the if statement is placed anywhere apart from the bottom, it breaks the rest of the code, unsetting variables, but ONLY if the condition is met (dependingvar !== undefined).
I'm hoping it's a stupid mistake, but can anyone spot it?
I've only quickly skimmed over your code, but a few things springs to mind:
.trigger('click') is run asynchronously. The event handler will set it to undefined (use null or something else by the way - undefined should only be used for undefined variables) .
In the very next line, you are referencing dependingvar again, but depending on whether or not the .cdesign-toggle click event has run to end, dependingvar may have one value or another. Instead of referencing dependingvar directly, try cloning it, so you know its value won't change inside your if statement, something along the lines of:
if (dependingvar !== undefined) {
var dependingvar_ = dependingvar; // or jQuery.clone(dependingvar) depending on the type of dependingvar
jQuery('.' + dependingvar_).children('.cdesign-toggle').first().trigger('click');
jQuery('.' + dependingvar_).hide();
lastdepend = dependingvar_;
} else {
jQuery('.' + lastdepend).show();
}
You defined dependingvar outside the function, so it is in global scope. Every change you make by other function-calls (in this case by calling children('.cdesign-toggle').first().trigger('click'); will also be effective within your current scope.
This code will demonstrate this: http://jsfiddle.net/petervanderwal/r87b1f9k/1/
Move the definition inside the function (commented out in the demo), so other calls to click wont alter the same dependingvar.

'Strange' variable assignment behavior inside JQuery on("click") function

I'm new to both javascript and jquery, and I'm having a small problem. It is happening with both the latest versions of Chrome and Firefox, so I don't think it's a browser issue.
Relevant code is here (this is a self-invoking function inside script tags on the HTML page).
(function () {
"use strict";
var submitbutton = $('#submitcommand'),
textinput = $('#textinput'),
userinput = textinput.val();
submitbutton.on('click', function() {
alert("textinput is " + textinput.val()); // => works
alert("userinput is " + userinput); // => undefined
});
}());
The first call to alert() works just fine, using 'textinput.val()'. The second call to alert() doesn't return any visible text, because 'userinput' is evaluating to 'undefined'.
I've tried going into the Firebug Console and pasting the four statements (the two assignments and the two calls to alert()) in, one after the other. That works, and gets me the result I expect.
So the question is: what changes about the 'userinput' variable inside the on('click') function? What am I not seeing here?
Thanks in advance!
As the function is self invoking, the variable will be set at page load. It is not reassessed every time the button is clicked. During page load you will probably find that:
The input is emtpy
The input is lower down the page than the script (More probable I think)
So at the time of setting there is no value. You probably want to make the variable scoped to the button click:
(function () {
"use strict";
var submitbutton = $('#submitcommand'),
textinput = $('#textinput')
submitbutton.on('click', function() {
var userinput = textinput.val();
alert("textinput is " + textinput.val()); // => works
alert("userinput is " + userinput); // => undefined
});
}());
Also, you will want to make sure the script block is at the bottom of the page, as then all the UI elements will be loaded in the browser when the function is invoked.
Your value is undefined inside the handler.
You should perhaps use it this way:
(function() {
"use strict";
var submitbutton = $('#submitcommand'),
textinput = $('#textinput')
userinput = textinput.val();
submitbutton.on('click', function() {
userinput = textinput.val();// sets the value in the handler
alert("textinput is " + textinput.val());
alert("userinput is " + userinput);
});
}());
working example:http://jsfiddle.net/avCay/
Note that this works this way due to the scope of the variable and the "reset" of the values inside the event handler. The first pass parses the script, the second executes it, and the subsequent event handler fires on the click event of the submitbutton element, setting the value at that point during that event.
EDIT: NOTE: regarding the jQuery read/load wrap (as in my example fiddle) if you wish to NOT have that, you can do:
$('#submitcommand').on('click', function() {
instead of the variable and jQuery will properly hook the event handler to the element.
EDIT2: or perhaps this will provide more insight here. If you do:
You will still need to re-access the variable however if you wish to have the "current" value of the input, not that in the "undefined" state during the initial execution due to the parse/execute cycle of the Javascript. The "re-access" of the .val(); vs the value during the initial script execution is the key to that "undefined" value. and setting it "inside" the handler gets the current value.
When
var userinput = textinput.val()
is evaluated:
textinput may not exist yet - you must be either in a document.ready() handler or the <script> block must be after #textinput in the DOM.
if it does exist, userinput gets its current value, not any future value it may happen to have.
This is because the value of #textinput is empty on page load (unless you set the value to something when the page loads). So the stored value in userinput is empty. When you read the value from textinput inside the event handler, it looks up the value of the input-field.
Makes sense? :)

How to programmatically change an inputs onblur?

I am trying to change the value of the onblur attribute of a text input after the page has finished loading.
When I do the following, it simply fires the function:
ip.onblur = stopCalcUpInt(this,10);
When I do the following, I have success:
ip.onblur = function onblur(event){stopCalcUpInt(this,10);}
Unfortunately, the whole point of this is to be able to dynamically set the second parameter for stopCalcUpInt(). If I hard code a value for it... it works fine... but any attempts to pass varibles to this fails... instead of putting the value of the variable as the second param it just puts the plain text of the variable name itself. Here is ideally what I am TRYING to do:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
In this example, when I alert the ip.onblur I get:
It depends what this is intended to refer to. In an event handler this refers to the element on which the event is being handled. If that's what you want then your code looks good as written; this will point to ip.
If you intend this to refer to the this from outside the event handler and not ip then try this:
var self = this;
ip.onblur = function(event) { stopCalcUpInt(self, self.value); };
The answer to getting this to work was super easy, yet not overly obvious. Instead of:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
I did this:
ip.setAttribute('onblur','stopCalcUpInt(this,\'' + ip.value + '\');');
Works perfectly... no more banging my head against the wall! Yay!
ip.onblur = function() {stopCalcUpInt(this,this.value);}
ip.onblur is an event handler... i.e. it's a function
Now, when you alert a function, FF will show you the source code for that function (if it's user defined).
That is why you're seeing the plain text of the variable name.
For an event handler, this is the element that is currently handling the event. So, if you're setting the onblur handler of an input box, you will have access to the contents of that input box.
The code sample that you provided:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
should work correctly. Try
ip.onblur = function onblur(event){alert(this.value); stopCalcUpInt(this,this.value);}
if you want to be sure
Is stopCalcUpInt expecting a number in the second parameter? The value attribute will return a String, while in your hardcoded example you're passing a number type. Try this:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value * 1);}
As explained in QuirksMode:
Since multiplying assumes numbers,
JavaScript makes the string a number,
if possible.

Categories