-1

I am building a form with a search input that shows and hides an x inside the search input to clear the contents of that one input, but not the others in the form. I've written a function to show and hide the x based on whether or not the search input specifically is empty. Currently, my page renders the form twice based on the page width (I know that's not the best, but it's what I have currently and I'd like to leave it alone). To do that, I need to check if either instance of the search input on the page has content.

The code below works, but I'm concerned that it's fragile. If a form is added or removed from the page, I'd like this code to keep working. Any suggestions on how to clean up the line below?

function toggleFilterInput() {
  // The line I'd like to clean up
  if ( !$(".filter-input").first().val() && !$(".filter-input").last().val() ) {
    $(".filter-clear").addClass("hidden");
  } else {
    $(".filter-clear").removeClass("hidden");
  }
}

EDIT: I did see this possible duplicate, but didn't like any of the answers, thus why I'm asking a similar question again.

styger
  • 430
  • 3
  • 13
  • 1
    First thing first, you don't need to run a query select every time. Save the returned values in a variable. Ex: `var input = $(".filter-input");` also check the length of your string, this should be more accurate. – Ibu Nov 13 '15 at 19:09
  • If ya'll are going to downvote the question, at least leave a constructive comment on WHY you're downvoting. – styger Nov 19 '15 at 16:43

3 Answers3

1

Well, I don't have your HTML structure, but I'm guessing the element with the class of filter-clear is located before/after the input element in the DOM.

If this is the case, I would do it like this:

$(".filter-input").keyup(function () {
    if ($(this).val().length) {
        $(this).siblings(".filter-clear").removeClass("hidden");
    } else {
        $(this).siblings(".filter-clear").addClass("hidden");
    }
});

This way, the event is applied to all elements with the class filter-input, so they can easily be cleared.

Alternatively, I would probably add/remove the filter-clear element dynamically, instead of already having it exist in the DOM and just hiding or showing it. This will keep your DOM cleaner.

One other thing to keep in mind: Some browsers implement this functionality natively, and something like this could conflict with that functionality.

EDIT: I put together this quick example for you https://jsfiddle.net/w704zwax/

This is a basic example, but provides a solution based on how I'm reading your question. Please let me know if you are trying to achieve something different.

Howard Renollet
  • 4,609
  • 1
  • 24
  • 31
  • Thanks for the heads up about browsers sometimes implementing this natively. I'm really only looking to clear the one input like this, though, so not really what I'm looking for. – styger Nov 18 '15 at 17:18
  • @styger - According to your comments on the other answer, "The issue is to find a cleaner way to check when **any input in a collection** of inputs has a value", which is exactly what my code does, however, you're telling me that you are only performing this check on one input. Which is it? – Howard Renollet Nov 19 '15 at 13:53
  • There is a filter bar input that is duplicated across two forms, so it is one type of input that is rendered multiple times. So, what I'm looking for is how to clear that filter bar input if either instance of that input is populated, not how to clear every input on the page. – styger Nov 19 '15 at 16:40
  • Ok, so the selector can be changed to match your criteria. See the edit above. Is this more of what you are looking for? If I'm still off, could you please update the question with the HTML of the page, or maybe put together a fiddle so I can see the structure myself so I can be of more assistance to you? Thanks! – Howard Renollet Nov 19 '15 at 19:38
1

Here's a helper function that will tell you if all inputs in a jQuery collection are blank:

function allAreBlank(inputs) {
    return inputs.get().every(function(input){
        return $(input).val() == "";
    });
}

It uses Array.prototype.every(), which comes from the browser's javascript engine rather than from jQuery. Using it lets us not care about how many inputs there are on the page. (A thing to note: many of these convenient functions available on Array.prototype are not available in older browsers, which may or may not be a concern to you. MDN's docs will usually have a polyfill you can use in case you need to support browsers that do not have the functionality natively.)

We have to call .every() on a javascript Array rather than a jQuery collection, so we use jQuery's .get() to turn the jQuery collection into a javascript array.

You could use this function in your code like this:

function toggleFilterInput() {
    if ( allAreBlank($(".filter-input")) ) {
        $(".filter-clear").addClass("hidden");
    } else {
        $(".filter-clear").removeClass("hidden");
    }
}

Ultimately, though, I prefer an approach like the one @howard suggests, where each pair of filter input and .filter-clear are self-contained, and typing something into the filter input at the top of the page doesn't cause the .filter-clear element to show up on the (empty) filter input at the bottom of the page.

hynkle
  • 301
  • 4
  • 6
0

first cache the dom somewhere. store the selector into a variable like Ibu mentioned.

Second, if you want to check if an input has text or not you could always do

$(selector) or in this case <varname>.keyup(function(){
   var text = $(this).val().length;

    if( text == 0 ){
       $(".filter-clear").addClass("hidden");
    }else{
       $(".filter-clear").removeClass("hidden");
    }
});
  • Yeah, I know how to check the value on an input. The issue is to find a cleaner way to check when any input in a collection of inputs has a value. – styger Nov 18 '15 at 17:19
  • so when you type into any input field, you want to check to see if that input has a value? If it does then display the 'X'? – Joshua JLIVE Williams Nov 18 '15 at 18:51
  • "Currently, my page renders the form twice"..."The code below works, but I'm concerned that it's fragile. If a form is added or removed from the page, I'd like this code to keep working. Any suggestions on how to clean up the line below?"... `if ( !$(".filter-input").first().val() && !$(".filter-input").last().val() )` I want to know if there is a value in one of the two search inputs. I only want suggestions for making that boolean check more robust and future proof. – styger Nov 18 '15 at 19:46