Solved

JavaScript GetElementsByClassName inside nested table or nested DIV not working

Posted on 2014-11-06
10
596 Views
Last Modified: 2014-11-12
I'm using the following code to populate a text box inside an APS.NET repeater using text on user input from other textboxes in the same repeater

<script type="text/javascript">
    window.populate_it = function populate_it(el) {
        //traverse up to the div
        var d = el.parentElement;
        // select childs 
        d.getElementsByClassName("tbPartNumber")[0].value = d.getElementsByClassName("tbGraphicID")[0].value + "-" + d.getElementsByClassName("tbSpecNumber")[0].value + d.getElementsByClassName("tbElementID")[0].value;
    }
</script>

Open in new window


<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div class="entry">
<table>
<tr>
<td>
<asp:TextBox ID="tbElementID" runat="server" class="tbElementID" name="tbElementID" oninput="populate_it(this)"></asp:TextBox><br />
<asp:TextBox ID="tbGraphicID" runat="server" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)"></asp:TextBox><br />
<asp:TextBox ID="tbSpecNumber" runat="server" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)"></asp:TextBox><br />
<asp:TextBox ID="tbPartNumber" runat="server" class="tbPartNumber" name="tbPartNumber"></asp:TextBox><br />
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>

Open in new window



This works fine. However, when I add the textboxes to a nested div or table, it no longer works
i.e.
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div class="entry">
<table>
<tr>
<td>
<table>
<tr>
<td><asp:TextBox ID="tbElementID" runat="server" class="tbElementID" name="tbElementID" oninput="populate_it(this)"></asp:TextBox></td>
<tr><td>
<asp:TextBox ID="tbGraphicID" runat="server" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)"></asp:TextBox></td>
<tr><td>
<asp:TextBox ID="tbSpecNumber" runat="server" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)"></asp:TextBox></td>
<tr><td>
<asp:TextBox ID="tbPartNumber" runat="server" class="tbPartNumber" name="tbPartNumber"></asp:TextBox></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>

Open in new window


Why is that? How can I make this work?
0
Comment
Question by:Mike Miller
  • 5
  • 4
10 Comments
 
LVL 4

Accepted Solution

by:
Ersoy Hasan earned 500 total points
ID: 40427848
see http://jsfiddle.net/qlayer/b3h7od32/
function closest(el, className) {
// find the first parent element which has className
  do {
    if (el.className.indexOf(className) > -1) {
      // tag name is found! let's return it. :)
      return el;
    }
  } while (el = el.parentNode);

  // not found :(
  return null;
}
window.populate_it = function populate_it(el) {
        //traverse up to the div
        var d = closest(el.parentElement, 'entry');
        // select childs 
        d.getElementsByClassName("tbPartNumber")[0].value = d.getElementsByClassName("tbGraphicID")[0].value + "-" + d.getElementsByClassName("tbSpecNumber")[0].value + d.getElementsByClassName("tbElementID")[0].value;
    }

Open in new window

Your html for every entry.
<div class="entry">
<table>
    <tr>
        <td>
            <table>
                <tr>
                    <td><input type="text" ID="tbElementID" class="tbElementID" name="tbElementID" oninput="populate_it(this)"></td>
                </tr>
                <tr>
                    <td>
                        <input type="text" ID="tbGraphicID" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)">
                    </td>
                </tr>
                <tr>
                    <td>
                        <input type="text" ID="tbSpecNumber" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)">
                    </td>
                </tr>
                <tr>
                    <td>
                        <input type="text" ID="tbPartNumber" class="tbPartNumber" name="tbPartNumber">
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
</div>

Open in new window

0
 
LVL 82

Expert Comment

by:leakim971
ID: 40427851
replace :
var d = el.parentElement;
by :
var d = el.parentElement.parentElement;
0
 
LVL 4

Expert Comment

by:Ersoy Hasan
ID: 40427860
I fixed the javascript a little:
function closest(el, className) {
  do {
    el = el.parentNode;
    if (el.className !== undefined && el.className.indexOf(className) > -1) {
      // class name is found! let's return it. :)
      return el;
    }
  } while (el.className !== undefined);

  // not found :(
  return null;
}
window.populate_it = function populate_it(el) {
        //traverse up to the div
        var d = closest(el.parentElement, 'entry');
        // select childs 
        d.getElementsByClassName("tbPartNumber")[0].value = d.getElementsByClassName("tbGraphicID")[0].value + "-" + d.getElementsByClassName("tbSpecNumber")[0].value + d.getElementsByClassName("tbElementID")[0].value;
}

Open in new window


This will work as long as you wrap your every entry (asp repeater item) in a parent element with class name 'entry'
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:Mike Miller
ID: 40428365
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
<script type="text/javascript">
    function closest(el, className) {
        do {
            el = el.parentNode;
            if (el.className !== undefined && el.className.indexOf(className) > -1) {
                // class name is found! let's return it. :)
                return el;
            }
        } while (el.className !== undefined);

        // not found :(
        return null;
    }
    window.populate_it = function populate_it(el) {
        //traverse up to the div
        var d = closest(el.parentElement, 'entry');
        // select childs 
        d.getElementsByClassName("tbPartNumber")[0].value = d.getElementsByClassName("tbGraphicID")[0].value + "-" + d.getElementsByClassName("tbSpecNumber")[0].value + d.getElementsByClassName("tbElementID")[0].value;
    }

</script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:Repeater ID="Repeater1" runat="server">
        <ItemTemplate>
        <div class="entry">
        <table>
        <tr>
        <td>
        <asp:TextBox ID="tbElementID" runat="server" Wrap="False" Width="178px" 
        Font-Names="Verdana" ForeColor="#666666" BackColor="#FFFFFF" 
        BorderColor="#999999" class="tbElementID" name="tbElementID" BorderWidth="1px" oninput="populate_it(this)"></asp:TextBox>
        </td>
        </tr>
        <tr>
        <td>
        GID: <asp:TextBox ID="tbGraphicID" runat="server" Wrap="False" Width="176" Font-Names="Verdana" ForeColor="#666666" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)"></asp:TextBox>
        </td>
        </tr>
        <tr>
        <td>
        SNL <asp:TextBox ID="tbSpecNumber" runat="server" Wrap="False" Width="176" Font-Names="Verdana" ForeColor="#666666" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)"></asp:TextBox>
        </td>
        </tr>
        <tr>
        <td>
        PN:<asp:TextBox ID="tbPartNumber" runat="server" Wrap="False" Width="176" Font-Names="Verdana" ForeColor="#666666" BackColor="#FFFFFF" 
        class="tbPartnumber" name="tbPartnumber" BorderColor="#999999" BorderWidth="1px"></asp:TextBox>
        </td>
        </tr>
        </table>
        </div>
        </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

Open in new window



The above code looks like this during runtime...

     <div class="entry">
        <table>
        <tr>
        <td>
        <input name="Repeater1$ctl00$tbElementID" type="text" id="Repeater1_ctl00_tbElementID" class="tbElementID" name="tbElementID" oninput="populate_it(this)" style="color:#666666;background-color:White;border-color:#999999;border-width:1px;border-style:solid;font-family:Verdana;width:178px;" />
        </td>
        </tr>
        <tr>
        <td>
        GID: <input name="Repeater1$ctl00$tbGraphicID" type="text" id="Repeater1_ctl00_tbGraphicID" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)" style="color:#666666;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        <tr>
        <td>
        SNL <input name="Repeater1$ctl00$tbSpecNumber" type="text" id="Repeater1_ctl00_tbSpecNumber" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)" style="color:#666666;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        <tr>
        <td>
        PN:<input name="Repeater1$ctl00$tbPartNumber" type="text" id="Repeater1_ctl00_tbPartNumber" class="tbPartnumber" name="tbPartnumber" style="color:#666666;background-color:White;border-color:#999999;border-width:1px;border-style:solid;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        </table>
        </div>
        
        <div class="entry">
        <table>
        <tr>
        <td>
        <input name="Repeater1$ctl01$tbElementID" type="text" id="Repeater1_ctl01_tbElementID" class="tbElementID" name="tbElementID" oninput="populate_it(this)" style="color:#666666;background-color:White;border-color:#999999;border-width:1px;border-style:solid;font-family:Verdana;width:178px;" />
        </td>
        </tr>
        <tr>
        <td>
        GID: <input name="Repeater1$ctl01$tbGraphicID" type="text" id="Repeater1_ctl01_tbGraphicID" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)" style="color:#666666;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        <tr>
        <td>
        SNL <input name="Repeater1$ctl01$tbSpecNumber" type="text" id="Repeater1_ctl01_tbSpecNumber" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)" style="color:#666666;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        <tr>
        <td>
        PN:<input name="Repeater1$ctl01$tbPartNumber" type="text" id="Repeater1_ctl01_tbPartNumber" class="tbPartnumber" name="tbPartnumber" style="color:#666666;background-color:White;border-color:#999999;border-width:1px;border-style:solid;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        </table>
        </div>
        
        <div class="entry">
        <table>
        <tr>
        <td>
        <input name="Repeater1$ctl02$tbElementID" type="text" id="Repeater1_ctl02_tbElementID" class="tbElementID" name="tbElementID" oninput="populate_it(this)" style="color:#666666;background-color:White;border-color:#999999;border-width:1px;border-style:solid;font-family:Verdana;width:178px;" />
        </td>
        </tr>
        <tr>
        <td>
        GID: <input name="Repeater1$ctl02$tbGraphicID" type="text" id="Repeater1_ctl02_tbGraphicID" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)" style="color:#666666;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        <tr>
        <td>
        SNL <input name="Repeater1$ctl02$tbSpecNumber" type="text" id="Repeater1_ctl02_tbSpecNumber" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)" style="color:#666666;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        <tr>
        <td>
        PN:<input name="Repeater1$ctl02$tbPartNumber" type="text" id="Repeater1_ctl02_tbPartNumber" class="tbPartnumber" name="tbPartnumber" style="color:#666666;background-color:White;border-color:#999999;border-width:1px;border-style:solid;font-family:Verdana;width:176px;" />
        </td>
        </tr>
        </table>
        </div>

