+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Whats the difference between FilterEXpression and MetaSearch

Whats the difference between FilterEXpression and MetaSearch

6 posts, 0 answered
  1. higgsy
    higgsy avatar
    336 posts
    Registered:
    05 Aug 2010
    13 Dec 2010
    Link to this post
    Hi,

    I have a ContentView that has a search feature. I have overridden the CreateDataSource as so:

    protected override IList CreateDataSource() {
     
        //this.FilterExpression = "ContactCounty = " + strCounty;
     
        //extract the selected POST parameters
        string strCounty = dotcentric.utilities.Main.ReturnRequestItem(dotcentric.utilities.Main.enumReqMethod.Post, "lstCounty");
        string strSearchTerm = dotcentric.utilities.Main.ReturnRequestItem(dotcentric.utilities.Main.enumReqMethod.Post, "txtSearchTerm");
         
        //create empty filter
        List<IMetaSearchInfo> oFilter = new List<IMetaSearchInfo>();
        if (!string.IsNullOrEmpty(strCounty)) {
            oFilter.Add(new MetaSearchInfo(MetaValueTypes.ShortText, "ContactCounty", strCounty, SearchCondition.Equal));
        }
        //oFilter.Add(new MetaSearchInfo(MetaValueTypes.ShortText, "Name", strSearchTerm, SearchCondition.Like, JoinType.Or));
         
        //get content
        ContentManager oContentMgr = new ContentManager(MembersManager.DefaultContentProvider);
        IList oFilteredItems = oContentMgr.GetContent(base.GetContentStartIndex(), base.GetPageSize(), "Name ASC", ContentStatus.Published, oFilter.ToArray());
     
        //bind repeater
        oRepeater.DataSource = oFilteredItems;
        oRepeater.DataBind();
     
        return oFilteredItems;
    }

    The problem I am experiencing is that although the MetaSearch works perfectly, it doesnt correctly tell the <telerik:Pager> how many pages should be rendered. Likewise, if I set the FilterExpression property, it correctly tells the Pager how many pages there should be, but it doesnt change the results of the search.

    How do I get these two to work together properly, or am I doing something completely wrong?

    Thanks
    higgsy
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    15 Dec 2010
    Link to this post
    Hi higgsy,

    There is no difference between FilterExpression and IMetaSearchInfo filter. The FilterExpression uses ContentFilterBuilder which is used by all ContentView based controls. The ContentFilterBuilder works with
    IMetaSearchInfo. The pager uses CreateDataSource as a source to generate and calculate its pages. CreateDataSource returns IList which we bind to the pager.

    Kind regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. higgsy
    higgsy avatar
    336 posts
    Registered:
    05 Aug 2010
    15 Dec 2010
    Link to this post
    Hi Ivan,

    Thanks for the response. I've now got the search results working perfectly using the code below.

    protected override ContentFilterBuilder GetFilterBuilder() {
     
        //extract the selected POST parameters
        string strCounty = dotcentric.utilities.Main.ReturnRequestItem(dotcentric.utilities.Main.enumReqMethod.Post, "lstCounty");
        string strSearchTerm = dotcentric.utilities.Main.ReturnRequestItem(dotcentric.utilities.Main.enumReqMethod.Post, "txtSearchTerm");
     
        this.Context.Response.Write("<br />The post items are, county: " + strCounty + " and search term: " + strSearchTerm);
     
        ContentFilterBuilder filterBuilder = base.GetFilterBuilder();
        MetaSearchInfo filter = new MetaSearchInfo();
     
        if (!string.IsNullOrEmpty(strCounty)) {
     
            filter = new MetaSearchInfo(MetaValueTypes.ShortText, "ContactCounty", strCounty, SearchCondition.Like, JoinType.And);
            filterBuilder.ClearFilter();
            filterBuilder.AddFilter(filter);
     
        }
     
        if (!string.IsNullOrEmpty(strSearchTerm)) {
     
            filter = new MetaSearchInfo(MetaValueTypes.ShortText, "Name", strSearchTerm, SearchCondition.Like, JoinType.And);
            filterBuilder.ClearFilter();
            filterBuilder.AddFilter(filter);
     
        }
     
        return filterBuilder;
     
    }
     
    protected override IList CreateDataSource() {
     
        this.Context.Response.Write("<br />start index: " + base.GetContentStartIndex().ToString());
         
        //get content
        ContentFilterBuilder filterBuilder = this.GetFilterBuilder();
        if (filterBuilder.IsFilterValid) {
     
            this.Context.Response.Write("<br />We are applying the filter");
     
            ContentManager oContentMgr = new ContentManager(MembersManager.DefaultContentProvider);
            IList oFilteredItems = oContentMgr.GetContent(base.GetContentStartIndex(),
                                                            base.GetPageSize(),
                                                            "Name ASC",
                                                            filterBuilder.ParseTagFilter(),
                                                            ContentStatus.Published,
                                                            null,
                                                            filterBuilder.ParseParentsFilter(),
                                                            filterBuilder.ParseMetaFieldsFilter());
     
     
            //bind repeater
            oRepeater.DataSource = oFilteredItems;
            oRepeater.DataBind();
     
            return oFilteredItems;
     
        }
     
        this.Context.Response.Write("<br />We are about to return the default datalist");
        return base.CreateDataSource();
    }

    The one problem I am still experiencing is that the pager does not display page two or greater. It always thinks GetContentStartIndex is equal to zero. I am using the pager in the RenderAsLink = false mode.

    Edit:
    I should also point out that it does work when I use RenderAsLink (but i cant use that mode because I am trying to persist form values), and it still works incorrectly even if i remove the custom data source and filterBuilder.

    Any ideas why it's not working?

    Thanks
    higgsy
  4. higgsy
    higgsy avatar
    336 posts
    Registered:
    05 Aug 2010
    15 Dec 2010
    Link to this post
    Hi Ivan,

    I have found out exactly why it is occuring, but I dont know how to fix out.

    My page has two contentplaceholders. 1 held the ContentView, the other held a SimpleControl. When I removed the SimpleControl from the page the paging worked OK.

    What is it from the SimpleControl that is affecting the ContentView?

    Thanks again
    higgsy
  5. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    21 Dec 2010
    Link to this post
    Hello higgsy,

    There should not be a problem to use SimpleView control with a ContentView based control. Here is how you should implement this

    1. Create a custom control which gets your data into a RadComboBox.
    2. Use QueryStrings data to filter the ContentView based control
    3. Do not rebind the control and do not recreate ChildControls indie the CreateDataSource method. This is done on another stage and making this inside the method you use for binding is not correct.
    You should not bind or rebind any controls in CreateDataSource method. The binding should be performed inside CreatChildControls and there the items list can be filtered.

    I created a custom control which gets the categories of a module ( it can be used with each other metakey or some custom property you might have)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Telerik.Web.UI;
    using Telerik.Cms.Web.UI;
    using Telerik.Cms.Engine;
    using System.ComponentModel;
     
    /// <summary>
    /// Summary description for Class8
    /// </summary>
    ///
     
    namespace Telerik.Sitefinity.Samples
    {
        public class CategoriesRadComboFilter : SimpleControl, IEmptyControl
        {
     
     
            private List<string> _categories;
            public List<string> Categories
            {
                get
                {
     
                    if (_categories != null)
                        return _categories;
                    return new List<string>();
                }
                set
                {
                    _categories = value;
                }
            }
     
        
     
            protected override void InitializeControls(System.Web.UI.Control controlContainer)
            {
                if (Page == null || DesignMode)
                {
                    this.Controls.Clear();
                    Label lblControlText = new Label();
                    lblControlText.Text = this.ControlText;
                    this.Controls.Add(lblControlText);
                }
     
                else if (CategoriesComboBox != null)
                {
                    base.InitializeControls(controlContainer);
                    BindCategories();
                }
            }
     
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
     
                CategoriesComboBox.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(CategoriesComboBox_SelectedIndexChanged);
            }
     
            void CategoriesComboBox_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
            {
                var QueryValue = e.Value;
                var QueryParameter = MetaKeyFilterQueryString;
                if (!String.IsNullOrEmpty(QueryValue))
                {
                    var url = HttpContext.Current.Request.CurrentExecutionFilePath + "?" + QueryParameter + "=" + QueryValue;
                    HttpContext.Current.Response.Redirect(url);
                }
                else
                {
                    HttpContext.Current.Response.Redirect(HttpContext.Current.Request.CurrentExecutionFilePath);
                }
            }
     
            /// <summary>
            /// here we are binding all categories or other metadata
            /// </summary>
            
            protected virtual void BindCategories()
            {
                CategoriesComboBox.DataSource = Categories;
                CategoriesComboBox.DataBind();
     
                RadComboBoxItem defaultitem = new RadComboBoxItem("Show All", string.Empty);
                CategoriesComboBox.Items.Insert(0, defaultitem);
     
                if (!String.IsNullOrEmpty(Context.Request.QueryString[MetaKeyFilterQueryString]))
                {
                    var query = Context.Request.QueryString[MetaKeyFilterQueryString];
                    if (!String.IsNullOrEmpty(query))
                    {
                        RadComboBoxItem selectedItem = CategoriesComboBox.Items.FindItemByValue(query);
                        if (selectedItem != null)
                        {
                            selectedItem.Selected = true;
                        }
                    }
                }
            }
     
            [Description("sets the template which our control will use")]
            public override string LayoutTemplatePath
            {
                get
                {
                    return TemplatePath;
                }
                set
                {
                    base.LayoutTemplatePath = value;
                }
            }
     
            [Description("sets the template which our control will use")]
            [WebEditor("Telerik.FileManager.UrlWebEditor, Telerik.FileManager")]
            public string TemplatePath
            {
                get
                {
                    return this._TemplatePath;
                }
                set
                {
                    this._TemplatePath = value;
                }
            }
     
            [Description("sets the mamanger which we will use to get the data")]
            protected virtual ContentManager Manager
            {
                get
                {
                    if (manager == null)
                        manager = new ContentManager(ProviderName);
                    return manager;
                }
            }
     
     
     
     
            [Description("sets the metakey which we will use to filter the data")]
            public string MetaKeyFilterQueryString
            {
                get
                {
                    return this._MetaKeyFilterQueryString;
                }
                set
                {
                    this._MetaKeyFilterQueryString = value;
                }
            }
     
     
            public string ProviderName
            {
                get
                {
                    return this._ProviderName;
                }
                set
                {
                    this._ProviderName = value;
                }
            }
     
            [Description("")]
            public string ControlText
            {
                get
                {
                    return this.controlText;
                }
                set
                {
                    this.controlText = value;
                }
            }
     
            protected virtual RadComboBox CategoriesComboBox
            {
                get
                {
                    return this.Container.GetControl<RadComboBox>("CategoriesComboBox", true);
                }
            }
     
     
            #region IEmptyControl Members
     
            public bool IsEmpty
            {
                get { return String.IsNullOrEmpty(this.ControlText); }
            }
     
            public string SetEmptyControlDefaultMessage()
            {
                return "The control cannot be previewed in edit mode";
            }
            #endregion
     
            private string controlText;
            private string _TemplatePath;
            private string _ProviderName;
            protected ContentManager manager;
            private string _MetaKeyFilterQueryString;
        }
    }

    4. Inside CreateChildControls() you need to filter the ContentView based controls. This has to be done before calling the base. The paging and data binding will be performed by the ContentView control and its base class ContentBase.

    Here  you only need to read the QueryString passed by the other control and pass the value to the ContentFilterBuild control which is used by ContentView based controls.

    The Repeater that ContentView based controls used will be bind the the base of CreateChildControls where we call RepeaterControl.DataBind();

    How the paging works? Here is sequence of the events

    1. CreateChildControls is called
    2. Filtering of the data source
    3. Calling CreateContentList() - here the page is constructed  and here we call CreateDataSource(); When you call RecreateChildControls or similar method you go back to step1.
    Inside this method we call only ItemDataBound  of the main Repeater  and then we call DataBind() outside of CreateContentList() at the end of  CreateChildControls().


    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  6. higgsy
    higgsy avatar
    336 posts
    Registered:
    05 Aug 2010
    21 Dec 2010
    Link to this post
    Hi Ivan,

    I have actually updated the support ticket.

    Thanks
    higgsy
Register for webinar
6 posts, 0 answered