6

I have a Multiview search feature on a Web User Controller that is called within a Repeater, OHMY!!

I have some training sessions being listed out on a page, each calling an employeeSearch Web User Controller so people can search for employees to add to the training session. I have the Employee Names and Employee IDs listed out in JS on the page and using the jQuery autocomplete i have them search for the employee and populate a hidden field in the User controller. Once the process is done they have the option of adding yet another employee.

So i had Autocompelte 'work' in all the employee search boxes, but one i do the initial search (postback) autocomplete won't work again.

Then i updated $().ready(function() to pageLoad() so it works correctly on multiple searches but only in the LAST item of the repeater (jQuery is loaded on the User Controller)

FYI: I have the JS string set as EMPLOYEENAME|ID and jQuery displays the Employee Name and if they select it throws the ID in a ASP:HIDDEN FIELD

    <script type="text/javascript">

    format_item = function(item, position, length) {
        var str = item.toString().split("|", 2);           
        return str[0];
    }

     function pageLoad() {    
        $("#<%=tb_EmployeeName.ClientID %>").autocomplete(EmployeeList, {
            minChars: 0,
            width: 500,
            matchContains: true,
            autoFill: false,
            scrollHeight: 300,
            scroll: true,
            formatItem: format_item,
            formatMatch: format_item,
            formatResult: format_item
        });
        $("#<%=tb_EmployeeName.ClientID %>").result(function(event, data, formatted) {                
            var str = data.toString().split("|", 2);
            $("#<%=hf_EmployeeID.ClientID %>").val(str[1]);
        });
    };       

    </script>

I can already guess that by repeating pageLoad within the User Controll i override the previous pageLoad.

THE QUESTION: Is there a way around this, a way to have all the jQuery appear in a single pageLoad or to somehow have a single jquery call to handle all my search boxes?

I can't move the jQuery into the page calling all the controllers because i have no way of referencing the specific tb_EmployeeName textbox AND hf_EmployeeID hidden field.

Thank you so much for any help or insight you can give me into this problem.

This is the Multiview that on the User Controller

        <asp:MultiView ID="mv_EmployeeArea" runat="server" ActiveViewIndex="0">

        <asp:View ID="vw_Search" runat="server">                  
            <asp:Panel ID="eSearch" runat="server">
                <b>Signup Employee Search</b> (<i>Last Name, First Name</i>)<br />
                <asp:TextBox ID="tb_EmployeeName" class="EmployeeSearch" runat="server"></asp:TextBox> 
                <asp:HiddenField ID="hf_EmployeeID" runat="server" />

                <asp:Button ID="btn_Search" runat="server" Text="Search" />
            </asp:Panel>                     
        </asp:View>

        <asp:View ID="vw_Confirm" runat="server">
            <b>Signup Confirmation</b>
            <asp:FormView ID="fv_EmployeeInfo" runat="server">
                <ItemTemplate> 
                    <%#(Eval("LastName"))%>, <%#(Eval("FirstName"))%><br />
                </ItemTemplate>
            </asp:FormView>    
            <asp:Button ID="btn_Confirm" runat="server" Text="Signup this employee" />  &nbsp; <asp:Button ID="btn_Reset3" runat="server" Text="Reset" />   
        </asp:View>

        <asp:View ID="vw_ThankYou" runat="server">
            <b>Thank You</b><br />
            The employee has been signed up and an email confirmation has been sent out.<br /><br />
            <asp:Button ID="btn_Reset" runat="server" Text="Reset" />
        </asp:View>              

    </asp:MultiView> 

------------UPDATE-------------

Thanks to Nalum i was able to solve the problem in a much better fashion then my previous (deleted) try. Now i have a single function that handles all instances for the searchbox without having to generate more code for each searchbox being created.

The following javascript is being called on the parent page that contains the repeater.

format_item = function(item, position, length) {
    var str = item.toString().split("|", 2);
    return str[0];
}

function pageLoad() {
    $(".ea_Autocomplete").each(function(i, element) {

        var tb_EmployeeName = $(this).children('input[id*=tb_EmployeeName]:first')
        var hf_EmployeeID = $(this).children('input[id*=hf_EmployeeID]:first')

        tb_EmployeeName.autocomplete(EmployeeList, {
            minChars: 0,
            width: 500,
            matchContains: true,
            autoFill: false,
            scrollHeight: 300,
            scroll: true,
            formatItem: format_item,
            formatMatch: format_item,
            formatResult: format_item
        });

        tb_EmployeeName.result(function(event, data, formatted) {
            var str = data.toString().split("|", 2);
            hf_EmployeeID.val(str[1]);
        });


    });
};

I didn't change anything in the Multiview beyond wrapping the two inputs in a div with the class ea_Autocomplete

  <asp:Panel ID="eSearch" runat="server">
                <b>Signup Employee Search</b> (<i>Last Name, First Name</i>)<br />
                <div class="ea_Autocomplete">
                    <asp:TextBox ID="tb_EmployeeName" class="EmployeeSearch" runat="server"></asp:TextBox> 
                    <asp:HiddenField ID="hf_EmployeeID" runat="server" />
                </div>                                                                                 

                <asp:Button ID="btn_Search" runat="server" Text="Search" />
   </asp:Panel>

Thanks again Nalum!

TheDPQ
  • 476
  • 1
  • 6
  • 13

1 Answers1

2

I'm kinda guessing here, I don't really know asp.net so correct me if I am wrong.

I'm assuming that multiview is doing some sort of ajaxy type thing in the background of asp.net in which case when your search form is reloaded the jQuery.autocomplete would not apply to the new form.

More than likely I'm completely wrong in what I just said though.


Edit for my second comment.

$('.autocomplete').each(function(i,element){
    $(element).autocomplete({...});
    $(element).result(function(event, data, formatted) { 
        // Now based on you're element id you can build up an id and work with that
        var id = element.id + '-extra-stuff';               
        var str = data.toString().split("|", 2);
        $('#' + id).val(str[1]);
    });
});
Nalum
  • 4,143
  • 5
  • 38
  • 55
  • You are correct, Postback messes with the jQuery. Looking into it i found information about using pageLoad() (see above code) which was working great when i only had one instance of the searchBox on the page. – TheDPQ Feb 26 '10 at 16:30
  • You seem to be accessing the form element by ID, if each instance of the search box has the same ID the JavaScript will fail because the ID should be unique. What if you change your code so that it is getting the input field by a class, that will allow for multiple auto-complete fields. e.g. `$(".autocomplete").autocomplete(EmployeeList` – Nalum Mar 02 '10 at 17:03
  • I did originally just use a cssclass when I was first testing this out. However there are pitfalls trying to split up name strings and assuming where their first/last name stop and start. First names like 'Mary Ann' or last names like 'Dela Cruz' would futz that all up. So i updated it with a hidden field with no need for a wonky way of searching again to get the ID. However the ASP:HIDDEN FIELD doesn't support a cssclass attribute, so I don't have a way of populating the EmployeeID hidden field once they have selected the employee from autocomplete. – TheDPQ Mar 04 '10 at 01:19
  • 1
    If you use the class and then use `.each` you would be able to work with each instance of the search box. I've put an example in my original answer. – Nalum Mar 08 '10 at 15:13
  • Thank you SO much, this is exactly what i was looking for. I updated my original question with the code i finally used. Let me know what you think. – TheDPQ Apr 02 '10 at 19:00