.each() function does not loop through my object - javascript

I have the following jquery function and it seems that the .each function never loop through my object (it goes right to the "$("#AppConnect").val(appConnectString);" line without iterating).
Here's the code :
$("input").focusin(function () {
if (!$(this).hasClass("appConnectData")) {
var key, value, appConnectString = "";
$(".appConnectData").each(function (index, element) {
if ($(element).hasClass("key")) {
key = $(element).val();
} else {
value = $(element).val();
}
if (!key && !value) {
appConnectString += key + "." + value + ";";
}
});
$("#AppConnect").val(appConnectString);
}
//alert($("#AppConnect").val());
});
What I've done to find the problem with no success so far :
Check if the $(".appConnectData") is empty
Check the .each syntax (you never know :p)
Insert a breakpoint to see if I have some errors
Put the content of $(".appConnectData") in a var and then loop through the said var
Maybe it is because my .each is inside a focusin function, or maybe I did something else wrong but I can't seem to find what.
I thank you all in advance for the help provided :)

I think the problem is the if condition, you should check key && value if you want to make sure key & value has a value.
if (key && value) {
appConnectString += key + "." + value + ";";
}
Demo: Fiddle

In each case, if key exists then value will not exist and vice-versa. so the correct logical operator would be or. even this is not enough!
You can separate if to test both key and value existence:
$("input").focusin(function () {
if (!$(this).hasClass("appConnectData")) {
var key, value, appConnectString = "";
$(".appConnectData").each(function (index, element) {
if ($(element).hasClass("key")) {
key = $(element).val();
} else {
value = $(element).val();
}
if (key) {
appConnectString += key".";
}
if(value){
appConnectString +=value;
}
if(key||value){
appConnectString +=";";
}
});
$("#AppConnect").val(appConnectString);
}
//alert($("#AppConnect").val());
});

Related

Check value against array and return another value

