www.webdeveloper.com
Results 1 to 14 of 14

Thread: Color Change that should be simple...

  1. #1
    Join Date
    Sep 2008
    Posts
    47

    Color Change that should be simple...

    This piece of code takes a term and the position of a letter in the term and is suppose to change the color of that letter. However, Firefox gives me a 'undefined' value for the part highlighted in blue. Can't figure out why.

    Code:
    function colorChangeAndPush(y,the_term){
    
    var the_tag=document.createElement('span');
    var the_letter=the_term.charAt(y);
    
    
    for (var i=0; i<y+1; i++){
    
      the_letter.style.color="#7a7fe8";
    }
    
    
    if (the_match.length==0){
    
     the_match.push(the_term);
    
    }
    else
    {
       for (var i=0; i<the_match.length; i++){
          if (the_term==the_match[i])
          {
             the_match.splice(i,1,the_term);
    	 my_match=true;
          }
          else
          {
             my_match=false;
          }
       }
    }
    
    if (my_match==false)
    {the_match.push(the_term);}
    
    }

  2. #2
    Join Date
    Apr 2003
    Location
    Netherlands
    Posts
    21,654
    the_letter should reference an object (an element)

    Why is it in the loop
    At least 98% of internet users' DNA is identical to that of chimpanzees

  3. #3
    Join Date
    Sep 2008
    Posts
    47
    Quote Originally Posted by Fang View Post
    the_letter should reference an object (an element)

    Why is it in the loop
    Well...I'm creating a yahoo like word suggest where the letters keyed by the user are highlighted in the list of words provided by an XML file.

    I really don't think you'd want to look at all of this code that I have so I didn't post the entire code..only the segment(s) that I'm having issues with.

    It was in a loop because the original idea was to get the position of each letter keyed (y) and use that same position to change the color of the letter in the matching word and then display the matching word. But never mind that...I'll figure that out..

    I tried your suggestion above with this code and I got the same results ('undefined'):

    Code:
    function colorChangeAndPush(y,the_term){
    
    var user_letter=document.createTextNode(the_term.charAt(y));
    user_letter.style.color="#b9bceb";
    
    
    if (the_match.length==0){
    
     the_match.push(user_term);
    
    }
    else
    {
       for (var i=0; i<the_match.length; i++){
          if (user_term==the_match[i])
          {
             the_match.splice(i,1,user_term);
    	 my_match=true;
          }
          else
          {
             my_match=false;
          }
       }
    }
    
    if (my_match==false)
    {the_match.push(user_term);}
    
    }

  4. #4
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    only html elements have the style property. 1 char which you copy from a string is not an element. the best idea is probably to encapsulate the text which you want to highlight in a span tag with a certain class and then change your css. there are some threads on this forum, which talk about this, so you can search for text highlight, text color change or something similar...

  5. #5
    Join Date
    Sep 2008
    Posts
    47
    Quote Originally Posted by haulin View Post
    only html elements have the style property. 1 char which you copy from a string is not an element. the best idea is probably to encapsulate the text which you want to highlight in a span tag with a certain class and then change your css. there are some threads on this forum, which talk about this, so you can search for text highlight, text color change or something similar...
    Sorry for the late response...I didn't expect a response for this post so I didn't check for the past week.

    I thought I came up with a solution to this, and yet again I failed and I can't seem to find out why. My solution speaks to your advice.

    My logic in the following code was this:

    1. Get access to the word through the passed argument 'the_term'.
    2. Break each letter of the word up and add each letter to a slot in an array.
    3. Loop through the letter array and add a <span> style to the slot that needs it.
    4. Create a string object.
    5. Loop through the letter array and add each letter to the string object (which will give me a full word).
    6. Display it.

    Here's the code:

    Code:
    function colorChangeAndPush(the_term){
    
    var color_text="";
    var word_array=new Array();
    
    
    var w=0;
    
    while (w<the_term.length){
    
      word_array[w]=the_term.charAt(w);
      w++;
    }
    
    
    
    for (var i=0; i<word_array.length; i++)
    {
    
      if(i==placeholder)
      {color_text += '<span style="color:blue">'+word_array[i]+'</span>';}
      else
      {color_text += word_array[i];}
    }
    
    //don't mind the rest of the code after this point...I'm working on this..
    
    var my_match;
    
    if (the_match.length==0){
    
      the_match.push(color_text);
    
    }
    else
    {
      for (var i=0; i<the_match.length; i++){
    
         if (color_text==the_match[i])
         {
           the_match.splice(i,1,color_text);
           my_match=true;
         }
         else
         {
           my_match=false;
         }
      }
    }
    
    if (my_match==false)
    {the_match.push(color_text);}
    
    }
    The result I get??!!?
    Code:
    <span style="color:blue">M</span>ariah Carey
    <span style="color:blue">M</span>ary J. Blige
    <span style="color:blue">M</span>axwell
    <span style="color:blue">M</span>ichael Jackson
    This is what displays in the browser...I swear everything looks fine to me..

  6. #6
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,755
    It looks like you are mixing #text nodes with HTML. When you put HTML tags in #text nodes, they show up as normal characters and the browser does not parse it into the document object model. You'll actually need to create at least three DOM nodes:

    1) A #text node for the text before the colored text

    2) A SPAN node for the colored text, which gets style.color = "foo".

    3) A #text node for the text after the colored text.

    Or, you could add the HTML to the string and inject the string into the DOM by assigning an HTML tag's innerHTML property.

    el.innerHTML = string_with_colored_text;

  7. #7
    Join Date
    Apr 2003
    Location
    Netherlands
    Posts
    21,654
    Give a working example.
    At least 98% of internet users' DNA is identical to that of chimpanzees

  8. #8
    Join Date
    Sep 2008
    Posts
    47
    Quote Originally Posted by toicontien View Post
    When you put HTML tags in #text nodes, they show up as normal characters and the browser does not parse it into the document object model. You'll actually need to create at least three DOM nodes:
    This is the part that throws me off because based on HTML/CSS rules (and please correct me if I'm wrong), you're suppose to be able to apply inline styles (<span>) to text.

    I took an argument, got the word out of the argument, spread the letters of the word over an array in which each letter should now be a string.

    With this line:
    Code:
    color_text += eval("<span class='keycolor'>"+word_array[i]+"</span>");
    word_array[i] should represent a string. So based off of what you're saying, you can't apply inline styles to a string..?..This is the confusing part. Or is it a string in the first place? Maybe toString() would solve the problem.

    Anyhow I will definitely try your suggestion. I appreciate it. But I do need to be educated on why my thought process isn't working because it seemed flawless.

  9. #9
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,755
    Quote Originally Posted by JohnBeason View Post
    This is the part that throws me off because based on HTML/CSS rules (and please correct me if I'm wrong), you're suppose to be able to apply inline styles (<span>) to text.
    This is correct, as long as you are working with the document object model or HTML, and not just a plain old string.

    Quote Originally Posted by JohnBeason View Post
    I took an argument, got the word out of the argument, spread the letters of the word over an array in which each letter should now be a string.

    With this line:
    Code:
    color_text += eval("<span class='keycolor'>"+word_array[i]+"</span>");
    word_array[i] should represent a string. So based off of what you're saying, you can't apply inline styles to a string..?..This is the confusing part. Or is it a string in the first place? Maybe toString() would solve the problem.

    Anyhow I will definitely try your suggestion. I appreciate it. But I do need to be educated on why my thought process isn't working because it seemed flawless.
    You need to turn that string, which is HTML, into objects and inject it into the document object model. That's why assigning the HTML string to the innerHTML property of a DOM node works, because that string HTML is then parsed in to objects and injected into the document object model.

  10. #10
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    have a look at this example, hopefully it summarises what have been told here:
    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
      <head>
        <title>strings hilite</title>
        <style type="text/css">
          .keycolor {color: #7a7fe8;}
        </style>
        <script type="text/javascript">
          document.onclick = function() {
            var searchedString = "example";
            var container = document.getElementById("target_div"); //reach the parent element
            var text = container.firstChild.data; //get the text from a text node
            var stringIndex = text.indexOf(searchedString);
            if (stringIndex !== -1) { //if the text contains desired string
              text = text.replace(new RegExp(searchedString,"g"), "<span class='keycolor'>" + searchedString + "</span>"); //replace every occurence of the string with these strings encapsulated in span tags
            }
            container.innerHTML = text; //replace the text node
          }
        </script>
      </head>
      <body>
        <div id="target_div">my example and only example text</div>
      </body>
    </html>
    when clicked somewhere on the page, the searched string gets highlited
    Last edited by haulin; 04-22-2009 at 01:07 PM.

  11. #11
    Join Date
    Sep 2008
    Posts
    47
    I modified the code according to you and Tocontein's suggestions. "The colored text has to be parsed in a DOM"

    This has been the most frustrating part of this entire process. This is a imitation yahoo word suggest, and I got the word suggest portion correct while this little detail has been a thorn in my side.

    Code:
    function colorChangeAndPush(the_term,a){
    
    var search_term=the_term;
    
    
    for (var i=0; i<search_term.length; i++)
    {
    
      if(i==placeholder)
      {
        var the_letter= search_term.charAt(i);
      }
    }
    
    search_term = search_term.replace(the_letter, "<span class='keycolor'>"+the_letter+"</span>");
    
    var search_text=document.createTextNode(search_term);
    var my_text=document.createElement("div");
    my_text.appendChild(search_text);
    
    
    if (a==0){
    
      the_match.push(my_text.firstChild.nodeValue);
    
    }
    else
    {
    
       for (var i=0; i<the_match.length; i++){
          
           if (my_text.firstChild.nodeValue==the_match[i].firstChild.nodeValue)
           {
     	 the_match.splice(i,1,my_text);
           }
           
        }
    }
    
    }
    Now I'm back to my original results (my first post) displayed on the browser:

    Code:
    <span style="color:blue">M</span>ariah Carey
    <span style="color:blue">M</span>ary J. Blige
    <span style="color:blue">M</span>axwell
    <span style="color:blue">M</span>ichael Jackson

  12. #12
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    yeah, maybe if you could comment the lines of your code a little bit, because i'm really lost there... what is a, placeholder, the_match?

    i understand that you are trying to encapsulate every letter with the span tags. that should work, but it might be a better idea to take it by larger steps, so if i type "Mar" to the search box, the result will be
    HTML Code:
    <span style="color:blue">Mar</span>iah Carey
    <span style="color:blue">Mar</span>y J. Blige
    instead of your
    HTML Code:
    <span style="color:blue">M</span><span style="color:blue">a</span><span style="color:blue">r</span>iah Carey
    <span style="color:blue">M</span><span style="color:blue">a</span><span style="color:blue">r</span>y J. Blige
    but this is not the problem. the main issue here is, that you need to somehow reach the parent element, where your text is displayed and replace the whole text node with the one you create (highlighted). you can use the innerHTML property of the parent element, as i did in my example, because the browser then parses the string and create desired elements. or you can use the replaceChild method, but still you need to have a pointer to the parent element in the dom tree.

    supposing that your html content looks like this:
    HTML Code:
    <div id="outer_container">
      <div id="list">
        <div>Mariah Carey</div>
        <div>Mary J. Blige</div>
        <div>Maxwell</div>
        <div>Michael Jackson</div>
      </div>
    </div>
    reach the outer_container at the beginning of your function with:
    Code:
    var container = document.getElementById("outer_container");
    then you can do what you did:
    Code:
    search_term = search_term.replace(the_letter, "<span class='keycolor'>"+the_letter+"</span>");
    
    var search_text=document.createTextNode(search_term);
    var my_text=document.createElement("div");
    my_text.appendChild(search_text);
    after all the lines are proceeded, you need to finally inject the div inside the html, so for example:
    Code:
    var oldNode = document.getElementById("list");
    container.replaceChild(my_text,oldNode);
    p.s.: next time post your whole html, so we can work with something that really exists instead of just guessing how does it look like...
    Last edited by haulin; 04-27-2009 at 09:01 AM.

  13. #13
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    whoops, i just realised - you actually cannot do this:
    Code:
    var search_text=document.createTextNode(search_term);
    this is the exact problem, you are creating a text node, in which you insert the string containing span elements, so they are not being parsed. the easiest solution again seems to be to use the innerHTML property.

    anyway, i adjusted my example more to suit your needs, so try this:
    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
      <head>
        <title>strings hilite</title>
        <style type="text/css">
          .keycolor {color: #7a7fe8;}
        </style>
        <script type="text/javascript">
          document.onclick = function() {
            var container = document.getElementById("outer_container"), //reach the parent element
                list = document.getElementById("list"), //reach the old child element, which will be replaced
                lines = list.getElementsByTagName("div"), //make an array of all the child divs of the list
                newLine, //every line will be encapsulated in a div, which will contain the highlighted span parts
                newList = document.createElement("div"), //create new child element, which will replace the old list
                searchedString = "Mar",
                text;
            for (var i = 0; i < lines.length; i+=1) //loop through all the lines
            {
              text = lines[i].firstChild.data; //get the inner text
              if (text.indexOf(searchedString) === 0) { //if the searched string is in the beginning of the line
                text = text.replace(new RegExp(searchedString,""), "<span class='keycolor'>" + searchedString + "<"+"/span>"); //replace it once
              }
              newLine = document.createElement("div");
              newLine.innerHTML = text;
              newList.appendChild(newLine);
            }
            container.replaceChild(newList,list);
          }
        </script>
      </head>
      <body>
        <div id="outer_container">
          <div id="list">
            <div>Mariah Carey</div>
            <div>Mary J. Blige</div>
            <div>Maxwell</div>
            <div>Michael Jackson</div>
          </div>
        </div>
      </body>
    </html>
    Last edited by haulin; 04-27-2009 at 10:59 AM.

  14. #14
    Join Date
    Sep 2008
    Posts
    47
    Haulin,

    wanted to thank you for your solutions you provided. They helped me see the real problem...the <span> tags couldn't be parsed because I was passing the results to an array and not a container.

    I was using var the_match=new Array();

    when it should've been var the_match=document.createElement("div");

    Right now there's one other little DOM issue I'm having...if you're burned out that's fine I understand.

    With this:

    <div id="container">
    <div><span class='keycolor'>M</span>usic</div>
    <div><span class='keycolor'>L</span>ife</div>
    </div>

    Let's say that I wanted to get access to only the string 'Music' without the span tags and pass this string to a variable.

    Right now I'm using:

    var the_div=document.getElementById("container");
    var its_childs=the_div.childNodes;
    maybe some loop...

    var the_text=its_childs[i].innerHTML;

    ..but this is giving me a string with the span tags..any solutions...?..

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles