Link to home
Start Free TrialLog in
Avatar of Gani tpt
Gani tpt

asked on

Editable combobox not populating properly if more than 1 million records

Hi,

I am using editable dropdown for searching or selecting records.

This will be working fine if we have less number of records (for example < 100 records).

if we have more than 1 million records, then it will not populate anything and it got struct.

i am using asp.net dropdown  with autocomplete jQuery.

How to solve this problem.?

sample code attached.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Combobox.aspx.cs" Inherits="Combobox.Combobox" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
    <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<style>
    .custom-combobox {
    position: relative;
    display: inline-block;
    height:35px;
    }
    .custom-combobox-toggle {
    position: absolute;
    top: 0;
    bottom: 0;
    margin-left: -1px;
    padding: 0;
    /* support: IE7 */
    *height: 1.7em;
    *top: 0.1em;
    }
    .custom-combobox-input {
    margin: 0;
    padding: 0.3em;
    background:#fff;
    outline:none;
    }
</style>
<script>
    (function ($) {
        $.widget("custom.combobox", {
            _create: function () {
                this.wrapper = $("<span>")
        .addClass("custom-combobox")
        .insertAfter(this.element);

                this.element.hide();
                this._createAutocomplete();
                this._createShowAllButton();
            },

            _createAutocomplete: function () {
                var selected = this.element.children(":selected"),
        value = selected.val() ? selected.text() : "";

                this.input = $("<input>")
        .appendTo(this.wrapper)
        .val(value)
        .attr("title", "")
        .addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
        .autocomplete({
            delay: 0,
            minLength: 0,
            source: $.proxy(this, "_source")
        })
        .tooltip({
            tooltipClass: "ui-state-highlight"
        });

                this._on(this.input, {
                    autocompleteselect: function (event, ui) {
                        ui.item.option.selected = true;
                        this._trigger("select", event, {
                            item: ui.item.option
                        });
                    },

                    autocompletechange: "_removeIfInvalid"
                });
            },

            _createShowAllButton: function () {
                var input = this.input,
        wasOpen = false;

                $("<a>")
        .attr("tabIndex", -1)
        .attr("title", "Show All Items")
        .tooltip()
        .appendTo(this.wrapper)
        .button({
            icons: {
                primary: "ui-icon-triangle-1-s"
            },
            text: false
        })
        .removeClass("ui-corner-all")
        .addClass("custom-combobox-toggle ui-corner-right")
        .mousedown(function () {
            wasOpen = input.autocomplete("widget").is(":visible");
        })
        .click(function () {
            input.focus();

            // Close if already visible
            if (wasOpen) {
                return;
            }

            // Pass empty string as value to search for, displaying all results
            input.autocomplete("search", "");
        });
            },

            _source: function (request, response) {
                var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
                response(this.element.children("option").map(function () {
                    var text = $(this).text();
                    if (this.value && (!request.term || matcher.test(text)))
                        return {
                            label: text,
                            value: text,
                            option: this
                        };
                }));
            },

            _removeIfInvalid: function (event, ui) {

                // Selected an item, nothing to do
                if (ui.item) {
                    return;
                }

                // Search for a match (case-insensitive)
                var value = this.input.val(),
        valueLowerCase = value.toLowerCase(),
        valid = false;
                this.element.children("option").each(function () {
                    if ($(this).text().toLowerCase() === valueLowerCase) {
                        this.selected = valid = true;
                        return false;
                    }
                });

                // Found a match, nothing to do
                if (valid) {
                    return;
                }

                // Remove invalid value
                this.input
        .val("")
        .attr("title", value + " didn't match any item")
        .tooltip("open");
                this.element.val("");
                this._delay(function () {
                    this.input.tooltip("close").attr("title", "");
                }, 2500);
                this.input.data("ui-autocomplete").term = "";
            },

            _destroy: function () {
                this.wrapper.remove();
                this.element.show();
            }
        });
    })(jQuery);
</script>
    <script language="javascript">
        $(document).ready(function () {
            $(".combo").combobox();
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <table>
        <tr>
            <td>
                Asp.net Dropdown as combobox
            </td>
            <td style="width: 40px;">
            </td>
            <td>
                HTML Select as combobox
            </td>
        </tr>
        <tr>
            <td>
                <asp:DropDownList ID="ddlCountries" runat="server" CssClass="combo">
                </asp:DropDownList>
            </td>
            <td>
            </td>
            <td>
                <select id="selCountries" class="combo">
                    <option value=""></option>
                    <option value="India">India</option>
                    <option value="USA">USA</option>
                    <option value="China">China</option>
                    <option value="New Zealand">New Zealand</option>
                    <option value="England">England</option>
                </select>
            </td>
        </tr>
    </table>
    </form>
</body>
</html>

Open in new window

Avatar of Chinmay Patel
Chinmay Patel
Flag of India image

Hi Ganesh,

Comboxbox is not really  good choice when the items are more than 20 (from end user perspective).

If you are filtering records, please change it so very few record are returned. Check the RAM and CPU usage of the browser when you are loading these items. So even if this close to million record works for you, it is a not advised to load so many items in a combobox.

I generally use another page, in which user can search and then return it to the main page.

Regards,
Chinmay.
Avatar of Gani tpt
Gani tpt

ASKER

thanks for your reply.

At max i said (But, this much records is not possible).

But, nearly 10,000 records atleast...
Hmmm.. think it like this. Put yourself in your end users's shoes. You have to "Select" a value from 10,000 records. How would you like to do it yourself? Another simple example, if you have ever tried to register for Microsoft certification, check their country picker - and try to pick India or some other country than US and see it for yourself. It is a horrible user experience. Even if you know the exact spelling... it does not help much. They have messed that dropdown box by prefixing country code with country name.

For you the real problem is data size ( I think there is a possibility) that user will make a mistake and won't be able to get the right value.
Also overall user experience will degrade if he has to scroll 10000 items.

If you still have to use Dropdown, another technique I can recommend is, do not list anything until user has entered first 3 (Or more, in your case maybe first 5) letters - then and only search your million+ records and return results, I am sure that will not hang the results.
can i have sample code..?
ASKER CERTIFIED SOLUTION
Avatar of Chinmay Patel
Chinmay Patel
Flag of India 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
Thanks..