Open in new window



I think that's what you're saying right? This does not work.
0
 
LVL 4

Expert Comment

by:Ersoy Hasan
ID: 40428417
your class names must be exactly equal to those in javascript:
<asp:TextBox ID="tbPartNumber" runat="server" Wrap="False" Width="176" Font-Names="Verdana" ForeColor="#666666" BackColor="#FFFFFF" 
        class="tbPartnumber" name="tbPartnumber" BorderColor="#999999" BorderWidth="1px"></asp:TextBox>

d.getElementsByClassName("tbPartNumber")

Open in new window


d.getElementsByClassName("tbPartNumber")!== tbPartnumber;
It is case sensitive it is not like Visual basic
0
 

Author Comment

by:Mike Miller
ID: 40428489
Gotcha. Bad habits...

Anything stick out to you here? Still not working...

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
<script type="text/javascript">
    function closest(el, className) {
        do {
            el = el.parentNode;
            if (el.className !== undefined && el.className.indexOf(className) > -1) {
                // class name is found! let's return it. :)
                return el;
            }
        } while (el.className !== undefined);

        // not found :(
        return null;
    }
    window.populate_it = function populate_it(el) {
        //traverse up to the div
        var d = closest(el.parentElement, 'entry');
        // select childs 
        d.getElementsByClassName("tbPartNumber")[0].value = d.getElementsByClassName("tbGraphicID")[0].value + "-" + d.getElementsByClassName("tbSpecNumber")[0].value + d.getElementsByClassName("tbElementID")[0].value;
    }

</script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:Repeater ID="Repeater1" runat="server">
        <ItemTemplate>
        <div class="entry">
        <table>
        <tr>
        <td>
        EID: <asp:TextBox ID="tbElementID" runat="server" class="tbElementID" name="tbElementID" oninput="populate_it(this)"></asp:TextBox>
        </td>
        </tr>
        <tr>
        <td>
        GID: <asp:TextBox ID="tbGraphicID" runat="server" class="tbGraphicID" name="tbGraphicID" oninput="populate_it(this)"></asp:TextBox>
        </td>
        </tr>
        <tr>
        <td>
        SNL <asp:TextBox ID="tbSpecNumber" runat="server" class="tbSpecNumber" name="tbSpecNumber" oninput="populate_it(this)"></asp:TextBox>
        </td>
        </tr>
        <tr>
        <td>
        PN:<asp:TextBox ID="tbPartNumber" runat="server" class="tbPartNumber" name="tbPartNumber"></asp:TextBox>
        </td>
        </tr>
        </table>
        </div>
        </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

Open in new window

0
 
LVL 4

Expert Comment

by:Ersoy Hasan
ID: 40428789
I cant see the problem can you share codebehind andare your running this in ie8 ?
0
 
LVL 4

Expert Comment

by:Ersoy Hasan
ID: 40428804
Here is a version of populate_it function that should work on ie8 :
  window.populate_it = function populate_it(el) {
        //traverse up to the div
        var d = closest(el.parentElement, 'entry');
        console.log(d.getElementsByClassName("tbPartNumber").length);
        // select childs 
        d.querySelectorAll(".tbPartNumber")[0].value = d.querySelectorAll(".tbGraphicID")[0].value + "-" + d.querySelectorAll(".tbSpecNumber")[0].value + d.querySelectorAll(".tbElementID")[0].value;
}

Open in new window


P.S. You still need closest function.
0
 

Author Closing Comment

by:Mike Miller
ID: 40429060
Got it. thanks again!
0
 

Author Comment

by:Mike Miller
ID: 40437761
0

Featured Post

Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question