0

I'm trying to get a basic search function working on a list that gets displayed inside a modal.

When I type something in the input box, input.value in the javascript function below is an empty string for some reason. As a result the javascript search/filter function doesn't do anything.

thanks for your help.

VB (generates HTML):

<WebMethod()>
    Public Function GetIionsList(schedTypeUID As Integer) As String
        
        Dim table As String = ""
        Dim sql As String = ""
        Dim inspListHTML As New StringBuilder

        Dim dif As DataInterfaceFactory = GetSettingsDIF()

        Dim UserInfo As New NAMEGenericCls.UserCls.NAMEUser
        Dim userName As String = GetUserName(dif)
        UserInfo.Initialise(userName, dif)
        Dim SchedDataRight As New NAMEGenericCls.SecDataRights
        SchedDataRight.LoadDataRights(dif, UserInfo.UID, UserInfo.GroupUID)

        Select Case schedTypeUID
            Case SchedType.PLANNED
                table = "TABLE_ONE"
            Case SchedType.ADHOC
                table = "TABLE_TWO"
            Case SchedType.EXISTING
                table = "TABLE_THREE"
        End Select

        sql = SchedDataRight.CheckDataRights(dif, "SELECT I_UID FROM " & table)

        inspListHTML.Append("<input type='text' id='textInput' onkeyup='IionSearch()' placeholder='Search..' title='Type in a word'>").AppendLine()
        inspListHTML.Append("<br>").AppendLine()
        inspListHTML.Append("<br>").AppendLine()
        inspListHTML.Append("<ul id='ISelectListUL' class='list-group'>").AppendLine()

        Using dr As New DataReader(dif)
            dr.ExecuteReader(sql)

            Dim PreviousIUID As String = ""
            Dim CurrentIUID As String = ""

            While dr.Read()
                If Not IsDBNull(dr!I_UID) Then
                    CurrentIUID = dr!I_UID

                    If CurrentIUID <> PreviousIUID Then
                        PreviousIUID = CurrentIUID
                        Using drlkp As New DataReader(dif)

                            Dim qp As New List(Of Sqlclient.SqlParameter)
                            qp.Add(New SqlClient.SqlParameter("@CurrentIUID", CurrentIUID))

                            Dim lkp As String = SchedDataRight.CheckDataRights(dif, "SELECT I_NAME FROM TABLE_TWO WHERE I_UID = @CurrentIUID ")
                            drlkp.ExecuteReader(lkp, qp)

                            If Not IsDBNull(lkp) Then
                                getInspListHTML(inspListHTML, dr!I_UID, drlkp!I_NAME, schedTypeUID)
                            End If
                        End Using

                    End If
                Else
                    getInspListHTML(inspListHTML, 999, "Error - No Iions Found", "")
                End If

            End While
        End Using

        inspListHTML.Append("</ul>").AppendLine()

        Return inspListHTML.ToString()


    End Function

Rendered HTML:

<input type='text' id='textInput' onkeyup='IionSearch()' placeholder='Search..' title='Type in a word'>
<br>
<br>
<ul id='ISelectListUL' class='list-group'>
<li><a id='li_InspID_117' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>1 Monthly - Safety Iion                     </a></li>
<li><a id='li_InspID_118' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>x1 and 2 Monthly - Safety Iion              </a></li>
<li><a id='li_InspID_119' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>Full Sector - Safety Iion                   </a></li>
<li><a id='li_InspID_120' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>x2 Monthly - Safety Iion                    </a></li>
<li><a id='li_InspID_121' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>x4 Monthly - Safety Iion                    </a></li>
<li><a id='li_InspID_122' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xHigh Traffic - Safety Iion                 </a></li>
<li><a id='li_InspID_123' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xHigh &amp; Med Traffic - Safety Iion           </a></li>
<li><a id='li_InspID_124' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xMed Traffic - Safety Iion                  </a></li>
<li><a id='li_InspID_125' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xLow Traffic - Safety Iion                  </a></li>
<li><a id='li_InspID_126' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xPeriod Full Sector - Safety Iion           </a></li>
<li><a id='li_InspID_127' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xPeriod Full Sector - Safety Iion           </a></li>
<li><a id='li_InspID_128' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xPeriod Full Sector - Safety Iion           </a></li>
<li><a id='li_InspID_129' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>3 Monthly - Safety Iion                     </a></li>
<li><a id='li_InspID_130' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>6 Monthly - Safety Iion                     </a></li>
<li><a id='li_InspID_131' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>1 and  3 Monthly - Safety Iion              </a></li>
<li><a id='li_InspID_132' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>Adhoc                                             </a></li>
</ul>

The rendered HTML is displayed using:

$('#IionList').html(inspListHTML);

JS:

function IionSearch() {
        var input, filter, ul, li, a, i, txtValue;
        input = document.getElementById("textInput");
        filter = input.value.toUpperCase();
        ul = document.getElementById("ISelectListUL");
        li = ul.getElementsByTagName("li");
        for (i = 0; i < li.length; i++) {
            a = li[i].getElementsByTagName("a")[0];
            txtValue = a.textContent || a.innerText;
            if (txtValue.toUpperCase().indexOf(filter) > -1) {
                li[i].style.display = "";
            } else {
                li[i].style.display = "none";
            }
        }
    };

