JQuery compare arrays for any match - javascript

I'm having a pretty simple issue I think but I cannot get it solved.
On form submit I want to compare the values of two hidden input types and if any match is found return an alert to the user and prevent submit. Pretty much the hidden input type values will be 1-3, could be 1, 12, 123, 13 etc. So if 1 and 123, throw an alert.
So I've tried something like this, but I'm obviously confused about what I'm doing hehe.
var new_products = $('#new_products');
var array_new_products = jQuery.makeArray(new_products);
var existing_products = $('#existing_products');
var array_existing_products = jQuery.makeArray(existing_products);
$("#my_form").submit(function(e) {
if (jQuery.inArray(existing_products, new_products) >= 0) {
e.preventDefault();
alert ("This Promotion matches one or more products already associated to this Group. If you continue the existing Promotion will be cancelled and replaced with the currently selected Promotion!");
}
return true;
});
I'm open to doing this by comparing strings and returning matches or anything really. I'm just pretty new to Jquery. Thanks in advance.

$.each($('#new_products').val().split(''), function(i, char) {
var existing = $('#existing_products').val();
if (existing.indexOf(char) != -1)
alert('mathces found');
});
checks if any of the characters in the returned value from #new_product exists in the value returned from #existing_products ?

Related

Javascript validation on dynamic inputs and combining inputs with some logic

In a form (named createform) many inputs are created dynamically by clicking on add button (from 0 to any number for each kind of input).
The problem I'm having is the validation of the inputs that were created dynamically, because there is a complex logic behind it.
THE SCENARIO
I can have several different inputs:
brand
model
country
region
The first of them is called brand1, model1, country1 and region1, then adding others they will be called for instance brand2... brand50
In the starting scenario there will be only brand1 and model1. The country and region inputs are added only by clicking on a button.
THE VALIDATION CONDITION
I have to submit the form only in two cases:
If there is at least one brand + one model where both of them are not empty (any brand and any model, so it can also be brand5 and model12)
If there is at least one brand + country + region not empty (all of them not empty, same logic than before)
I made the following validation function which works good if I assume that I just have the first brand,model,country and region (so brand1,model1,country1 and region1).
THE CODE
function validateForm() {
var brand = document.forms["createform"]["brand1"].value;
var model = document.forms["createform"]["model1"].value;
if (document.forms["createform"]["country1"] === undefined) {
var country = "";
} else {
var country = document.forms["createform"]["country1"].value;
}
if (document.forms["createform"]["country1"] === undefined) {
var region = "";
} else {
var region = document.forms["createform"]["region1"].value;
}
if ((brand != "") && (model != "")) {
alert("Send");
return true;
} else if ((brand != "") && (country != "") && (region != "")) {
alert("Send");
return true;
} else {
alert("Impossible to send");
return false;
}
}
For better reading of the code I added return true even if it is not necessary.
The main problem is that it is impossible to know how many inputs there will be of every different kind. I was thinking about trying by checking if the inputs are starting with brand,model,country or region but I don't know how to cross my controls in my validation function with all the possible results.
Do you guys have any idea of how to solve this?
What you need is a way to access all your brand and model elements by the start of their name.
var elements = document.querySelectorAll("form[id='createform']>input[id^='brand']");
This will give you an array (instead of your single valued variable) which you can loop through looking for your values.
The nifty querySelectorAll accepts selectors which can narrow your search to all matching elements. In the example, it gets all input elements within a form named "createform" which start with (^=) "brand".
var brandelements = document.querySelectorAll("#createform select[name^='brand'] option:checked:not([value=''])");
This is the best way to get all the values of a select (you can easily change with a normal input) that are not empty.

Filter options by reading character length inside for loop

