【问题标题】:jquery autocomplete passing parametersjquery自动完成传递参数
【发布时间】:2017-10-23 10:55:21
【问题描述】:

我需要帮助来通过 JQuery 的自动完成传递参数。我有一个输入:

<input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" name="searchName" id="searchName" placeholder="Nom et/ou prénom" />

在表单中。当您键入时,jquery 自动完成功能会在 Active Directory 中启动搜索并在下拉列表中显示结果:

    $(document).ready(function () {
        $("#searchName").autocomplete({
            source: function (request, response) {
                $.ajax({
                    url: "/Home/SearchUserWhileTyping",
                    type: "GET",
                    data: { name: $("#searchName").val() },
                    contentType: "application/json;charset=utf-8",
                    dataType: "json",
                    success: function (data) {
                        $("#searchName").html(''),
                        response($.map(data, function (item) {
                            return {
                                label: item
                            }
                        }));
                    }
                });
            },
            minLength: 4
        })
    });
    $(document).ready(function(){
        $('#searchName').on('autocompletechange change', function () {
                $('#searchValue').html('You selected: ' + this.value);
            }).change()});

目前我只能在表单验证后执行此操作:表单已验证 -> 我加载找到的用户及其唯一 ID -> 单击一个链接,由于通过了他们的唯一 ID,它会显示用户信息。我想要做的是:如果您单击自动完成选项之一,它会直接显示您的用户信息。

这是您键入时的搜索代码:

[HttpGet]
    public ActionResult SearchUserWhileTyping(string name)
    {
        ADManager adManager = new ADManager();
        List<string> lastName = adManager.SearchUserByName(name);
        List<string> splitList = new List<string>();
        if (lastName != null)
        {
            if (lastName.Count <= 10)
            {
                int inc = 0;
                foreach(string splitter in lastName)
                {
                    if (inc % 2 == 1)
                    {
                        splitList.Add(splitter);
                    }
                    inc++;
                }
                return Json(splitList, JsonRequestBehavior.AllowGet);
            }
        }
        return null;
    }

我使用拆分器是因为另一个函数允许我搜索 AD 并返回几个参数(这将有助于通过其唯一 id 立即找到用户,这是我的难点)。 这会调用以下函数:

public List<string> SearchUserByName(string name)
        {
            try
            {
                DirectoryEntry ldapConnection = createDirectoryEntry();
                DirectorySearcher search = new DirectorySearcher(ldapConnection);
                var sidInBytes=new byte[0];
                //anr permet de chercher tout utilisateur contenant "name"
                search.Filter = "(&(objectClass=user)(anr=" + name + "))";
                //search.Filter = "(&(objectClass=User) (name=" + name + "*))";
                search.PropertiesToLoad.Add("displayName");
                search.PropertiesToLoad.Add("distinguishedName");
                resultCollection = search.FindAll();

                if (resultCollection.Count == 0)
                {
                    return null;
                }
                else
                {
                    foreach(SearchResult sResult in resultCollection)
                    {
                        if (sResult.Properties["distinguishedName"][0].Equals(null) ||
                            sResult.Properties["displayName"][0].Equals(null))
                            continue;

                        displayName.Add(sResult.Properties["distinguishedName"][0].ToString());
                        displayName.Add(sResult.Properties["displayName"][0].ToString());
                    }
                }
                ldapConnection.Close();
                ldapConnection.Dispose();
                search.Dispose();
                return displayName;
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception caught:\n\n" + e.ToString());
            }
            return null;
        }

最后,当我有我的用户列表时,我可以点击他们的链接并使用此功能加载有关用户的信息:

