0

I have an html table within a list view, and have a hidden label in it called "vehicle_num". I am able to get the selected row of the table, as well as any of the td, however I cannot seem to get the value of the label. I have tried:

var vehicle_number = $(this).closest('tr').children('#vehicle_num').text();

Below is the code for the listview. How can I get the value of the label?

<asp:ListView ID="lvEquipmentList" runat="server" DataKeyNames="vehicle_number">
    <LayoutTemplate>
            <table id="table-equipment-list" class="table table-list">
                <thead>
                    <tr>
                        <th scope="col" class="product-line">Product line</th>
                        <th scope="col" class="model-number">Model #</th>
                        <th scope="col" class="serial-number">Serial #</th>
                        <th scope="col" class="dar-status">DAR Status</th>
                        <th scope="col" class="ship-date">Ship Date</th>
                    </tr>
                </thead>
                <tbody>
                    <asp:PlaceHolder ID="ItemPlaceholder" runat="server" /> 
                </tbody>
            </table>
    </LayoutTemplate>
    <ItemTemplate>
        <tr>
            <th scope="row" class="product-line"><div class="icon"><img src='<%#Eval("image_path")%>' onerror="this.src='assets/images/placeholder.png';" alt=""/></div> <span class="line-title"><%#Eval("product_line")%></span></th>
            <td class="model-number"><%#Eval("model")%><label class="vehicle_num" hidden="hidden"><%#Eval("vehicle_number")%></label></td>
            <td class="serial-number"><%#Eval("serial_number")%></td>
            <td class="dar-status"><img src='<%#Eval("display_status") %>'/></td>
            <td class="ship-date"><%#Eval("date")%></td>
        </tr>
    </ItemTemplate>
    <EmptyDataTemplate>
        <table id="table-equipment-list" class="table table-list">
            <thead>
                <tr>
                    <th scope="col" class="product-line">Product line</th>
                    <th scope="col" class="model-number">Model #</th>
                    <th scope="col" class="serial-number">Serial #</th>
                    <th scope="col" class="dar-status">DAR Status</th>
                    <th scope="col" class="ship-date">Ship Date</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <th scope="row" class="product-line"><div class="icon"></div> <span class="line-title"></span></th>
                    <td class="model-number"></td>
                    <td class="serial-number"></td>
                    <td class="dar-status"></td>
                    <td class="ship-date"></td>
                </tr>   
            </tbody>
        </table>
    </EmptyDataTemplate>
</asp:ListView>

EDIT

I have edited the code above to put the label in a table column. I was able to get the value using:

var vehicle_number = $(this).closest('tr').find('.vehicle_num').text();
KateMak
  • 1,619
  • 6
  • 26
  • 42
  • 1
    ` – David Oct 10 '14 at 14:45
  • 1
    `ASP.NET` tends to change the `Control` `ID` specially when using `MasterPages`. – emerson.marini Oct 10 '14 at 14:46
  • Check this out: [Control.ClientIDMode Property](http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode(v=vs.110).aspx) – emerson.marini Oct 10 '14 at 14:47
  • Related: [How to stop ASP.NET from changing IDs in order to use jQuery](http://stackoverflow.com/questions/497802/how-to-stop-asp-net-from-changing-ids-in-order-to-use-jquery) – emerson.marini Oct 10 '14 at 14:49
  • Also fix your `HTML` markup as suggested by @David. – emerson.marini Oct 10 '14 at 14:50
  • Thank you everyone, you were correct in that a label is not a valid child of a tr. Issue was solved by instead placing the hidden label in one of the columns. I have edited my code above to include this. – KateMak Oct 10 '14 at 15:17

1 Answers1

2

This is invalid markup:

<tr>
    <th scope="row" class="product-line"><div class="icon"><img src='<%#Eval("image_path")%>' onerror="this.src='assets/images/placeholder.png';" alt=""/></div> <span class="line-title"><%#Eval("product_line")%></span></th>
    <td class="model-number"><%#Eval("model")%></td>
    <td class="serial-number"><%#Eval("serial_number")%></td>
    <td class="dar-status"><img src='<%#Eval("display_status") %>'/></td>
    <td class="ship-date"><%#Eval("date")%></td>
    <label id="vehicle_num" hidden="hidden" runat="server"><%#Eval("vehicle_number")%></label>
</tr>

There's an errant label as a child of a tr, which isn't valid. When the browser tries to make sense of this, it could be doing anything with that label to construct a valid DOM, which is going to effect your jQuery selectors.

The label needs to be in a table cell:

<tr>
    <th scope="row" class="product-line"><div class="icon"><img src='<%#Eval("image_path")%>' onerror="this.src='assets/images/placeholder.png';" alt=""/></div> <span class="line-title"><%#Eval("product_line")%></span></th>
    <td class="model-number"><%#Eval("model")%></td>
    <td class="serial-number"><%#Eval("serial_number")%></td>
    <td class="dar-status"><img src='<%#Eval("display_status") %>'/></td>
    <td class="ship-date"><%#Eval("date")%></td>
    <td><label id="vehicle_num" hidden="hidden" runat="server"><%#Eval("vehicle_number")%></label></td>
</tr>

(Or, if it's always hidden anyway, you can probably put it in an existing table cell. Either way should work.)

Additionally, if the client-side id is being explicitly set here, then any repetition of these records will result in duplicate ids in the DOM, which is also invalid. Different browsers respond to id-based selectors in different ways when there are duplicate ids, because the behavior is undefined. You probably want to use a class instead:

<label class="vehicle_num" ...

Since the label is no longer a child of the tr but rather a descendant of it, use find() instead of children():

$(this).closest('tr').find('.vehicle_num')
David
  • 208,112
  • 36
  • 198
  • 279
  • Great suggestion, putting the label inside of one of the other td! I will try this now. – KateMak Oct 10 '14 at 15:01
  • I have edited my code above to place the label inside a td. I was able to get the value by using: var vehicle_number = $(this).closest('tr').find('#vehicle_num').text(); – KateMak Oct 10 '14 at 15:14
  • @KateMak: I still recommend making sure you're not re-using the client-side `id`. If that selector works then it means you are (provided there's more than one record in the `ListView`), which means that selector is *coincidentally* working in this particular case, but the markup remains invalid so there's no guarantee that it will always work or that other similar selectors will work. – David Oct 10 '14 at 15:16
  • Since this is a listview, the client side id would indeed be repeated...is there a better way I can achieve the desired result? – KateMak Oct 10 '14 at 15:48
  • @KateMak: I imagine you could let ASP.NET manage the "id" and just use a "class" for the JavaScript selector. – David Oct 10 '14 at 16:18
  • Sounds good! I will alter my code to use class instead. Thank you again! – KateMak Oct 10 '14 at 16:28