Highlight matches using LoadOnDemand

10 posts, 1 answers
  1. Eric Smith
    Eric Smith avatar
    9 posts
    Member since:
    Nov 2004

    Posted 21 Jan 2013 Link to this post

    I am trying (once again) to use LoadOnDemand and still highlight matches to text typed by the user in the list. I've tried to use sender.highlightAllMatches(sender.get_text()) but I can not figure out how to call it AFTER the control is loaded. It seems like I need some kind of client side event after load to connect it to. Is there any solution that will allow me to fill the combobox in code and still highlight the matches without having to parse and highlight the match string in each item?
  2. Princy
    Princy avatar
    17421 posts
    Member since:
    Mar 2007

    Posted 21 Jan 2013 Link to this post

    Hi,

     You can use MarkFirstMatch property of the RadComboBoxby which text is completed to the match, which is found among the items from the Items collection of the control. Check the following demo which explains the same.
    ComboBox / Autocomplete

    Thanks,
    Princy

  3. Eric Smith
    Eric Smith avatar
    9 posts
    Member since:
    Nov 2004

    Posted 22 Jan 2013 Link to this post

    It appears that I was not clear enough: I DO NOT wish to highlight the first match... but to highlight ALL matching text in the drop-down list.
  4. Princy
    Princy avatar
    17421 posts
    Member since:
    Mar 2007

    Posted 22 Jan 2013 Link to this post

    Hi,

    You can use filtering functionality of RadComboBox to achieve your scenario.

    Please take a look into this demo for more information.

    Hope this helps.

    Regards,
    Princy.
  5. Eric Smith
    Eric Smith avatar
    9 posts
    Member since:
    Nov 2004

    Posted 23 Jan 2013 Link to this post

    is it possible to use the script based filtering functionality with LoadOnDemand?
  6. Princy
    Princy avatar
    17421 posts
    Member since:
    Mar 2007

    Posted 23 Jan 2013 Link to this post

    Hi,

    I suppose you want to add filtering feature with LoadOnDemand. Following is the sample code that I tried to achieve the scenario.

    ASPX:
    <telerik:RadComboBox ID="RadComboBox1" runat="server" EnableLoadOnDemand="true" ShowMoreResultsBox="true" Filter="Contains" MarkFirstMatch="true" EnableVirtualScrolling="true" EmptyMessage="choose"  OnItemsRequested="RadComboBox1_ItemsRequested">
    </telerik:RadComboBox>

    C#:
    protected void RadComboBox1_ItemsRequested(object o, Telerik.Web.UI.RadComboBoxItemsRequestedEventArgs e)
    {
        String str = System.Configuration.ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
        SqlConnection con = new SqlConnection(str);
        String command = "SELECT top 20 * from Customers WHERE CompanyName LIKE @text + '%'";
        SqlDataAdapter adapter = new SqlDataAdapter(command, con);
        adapter.SelectCommand.Parameters.AddWithValue("@text", e.Text);
        DataTable data = new DataTable();
        adapter.Fill(data);
        try
        {
            int itemsPerRequest = 10;
            int itemOffset = e.NumberOfItems;
            int endOffset = itemOffset + itemsPerRequest;
            if (endOffset > data.Rows.Count)
            {
                endOffset = data.Rows.Count;
            }
            for (int i = itemOffset; i < endOffset; i++)
            {
                RadComboBox1.Items.Add(new RadComboBoxItem(data.Rows[i]["CompanyName"].ToString(), data.Rows[i]["CompanyName"].ToString() + "'"));
            }
            if (data.Rows.Count > 0)
            {
                e.Message = String.Format("Items <b>1</b>-<b>{0}</b> out of <b>{1}</b>", endOffset.ToString(), data.Rows.Count.ToString());
            }
            else {
                e.Message = "No matches"; }
        }
        catch
        {
            e.Message = "No matches";
        }
    }

    Please elaborate your scenario with full code if it doesn't helps.

    Regards,
    Princy.
  7. Eric Smith
    Eric Smith avatar
    9 posts
    Member since:
    Nov 2004

    Posted 31 Jan 2013 Link to this post

    In this application I:
    - use a server business object (datatable) to contain a list of all possible items for the combobox (approximately 4000 items unfiltered)
    - apply a filter to the server business object based on the text typed in the combobox producing, and then databinding, a dataview to the combobox list (called by combobox_ItemsRequested and with EnableLoadOnDemand="true")

    This is faster than client side filtering. Unfortunately, I can not figure out a way (except iterating the list of combobox items, parsing the text, and marking the matching sub-string manually.
    Does anybody have a better way to achieve the speed of LoadOnDemand while still having the feature of  highlighting mathching text strings in the item list achieved when using client side filtering?
  8. Answer
    Chuck
    Chuck avatar
    7 posts
    Member since:
    Jan 2013

    Posted 31 Jan 2013 Link to this post

    Hi Eric

    If I understand your scenario correctly, one thing I can confirm is that you must set Filter="Contains" to have matching text highlighted.

    e.g.
    <telerik:RadComboBox ID="RadComboBox1" runat="server" 
    EnableLoadOnDemand="True" Filter="Contains" 
    OnItemsRequested="RadComboBox1_ItemsRequested"></telerik:RadComboBox>


    This is my current implementation which sounds similar to what you are aiming for.

    Markup
    <!-- Single column RadComboBox -->
    <!-- OnClientKeyPressing event opens combobox drop down when text is being typed (e.g. when control is tabbed to) -->
    <telerik:RadComboBox ID="RadComboBox1" runat="server" AutoPostBack="true" Height="170px"
      Width="300px" EnableLoadOnDemand="True" Filter="Contains" NoWrap="True" ShowMoreResultsBox="True"
      OnItemsRequested="RadComboBox1_ItemsRequested" OnSelectedIndexChanged="RadComboBox1_SelectedIndexChanged"
      OnClientKeyPressing="(function(sender, e) { if (!sender.get_dropDownVisible()) sender.showDropDown(); })">
    </telerik:RadComboBox>

    C#
    protected void RadComboBox1_ItemsRequested(object o, RadComboBoxItemsRequestedEventArgs e)
    {
        int recordCount = 0;
        int itemsPerRequest = 100;  // how many items to list in combobox
        int itemOffset = e.NumberOfItems;
        int endOffset = itemOffset + itemsPerRequest;
        string searchValue = e.Text;
      
        // prevent filtering on whitespace
        if (String.IsNullOrWhiteSpace(searchValue))
            searchValue = null;
      
        // get data from database
        InstitutesData records = new InstitutesData();
        records = records.ReadRecordsComboBox(searchValue);
      
        // if there are records
        if (records != null)
        {
            // get count
            recordCount = records.Count;
      
            // add INST_NO to front of INST_NAME (custom functionality)
            for (int i = 0; i < recordCount; i++)
            {
                records[i].INST_NAME = records[i].INST_NO.ToString() + " - " + records[i].INST_NAME;
            }
        }
      
        // ensure offset isnt greater than the number of records available
        if (endOffset > recordCount)
            endOffset = recordCount;
      
        // bind data to combobox
        RadComboBox1.DataTextField = "INST_NAME";    // "123 - Number One School"
        RadComboBox1.DataValueField = "INST_NO";     // 123
        RadComboBox1.DataSource = records;
        RadComboBox1.DataBind();
      
        // populate combobox with items within offsets
        RadComboBox1.Items.Clear();
        for (int i = itemOffset; i < endOffset; i++)
        {
            RadComboBox1.Items.Add(new RadComboBoxItem(records[i].INST_NAME, records[i].INST_NO.ToString()));
        }
      
        // display record count information in results box
        if (recordCount > 0)
        {
            e.Message = String.Format("Items <b>0</b>-<b>{0}</b> out of <b>{1}</b>", endOffset, recordCount);
        }
      
        else
        {
            // display 'no data in database' message
            if (String.IsNullOrEmpty(searchValue))
                e.Message = "No data";
      
            // display 'no matches in database' message
            else
                e.Message = "No matches";
        }
    }
      
    protected void RadComboBox1_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
    {
        // do something when the selected index is changed
        string selectedValue = e.Value;
    }

    So ItemsRequested is called whenever a new letter is typed in the combobox, so it makes a fair few database calls but the response is decent.  Note: I've joined two columns so the user can filter by a number or by a name (e.g. 123 or "school").

    Hope this helps
    Chuck
  9. Chuck
    Chuck avatar
    7 posts
    Member since:
    Jan 2013

    Posted 31 Jan 2013 Link to this post

    You may also be interested in this related issue that I am having, affecting multi-column comboboxes, and may be useful for you if you wish extend your single column combobox to multi-column.
    http://www.telerik.com/community/forums/aspnet-ajax/combobox/text-highlight-in-multi-column-combobox.aspx
  10. Eric Smith
    Eric Smith avatar
    9 posts
    Member since:
    Nov 2004

    Posted 31 Jan 2013 Link to this post

    Chuck, thank you for your response... I was apparently NOT being adventerous enough as I thought that one couldn't have Filter="Contains" if one had EnableLoadOnDemand ="True". Based on your example, I've set Fiter as well and the script based highlighting works with only a little loss of performance. I had been operating under the misconception that the script base filtering should not be used in conjunction with LoadOnDemand. Thanks again :)
Back to Top