1074

I have a shopping cart that displays product options in a dropdown menu and if they select "yes", I want to make some other fields on the page visible.

The problem is that the shopping cart also includes the price modifier in the text, which can be different for each product. The following code works:

$(document).ready(function() {
    $('select[id="Engraving"]').change(function() {
        var str = $('select[id="Engraving"] option:selected').text();
        if (str == "Yes (+ $6.95)") {
            $('.engraving').show();
        } else {
            $('.engraving').hide();
        }
    });
});

However I would rather use something like this, which doesn't work:

$(document).ready(function() {
    $('select[id="Engraving"]').change(function() {
        var str = $('select[id="Engraving"] option:selected').text();
        if (str *= "Yes") {
            $('.engraving').show();
        } else {
            $('.engraving').hide();
        }
    });
});

I only want to perform the action if the selected option contains the word "Yes", and would ignore the price modifier.

cнŝdk
  • 28,676
  • 7
  • 47
  • 67
Jordan Garis
  • 10,759
  • 3
  • 13
  • 4
  • 13
    Change your selector from `$('select[id="Engraving"]')` to `$('#Engraving')`. It will be faster. And inside the `change` handler, `this` refers to the `#Engraving` element, so you can do `$(this).find('option:selected')`. – user113716 Aug 13 '10 at 21:33
  • How about :contains selector? – Oliver Ni Nov 28 '13 at 21:02
  • 3
    What this has to do with jQuery? This is pure JavaScript question. –  Mar 01 '14 at 07:28

13 Answers13

2226

Like this:

if (str.indexOf("Yes") >= 0)

...or you can use the tilde operator:

if (~str.indexOf("Yes"))

This works because indexOf() returns -1 if the string wasn't found at all.

Note that this is case-sensitive.
If you want a case-insensitive search, you can write

if (str.toLowerCase().indexOf("yes") >= 0)

Or:

if (/yes/i.test(str))

The latter is a regular expression or regex.

Regex breakdown:

  • / indicates this is a regex
  • yes means that the regex will find those exact characters in that exact order
  • / ends the regex
  • i sets the regex as case-insensitive
  • .test(str) determines if the regular expression matches str To sum it up, it means it will see if it can find the letters y, e, and s in that exact order, case-insensitively, in the variable str
RedGuy11
  • 95
  • 2
  • 13
SLaks
  • 800,742
  • 167
  • 1,811
  • 1,896
  • 33
    Can anyone explain the `if (/yes/i.test(str))`? – Drew S Feb 05 '15 at 23:31
  • 53
    @DrewS: That's a regex literal. – SLaks Feb 05 '15 at 23:45
  • 6
    Was looking for just the opposite of this. Will return a -1 if it does not exist. http://www.w3schools.com/jsref/jsref_indexof.asp Return value: A Number, representing the position where the specified searchvalue occurs for the first time, or -1 if it never occurs. For my needs: if (str.toLowerCase().indexOf("yes") == -1) – nwolybug Sep 14 '15 at 16:23
  • 7
    Note that `indexOf` isn't supported in IE8. – Nate Jenson Oct 02 '15 at 19:35
  • a bit shorter syntax: if (str.indexOf("Yes")+1) – Denis Apr 12 '16 at 17:07
  • I recognize this is old, but wouldn't `> -1` be more efficient than `>= 0`? I know it's likely to be marginal difference, but if you plan to do a lot of this on a page... – SnakeDoc May 18 '16 at 22:26
  • @SnakeDoc - He should actually just use `!= -1`. This is the official way to do it, and my instincts tell me it's probably also even faster – myfunkyside May 24 '16 at 01:12
  • 4
    @njenson: It is for strings - just not for Array objects. But thanks for freaking me out. http://stackoverflow.com/questions/21772308/what-is-the-alternate-function-for-indexof-for-string-in-ie8 – J Bryan Price Sep 01 '16 at 21:35
  • `if (~str.indexOf("Yes"))` fails if the string you are searching for is empty string or anything that results in the index being less than 0 – ParoX Dec 03 '17 at 04:10
  • 1
    @ParoX: No; that's exactly what you want. – SLaks Dec 03 '17 at 14:06
  • 1
    further short method you can use includes method. like "YesNo".includes("Yes") will give true. – Aditya kumar Jan 06 '18 at 16:20
  • Nice, but one note is I believe that'd be case-INsensitive when transforming target string to lowercase. – Donna Apr 05 '18 at 17:15
129

You could use search or match for this.

str.search( 'Yes' )

will return the position of the match, or -1 if it isn't found.