I'm building a click type game and I need to see if the answer the user selected is correct by comparing it to an array.
This is the JSON
{
quiztitle: "Select the States",
correct_answers: "9",
states: [
{
state_name: "Alabama",
image: "alabama_image",
answer: "correct"
},
{
state_name: "Alberta",
image: "alberta_image",
answer: "incorrect"
},
ect...
When a user clicks a button, it takes the value and needs to check if it's correct. What is the best way to do this.
This is my attempt so far:
$('body').on('click', '.matchBtns', function(){
var value = $(this.innerHTML);
if($.inArray(value, data.states)){
//its in the array
}else{
//its not
}
});
I'm unsure how to access the value 'answer' to check if correct or not
This is the html button
<button class="matchBtns">*State Name Here*</button>
You've got a bit of the way, but there's still a lot to do. First off, you don't want a jQuery object of the text inside the button; you just want the text. So you can do something like this:
var value = $(this).text();
Secondly. $.inArray won't work for two reasons. One - It's a multidimensional array of objects. Two - you don't just want to check if it's in the array; you want to check if it's in the array and has the correct property.
So, you could iterate over the array and see if any of the answers are correct:
$('body').on('click', '.matchBtns', function() {
var value = $(this).text();
var correct = false;
$.each(data.states, function(i, state) {
if ( state.state_name == value && state.answer == 'correct' ) {
correct = true;
return false; // break out of $.each()
}
});
if ( correct ) {
// true
}
else {
// false
}
});
Here's a working jsFiddle: https://jsfiddle.net/s0gtqjcL/
You could simplify this by storing answer (or correct) as a boolean, not a string. That way, you could do something like this:
if ( state.state_name == value && state.correct )
if you like underscore you may try:
$('body').on('click', '.matchBtns', function(){
var value = $(this.innerHTML);
if(_.contains(_.pluck(data.states, "answer"), value)) {
//is in the array
}
else{
//is not
}
});
_.pluck(array, "x") is a shorthand for _.map(array, function(x){return x.x;), so that you won't try to compare string and object
You are going to have to loop through the answers.
$('body').on('click', '.matchBtns', function(){
...
var value = this.innerHTML;
for (var i = 0,l = data.states.length; i< l; i++){
if (data.states[i].state_name === value && data.states[i].answer === 'correct'){
/// is correct
break; // to stop the loop
}else {
// not correct, continue
}
}
...
}

If else condition Javascript

I have four TextFields on my UI page.I get the input values of the user from all textfields for example values Textfield1.getvalue(),Textfield2.getvalue(),Textfield3.getvalue(),Textfield4.getvalue().
Now on a button click, I need to check which textfields are actually filled by the user and attach those values I need to send a http request to the server to query on the database. These values are used to filter values from a table. SO basically the values are "TABLE COLUMN" values. For this, I thought of using old school combinations like:
if (Textfield1.getvalue()=="" && Textfield2.getvalue()!=""){
//do something
}
else if (Textfield2.getvalue()=="" && Textfield3.getvalue()!=""){
//do something
}
else if (Textfield3.getvalue()=="" && Textfield4getvalue()!=""){
//do something
}
......
and so on.
This, I personally feel is not efficient and not a good programming way. I am pretty sure there might be some other way of doing it which I am not aware of and couldnt find googling it either. Can anyone share some ideas for a better solution.
Thanks in advance.
If you want to do something based on first field that has a value, at least that is what it looks like from your sample, you could do something like:
» Simple Fiddle. «
var do_something = {
0 : function(val) { console.log("Doing x width " + val)},
1 : function(val) { console.log("Doing y width " + val)},
2 : function(val) { console.log("Doing z width " + val)},
3 : function(val) { console.log("Doing w width " + val)},
}
$("#post").on("click", function() {
var val;
$(".test").each(function(i) {
val = $(this).val();
if (val) {
do_something[i](val);
return false; // Break
// (Or omit the break if you want to "do_something" with all fields
// having a value.)
}
});
});
Or, depending on various, a better solution could be:
var do_something2 = {
act1 : function(k, val) { console.log("Doing x width " + val + " k=" + k) },
act2 : function(k, val) { console.log("Doing y width " + val + " k=" + k) },
act3 : function(k, val) { console.log("Doing z width " + val + " k=" + k) }
};
$("#post2").on("click", function() {
var val;
$(".test").each(function(i) {
val = $(this).val();
if (val) {
do_something2[$(this).data("act")](i, val);
return false; // Break
}
});
});
Where you have input fields like this (dynamically or otherwise created):
<input type="text" data-act="act1" class="test" value="one" />
<input type="text" data-act="act2" class="test" value="two" />
This way you can also easily change what action is taken per field simply by setting the data-act value to wanted function.
One idea - check individual fields once and combine into a single unique value:
var c=0;
if (condition1) c+=1;
if (condition2) c+=2;
if (condition3) c+=4;
Etc. now every combination of conditions has a unique value associated with it and you can use a switch statement for cleaner flow.
Think of data instead of control flow. I'd suggest thinking of the problem this way:
Data -> Validation -> Side effects
All those steps must be uncoupled. Here's example, you may have to re-think your data to adapt your code:
// Data
var fields = [Textfield1, Textfield2, Textfield3, Textfield4];
// Validation
var valid = fields.filter(function(x) {
return x.getvalue();
});
// Side effects
valid.forEach(function(field) {
var value = field.getvalue();
// do something
});

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.

jquery each function does not work the way I want it to

I have following code:
$.each(data, function (key, val) {
var items = val.items;
console.log(val.id);
if (val.id === this.id) {
console.log('hello');
}
});
In the above code, I am looping through data which is a JSON object. Then I compare the id of val with this.id which has value of 4. Thus what I want is when val.id (4) equals to this.id (4) then log hello, however, since data has several objects so it logs several hellos.
Why and how can I make it so that it says hello only when it matches that condition and get out of that loop?
In the function defined within the call to each(), this === val.
If you're trying to compare to the value of this.id from before the call to each, you'll need to cache it, like so:
var someId = this.id;
$.each(data, function (key, val) {
var items = val.items;
console.log(val.id);
if (val.id === someId) {
console.log('hello');
}
});
As Alison has said, this in side the function is val so you need some kind of caching. (This feature is useful when you only need the value but not the key, so you can have function(){...} and use this instead)
Also, if you want to break from the .each loop, return false inside the loop function:
var someId = this.id;
$.each(data, function (key, val) {
var items = val.items;
console.log(val.id);
if( val.id === someId ) {
console.log('hello');
return false;
}
});
as specified in the documentation.
what you have here is, you are comparing the same data in if condition which is always true..
this represent to current element in each loop which in your case is data and same goes to val too.. you can try with console.log(this) inside the loop ..
if( val.id === this.id ){ //this will always be true
so you have to rethink your logic ..... what actually you need to match in the(that) condition.
when it matches that condition and get out of that loop
try it out in fiddle

jQuery auto correction acts weird on duplicated fields

I am using a script to auto-correct input on forms using jQuery. For example, when someone writes "abc" as his initials, the field will auto-correct the input directly to A.B.C.
These scripts work excellent. However, anyone can fill out several forms with several names. I am using knockout to duplicate the forms. So far so good, but auto-correction doesn't work on duplicated fields anymore..
The auto-correction looks like this (small part):
// Lowercase
$(".lowercase").keyup(function(e)
{
$(".lowercase").val(($(".lowercase").val()).toLowerCase());
if (/[a-z]/g.test(this.value))
{
this.value = this.value.replace(/[^a-z ]/g, '');
}
});
// Initials
$(".initials").focus(function() {
var current = $(".initials").val();
$(".initials").keyup(function(e) {
var key = String.fromCharCode(e.keyCode);
if (key >= 'A' && key <= 'Z') {
current += key + ".";
this.value = current;
}
else {
current = "";
}
});
$(".initials").blur(function() {
var i = $(".initials").val();
var last = i[i.length - 1];
if (last != "." && i.length !== 0){
this.value += ".";
}
});
});
// Capitalize
$(".cap").keyup(function(e)
{
function convertToUpper() {
return arguments[0].toUpperCase();
}
val = this.value.toLowerCase().replace(/\b[a-z]/g, convertToUpper);
this.value = val;
});
A fiddle can be found here
Update
Thanks to raghaw Numbers now work. But other fields don't yet.
You are binding event that is not working on elements that get created in future. Here is the change I made to your code:
$(document).on("keyup", ".numbers", function(e)
// $(".numbers").keyup(function(e)
Your modified fiddle is here http://jsfiddle.net/QUxyy/9/

Categories