on Click Redirect page on javascritp

 /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder

we keep the URL in the button.

  <a class="btn btnProductFinderSearch" data_src=@Url.Action("SearchByProductFinderSelection", "ProductList")>@Sana.SimpleText("ProductFinderSearch", "Search")</a>


on js 

set URL and parameters. 

$(function () {
       $('.btnProductFinderSearch').click(function () {
 
           ...
 
           var actionUrl = $(".btnProductFinderSearch").attr('data_src');
           var paramerters = "?type=" + selectedType + "&otherFilters=" + selectedVal;
 
           if (selectedVal != "") {
 
                // Sana.Urls.Home()
                var getUrl = actionUrl + paramerters;  // ?type:SANAECOM_FILTER1:Apple,SANAECOM_FILTER4:ModelNR1&otherFilters:Series:3" //"ProductList/SearchByProductFinderSelection?" + "type" + selectedType "", otherFilters: selectedVal;   // 'ProductFilter/SearchProduct'
                //window.location.href = getUrl; // data.RedirectUrl;                 


register in rought

protected override void RegisterSystemRoutes(SanaRouteCollection routes)
        {
            base.RegisterSystemRoutes(routes);
 
            /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
            routes.MapSystemPageRoute(Name, "SearchByProductFinderSelection", "SearchByProductFinderSelection");
            routes.MapSystemPageRoute(Name, "Testmethodss", "Testmethodss");
        }


set HttpGet method

[HttpGet]
       [ActionName("SearchByProductFinderSelection")]
       public virtual async Task<ActionResult> SearchByProductFinderSelection(string type, string otherFilters, [PageIndex] int page, int count = 0, SortOption sort = null, string viewMode = null)
       {
           .........................
            ..






get Fake request with facets /Facet related customizations / update facet selection by code.

 /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder

https://sanacommerce.visualstudio.com/Sana%20Projects/_workitems/edit/100006/


get Fake request with facets 

public class ExtendedCatalogApi : CatalogApi
    { 
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder        
        public virtual SearchResponse GetProductsResponseWithoutProducts(FieldFilterCollection facets)
        {              
            var request = CreateProductSearchRequest(string.Empty, 0, 10, null, facets, null,false);                       

            var responce = ((ExtendedProductSearchManager)CommerceFrameworkBase.ProductSearch).GetSearchProductResponseWithoutProducts(request);
            
            return responce;
 
        }
    }

public class ExtendedProductSearchManager : ProductSearchManager<ExtendedProductSearchIndexProvider>
    {          
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        /// Get search product response without products
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public virtual SearchResponse GetSearchProductResponseWithoutProducts(CatalogSearchRequest request)
        {
            var response = SearchProducts(request);
            return response;
        } 
    }







insert Save /update/delete by nhibernate

 


 
namespace Sana.Commerce.Customization.Common
{
    public class ExtendedOfflineCommonProvider : OfflineCommonProvider, IExtendedCommonProvider
    {
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        /// Delete all product types.
        /// </summary>
        public virtual void DeleteAllProductTypes()
        {
            WrapDataAccessException(() =>
            {
                using (var sm = CreateSessionManager(false))
                {
                    var productTypes = GetProductTypes();
                    foreach (var productType in productTypes)
                    {
                        sm.Session.Delete(productType);
                    }
                    sm.Commit();
                }
            }, "Cannot delete product types for {0} website".FormatWith(Context.WebsiteId));
        }
 
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        ///  Get product types.
        /// </summary>
        /// <returns></returns>
        public virtual IList<IProductType> GetProductTypes()
        {
            using (var sm = CreateSessionManager(true))
            {
                var productTypes = sm.Session.CreateCriteria(GetRegisteredType<IProductType>())
                    .Add(NHibernate.Criterion.Restrictions.Eq("WebsiteId", CommerceFrameworkBase.Context.WebsiteId))
                    .List<IProductType>();
                return productTypes;
            }
        }
 
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        /// Save product types.
        /// </summary>
        /// <param name="productTypes"></param>
        public virtual void SaveProductTypes(IList<IProductType> productTypes)
        {
            WrapDataAccessException(() =>
            {
                using (var sm = CreateSessionManager(false))
                {
                    productTypes.Each(c => sm.Session.SaveOrUpdate(c));
                    sm.Commit();
                }
            }, "Cannot save product types");
        }
 
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        /// Save product finder types
        /// </summary>
        /// <param name="productFinderTypes"></param>
        public virtual void SaveProductFinderTypes(IList<IProductFinderTypeModel> productFinderTypes)
        {
            // Delete data for Website and product type ID,Then save 
 
            if (productFinderTypes != null)
            {
                DeleteProductFinderTypesByProductTypeCode(productFinderTypes[0].ProductTypeCode);
            }
            WrapDataAccessException(() =>
            {
                using (var sm = CreateSessionManager(false))
                {
                    productFinderTypes.Each(c => sm.Session.SaveOrUpdate(c));
                    sm.Commit();
                }
            }, "Cannot save product finder types");
        }
 
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        /// Get product finder types by product type code
        /// </summary>
        /// <param name="typeCode">product type Code</param>
        /// <returns></returns>
        public virtual IList<IProductFinderTypeModel> GetProductFinderTypesByProductTypeCode(string typeCode)
        {
            return WrapDataAccessException(() =>
               {
                   using (var sm = CreateSessionManager(true))
                   {
                       var criteria = sm.Session.CreateCriteria(GetRegisteredType<IProductFinderTypeModel>())
                          .Add(Expression.Eq("WebsiteId", Context.WebsiteId))
                          .Add(Expression.Eq("ProductTypeCode", typeCode));
                       return criteria.List<IProductFinderTypeModel>();
                   }
               }, "Cannot get related products set for products with Ids = {0} and website = {1}.", typeCode, Context.WebsiteId);
        }
 
        /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder
        /// <summary>
        ///  Delete product finder types by product type code
        /// </summary>
        /// <param name="typeCode">product type Code</param>
        public virtual void DeleteProductFinderTypesByProductTypeCode(string typeCode)
        {            
            WrapDataAccessException(() =>
            {
                using (var sm = CreateSessionManager(false))
                {
                    var productFinderTypes = GetProductFinderTypesByProductTypeCode(typeCode);
                    foreach (var productFinderType in productFinderTypes)
                    {
                        sm.Session.Delete(productFinderType);
                    }
                    sm.Commit();
                }
            }, "Cannot delete product types for {0} website".FormatWith(Context.WebsiteId));
        }  
    }
}

How to read Index file by Lucen index

 run luke 

D:\Software\LukeNet\LukeNet

File > open luke index > add index file 

eg:\\corp-fs08\Shares\ISM-APAC\Fileshare\SanaIndexing\ST4\Topmedia_935\7fa1bda9-7bf4-4c77-b310-f91218ef1f36

navigate to Documents tab








How to dynamically create a drop-down list with JavaScript and jQuery

 Project Topmedia

Ticket 100006: [Topmedia] 3.1. Search – Product Finder

page.productfinderselection.js

use 

https://www.techiedelight.com/dynamically-create-drop-down-list-javascript/#:~:text=To%20add%20a%20drop%2Ddown,appendChild()%20method%20or%20jQuery's%20.

$(MakeListDropdown).on('change', function () {
 
        $("#productFacets").empty();
        debugger;
        var option = MakeListDropdown.find('option:selected');
        var typeId = option.attr('value');
        var getUrl = Sana.Urls.Home() + 'ProductFilter/GetProductFinderTypes'; //MakeListDropdown.attr('data-src');
        $.ajax({
            url: getUrl,
            type: "GET",
            dataType: "JSON",
            data: { typeId: typeId },
            success: function (data) {
 
                if (data) {
 
                    const values = data;
                   
                    for (const val of values) {
                        //create new dropdown list
                        var select = document.createElement("select");
                        select.name = val.Name;
                        select.id = val.Name;
 
                       var labelName = val.Name;                                              
 
                        for (const facet of val.Items) {
                            // create options for the drop down list
                            var option = document.createElement("option");                        
                            option.value = facet.Title;
                            option.text = facet.Title;
                            select.appendChild(option);
                        }
 
                        var label = document.createElement("label");
                        label.innerHTML = labelName;
                        label.htmlFor = labelName;
 
                        $("#productFacets").append(label).append(select);
                                                                      
                    }














How to set extra fields to Request / GetProduct request extra fields.


public class ExtendedProductProvider : ProductProvider, IExtendedProductProvider
    {
        public override IProductCollection GetProducts(IProductListLoadOptions options)
        {
            Guard.ThrowIfNull(options, "options");

            var request = new List<XElement>()
            {
                XParam("VisibleOnly", options.VisibleOnly),
                XParam("LoadRelatedSkus", options.LoadRelatedSkus),
                XParam("LoadVisibilityRules", options.LoadVisibilityRules),
                XParam("CalculatePrices", options.CalculatePrices),
                XParam("CalculateInventory", options.CalculateInventory),
                XParam("CalculateSkuPrices", options.CalculateSkuPrices),
                XParam("CalculateSkuInventory", options.CalculateInventory && options.CalculateSkuInventory),
                XParam("CheckStock", Context.Settings.CheckStock),
                XParam("AccountId", Context.AccountId),
                XParam("AccountType", Context.AccountType),
                XParam("MultiCurrency", options.MultiCurrency),
            };
 
            IEnumerable<string> extraFields = new List<string>() { "SANAECOM_FILTER1", "SANAECOM_FILTER2", "SANAECOM_FILTER3","SANAECOM_FILTER4","SANAECOM_FILTER5" };
            
            options.EntityFields = extraFields;

            AddLoadOptions(request, options);

            OnGetProducts(request, options);
            var result = ExecuteRequest("GetProducts", request);
            var products = Parser.ParseCollection<IProductCollection, IProduct>(result, "Product", Parser.ParseProduct);

            if (options.LoadRelatedSkus)
            {
                foreach (var p in products)
                {
                    if (p.Variants == null)
                        p.Variants = ObjectFactory.Create<IProductVariantCollection>();
                    if (p.Prepacks == null)
                        p.Prepacks = ObjectFactory.Create<IProductPrepackCollection>();

                    FillVariantsDimensions(p);
                }
            }
            return products;
        }
 
 
        protected override void AddLoadOptions(IList<XElement> request, IEntityListLoadOptions options)
        {
            AddPagingAndSorting(request, options);
            request.Add(XmlHelper.CreateQueryFieldsElement(options.EntityFields));
            request.Add(XmlHelper.CreateFilterElement(options.Filter));
        }
    }


To extra fields called by CreateQueryFieldsElement method

 protected override void AddLoadOptions(IList<XElement> request, IEntityListLoadOptions options)
        {
            AddPagingAndSorting(request, options);
            request.Add(XmlHelper.CreateQueryFieldsElement(options.EntityFields));
            request.Add(XmlHelper.CreateFilterElement(options.Filter));
        }


set as follow

 IEnumerable<string> extraFields = new List<string>() { "SANAECOM_FILTER1", "SANAECOM_FILTER2", "SANAECOM_FILTER3","SANAECOM_FILTER4","SANAECOM_FILTER5" };
            
            options.EntityFields = extraFields;







 

ajax call / partial view not work as expected need to initial again on sucess

 need to initialize the funtion again on sucess page 


// This need to rap with product Finder

$('#ProductType').change(function () {
    debugger;
    
    var selectedTypeId = $(this).val();    
    LoadFacetFieldsforSelectedType(selectedTypeId); 
});
 
function LoadFacetFieldsforSelectedType(selectedTypeId) {
    
    var urlPath = window.location.origin + '/admin/productindex/loadfacetfields'
 
    
    $.ajax({
        //url: Sana.Urls.Home() + 'ProductIndex/loadfacetfields',
        url: urlPath,
        method: "POST",
        data: { id: selectedTypeId },        
        
    }).done(function (data) {
 
        if (data != null) {
 
            $("#ProductFinderFacet-panel").html(data);
 
            $(FacetsEditor.init); <----
 
           
        }
 
    })
}


this function on page.facets.js

var FacetsEditor = (function () { <--------------------
    var initEditor = function (cnt) {
        
        ................  
 
 
})();
 


partial  view in Product finder settings

<div id="ProductFinderFacet-panel">
        @Html.Partial("_FacetsProductTypeEditor", Model.Facets)
    </div>



https://entityframework.net/knowledge-base/32975369/ajax-post-to-controller-action-to-update-view-model--and-then-reload-div