function IionSearch() {
  var input, filter, ul, li, a, i, txtValue;
  input = document.getElementById("textInput");
  filter = input.value.toUpperCase();
  ul = document.getElementById("ISelectListUL");
  li = ul.getElementsByTagName("li");
  for (i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName("a")[0];
    txtValue = a.textContent || a.innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
};
<input type='text' id='textInput' onkeyup='IionSearch()' placeholder='Search..' title='Type in a word'>
<br>
<br>
<ul id='ISelectListUL' class='list-group'>
  <li><a id='li_InspID_117' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>1 Monthly - Safety Iion                     </a></li>
  <li><a id='li_InspID_118' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>x1 and 2 Monthly - Safety Iion              </a></li>
  <li><a id='li_InspID_119' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>Full Sector - Safety Iion                   </a></li>
  <li><a id='li_InspID_120' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>x2 Monthly - Safety Iion                    </a></li>
  <li><a id='li_InspID_121' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>x4 Monthly - Safety Iion                    </a></li>
  <li><a id='li_InspID_122' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xHigh Traffic - Safety Iion                 </a></li>
  <li><a id='li_InspID_123' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xHigh &amp; Med Traffic - Safety Iion           </a></li>
  <li><a id='li_InspID_124' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xMed Traffic - Safety Iion                  </a></li>
  <li><a id='li_InspID_125' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xLow Traffic - Safety Iion                  </a></li>
  <li><a id='li_InspID_126' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xPeriod Full Sector - Safety Iion           </a></li>
  <li><a id='li_InspID_127' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xPeriod Full Sector - Safety Iion           </a></li>
  <li><a id='li_InspID_128' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>xPeriod Full Sector - Safety Iion           </a></li>
  <li><a id='li_InspID_129' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>3 Monthly - Safety Iion                     </a></li>
  <li><a id='li_InspID_130' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>6 Monthly - Safety Iion                     </a></li>
  <li><a id='li_InspID_131' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>1 and  3 Monthly - Safety Iion              </a></li>
  <li><a id='li_InspID_132' onclick="javascript:selectIion(this.id,'1');" class='list-group-item'>Adhoc                                             </a></li>
</ul>
NickyLarson
  • 115
  • 1
  • 2
  • 18
  • Look at what the rendered HTML becomes - that'll probably help you identify the problem. It sounds like it doesn't include the elements with those IDs – CertainPerformance Aug 24 '20 at 15:14
  • @CertainPerformance I've added the rendered HTML above, it looks ok as far as I can tell – NickyLarson Aug 24 '20 at 15:24
  • If that's the HTML, it looks to work fine. The code there *shouldn't* produce the error you describe, as you can see in the snippet - it works as desired. If you can't figure out how to reproduce the problem here, can you link to a site where this doesn't work? – CertainPerformance Aug 24 '20 at 15:52
  • I can't unfortunately. In that case, I'm wondering if the the element hasn't yet loaded in the dom and requires `window.onload = ` at the start of the function. For some reason the function no longer triggers when doing this though, neither does it trigger when I wrap it in `$(document).ready(function () {...}` – NickyLarson Aug 24 '20 at 16:08
  • `InspectionSearch` is only called on keyup, which will occur *after* the DOM is loaded, so wrapping everything in `.ready` or `.onload` won't help - and, since you're using inline handlers (which you [shouldn't](https://stackoverflow.com/a/59539045)), wrapping will actually cause your script to *break*. But it should work fine without wrapping. – CertainPerformance Aug 24 '20 at 16:16
  • Which variable exactly becomes `null` in your code? What is the line that throws? – CertainPerformance Aug 24 '20 at 16:17
  • @CertainPerformance there is no line that throws, it's just that value of `filter` is an empty string in this line: `filter = input.value.toUpperCase();` even after I type something in the search bar. So the filter doesn't work – NickyLarson Aug 24 '20 at 16:45
  • `InspectionSearch` is bound to the `keyup` event of your `INPUT`; shouldn't it be bound to the `change` event instead? Otherwise it is going to be called every time you release a key, which may have something to do with it being called with no value present. – CB_Ron Aug 24 '20 at 20:03
  • @CB_Ron, I've bound it to the keyup event on the input so that it filters dynamically as the user types. I've tried binding it to a change event instead but I still have the same issue with `filter` being an empty string – NickyLarson Aug 25 '20 at 09:05

1 Answers1

0

After this line

 inspListHTML.Append("</ul>").AppendLine()

add this:

inspListHTML.AppendLine("<script type='text/javascript'>  (function test() { document.getElementById('textInput').addEventListener('keyup', function execute() { InspectionSearch(); }) })();</script>")
G3nt_M3caj
  • 2,497
  • 1
  • 14
  • 16
  • Thanks for the suggestion. Unfortunately I still have the same issue. `filter` is an empty string regardless of what I type – NickyLarson Aug 25 '20 at 08:58
  • @NickyLarson How is placed your Html data that you reverie by GetInspectionsList Server function. Is that wrote by javascript? If yes, you need to transform/parse before as dom elements and ad those as elements not as literal string. At this point you can have access to those elements by dom. – G3nt_M3caj Aug 25 '20 at 09:40
  • If I remove `onkeyup='InspectionSearch()'` from my code and add the event listener you suggested, InspectionSearch() doesn't get triggered at all. EDIT: just saw your second comment, looking into it now – NickyLarson Aug 25 '20 at 09:43
  • If your keyup event is triggered regulary but you are not able to find input element by document.getElementById, so pass that input as parameter like this onkeyup="InspectionSearch(this);" – G3nt_M3caj Aug 25 '20 at 09:51
  • the HTML data is placed by running: `$('#inspectionList').html(inspListHTML);` that jquery function expects a string so it does not work if I parse to dom. I also tried passing the input as a parameter but it didn't make any difference. – NickyLarson Aug 25 '20 at 09:59
  • Use the DOMParser to transform generated string in dom elements. Then append the first element as a child to body or to another element. – G3nt_M3caj Aug 25 '20 at 10:57