Link to home
Start Free TrialLog in
Avatar of pamela rizk
pamela rizkFlag for Lebanon

asked on

Autocomplete jquery

dear all

i need to build a jQuery autocomplete from two sources is it possible?
here are teh details:
source 1 :return all employees
source 2 :return all locations
i need to merge these data in one autocomplete control
how to do that ?
Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

If the two sources are different just join the arrays:
var source1 = [
      "ActionScript",
      "AppleScript",
      "Asp",
      "BASIC",
      "C",
      "C++",
      "Clojure",
      "COBOL"];
var source2 = [ "ColdFusion",
      "Erlang",
      "Fortran",
      "Groovy",
      "Haskell",
      "Java",
      "JavaScript",
      "Lisp",
      "Perl",
      "PHP",
      "Python",
      "Ruby",
      "Scala",
      "Scheme"
    ];
var sourceMerge = $.merge(source1, source2);

Open in new window

Then use the code shown in the Autocomplete jquery example shown here.

Note: The reason I ask for different values is that it easier to identify from which source is coming from if that is needed later on. Otherwise it would be difficult to say which value comes from which source(unless you add a suffix to make it unique.
Avatar of pamela rizk

ASKER

but how to solve the below :
if i select lets' say php FOR THE LIST , I NEED TO RETURN AN INTERNAL CODE EX:9
BECAUSE I HAVE BELOW SOURCES:
ACTIONSCRIPT HAS A INTERNAL VALUE 1 EX
APPLE SCRIPS HAS AN INTERNAL VALUE 2 EX
AND SO ON HOW TO KNOW THAT WHEN I SELECT FROM SOURCE 1 THE  VALUE IS SELECTED SUCCESSFULLY
I  MEANT THAT I NEED TO KNOW WHEN I SELECT A VALUE FRO ANY SOURCE  , THE VALUE RELATED SO I CAN STORE IT IN A HIDDEN FIELD LETS SAY .
I REFERED TO THE BELOW LINK;
https://forum.jquery.com/topic/jquery-autocomplete-with-multiple-sources
Why do you want to merge these in the client? Why not query your external resource and have it merge the results and send back a single list as is suggested in the forum link you posted above.

I cannot see any merit in doing this in the client.
because i need upon searching for a file to return it if exist without the need to get all the data
i need to know the value that i select from source 1 for example
Yes but you include all that functionality in the service that you are calling by AJAX - no need to make two calls from the client. Combine them on the server and only return to the client the data it needs.
but as per below link:https://forum.jquery.com/topic/jquery-autocomplete-with-multiple-sources

it should be feasible i need a solution for that  as i don't want to change the method
From that forum post
Of course it is always better to merge the data in 1 ajax call.

And you don't have to change the method - you can create a new one that combines the two calls.
do yiou mean it is not feasible?since i want to apply the method of using 2 sources o anautocomplete
of course it is better to merge the data in 1 ajax but we can use the link already provided no?
It is possible to merge them on the client - but it is unnecessarily complicated.

You have two asynch functions running - now you need to check for the completion status on both of those events using Promise.All or similar - which requires a bit of effort to setup.

Once both promises complete you now have to create your merged array - combining the data items based on some relationship in the data to relate employee to location.

As opposed to call 1 AJAX function that creates the list as you need it in the Autocomplete and plugs in to what you already have.
is there any link i can refer too?
if you refer to the below link already sent , you will notice that we are using reduce method to concatenate result between source1 and source2
i realize  that if source 1 return an object as below {label:xxx, value:x1x1x1)
and source 2 return object as below {label:yyy, value :y1y1y1}
upon conatentaing these 2 sources  the select method will return one object as below:
{label:xxx, value:xxx}
{labek:yyy, value :yyy}
any idea why ?
any idea why ?
Can I ask what you were expecting?
i expect that concatenate will return an object defined as below :
return object {label:xxx, x1x1x1}
{label yyy, y1y1y1}
I am sorry but that does not make sense - what am I looking at? An array of objects, an object with two objects as properties.
Ok I think I see what you mean - can you post the code that you are using along with some sample data (inputs) and what you expect the output to look like.
i have a textbox called txtSearch_File
below is teh design:
<script type="text/javascript">

    //Begin document is ready
    $(document).ready(function () {


        EndRequestHandler();
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
        //Begin EndRequestHandler
        function EndRequestHandler(sender, args) {

            var m_GlobalArray = [];
            var m_SplitResult = [];
            ///////////////////
            var ajaxes = []
            function killAjaxes() {
                $.each(ajaxes, function (i, ajax) {
                    ajax.abort()
                })
            }

            function getdata1(i_sSearchText, _jsonString, _response) {
                data1 = $.ajax({
                    url: '<%=ResolveUrl("AutoCompleteForFile.asmx/RetrieveFileDataTest")%>',
                    data: _jsonString,
                    dataType: "json",
                    delay: 0,
                    autoFocus: true,
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {
                        _response($.map(data.d, function (item) {
                            return {
                                label: item.split('|')[0],//show key
                                value: item.split('|')[1],
                                id: item.split('|')[2]
                            }
                        }))
                    },
                    //A function to be called if the request fails. 
                    error: function (jqXHR, exception) {
                        var msg = getErrorMessage(jqXHR, exception);
                        alert(msg);
                    }
                });
                return data1;
            }
            function getdata2(i_sSearchText, _jsonString, _response) {
                data2 = $.ajax({
                    url: '<%=ResolveUrl("AutoCompleteForFile.asmx/RetrieveFileData")%>',
                    data: _jsonString,
                    dataType: "json",
                    delay: 0,
                    autoFocus: true,
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {
                        _response($.map(data.d, function (item) {
                            return {
                                label: item.split('|')[0],//show key
                                value: item.split('|')[1],
                                id: item.split('|')[2]
                            }
                        }))
                    },
                    //A function to be called if the request fails. 
                    error: function (jqXHR, exception) {
                        var msg = getErrorMessage(jqXHR, exception);
                        alert(msg);
                    }
                });
                return data2;
            }
            ///////////////////
            $("#<%=txtSearch_File.ClientID%>").autocomplete({
                delay: 1000,

                //Begin on source
                source: function (request, response) {
                    var m_Category = $("#<%=hdn_Category_File.ClientID%>").val();
                    var m_SubCategory = $("#<%=hdn_SubCategory_File.ClientID%>").val();
                    var m_SessionId = $("#<%=hdn_SessionID_File.ClientID%>").val();
                    var m_TransFilePath = $("#<%=hdn_TransFilePath.ClientID%>").val();
                    var jsonObjects = {
                        "prefixText": request.term, "m_Category": m_Category,
                        "m_SubCategory": m_SubCategory, "m_SessionID": m_SessionId,
                        "m_TransFilePath": m_TransFilePath
                    };
                    var jsonString = JSON.stringify(jsonObjects);

                    killAjaxes();
                    ajaxes =
                       [
                        getdata1(request.term, jsonString, response),
                        getdata2(request.term, jsonString, response)
                       ]
                   
                        function () {
                            var m_map = Array.prototype.map;
                            m_globalarray = [];
                            m_splitresult = [];
                            response(
                            m_map.call(arguments, function (res) {
                                
                                return res[0]
                            })//end prototyoe map call
                                //for each elemet in p.d array return its description
                           .reduce(function (p, c) {
                                
                                return $.map(p.d, function (item1) { return item1.split('|')[0] }).concat($.map(c.d, function (item2) { return item2.split('|')[0] }))
                            })
                            )//endresponse
                        }//end funcion 
                    )//end when apply
                },//end source function 
                //end on source
                //Begin on select
                select: function (e, i) {
                    killAjaxes();
                  
                        var m_value = i.item.value.trim();
                        alert(m_value);


                },
                //end on select
                minLength: 1,
                //CHAHID ON 4-1-2016
                //begin change event that work whenever we exit the autocomlpete
               


                //CHAHID ON 4-1-2016
                autoFocus: true //IF TRUE IT WILL SELECT THE FIRST ROW BY DEFAULT
            })


            }//end request handler

    });
        //end document is ready

