Monday, May 27, 2013

Entity Selector in ASP.NET MVC using jQuery - An alternative approach to people picker in SharePoint

Developer’s life is full of challenges. On some sunny morning, your client comes with very cool idea or you think of very cool idea for implementation of a control. Even if idea seems cool, when it comes to implementation it annoys a lot many times. I wanted to implement something cool in my project too. For that I thought of one idea. I wanted to implement an entity selector control in ASP.NET MVC. A control which will allow user to select one or more users. You can say similar to people picker in SharePoint. I wanted to implement it differently. So I started thinking about implementation. I searched web for good implementations. After some research I started my work inspired by few of the social networking sites. I did not want to use any third party control or jQuery plug in. Therefore I started writing script. And to my surprise I finished my task using very less script. With the combination of some HTML, jQuery and jQuery UI, I created my control. It is nothing but a partial view. It can be plugged in any view in my MVC application. Following is the code:
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript">
    $(".remove").on('click', function () {
        $(this).parent().remove();
    });
    var t = 0;
    $('#userinput').on('keyup', function (event) {
        var query = '';
        query = $(this).val();
        if (event.keyCode == 8) {
            if (query == '' && t == 1) {
                if ($("#userList").children().length > 0) {
                    $("#userList").children().last().remove();
                    t = 0;
                }
            }           
        } else {
            t = 0;
        }
    });
 
    $('#userinput').on('keydown', function (event) {
        var inputWidth = (this.value.length + 1) * 10;
        $(this).width(inputWidth);
        var query = '';
        query = $(this).val();
        if (event.keyCode == 8) {
            if (query == '' && t == 0) {
                t++;
            }
        }
    });
 
    $(function () {
        var filteredUsers = ["Bhushan", "Nikhil", "Onkar", "Pranjali", "Prasad", "Prashant", "Sayali", "Ramiz", "Vikrant"];
        $("#userinput").autocomplete({
            source: filteredUsers,
            select: function (event, ui) {
                var user = '';
                user = ui.item.value;
                $("#userList").append('<div style="background-color:white;height:25px;margin:10px; float: left; display: inline-block;">' + user + '<a href="#" class="remove">X</a></div>');
                $(this).val('');
                $(this).focus();
                t = 1;
                return false;
            },
            messages: {
                noResults: '',
                results: function () { }
            }
        });
    });
 
 
</script>
<style type="text/css">
    .ui-autocomplete-input {
        border: none;
        background-color: azure;
    }
 
        .ui-autocomplete-input:focus {
            border: none;
            background-color: azure;
        }
</style>
<h3>Select User:</h3>
<div>
    <div id="picker" style="background-color: azure; float: left; display: inline-block">
        <div id="userList" style="background-color: azure; float: left; display: inline-block;">
        </div>
        <input id="userinput" />
    </div>
</div>

Please ignore style as I am not a designerJ. For demo I have hard-coded values bound to the autocomplete box. You can provide proper data source through view model. This is the basic implementation of control. You can do many fancy things by adding more features and applying styles. I would like to know your story about how you extended this control. So keep posting your stories and enjoy!!

5 comments:

  1. can we configure the users list to be driven from Active Directory

    ReplyDelete
    Replies
    1. Yes, you can bind the list. For that you have to tweak HTML of div appended using $("#userList").append() little bit. I have set user name as value there. To bind additional property you can add data attribute(s). You can get json object array from server and use necessary property of object to set data attribute of div.

      Delete
  2. Can I use SQL Server database instead of hard coded names?

    ReplyDelete
    Replies
    1. Sure. You can get data from SQL server and pass json object array to client. Use that array as source.

      Delete
  3. Hi Prasad
    Thanks for your response. I am doing as below but is not working. Any help?
    $(function () {
    var connection = new ActiveXObject("ADODB.Connection");
    var connectionstring = "Data Source=clinton;Initial Catalog=RiskMgmt;Integrated Security=true;";
    connection.Open(connectionstring);
    var rs = new ActiveXObject("ADODB.Recordset");
    rs.Open("SELECT * FROM Users", connection);
    rs.MoveFirst
    while (!rs.eof) {
    document.write(rs.fields(1));
    rs.movenext;
    }
    rs.close;
    connection.close;
    $("#userinput").autocomplete({
    source: filteredUsers,
    select: function (event, ui) {
    var user = '';
    user = ui.item.value;

    ReplyDelete