public List<KeyValuePair<string,string>> GetUserInfoBySAMAN(string sAMAccountName)
        {
            try
            {
                DirectoryEntry ldapConnection = createDirectoryEntry();
                DirectorySearcher search = new DirectorySearcher(ldapConnection);


                search.Filter = "(sAMAccountName=" + sAMAccountName + ")";
                search.PropertiesToLoad.Add("objectSID");
                search.PropertiesToLoad.Add("displayName");
                search.PropertiesToLoad.Add("memberOf");
                search.PropertiesToLoad.Add("description");
                search.PropertiesToLoad.Add("accountExpires");
                search.PropertiesToLoad.Add("sAMAccountName");
                result = search.FindOne();

                ///Conversion du SID en chaine de caractères
                var sidInBytes = (byte[])result.Properties["objectSID"][0];
                var sid = new SecurityIdentifier(sidInBytes, 0);

                String time;
                if (result.Properties["accountExpires"][0].ToString().Equals("0")|| result.Properties["accountExpires"][0].ToString().Equals("9223372036854775807"))
                {
                    time = "Jamais";
                }
                else
                {
                    ///Conversion de la date en entier puis en date
                    DateTime dt = new DateTime(1601, 01, 02).AddTicks((Int64)result.Properties["accountExpires"][0]);
                    time = dt.ToString();
                }

                string desc="";
                if (result.Properties.Contains("description"))
                {
                    desc = result.Properties["description"][0].ToString();
                }
                else
                {
                    desc = "Pas de description disponible";
                }
                userInfo = new List<KeyValuePair<string, string>>()
                {
                    new KeyValuePair<string, string>("displayName",result.Properties["displayName"][0].ToString()),
                    new KeyValuePair<string, string>("memberOf", result.Properties["memberOf"][0].ToString()),
                    new KeyValuePair<string, string>("accountExpires",time),
                    new KeyValuePair<string, string>("description",desc),
                    new KeyValuePair<string, string>("sid",sid.ToString()),
                    new KeyValuePair<string, string>("sAMAccountName",result.Properties["sAMAccountName"][0].ToString())
                    /*lastName.Add(result.Properties["displayName"][0].ToString());
                    lastName.Add(result.Properties["memberOf"][0].ToString());
                    lastName.Add(sid.ToString());
                    lastName.Add(result.Properties["accountExpires"][0].ToString());
                    lastName.Add(result.Properties["description"][0].ToString());*/
                };

                return userInfo;
            }
            catch(Exception e)
            {
                Console.WriteLine("Exception caught:\n\n" + e.ToString());
            }
            return null;
        }

如果我通过 distinctName 更改 sAMAccountName,最后一个函数不起作用,因为显然这个属性不能像那样使用。我想使用 distinctName 并立即拥有我的对象。

所以我需要在我输入的同时进行搜索,如果我选择其中一个建议的选项,验证表单会立即将我发送到用户信息页面。

感谢您的帮助,希望它足够清楚

编辑我添加了第二个脚本,可以获取所选项目的值,但我需要通过控制器传递的数据

【问题讨论】:

  • 如何使用选择的插件,在更改时,获取选择的值,显示您想要显示的内容?
  • 我已经编辑了我的问题。正如您所建议的,我添加了一个脚本,允许我获取选定的值。问题出在 SearchUserWhileTyping 方法中,我只检索名称列表,如果我添加 distinctName 属性,它会在我的列表中显示它(我不想要)。

标签: asp.net-mvc jquery-ui autocomplete active-directory


【解决方案1】:

如果我理解正确,autocomplete 方法有 select 事件。

 $(document).ready(function () {
    $("#searchName").autocomplete({
        source: function (request, response) {
            $.ajax({
                url: "/Home/SearchUserWhileTyping",
                type: "GET",
                data: { name: $("#searchName").val() },
                contentType: "application/json;charset=utf-8",
                dataType: "json",
                success: function (data) {
                    $("#searchName").html(''),
                    response($.map(data, function (item) {
                        return {
                            label: item
                        }
                    }));
                },

               select: function(e, ui)
               {
                 //Just Example
                 $.get("UserController", {ID: ui.Id}).done(
                  function(data){
                  });
                 //Write your ajax post or get method
                 //that fetches user data directly as soon as 
                 //the item in list clicked
               }  
            });
        },
        minLength: 4
    })
});

编辑:我看到了您的编辑,因此您可以在 select 事件中使用您的 GetUserInfoBySAMAN 函数获取 ajax 请求(而不是我写“UserController”的地方),并且您可以将返回数据绑定到输入或标签也是。

【讨论】:

  • 好的,谢谢,我会试试这个。另一件事是我传递了一个列表 splitList ,其中只有名称,否则我将在我的下拉列表中显示 ID。知道如何在ajax中处理这个吗?说:我通过了完整的列表,在 ajax 中我决定从两个中选择一个?
  • 好的,我觉得这样可以,你写ID,是给我的distinguishedName吗?
  • ID 只是一个例子,我看到你只使用AccountName 来过滤用户和获取用户数据。顺便说一句,如果我是你,我会创建一个 DTO 对象类来在后端到客户端之间传递数据,例如; “UserInfo”你可以查看here我的意思
  • 好的,谢谢。是的,我也在考虑这个问题,例如用我的属性创建一个类来传递,对吗?
  • 我做了 DTO 但仍然不明白如何使用您放置的功能:(
猜你喜欢
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-31
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
相关资源
最近更新 更多