hookedonwinter
  • 11,741
  • 17
  • 55
  • 73
  • 24
    Good to know alternatives but using indexOf is faster. http://stackoverflow.com/questions/354110/in-javascript-what-is-the-difference-between-indexof-and-search – Blowsie Feb 02 '12 at 15:55
  • 5
    yeah but also not supported on IE – isJustMe Feb 14 '12 at 16:20
  • 4
    It is for strings, see http://www.w3schools.com/jsref/jsref_indexof.asp – Ian Stanway Jun 07 '12 at 16:57
  • 20
    @IanStanway and hookedonwinter Please don't link to w3schools. They are not a legitimate source and they try to sell stupid stuff like their certs. Links: search (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) match (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) indexof (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexof) MDN is a great source for javascript. w3fools.com can tell you more. – DutGRIFF Jan 24 '14 at 21:23
  • 9
    @DutGRIFF Yes and no. Discussion about that is not for here, but since w3fools was created and since everyone started warning people away from w3schools, they have improved their site. I do agree with you generally though and avoid it, but sadly the Google rankings think otherwise and I was too lazy to find a better site for the purpose of my link :-) – Ian Stanway Feb 04 '14 at 11:44
  • and here are some performance tests: http://jsperf.com/exec-vs-match-vs-test-vs-search/11 – elad silver May 06 '15 at 09:23
  • 2
    Be aware `search` uses regular expressions, so `'abc'.search('.') > -1` returns true even if there is no `.` character. – Oriol Apr 16 '16 at 22:49
  • Fully supported on IE: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf People seem to confuse `indexOf` method in `Array` prototype with the one in `String` prototype. Method `indexOf`prototyped in `Array` is not fully supported on IE, while the latter is. – adi518 Jun 26 '16 at 16:39
  • That indexOf is not cross browser compatible. match() and search() for me from here on out. Simply converting the array index text to string is a light lift to get cross browser peace of mind. – Alexander Dixon Jun 28 '16 at 19:20
  • In Chrome: .search is not a function. – Marcelo Agimóvel Apr 25 '18 at 13:11
42

It's pretty late to write this answer, but I thought of including it anyhow. String.prototype now has a method includes which can check for substring. This method is case sensitive.

var str = 'It was a good date';
console.log(str.includes('good')); // shows true
console.log(str.includes('Good')); // shows false

To check for a substring, the following approach can be taken:

if (mainString.toLowerCase().includes(substringToCheck.toLowerCase())) {
    // mainString contains substringToCheck
}

Check out the documentation to know more.

Munim Dibosh
  • 2,201
  • 1
  • 16
  • 27
28

Another way:

var testStr = "This is a test";

if(testStr.contains("test")){
    alert("String Found");
}

** Tested on Firefox, Safari 6 and Chrome 36 **

az7ar
  • 4,947
  • 2
  • 13
  • 23
