0

in the Author and Title fields a user may enter strings like:

contains Ad or contains Jack or contains ack etc..

and my html table will display the appropriate information (ie books where the title (or author, if we're talking about the Author field..) contains the given substring.. But it's not working.. What am I doing wrong? I keep getting contains is not defined in my error console..

(by the way, all of my conditionals var author=... etc. definitions should be place before if(moz)? Otherwise this will only work in Firefox right?)

 <html>
  <script type="text/javascript">

  function filterTable(f)
  {
  var xmlDoc = loadXML("books.xml");
  var stylesheet = loadXML("books.xsl");
  var moz = (typeof document.implementation.createDocument != 'undefined');
  var ie = (typeof window.ActiveXObject != 'undefined');

  if (moz)
  {
    var nsResolver = stylesheet.createNSResolver( stylesheet.ownerDocument == null ? stylesheet.documentElement : stylesheet.ownerDocument.documentElement);

    var value = stylesheet.evaluate("//xsl:template[@match='/']//xsl:for-each", stylesheet, nsResolver, XPathResult.ANY_UNORDERED_NODE_TYPE, null);


    var author = document.getElementById("inauthor").value;
    var title = document.getElementById("intitle").value;
    var filter = "";

    if (author != "")
    {
       if(contains(author,"contains"))
       {
              filter = filter + "contains(author," + "'" + author.substr(10) + "'" + ")";
       }

       else filter= filter + "author='" + author.substr(1) + "'";
    }

    if (title != "")
    {
        if (filter != "") filter = filter + " and ";

        if(contains(title,"contains"))
        {
          filter = filter + "contains(title," + "'" + title.substr(10) + "'" + ")";
        }

        else
        {
          filter = filter+ "title='" + title.substr(1) + "'";
        }
    }

    if (filter != "") filter = "[" + filter + "]";

    value.singleNodeValue.setAttribute("select", "books/scifi"+filter);

    var proc = new XSLTProcessor();
    proc.importStylesheet(stylesheet);
    var resultFragment = proc.transformToFragment(xmlDoc, document);
    document.getElementById("target4").appendChild(resultFragment);
  }

  else if (ie)
  {

    var value = stylesheet.selectSingleNode("//xsl:template[@match='/']//xsl:for-each");
    value.setAttribute("select", "books/scifi"+filter);
    document.write(xmlDoc.transformNode(stylesheet));
  }


 }

    </script>
<center>
  <table border="1" cellpadding="8">
  <tr><td>
  </br>
    <form>
      <center>
        <b> search by </b>
        Author(s): <input type="text" name="authors" id="inauthor"/>
        Title: <input type="text" name="title" id="intitle" />
        </br></br>
        <input type="button" value="Display" onClick="filterTable(this.form)"/>
     </center>
    </form>
   </td></tr>
   </table>
</center>

</body>

</html>

2 Answers2

0

How to check whether a string contains a substring in JavaScript?

Usually I would expect a String.contains() method, but there doesn't seem to be one.

indexOf returns the position of the string in the other string. If not found, it will return -1.

Edit:

if (contains(author,"contains")) {

Should be:

if (myString.indexOf(author) !== -1) {
Community
  • 1
  • 1
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • I found an `contains(string1,string2)` XPath function at w3schools.. So do you mean I should use something like if( indexof..==-1) etc.. ? –  Mar 08 '12 at 19:06
  • information found at w3schools is often incorrect, www.w3fools.com – jbabey Mar 08 '12 at 19:07
  • hehe, I should stick to stackoverflow I guess! If that's the case, then after my conditional what should I add to my `filter=`? –  Mar 08 '12 at 19:12
  • @user1073400, make sure to clearly distinguish between languages when you using more than one at a time: contains **is** XPath function, but you've tried to use it for both JavaScript and XPath. – Alexei Levenkov Mar 08 '12 at 19:19
  • @user1073400 i am not sure what contains is supposed to do, so i am not sure what your filter is supposed to accomplish. – jbabey Mar 08 '12 at 19:20
  • @Alexei Levenkov it's true I still have trouble with such distinctions.. Based on what you see in my html file above, do you know what I should put inside the body of `if (myString.indexOf(author) !== -1) {` ? –  Mar 08 '12 at 19:22
  • @jbabey the user should type in the word "contains" followed by a substring that might be part of the title or author the user is looking for.. –  Mar 08 '12 at 19:23
  • This is what I came up with : `if (author != "") { if(author.indexOf("contains")!=-1) { filter = filter + "author.indexOf(author.substr(10))!=-1)"; } else filter= filter + "author='" + author.substr(1) + "'"; }` –  Mar 08 '12 at 19:25
  • Whatever you have in original XPath creation seems to be ok as it is (`filter = filter + "contains(ti...`. Make sure to step through the code in debugger and verify if resulting XPath looks good. BTW, your XPath creation will likely have problems with strings with single/double quotes. – Alexei Levenkov Mar 08 '12 at 19:26
  • @jbabey In this particular case, W3Schools is correct. The XPath `contains(haystack, needle)` function works just like they say it does. – Ross Patterson Mar 08 '12 at 20:16
0

Your mistake is in thinking that XPath functions are available as JavaScript functions. The XPath contains(haystack, needle) function is only available in XPath expressions. So your if (contains(author,"contains")) and if(contains(title,"contains")) should be if(author.indexOf("contains") >= 0) and if (title.indexOf("contains") >= 0). For extra credit, you should also escape any ' characters in *blah*.substr(10), so your code doesn't blow up when the author's name is "O'Malley, Liam".

Ross Patterson
  • 9,527
  • 33
  • 48
  • Thanks a lot for your input Ross! I am now trying something like this: `if (author != "") { if(author.indexOf("contains")!=-1) { filter = "author.indexOf(" + author.substr(9) + ")!=-1"; }` but it's not working, what do you think is the problem now? –  Mar 08 '12 at 20:34
  • Again, you're coding in two different environments - XPath and JavaScript - and you have to use the correct function for each environment. Use `indexOf` in JavaScript and `contains` in XPath. – Ross Patterson Mar 08 '12 at 20:37
  • oh I think I got it now : I should use the contains() function in my `value.setattribute` because this is XPath, and indexOf in my conditional because that is Javascript.. right? wow, i'm in the same javascript filterTable() function and Javascript and Xpath keep switching between each other.. complicated.. –  Mar 08 '12 at 20:41
  • `if (author != "") { if(author.indexOf("contains")!=-1) { filter = "contains(author," + "'"+author.substr(9) + "'" + ")"; } else filter= "author='" + author.substr(1) + "'"; }` is this correct? –  Mar 08 '12 at 20:50
  • yup, it is :) Thanks to everyone! –  Mar 08 '12 at 20:54