</script>

Open in new window

RetrieveFileDataTest is a method defined as below:
 <WebMethod()>
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
    Public Function RetrieveFileDataTest(ByVal prefixText As String,
                                 ByVal m_Category As String,
                                 ByVal m_SubCategory As String,
                                 ByVal m_SessionID As String,
                                 ByVal m_TransFilePath As String) As String()
        prefixText = Decodifycharacters(prefixText)
        m_Category = Decodifycharacters(m_Category)
        m_SubCategory = Decodifycharacters(m_SubCategory)
        m_SessionID = Decodifycharacters(m_SessionID)
        m_TransFilePath = Decodifycharacters(m_TransFilePath)
        Dim m_ReturnError As String = "0"
        Dim m_ReturnMsg As String = "Success"

        Dim files As New List(Of String)()
        Dim m_internalKey As String = "999998;testFile;10"
        files.Add(String.Format("{0}|{1}|{2}", "testFile", m_internalKey, "999998"))
        If files Is Nothing Then
            Return Nothing
        Else
            Return files.ToArray()
        End If
    End Function

Open in new window


RetrieveFileData is a method defined as below:
 <WebMethod()>
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
    Public Function RetrieveFileData(ByVal prefixText As String,
                                 ByVal m_Category As String,
                                 ByVal m_SubCategory As String,
                                 ByVal m_SessionID As String,
                                 ByVal m_TransFilePath As String) As String()
        prefixText = Decodifycharacters(prefixText)
        m_Category = Decodifycharacters(m_Category)
        m_SubCategory = Decodifycharacters(m_SubCategory)
        m_SessionID = Decodifycharacters(m_SessionID)
        m_TransFilePath = Decodifycharacters(m_TransFilePath)
        Dim m_ReturnError As String = "0"
        Dim m_ReturnMsg As String = "Success"

        Dim files As New List(Of String)()
        Dim m_internalKey As String = "999999;testFile9;10"
        files.Add(String.Format("{0}|{1}|{2}", "testFile9", m_internalKey, "999999"))
        If files Is Nothing Then
            Return Nothing
        Else
            Return files.ToArray()
        End If
    End Function

Open in new window



appreciate your help as always.
I need to see the data coming back from the requests rather than the web-methods.

I am also confused as to why you are doing a map in your success callbacks in the AJAX routines - why not send the data in the correct format to begin with?

I am belabouring the point here because it is important - just because we can do something on the client doesn't mean we should. The best approach (for the majority of situations) for getting data by AJAX is to have the server send back as close a representation of the data to how it is to be consumed in the client as it is possible to get.

I am unclear as to what your intent is in lines 92 - 98

function() {
 ...
}

Open in new window

Is meant to do what exactly?
ASKER CERTIFIED SOLUTION
Avatar of pamela rizk
pamela rizk
Flag of Lebanon image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
this solution worked properly in case anyone wants to apply it