I have a widget (the widget code in the pen linked below is not the actual code, please just pay attention to the filtering function jQuery.fn.doFilterOptions(){..}).
Use case:
I have a non-native selectbox. I need to extend its functionality to accept an onclick event which allows the user to type data into the selectbox (not targeting a traditional <select>), it should filter the .options available by simply showing or hiding them based on its inner HTML value, if no match is found at any point during the loop through the string being entered by the user, I need the options to continue not being displayed.
Issue:
Right now it works 95% of the way, the only issue is that if an invalid char is found, the loop keeps checking the rest of the users entries char by char, and if the next char is a match to any of the options in the same index, it re-display's this as a valid .option.
$('.selectbox .selected').on('keyup', function(){
var theseOptions = $(this).parent('.selectbox').find('.option');
var defaultPlaceholder = $(this).data('placeholder');
var filterOptions = (function(curSelectedVal){
if (curSelectedVal === ' ' || curSelectedVal.length === 0 || curSelectedVal === defaultPlaceholder){
theseOptions.show();
}
var optionsVal;
var doInputOptionsComparison = (function(){
var invalidOption = false;
for (var letterPos = 0; letterPos < curSelectedVal.length; letterPos++){
theseOptions.each(function(optionIteration){
var thisOption = $(this);
thisOptionsVal = thisOption.html();
if (curSelectedVal.length > thisOptionsVal.length ){ // If a longer string has been input by the user than exists in the option being iterated over, hide this option
thisOption.hide();
invalidOption = true;
}
else if ((thisOptionsVal[letterPos].toLowerCase().trim() === curSelectedVal[letterPos].toLowerCase().trim()) && invalidOption === false){ // If the input string matches this option and no invalid options have been found in the letterPos prior to it, show this option
thisOption.show();
}
else { // If the string does not match any option
invalidOptionFound = true;
thisOption.hide();
}
});
}
})();
})($(this).html());
});
Here is the demo, try selecting then typing abz you will see the filter working properly.
Now erase that input data, and now type azc. You will see the abc option comes available again because the c matches in that same index (user input[i] = optionsHtml[i] = show();), resulting the the above described undesirable effect.
http://codepen.io/nicholasabrams/pen/KwwMPG?editors=001
BONUS:
Would this be easier by using regEx to do the filtering?
I managed to use a dynamic regEx filter function it it cut the code down big time! Wow what a better solution.
$.fn.filterOptionsByUserInput = function(optionSelector){
var curInput = $(this).html().trim().replace(/ /g, '').toLowerCase();
$(optionSelector).each(function(optionIndex){
var userInputRegEx = new RegExp('^'+curInput+'.*');
if ($(this).html().toLowerCase().trim().match(userInputRegEx)){
$(this).fadeIn('slow');
}
else {
$(this).fadeOut('slow');
}
});
};
http://codepen.io/nicholasabrams/pen/LEEwrm?editors=001

jquery filter values according to specific character at specific position