Andy Braham
  • 7,763
  • 4
  • 38
  • 44
  • 3
    Which browser you're using? "TypeError: Object This is a test has no method 'contains'" – nuala Mar 14 '13 at 13:41
  • 2
    yoshi, Looks like this is only available in FireFox... sorry for the confusion, was in front of FF didn't think to test in other browsers... – Andy Braham Mar 19 '13 at 21:00
  • 2
    At the time of writing, it seems to be supported in Chromium 36. [More detail here](https://kangax.github.io/es5-compat-table/es6/#String.prototype.contains). – Léo Lam Apr 19 '14 at 14:04
  • In Opera 25 and Safari 5 doesn't work. – joan16v Oct 28 '14 at 16:29
16

ECMAScript 6 introduces String.prototype.includes, previously named contains.

It can be used like this:

'foobar'.includes('foo'); // true
'foobar'.includes('baz'); // false

It also accepts an optional second argument which specifies the position at which to begin searching:

'foobar'.includes('foo', 1); // false
'foobar'.includes('bar', 1); // true

It can be polyfilled to make it work on old browsers.

Oriol
  • 225,583
  • 46
  • 371
  • 457
  • This, polyfilled, in addition to hint from [Munim Dibosh](https://stackoverflow.com/a/37089247/3548026) pointing to case sensitive, is doing a real stable work, also for older browsers. – pixelDino Feb 23 '19 at 13:02
10

The includes() method determines whether one string may be found within another string, returning true or false as appropriate.

Syntax :-string.includes(searchString[, position])

searchString:-A string to be searched for within this string.

position:-Optional. The position in this string at which to begin searching for searchString; defaults to 0.

string = 'LOL';
console.log(string.includes('lol')); // returns false 
console.log(string.includes('LOL')); // returns true 
Community
  • 1
  • 1
Parth Raval
  • 3,325
  • 2
  • 20
  • 30
  • This doesn't have great browser support: https://caniuse.com/#feat=es6-string-includes currently 90% in the US note: **not** supported in IE <= 11 – Josh Nov 28 '18 at 00:57
9

You can use this Polyfill in ie and chrome

if (!('contains' in String.prototype)) {
    String.prototype.contains = function (str, startIndex) {
        "use strict";
        return -1 !== String.prototype.indexOf.call(this, str, startIndex);
    };
}
robkorv
  • 509
  • 6
  • 4
  • The title said that it is to be done in jQuery. Why go to such extends and complicate things with unreadable code when you can do it with a simple `if` in jQuery? – Dzhuneyt Jul 15 '13 at 14:38
  • 5
    this is in my opinion a nice solution. gives you a .contains method that does what was asked for. sure its not nice to look at but its a great utility... also "if" has nothing to do with jQuery... all the other answers have been js implementations... – Code Novitiate Oct 10 '13 at 01:42
8

Returns number of times the keyword is included in the string.

var count = "I have one keyword".match(/keyword/g);
var clean_count = !count ? false : count.length;
Kareem
  • 4,110
  • 37
  • 34
  • `match` can return `null`, and thus make your code throw – Oriol Nov 14 '16 at 16:39
  • match returns arrays. It is not possible for an array to be null. It could be empty. This is why I added "length". length of an empty array is false. @Oriol – Kareem Nov 17 '16 at 02:11
  • @Kareem Try `'a'.match(/b/).length` – Oriol Nov 17 '16 at 02:18
  • Yes, now it won't trow. Sometimes people use something like `(str.match(regex) || []).length` – Oriol Nov 17 '16 at 15:03
  • @Oriol you are not getting it. Try this function test(){ if('a'.match(/b/)){ return true; }else{ return false; } } test(); – Kareem Jul 23 '19 at 07:54
4

If you are capable of using libraries, you may find that Lo-Dash JS library is quite useful. In this case, go ahead and check _.contains() (replaced by _.includes() as of v4).

(Note Lo-Dash convention is naming the library object _. Don't forget to check installation in the same page to set it up for your project.)

_.contains("foo", "oo");     // → true
_.contains("foo", "bar");    // → false
// Equivalent with:
_("foo").contains("oo");     // → true
_("foo").contains("bar");    // → false

In your case, go ahead and use:

_.contains(str, "Yes");
// or:
_(str).contains("Yes");

..whichever one you like better.

Selfish
  • 5,210
  • 3
  • 35
  • 54
  • 3
    Note for readers that googled and landed here like me: `_.contains()` is replaced by `_.includes()` as of version 4. ;) – pataluc Dec 12 '16 at 14:16
3

I know that best way is str.indexOf(s) !== -1; http://hayageek.com/javascript-string-contains/

I suggest another way(str.replace(s1, "") !== str):

var str = "Hello World!", s1 = "ello", s2 = "elloo";
alert(str.replace(s1, "") !== str);
alert(str.replace(s2, "") !== str);
Sherali Turdiyev
  • 1,586
  • 14
  • 26
1

You can also check if the exact word is contained in a string. E.g.:

function containsWord(haystack, needle) {
    return (" " + haystack + " ").indexOf(" " + needle + " ") !== -1;
}

Usage:

containsWord("red green blue", "red"); // true
containsWord("red green blue", "green"); // true
containsWord("red green blue", "blue"); // true
containsWord("red green blue", "yellow"); // false

This is how jQuery does its hasClass method.

bashaus
  • 1,402
  • 1
  • 14
  • 27
0

None of the above worked for me as there were blank spaces but this is what I did

tr = table.getElementsByTagName("tr");

    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[0];
        bottab.style.display="none";
        bottab2.style.display="none";
        if (td) {
        var getvar=td.outerText.replace(/\s+/, "") ;

            if (getvar==filter){
                tr[i].style.display = "";
            }else{
                tr[i].style.display = "none";
            }

        }
    }
Kingsley Mitchell
  • 2,111
  • 14
  • 25
-1

you can define an extension method and use it later.

String.prototype.contains = function(it) 
{ 
   return this.indexOf(it) != -1; 
};

so that you can use in your page anywhere like:

var str="hello how are you";
str.contains("are");

which returns true.

Refer below post for more extension helper methods. Javascript helper methods

Vikas Kottari
  • 465
  • 1
  • 8
  • 22