Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

JavaScript GetElementsByClassName inside nested table or nested DIV not working

Posted on 2014-11-06
10
Medium Priority
?
753 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 2000 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 83

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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

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

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

Dramatic changes are revolutionizing how we build and use technology. Every company is automating, digitizing, and modernizing operations. We need a better, more connected way to work together as teams so we can harness the insights from our system…
Ready to get certified? Check out some courses that help you prepare for third-party exams.
This tutorial walks through the best practices in adding a local business to Google Maps including how to properly search for duplicates, marker placement, and inputing business details. Login to your Google Account, then search for "Google Mapmaker…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses
Course of the Month15 days, 1 hour left to enroll

577 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