Check for partial match in JavaScript if statement - javascript

I've got elements set up something like this:
<div class="cat" data-cat="example-cat, test-cat, test-category">
...
</div>
<div class="cat" data-cat="test-category">
...
</div>
<div class="cat">
...
<div class="cat" data-cat="example-cat, test-category">
...
</div>
<div class="cat" data-cat="test-category, one-more-cat">
...
</div>
</div>
Using JavaScript, I need to check each bit of text between commas for a match with a user selected value. For example, if the user selected "test-cat," I need to check each div to see if data-cat matches the selection. If it does, I need to add class="active" to each matching div.
Part of the trick is that if the user selects test-cat, a div with a data-cat of test-category should not return positive. Only exact matches should be consider matches.
I had already set up a complex filtering system with support for multiple filters, but the client wants to be able to set multiple categories per div, which is making this tricky. I have a script set up to show matches if the attribute is an exact match, and I'll be trying to modify this to work as I need it to:
$(document).ready(function() {
var changedOnce = false;
$("#filters select").change(function() {
$(".cat").each(function() {
$(this).attr("data-match", "true");
$(this).removeClass("open");
});
$("#filters select").each(function() {
var filter = $(this).attr("name");
var value = $(this).val();
$(".cat").each(function() {
if ($(this).attr("data-match") === "false") {
return true;
}
var attr = $(this).attr("data-" + filter);
var childAttr = $(this).find(".cat").attr("data-" + filter)
if ((typeof attr !== typeof undefined && attr !== false) || (typeof childAttr !== typeof undefined && childAttr !== false)) {
if ($(this).attr("data-" + filter) === value || $(this).find(".cat").attr("data-" + filter) === value || value === "") {
$(this).attr("data-match", "true");
$(this).parents(".cat").attr("data-match", "true");
} else {
$(this).attr("data-match", "false");
return true;
}
} else {
if (value !== "") {
$(this).attr("data-match", "false");
return true;
} else {
$(this).attr("data-match", "true");
$(this).parents(".cat").attr("data-match", "true");
}
}
});
});
});
});
My filters are set up something like:
<div id="filters">
<select name="cat">
<option value="test-cat">Test Cat</option>
<option value="example-cat">Example Cat</option>
...
</select>
...
<select name="nth-filter">
...
</select>
</div>
It's probably not the most elegant solution (I'm no JavaScript master), but it was working, until I made this most recent change. If you need more information, just let me know.
UPDATE: Here's my current script, using .data() and .split() as suggested. I'm having trouble getting the parent category to show as a miss if all its children are misses, but I'll post a separate question for that.
$(document).ready(function() {
$("#filters select").change(function() {
$(".cat").each(function() {
$(this).data("match", true);
$(this).css("opacity", "1");
// $(this).removeClass("open");
});
$("#filters select").each(function() {
var filter = $(this).attr("name");
var value = $(this).val();
$(".cat").not(".primary").each(function() {
if ($(this).data(filter)) {
var match = $(this).data("match");
var attributes = $(this).data(filter).split(", ");
var i = 0;
$(attributes).each(function() {
if (value && attributes[i] !== value) {
match = false;
} else {
match = true;
return true;
}
i++;
});
$(this).data("match", match);
}
if ($(this).data("match") === false) {
$(this).css("opacity", "0.25");
} else {
$(this).css("opacity", "1");
}
});
});
});
});

