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 ?
LVL 1
pamela rizkDeveloperAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Miguel OzSoftware EngineerCommented:
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.
pamela rizkDeveloperAuthor Commented:
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
pamela rizkDeveloperAuthor Commented:
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
OWASP Proactive Controls

Learn the most important control and control categories that every architect and developer should include in their projects.

Julian HansenCommented:
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.
pamela rizkDeveloperAuthor Commented:
because i need upon searching for a file to return it if exist without the need to get all the data
pamela rizkDeveloperAuthor Commented:
i need to know the value that i select from source 1 for example
Julian HansenCommented:
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.
pamela rizkDeveloperAuthor Commented:
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
Julian HansenCommented:
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.
pamela rizkDeveloperAuthor Commented:
do yiou mean it is not feasible?since i want to apply the method of using 2 sources o anautocomplete
pamela rizkDeveloperAuthor Commented:
of course it is better to merge the data in 1 ajax but we can use the link already provided no?
Julian HansenCommented:
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.
pamela rizkDeveloperAuthor Commented:
is there any link i can refer too?
pamela rizkDeveloperAuthor Commented:
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 ?
Julian HansenCommented:
any idea why ?
Can I ask what you were expecting?
pamela rizkDeveloperAuthor Commented:
i expect that concatenate will return an object defined as below :
return object {label:xxx, x1x1x1}
{label yyy, y1y1y1}
Julian HansenCommented:
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.
Julian HansenCommented:
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.
pamela rizkDeveloperAuthor Commented:
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.
Julian HansenCommented:
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?
pamela rizkDeveloperAuthor Commented:
dear mr julien

i solve it as below , i declare a global array that contains what should be shown
and another array that contains the values so when user select a row  i have what should be shown so i searched for its value in the array of values and it is solved.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
pamela rizkDeveloperAuthor Commented:
this solution worked properly in case anyone wants to apply it
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.