jquery/javascript: arrays - javascript

I am a begginer with Javascript/jQuery and I hope someone can help me with the following:
I have a simple form (7 questions; 3 radio buttons/answers per question - except for question 5 with 8 possible choices ) and based on the selected answers, when user clicks on 'view-advice' I want to display relevant advices (combination of 38 possible advices) below the form.
I have given "a", "b", "c",... values to radio buttons and I am collecting them in an array.
The part where the script alerts the array works ok.
I can't figure out the part where I display the advices depending on the values in the array.
I'd appreciate your help! Thanks!
Here is the code:
var laArray = new Array();
$('.button-show-advice').click(function(){
$(":radio:checked").each(function(i){
laArray[i] = $(this).val();
if (laArray == ["a","d","g","j","m","u"]) {
$("#advice-container, #advice1, #advice2").show(); // something is wrong here :(
};
})
alert(laArray) // testing to see if it works
})

Rather than test for equality, I think the better means is to check whether or not each of your values are in the array using the jQuery inArray function.
Granted, this is just the beginning of code. You could probably write a function to shore this up, like so.
function radioSelected(val) {
return ($.inArray(val, laArray) != -1);
}
and adapt it to your existing script.

You cannot compare arrays this way you should probably
either compare each element of the 2 arrays
function compare_array(array1,array2) {
var i;
for(i=0;i=array1.length;i++) {
if(array1[i]==array2[i]) {
return false;
}
}
return true;
}
or serialize the array in a comparable form ( comma separated string for example )
function compare_array(array1,array2) {
return array1.join(",")==array2.join(",");
}

Would be nice to see the HTML code. But I guess you want to do something like this:
var laArray = [];
var compareValues = function(arr1, arr2) {
$(arr1).each(function(index, el) {
if(el !== arr2[index]) {
return false;
}
});
return true;
};
$('.button-show-advice').click(function(){
$(":radio:checked").each(function(i){
laArray.push($(this).val());
});
if(compareValues(laArray,["a","d","g","j","m","u"])) {
$("#advice-container, #advice1, #advice2").show();
}
});
EDIT: updated the code, forgot the }); ...

Related

jQuery/Javascript - check if every element in a given array is within each of the others