You can use the String's split function to split the comma-separated values into an array, and then use the Array's indexOf function to check for a match.
var attr = $(this).attr("data-" + filter);
if (attr && (attr.split(/[\s*,\s*]+/).indexOf() >= 0)) {
Note: I left out this part of the check: attr !== false. attr should either be a String or undefined, so it will never be false. Did you mean to check if it is the string "false"?
Also, when you call the following:
var childAttr = $(this).find(".cat").attr("data-" + filter)
You should be aware that .attr() will return the value of the first matched element, and from your markup it looks like there could be multiple matched elements.

Related

Check existence of values in array on multi select dropdown focusout in jQuery

i have a default array that have some fixed values from which i am showing a multiselect dropdown to user.So on focusout of the drop down i want to check that whether the values are selected have the all those values that are in the default array.If the values are missing i want to alert them to the user
HTML
<form action="#" method="post">
<fieldset>
<label for="selectedItemLists">Select values:</label>
<select id="selectedItemLists" name="selectedItemLists" multiple>
<option val="value1" selected >value1</option>
<option val="value2">value2</option>
<option val="value3" selected>value3</option>
<option val="value4">value4</option>
<option val="value5">value5</option>
</select>
</fieldset>
<fieldset>
<input type="submit" value="submit" />
</fieldset>
</form>
jQuery
var default_values = ["value1","value3"];
$("#selectedItemLists").live('focusout',function(){
var new_selectedvalues = $("#selectedItemLists").val();
//here i want to compare both the arrays and alert him that default values are missing
});
A simple nested $.each loop will do it:
Demo
//here i want to compare both the arrays and alert him that default values are missing
$.each(default_values, function(_, defaultVal){
var found = false;
$.each(new_selectedvalues, function(){
if(this == defaultVal){
found = true;
return false;
}
});
if(!found){
alert("Please select the default: " + defaultVal);
}
});
Note: .live() is deprecated from jQuery 1.7, so .on should be used instead (unless you are working with the old version).
Just try with:
var default_values = ["value1","value3"];
$("#selectedItemLists").on('blur',function(){
var values = $(this).val();
if ($(values).not(default_values).length == 0 && $(default_values).not(values).length == 0) {
console.log('equal');
} else {
console.log('not equal');
}
});
http://jsfiddle.net/f5BbT/
try something like this
var default_values = ["value1","value3"];
$("#selectedItemLists").focusout(function() {
var selected_val = $('#selectedItemLists').val();
if(selected_val.length < default_values.length){
alert('value not present');
}else{
var flag = true;
for(var i= 0;i<default_values.length;i++){
if(selected_val.indexOf(default_values[i]) == -1){
flag = false;
}
}
if(!flag){
alert('value not present');
}else{
alert('value present');
}
}
});
I would do someting like this:
var default_values = ["value1","value3"];
var displayValues = [];
$("#selectedItemLists").on('blur',function(){
$.each(default_values, function(index, value) {
if($.inArray(value, $("#selectedItemLists").val()) === -1)
{
displayValues.push(value);
}
});
});
alert(displayValues);
please use
$("#selectedItemLists").on('blur',function(){
instead of
$("#selectedItemLists").live('focusout',function(){
live is deprecated since jQuery 1.7 and removed in 1.9
try this JSFIDDLE
var default_values = ["value1", "value3"];
$("#selectedItemLists").on('blur', function () {
var missing_values = [];;
var values = $(this).val();
//******************************************
//checking missing values in default_values
//******************************************
$.each(values, function (key, value) {
if ($.inArray(value, default_values) == -1) {
missing_values.push(value);
}
});
alert(missing_values);
// alerts missing selected values in default_values
});
or try
var default_values = ["value1", "value3"];
$("#selectedItemLists").on('blur', function () {
var missing_values = [];
var values = $(this).val();
//******************************************
//checking default values in selection
//******************************************
$.each(default_values, function (key, value) {
if ($.inArray(value, values) == -1) {
missing_values.push(value);
}
});
alert(missing_values);
// alerts missing default values in selected
});

I want to disable the button if specific text has been found in any label

I want to disable the button if specific text has been found in any label.
The following code doesn't run because aTags[i].innerText is not equal to searchText all the time which is wrong because the label has inner text = "a" and the searchText variable have "a" as text - I need it to run in IE
<html>
<script language="javascript">
$(document).ready(function () {
var aTags = document.getElementsByTagName("label");
var searchText = "a";
var found;
for (var i = 0; i < aTags.length; i++) {
if (aTags[i].innerText == searchText) {
document.getElementById('choose').disabled=true;
break;
}
else
{
alert("failed")
}
}
});
</script>
<label> a </label> <br/>
<label> b </label> <br/>
<label> c </label> <br/>
<input type='button' value='choose' id='choose' />
</html>
Seems like there should be easier ways to do that with jQuery
$(function () {
var searchText = "a";
$('#choose').prop('disabled', function() {
return $('label').filter(function(_,el) {
return $.trim( $(el).text() ) === searchText;
}).length > 0;
});
});
FIDDLE
The issue is that your label contains " a " (with the spaces), but you're comparing with "a" (no spaces).
If you want to ignore the spaces, you can use jQuery's $.trim(...) to trim the text off the innerText.
But as you're using jQuery, you can dramatically reduce that code:
$(document).ready(function() {
var searchText = "a";
var found = false;
$("label").each(function() {
found = $.trim($(this).text()) === searchText;
if (found) {
return false; // No need to keep looking
}
});
$("#choose").prop("disabled", true);
});
Since you're already using jQuery, you can do what you like with much less complexity.
This will work:
(function ($) {
var searchText = "a";
$('label').each(function(){
if ($.trim($(this).text()) === searchText) {
$('#choose').prop('disabled', true);
}
});
})(jQuery);
You have to trim label's text. Try with:
if (aTags[i].innerText.trim() == searchText)
or without trim method:
if (aTags[i].innerText.replace(/^\s+|\s+$/g, '') == searchText)
If you want to match if a substring exists you can try with
aTags[i].innerText.indexOf(searchText) > -1
instead of
aTags[i].innerText == searchText

Client-side searching in checkbox value

I need help.. for now I'm trying to create a client search but I don't know how to compare values from input text to checkboxes.
jsFiddle Example
Example:
jQuery("#searchBox").on("keyup paste", function() {
var value = jQuery(this).val().toUpperCase();
var rows = jQuery(".sp_country");
rows.hide();
if(value === '') {
rows.show();
return false;
}
//need something here to compare values on checkboxes and show does checkedbox who match
});
Here is my check box located
<span class="sp_country">
<input class="cp_country" style="cursor:pointer; display:none;" type="checkbox" name="country" value="Afghanistan"> Afghanistan
</span>
You can use .filter() method:
rows.filter(function() {
return $(this).text().toUpperCase().indexOf(value) > -1;
}).show();
Or in case that you want to compare the input with value of checkboxes:
rows.filter(function(){
return this.children[0].value.toUpperCase().indexOf(value) > -1;
}).show();
You can can also use the jQuery's .find() method for selecting the input descendants.
Try this
$("cp_country").each(function(){
if($(this).val()==("#searchBox").val()){
$(this).parent(".sp_country").show();
}
});
Whole idea is:
iterate through each of the checkbox value
if the value matches with search box value then
show the parent span element
Try this:
$("#searchBox").on("keyup paste", function() {
var value = $(this).val().toUpperCase();
var rows = $(".cp_country");
rows.hide();
if(value === '') {
rows.show();
return false;
}
else{
rows.each(function(){
if($(this).val().toUpperCase().indexOf(value) != -1){
$(this).show();
}
else{ $(this).hide();}
});
}
});

jQuery, same function for multiple ids

i want to clear specified input if the value is not number. function works for one ID, but i want it to work for multiple. of course i can write function multiple times but i dont want to do that.
the following code gets effect only for input with id "d". i dont know how to identify other ids. can anyone help?
<input id="d" />
<input id="d2" />
<input id="d3" />
<script type="text/javascript">
$('#d,d2,d3').keyup(function(){
if($('#d,d2,d3').val() != "") {
var value = $('#d,d2,d3').val().replace(/^\s\s*/, '').replace(/\s\s*$/, '');
var intRegex = /^\d+$/;
if(intRegex.test(value)) {}
else {
$(this).val('');
}
}
});
</script>
Instead of $('#d,d2,d3') use $('#d, #d2, #d3') and for the if statement use $(this).val()
You can use starts with selector instead of putting in multiple ids like this:
$('[id^=d]')
Above selector will work for all elements whose ids start with d eg d1, d2, d3 and so on.
Here is how your code should be (fixing other errors as well):
$('[id^=d]').keyup(function(){
if(this.value != "") {
var value = this.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
var intRegex = /^\d+$/;
if(intRegex.test(value)) {}
else {
this.value = '';
}
}
});
$('input[id^=d]').keyup(function() {
var val = $.trim( this.value ); // or $.trim( $(this).val() )
if (val != "") {
var value = val.replace(/^\s\s*/, '').replace(/\s\s*$/, ''),
intRegex = /^\d+$/;
if (intRegex.test(value)) {
// do something
} else {
$(this).val('');
}
}
});​
[id^=d] is a start with selector that means, id start with d.
Read about jQuery start selector
You forgot the # for d2 & d3. And also a this.
$('#d,#d2,#d3').keyup(function(){
if($(this).val() != "") {
var value = $(this).val().replace(/^\s\s*/, '').replace(/\s\s*$/, '');
var intRegex = /^\d+$/;
if(intRegex.test(value)) {}
else {
$(this).val('');
}
}
});
You forgot the hash for the other two Ids:
$('#d,#d2,#d3')
see also
jQuery Multiple ID selectors
You can add class attribute
<input id="d" class="A"/>
<input id="d2" class="A"/>
<input id="d3" class="A"/>
use following selector by class name
$('.A').keyup

More efficient way of writing this javascript

I am creating a contact form for my website and and using javascript to the first layer of validation before submitting it which is then checked again via php but i am relatively new to javascript, here is my script...
$("#send").click(function() {
var fullname = $("input#fullname").val();
var email = $("input#email").val();
var subject = $("input#subject").val();
var message = $("textarea#message").val();
if (fullname == ""){
$("input#fullname").css("background","#d02624");
$("input#fullname").css("color","#121212");
}else{
$("input#fullname").css("background","#121212");
$("input#fullname").css("color","#5c5c5c");
}
if (email == ""){
$("input#email").css("background","#d02624");
$("input#email").css("color","#121212");
}else{
$("input#email").css("background","#121212");
$("input#email").css("color","#5c5c5c");
}
if (subject == ""){
$("input#subject").css("background","#d02624");
$("input#subject").css("color","#121212");
}else{
$("input#subject").css("background","#121212");
$("input#subject").css("color","#5c5c5c");
}
if (message == ""){
$("textarea#message").css("background","#d02624");
$("textarea#message").css("color","#121212");
}else{
$("textarea#message").css("background","#121212");
$("textarea#message").css("color","#5c5c5c");
}
if (name && email && subject && message != ""){
alert("YAY");
}
});
How can i write this more efficiently and make the alert show if all the fields are filled out, thanks.
$("#send").click(function() {
var failed = false;
$('input#fullname, input#email, input#subject, textarea#message').each(function() {
var item = $(this);
if (item.val()) {
item.css("background","#121212").css("color","#5c5c5c");
} else {
item.css("background","#d02624").css("color","#121212");
failed = true;
}
});
if (failed){
alert("YAY");
}
});
glavic and matt's answers were exactly what I was going to suggest, except I would take it a step further by separating the logic from the presentation.
Have classes defined in your css for when a field contains an invalid entry, and add or remove that class using $.addClass() or $.removeClass()
Since you're using jQuery, I would recommend setting a class on each field that requires a non-blank value (class="required").
Then you do something like this:
var foundEmpty = false;
$(".required").each(function()
{
if($(this).val())
{
foundEmpty=true;
$(this).style("background-color", "red");
}
});
if(foundEmpty)
{
alert("One or more fields require a value.");
}
Giving them a common class, define classes to apply the styles, and do this:
JS
$("#send").click(function() {
$('.validate').attr("class", function() {
return $(this).val() === "" ? "validate invalid" : "validate valid";
});
if( $('.invalid').length === 0 ) {
alert('YAY');
}
});
CSS
.valid {
background:#121212;
color:#5c5c5c
}
.invalid {
background:#d02624;
color:#121212;
}
HTML
<button id="send">SEND</button><br>
<input class="validate"><br>
<input class="validate"><br>
<input class="validate"><br>
<input class="validate">
JSFIDDLE DEMO
A little bit more efficient approach:
var validate = $('.validate');
$("#send").click(function() {
validate.attr("class", function() {
return $(this).val() === "" ? "validate invalid" : "validate valid";
});
if( validate.filter('.invalid').length === 0 ) {
alert('YAY');
}
});
You can use jQuery to iterate over each object and get their values. Depending on your form, this code will change, but it's to give you an example. I'm probably missing a couple of brackets here and there but the concept is there.
var objectName=$(this).attr('id');
$('#formId').children().each(
function(){
if ($(this).value == ""){
$(this).css("background","#d02624");
$(this).css("color","#121212");
$error[objectName]='true';
}else{
$(this).css("background","#121212");
$(this).css("color","#5c5c5c");
$error[objectName]='false';
}
}
);
$.each(error, function(key, value){
if (value=='false'){
alert (key + 'is empty');
}
});
I would probably divide part of this up into my css file. If any of the fields are empty add a class like "empty" to the object, if not, remove it. Then in your css file you can add some descriptors like:
input#fullname,
input#email {
...
}
input#fullname.empty,
input#email.empty {
...
}
You can use jQuery addClass() and removeClass().
You can then add a loop as follows:
var inputs = new Array();
inputs[0] = "input#fullname";
inputs[1] = "input#email";
inputs[2] = "input#subject";
inputs[3] = "textarea#message";
var complete = true;
for (var i = 0; i < 4; i++) {
var value = $(inputs[0]).val();
if (value.length > 0) {
$(inputs[i]).removeClass("empty");
} else {
complete = false;
$(inputs[i]).addClass("empty");
}
}
if (complete) {
}
EDIT:
There you go, fixed it for you.

Categories

Resources