0

Let's say I have 3 textboxes in cshtml. What I am trying to do in Javascript is the following:

Check if ANY OF those 3 values and ONLY THEM is not null.

The only way I can think of is doing it manually:

if ((val1 & !val2 & !val3) || (!val1 & val2 & !val3) || (!val1 & !val2 & val3))

It is okay if it is a small number of textboxes, but if such number grows to 10+, it might become a hassle.

Is there any efficient way to implement such logic in Javascript regardless of how many textboxes we are dealing with?

10
  • 1
    Why would a checkbox ever have the value null, it should always return a string ? Commented Oct 11, 2016 at 15:39
  • 1
    And yes, there are at least somewhat efficient ways to write such code, using a common selector and Array.some etc. Commented Oct 11, 2016 at 15:40
  • 1
    @VadzimSavenok OK, then why would a text box ever have the value null as opposed to an empty string? Commented Oct 11, 2016 at 15:42
  • 2
    [...values].some( val => val === null ) Commented Oct 11, 2016 at 15:43
  • 1
    Do like [...element.querySelectorAll(selector)].filter(e => e.value === null).length === 1 ? doThis() : doThat() Commented Oct 11, 2016 at 15:50

4 Answers 4

2

just keep in th array values not null and then count how many remains :

var arr = ["hello", "", ""];

var result = arr.filter(x => x !== "").length;

if (result === 1) console.log("exactly one is not empty");
Sign up to request clarification or add additional context in comments.

1 Comment

It is partially of what I need, but I also need to make sure EXACTLY ONE element is not empty. In your case, it sounds AT LEAST ONE element is not empty.
1

You can use .reduce:

var nonEmpty = [val1, val2, val3].reduce(((c, v) => c += (v !== "")), 0);
if (nonEmpty === 1) {
  // exactly one is not empty
}

Any other way of counting the non-empty inputs and checking that the count is equal to 1 would work too of course.

What that .reduce() code does is use an "arrow function" that increments a counter (c) when a value is not the empty string. (If you want to check for null, you can do that instead of course.) You could use a plain old-fashioned function too:

var nonEmpty = [val1, val2, val3].reduce(function(c, v) {
  return c += (v !== "");
}, 0);

The .reduce() function is passed 2 parameters: that callback function, and the initial value of c (zero in this case). The return value will be the final value of c returned by the last call to the callback.

2 Comments

I believe that might be exactly what I need. Can you please briefly explain the logic inside reduce method, so I can get the idea of properly using it.
@VadzimSavenok yes I will extend the answer
1

You can directly check the textboxes for the values. If you are working in razor means you can use Jquery. Also this solution will work for any number of textboxes.

 var count=0;
 var isExactlyOneNotEmpty= 
    function(){
    $('input[name="text[]"]').each(function() {
        if($(this).val()!="")
        {
          ++count;
        }
    });
    if(count==1)
    return true
    else
    return false;
    }
 var check=isExactlyOneNotEmpty();
 alert(check);
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="text1" name="text[]">
<input type="text" id="text2" name="text[]" value="test">
<input type="text" id="text3" name="text[]">

Comments

1

You could use the Exclusive OR (XOR) operator for that. Let's see what we can get with it:

enter image description here

However, the only result that doesn't fit your need is the last one (it returns true when all of them are also true).

To solve that, you could check if all values are not true at the same time. Summarizing, this expression does the trick:

if( !(val1 && val2 && val3) && (val1^val2^val3) )

3 Comments

It is good for small values, but if number grows to 10 or 20, it becomes a long line.
You're right, I've missed the "regardless of how many textboxes" part
I still appreciate this answer because I was looking explicitly for a small number. +1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.