I think I need some help with this. I'm sure there's an easy solution but I'm not getting it.
I have a search box in a page which automatically displays the FAQ questions which contain the search criteria as it is typed in.
Here's what I have at the moment:
var criteria = $('#search-criteria').val().toLowerCase().replace(/[^a-zA-Z 0-9]+/g," ");
$('.questions').each(function(){
if ($(this).text().toLowerCase().match(criteria)) {
$(this).attr('data-search','1');
} else {
$(this).attr('data-search','0');
}
});
It works, but the problem is it will only display questions which contain the search criteria consecutively i.e. word for word. I want to split each of these questions into an array and check that every word in the search criteria is SOMEWHERE in each question, enabling people to search for multiple keywords too rather than exact phrases.
I know that to turn each question into an array I need this:
$('.questions').each(function(){
var questionSplit = $(this).text().toLowerCase().replace(/[^a-zA-Z 0-9]+/g," ").split(" ");
// if all of the parts in the criteria array are found in the given question
// {
// $(this).attr('data-search','1');
// } else {
// $(this).attr('data-search','0');
// }
// }
It's the last comparison bit I'm lacking. Any help appreciated!
Thanks
You can iterate though the search values like this:
$(this).attr('data-search','0');
for (var i = 0; i < questionSplit.length; i++) {
if ($(this).text().toLowerCase().match(questionSplit[i])) {
$(this).attr('data-search','1');
break;
}
}
I have written this some time ago for an other project.
What about this:
$(table+" tbody td:MyCaseInsensitiveContains('"+val+"')").parent().show();
Where val is your search...
Sorry, I forgot -> You have to extend jquery like this:
$.extend($.expr[":"], {
"MyCaseInsensitiveContains": function(elem, i, match, array) {
return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});
Then you can use :MyCaseInsensitiveContains as an pseudo-class for every element.
The trick with my example was: Show all content in a table. If user searches (variable val) hide all td`s and only show the ones with the text containing from the searchbox.

Compare two lists and remove common elements using angular js

I am having 2 lists like below
list1 =
['option1','option2','option3','option4','option5','option6','option7'];
list2 = ['option3', 'option4', 'option7'];
I want the list to be
listFinal = ['option1','option2','option5','option6','option7'];
Please give me the suggestion using angular js how to solve this using filter
Tried to use this code to solve this using filter but unable to succeed.
app.filter('unique', function() {
return function(collection, keyname) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var key = item[keyname];
if(keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
return output;
};
});
I'm not sure that you really want a filter here. This is something that you should probably solve outside of Angular. If you're willing to add lodash to your project, you could do this:
var diff = _.difference(array1, array2);
If you must use a filter, you could try something like this?
app.filter('difference', function() {
return function(input, diff_array) {
var result = [];
for (var i = 0; i < input.length; i++) {
if (diff_array.indexOf(input[i]) == -1) {
result.push(input[i]);
}
}
return result;
}
}
Note that if you do this, your template has to look something like:
{{ input | difference:diff_arr }}
I haven't actually tested any of this, but this should be the general idea. I concur with Phillip that this really isn't something you should try to solve in Angular.
What you are describing is an "array/set difference". There are many questions on StackOverflow asking about this already. This is not related to Angular.js, but is an problem with an algorithmic solution. Just to add bit of interesting material, a "naive" solution runs in O(nlogn) which would be:
Sort the two lists/arrays from lowests to highest
Traverse each array setting the internal pointer to 0 initially, compare the elements. If the element in Array A is larger than the on in Array B advance the pointer by 1 in Array B, else B, else if they are equal, remove the result from the array and advance both pointers
What is the fastest or most elegant way to compute a set difference using Javascript arrays?
JavaScript array difference

I want object keys to check for duplicates, but I also want to sort the objects later, what should I do?

I have an array called newposts
I itterate through it and if it meets certain criteria, I add it to another array:
for (newpost in newposts){
if (!( newposts[newpost][0] in currentposts )){
var triploc1 = locations[newposts[newpost][1]].location;
var triploc2 = locations[newposts[newpost][2]].location;
var detour_distance = fourpoint_distance(newloc1, triploc1, triploc2, newloc2);
if (worthwhile_detour(original_distance,detour_distance)){
currentposts.push(posts[newposts[newpost][0]])
}
}
}
The second row, is intended to check for duplicates(newposts[newpost][0]) is an ID. When I wrote it I had forgotten that currentposts was an array. Obviously, this doesn't work. I need currentposts to be an array, because just below i sort it. I could ofcourse convert it into an array once the selection is done. But I'm new to javascript and believe someone might know a better way to do this.
function sortposts(my_posts){
my_posts.sort(function(a, b) {
var acount = a.sortvar;
var bcount = b.sortvar;
return (bcount-acount);
});
}
I'm not exactly sure what your desired goal here is, but I can try and clean this up for you. Please note that I'm using the underscore.js library as it makes working with arrays a HECK OF A LOT easier :) If you can't include underscore.js into your project, let me know and I'll write it in "pure" javascript :)
_.each(newposts, function(item) {
if ( _.indexOf(currentposts, posts[item[0]]) >= 0 ) {
var triploc1 = locations[item[1]].location;
var triploc2 = locations[item[2]].location;
var detour_distance = fourpoint_distance(newloc1, triploc1, triploc2, newloc2);
if (worthwhile_detour(original_distance, detour_distance)){
currentposts.push(posts[item[0]])
}
}
});
_.sortBy(currentposts, function(item) {
return item.sortvar;
});
I have to question, however, why you're using so many arrays (newposts, locations, posts, etc)? Are they all needed?

javascript - coldfusion - working with a list

This is probably easy for someone.
I am returning a list of campaignIDs (12,45,66) via JSON to a javascript variable
var campaignList = res.DATA.CAMPAIGNS
Now, given a specified campaignID passed in the URL
var campaignId ='<cfoutput>#url.campaignID#</cfoutput>'
I want to check if the returned list contains this campaignID
Any help much appreciated.
Plenty of ways to do it, but I like nice data structures, so ...
Split the list on comma, then loop over list, looking for value:
function campaignExists(campaignList,campaignId) {
aCampaignList = campaignList.split(',');
for (i=0;i<aCampaignList.length;i++) {
if (aCampaignList[i]==campaignId)
return true;
}
return false;
}
Since Array.indexOf sadly isn't cross browser, you're looking at something like:
// assume there is no match
var match_found = false;
// iterate over the campaign list looking for a match,
// set "match_found" to true if we find one
for (var i = 0; i < campaignList.length; i += 1) {
if (parseInt(campaignList[i]) === parseInt(campaignId)) {
match_found = true;
break;
}
}
If you need to do this repeatedly, wrap it in a function
Here's a bit of a "out of the box" solution. You could create a struct for your property id's that you pass into the json searilizer have the key and the value the same. Then you can test the struct for hasOwnProperty. For example:
var campaignIDs = {12 : 12, 45 : 45, 66 : 66};
campaignIDs.hasOwnProperty("12"); //true
campaignIDs.hasOwnProperty("32"); //false
This way if the list is pretty long you wont have to loop through all of the potential properties to find a match. Here's a fiddle to see it in action:
http://jsfiddle.net/bittersweetryan/NeLfk/
I don't like Billy's answer to this, variables within the function have been declared in the global scope and it is somewhat over complicated. If you have a list of ids as a string in your js just search for the id you have from user input.
var patt = new RegExp("(^|,)" + campaignId + "(,|$)");
var foundCampaign = campaignList.search(patt) != -1;

Need help with setting multiple array values to null in a loop - javascript

I have been working on creating a custom script to help manage a secret questions form for a login page. I am trying to make all the seperate select lists dynamic, in that if a user selects a question in one, it will no longer be an option in the rest, and so on. Anyways, the problem I am having is when I try to set the variables in the other lists to null. I am currently working with only 3 lists, so I look at one list, and find/delete matches in the other 2 lists. Here is my loop for deleting any matches.
for(i=0; i<array1.length; i++) {
if(array2[i].value == txtbox1.value) {
document.questions.questions2.options[i] = null
}
if(array3[i].value == txtbox1.value) {
document.questions.questions3.options[i] = null
}
}
This works fine if both the matches are located at the same value/position in the array. But if one match is at array1[1] and the other match is at array3[7] for example, then only the first match gets deleted and not the second. Is there something I am missing? Any help is appreciated. Thanks!
I don't see too many choices here, considering that the position in each array can vary.
Do it in separate loops, unless of course you repeat values in both arrays and share the same position
EDTI I figured out a simple solution, it may work, create a function. How about a function wich recives an array as parameter.
Something like this:
function finder(var array[], var valueToFound, var question) {
for (i=0; i<array.lenght; i++) {
if (array[i].value == valueToFound) {
switch (question) {
case 1: document.questions.questions1.options[i] = null;
break;
}
return;
}
}
}
I think i make my point, perhaps it can take you in the right direction
My bet is that the code isn't getting to array3[7] because either it doesn't exist or that array2 is too short and you're getting a JavaScript exception that's stopping the code from doing the check. Is it possible that array2 and array3 are shorter than array1?
It is more code, but I would do it like this:
var selectedvalue == txtbox1.value;
for(i=0; i<array2.length; i++) { // iterate over the length of array2, not array1
if(array2[i].value == selectedvalue) {
document.questions.questions2.options[i] = null;
break; // found it, move on
}
}
for(i=0; i<array3.length; i++) {
if(array3[i].value == selectedvalue) {
document.questions.questions3.options[i] = null;
break; // you're done
}
}

Categories