I am trying to filter a table of part numbers according to a user-defined value at a specific position.
see jsFiddle --> http://jsfiddle.net/bagofmilk/wx9F3/12/
The problem is that I'm allowing multiple conditions - not just ONE character at ONE position.
If you take a look at the fiddle you will see I use Table Sorter 2.0 Plugin which works great. But I also created a small table above that with 7 textboxes. Each of these textboxes represents a value of a part number in the table below.
'data-log' = if the textbox is null the value is 0, else the value will be 1.
'data-val' = the character position in the part number string.
Example: If the user types "07" into item# 2, then the script will need to filter the table where the part number has a "0" at character position 2 in the string, and "7" at character position 3 in the string
Most filters will search the ENTIRE string for a "07", but I need this to be specific to its position.
I also need it so that when the user also types in "L" into item#7 that the script will filter the part numbers where "07" are at char positions 2,3 AND where "L" is at char position 11 in the string.
Here's the main function I'm trying to deal with:
$('.modx').keyup(function() {
//I emtpy the "values" array and "position" array
arrval = [];
arrpos = [];
//Whatever textbox the user types in must indicate there is a value
$(this).attr('data-log', '1');
//I create an array of user input values and their positions
$('.modx').each(function() {
if ($(this).attr('data-log') == 1) {
arrval.push($(this).val());
arrpos.push($(this).attr('data-val'));
} else {}
});
/* THIS IS WHERE IM STUCK...Using the "values" array and "position" array,
check each part number where all values and positions are true.
I CANNOT COME UP WITH THE LOGIC HERE... */
});
I might be approaching this completely the wrong way. If so, I'd love to hear any other methods, or if you can think of the logic I could apply at the end of this keyup function that would be awesome too.
It is a regex bases solution
Add an additional data-* attribute data-length to the second and 5th modx text fields as shown below
<input type='text' data-log='0' data-val='1' tabindex='2' placeholder='03' class='size2 modx' id='item2' data-length="2"/>
....
<input type='text' data-log='0' data-val='7' tabindex='6' placeholder='53'class='size2 modx' id='item6' data-length="2"/>
then
var $modxs = $('.modx').keyup(function () {
var string = $modxs.map(function () {
var value = $.trim(this.value),
length = $(this).data('length') || 1;
while (value.length < length) {
value += '.';
}
return value;
}).get().join('');
string = string.replace(/(.{3})(.{5})(.{1})/, '$1-$2-$3');
var regex = new RegExp(string, 'i');
$('#partNumbers tbody tr').hide().filter(function () {
return regex.test($.trim($(this).children().first().text()))
}).show()
});
$('#clearBtn').click(function(){
$modxs.val('');
$('#partNumbers tbody tr').show()
})
Demo: Fiddle
First, let's see the logic. jQuery's filter() function, which seems to be the most practical to use here, works by running a filter function for every result element. When this function returns true, the element will be included in the filtered set.
So, in the filter function we need to check whether the value for the actual row (the text value of the first cell in the row in this case) satisfies all the requirements stored in your arrays.
For this, we iterate on arrpos. For every value we use substr() to extract the relevant part of the examined string (position is the current one from arrpos, length is the length of the current arrval element) and then compare it to the current value from arrval. If they are not equal, the check already failed, so we return false. If the for loop finishes running, we are certain we can return true (every check was successful).
A simple implementation (not thoroughly tested, just an illustration):
$('#partNumbers tbody tr') //get the rows
.hide() //hide all of them
.filter(function () {
var tValue = $(this).find('td:first').text();
for (var i = 0, l = arrpos.length; i < l; i++) {
if (tValue.substr(arrpos[i], arrval[i].length) !== arrval[i]) {
return false;
}
}
return true;
})
.show(); //show only the filtered ones (for which true was returned)
jsFiddle Demo

What does unescape() function returns?

I have to use unescape() function in an if-else statement. In my website I have two pages, one with a form that the user fills and the second page have to get the information from the filled form by unescape function. I need the if-else statement because in the form I put two radio buttons that each one adds different text areas with different ids' and names so I want to check in the second page what text fields are are filled. (all the fields created by clicking on a radio button which starts a javascript function so in the next page I must check if the field was created and not just to check if it is an unfilled text field).
It is a little bit hard for me to explain so just check the code. In the code you will see params["placeName"] and so on, so placeName for example like all the others is a text field name from the previous page.
So the question is - what does unescape function returns if the component name I insert as a paramater does exist in the previous page?
<script type="text/javascript">
function getParams() {
var idx = document.URL.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = document.URL.substring(idx + 1, document.URL.length).split('&');
for (var i = 0; i < pairs.length; i++) {
nameVal = pairs[i].split('=');
params[nameVal[0]] = nameVal[1];
}
}
return params;
}
params = getParams();
//from here it is what I want to do (I don't know if this condition in the if statement is correct, this is what I ask)
// if (unescape(params["placeName"]) == false) {
// }
// else {
var place = unescape(params["placeName"]);
var country = unescape(params["country"]);
var city = unescape(params["city"]);
var address = unescape(params["address"]);
var type = unescape(params["type"]);
var rate = unescape(params["rate"]);
// }
</script>
It can also work if I could check what radio button is checked
You are asking what will unescape(params["something"]) return if params["something"] is not present. The answer is undefined. So you need to check equivalence to "undefined". Meaning: if (unescape(params["placeName"]) == "undefined") (in this case params["placeName"] is not present (was not created).
The undecode function returns -as it's name indicated- a decoded string. If you enter a value that's not defined it will probably cause an error because of the indefinition. If what you want is to check whether the element was or not created or not you could use
if (params.placeName !== undefined) {
// It was created
}
instead.
Aditionally, if you want to check which radio button was checked use
if (document.getElementById('foo').checked) {
// Radio button with id 'foo' was checked
} else if (document.getElementById('bar').checked) {
// Radio button with id 'bar' was checked
} else if
...

jquery/javascript: arrays

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 }); ...

Categories