Developer forum

Forum » Development » Sort order of property fields in frontend/pim/ecom

Sort order of property fields in frontend/pim/ecom

Aki Ruuskanen
Aki Ruuskanen
Reply

Hi,

I am trying to get my head around the sorting of property fields.

I have attached three screenshots of same fields in PIM, eCom and when rendered with the ProductFieldService. 

They have all different sortorder. 

What I am trying to achive is to render the fields in frontend in the same order as they appear in the PIM.

Any advice on how to achive this?

Regards / Aki

 

eCom-sortorder.png PIM-sortorder.png ProductFieldService-sortorder.png

Replies

 
Alexander Gubenko
Alexander Gubenko
Reply

Hello Aki Ruuskanen

1) In Ecom we render product category fields in the natural order, I mean in that order when fields was added(and shown) in Setting >> Ecommerce >> Product catalog >> Product categories >> <Edit Category>
2) In PIM you set up order product category fields by yourself using "Visible Fields". And this is user specific. So each user can set up order by himself.
3) It is not simple to recognize how you're rendering category fields in frontend using ProductFieldService becase we haven't service with such name.

So below I want to show two ways to render fields which you can use:
a) Render category fields in Ecom order:
Just use Services.ProductCategoryFields.GetFieldsByCategoryId to get category fields and transform it to ProductField. Similar like these lines:

private IEnumerable<ProductField> GetCategoryFields(string categoryId)
{
    var categoriesFieldsIdx = ProductField.GetCategoryFields().ToDictionary(f => f.SystemName);
    var category = Dynamicweb.Ecommerce.Services.ProductCategories.GetCategoryById(categoryId);
    if (category == null)
    {
        throw new ArgumentException($"The category {categoryId} doesn't exist");
    }
    var fields = category.Fields;
    var result = new List<ProductField>();
    foreach(var field in fields)
    {
        var sysName = $"ProductCategory|{field.Category.Id}|{field.Id}";
        ProductField prodField;
        if (categoriesFieldsIdx.TryGetValue(sysName, out prodField))
        {
            result.Add(prodField);
        }
    }
    return result;
}

Look to whole example in CategoryFieldsRenderer.cs in Gist1

b) Use the 'Field display group' to render fields:
So go to Setting >> Ecommerce >> Product catalog >> Field display groups and create display group with needed fields.
You need find Id this display group: Go to "Edit" this group and Id will in URL(yes it's alitle bit tricky we already added systemname for it. The system name will be delivered in the 9.9 only).
So after use can get display group ProductFields using:

private IEnumerable<ProductField> GetDisplayGroupFields(int displayGroupId)
{
    var displayGroup = Dynamicweb.Ecommerce.Services.FieldDisplayGroups.GetById(displayGroupId);
    if (displayGroup == null)
    {
        throw new ArgumentException($"The display group {displayGroupId} doesn't exist");
    }
    var fieldsUniqueSystemNames = Core.Converter.ToString(displayGroup.FieldIds).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    var allFields = ProductField.GetAllEditableProductFields();
    var result = new List<ProductField>();
    foreach (var fieldSystemName in fieldsUniqueSystemNames)
    {
        ProductField prodField;
        if (allFields.TryGetValue(fieldSystemName, out prodField))
        {
            result.Add(prodField);
        }
    }
    return result;
}

Look to whole example in FieldsDisplayGroupRenderer.cs in Gist2

I hope I help you.

P.S.
And also in the  product catalog frontend pages you can use field display groups as tags just look into FieldDisplayGroups tag loop

 

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Hi Alexander,

Thanks for a well written answer.

I forgot to mention that the fields I am working with are of type "Property". Different products (even in same category) have different property fields. That means I cannot create a "Field Display Group". 

 

In PIM you set up order product category fields by yourself using "Visible Fields". And this is user specific. So each user can set up order by himself.

I guess you mean that it's specific for a backend user. Is there a way to render the property fields based on a specific user. 

Lets say user "A" sets a "Visible Fields" order. Can I render the fields in frontend based on user "A"s sortorder?

Regards / Aki

 

 

 
Alexander Gubenko
Alexander Gubenko
Reply
Original message by Aki Ruuskanen posted on 15/05/2020 08:12:41:

Hi Alexander,

Thanks for a well written answer.

I forgot to mention that the fields I am working with are of type "Property". Different products (even in same category) have different property fields. That means I cannot create a "Field Display Group". 

It works for properties too just add to your  field display groups all properties. If for the property doesn't exist fo current product then Dynamicweb.Ecommerce.Services.Products.GetFieldValue(product, field) returns object with Data property == null. 

In PIM you set up order product category fields by yourself using "Visible Fields". And this is user specific. So each user can set up order by himself.

I guess you mean that it's specific for a backend user. Is there a way to render the property fields based on a specific user. 

Lets say user "A" sets a "Visible Fields" order. Can I render the fields in frontend based on user "A"s sortorder?

Well, you can... But this is internal implementation and potentially it would be changed in future. So I can't recommend you use it. The way with Field Display groups is standard way.
In anyway  you can... Use this lines to get ProductField system names:

private IEnumerable<string> GetProductFieldsSystemNames()
{
    var fields = string.Empty;
    var pimEditUrl = "/Admin/Module/eCom_Catalog/dw7/PIM/PimMultiEdit.aspx";
    var userId = <USERID>;
    var fieldsDisplayGroupId = Core.Converter.ToInt32(Dynamicweb.Controls.PersonalSettings.GetData(userId, pimEditUrl, "preset"));
    if (fieldsDisplayGroupId > 0)
    {
        var displayGroup = Dynamicweb.Ecommerce.Services.FieldDisplayGroups.GetById(fieldsDisplayGroupId);
        if (displayGroup != null)
        {
            fields = displayGroup.FieldIds;
        }
    }
    if (string.IsNullOrEmpty(fields))
    {
        fields = Dynamicweb.Controls.PersonalSettings.GetData(userId, pimEditUrl, "fields");
    }
    var fieldsUniqueSystemNames = Core.Converter.ToString(fields).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    return fieldsUniqueSystemNames;
}
 
Aki Ruuskanen
Aki Ruuskanen
Reply

OK, thanks for the feedback. Very helpful. yes

I will try this out next week (in another project today).

Regards / Aki

 

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Hello again Alexander. 

I have worked a bit with th different approaches that you shared and they work as expected. yes

My main problem, which I should have mentioned in the first post,  is that I would need to have different sortorders of category fields per product.

Maybe this is not possible?

Regards / Aki

 

 
Alexander Gubenko
Alexander Gubenko
Reply

Hello Aki

I think it's possible.

Just create different field display groups with fields which you want and with right sort orders. And swich it as you wish according your product logic.  Look I can swich field display groups in PIM admin:

https://www.screencast.com/t/iiE6qBwouY

You can  to do the trick in frontend too.

So I suggest you use gist2 and pass different displayGroupId values for different products. I think it should work for you.

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Hi Alexander,

Thank for the input.

In that case would I need to somehow assign a "Field display group" to a product. Not sure how to do that. Perhaps a FieldTypeProvider? 

The ideal scenario would be to be able to set a sort order for frontend in the product view in the PIM. Maybe that is a feature request. :) 

Regards / Aki

 
Alexander Gubenko
Alexander Gubenko
Reply

Hi Aki,

There is no need to assign fields display group to product. You just create as many fields display groups with sorting you need and then during the rendering use(you can use customfield to store fields group id for this product) needed group for specific product. 

That was my thought.

Another option if you need sort order ONLY category property fields in frontend you can use standart loops which allready sort it that order which choose when you add it in 'Add property' in Pim.

https://www.screencast.com/t/9LMdFgxBDi

loop:

<!--@LoopStart(ProductCategories)-->
<br/>
<b><!--@Ecom:Product.Category.Name--></b>
<br/>
<!--@LoopStart(ProductCategoryFields)-->
<i><!--@Ecom:Product.CategoryField.Label--></i>
<br/>
<!--@LoopEnd(ProductCategoryFields)-->
<!--@LoopEnd(ProductCategories)-->

 

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Thanks for your patience. :)

Well if I could use standard loops that would be fantastic. That was my inital approach. 

The scenario is that I have a product and that product has variants (the variants are created as a family in PIM).

On a product detail page I need to loop through those variant products and display their product category fields in a predefined order. 

But the loop for rendering varints dont have that kind of information. So I tried to get that information otherwise. 

/Aki

 

 
Aki Ruuskanen
Aki Ruuskanen
Reply
Hi again Alexander,
 
 
I made a productfeed that shows variants for a product and in the Products loop I use this code to get the product category values.
 
        foreach (var productCategory in product.GetLoop("ProductCategories"))
        {
            foreach (var productCategoryField in productCategory.GetLoop("ProductCategoryFields"))
            {
                productObject.PropertyFields.Add(new PropertyField
                {
                    name = productCategory.GetString("Ecom:Product.Category.Name"),
                    label = productCategoryField.GetString("Ecom:Product.CategoryField.Label") ,
                    value = productCategoryField.GetString("Ecom:Product.CategoryField.Value")
                });
            }
        }
 
Example product id : ImportedPROD224
 
The feed for that product:
 
http://industrilas.softgear.se/variants?MainProductID=ImportedPROD224&OnlyShowVariants=true&feed=true
 
I attached a screenshot of the order of the category fields rendered by the ProductCategoryFields loop. I cannot find that order anywhere in the system. 
Do you have an idea from where this sort order comes from?
 
 
And for some reason I annot sort columns the way you did in the example:
https://drive.google.com/file/d/1qSdcSHW-7sSdbD4ykzLNcVhYLtM3A-XL/view
 
Regards / Aki
Rendered_sort_order.png
 
Alexander Gubenko
Alexander Gubenko
Reply

Hello Aki,

It's bug that the property category fields ordered wrong for variants on frontend. It works for product(not variant).
So, we've created bug tfs#81390.
I'm pretty sure we will fix it soon.

-Alexander

 
Aki Ruuskanen
Aki Ruuskanen
Reply

OK, thanks for info. That explains a lot. :)

/Aki

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Hi,

Do know when this bug is about to get fixed. I cannot find that bug number in "Known bugs" or "Release notes"?

Regards / Aki

 
Kristian Kirkholt Dynamicweb Employee
Kristian Kirkholt
Reply
This post has been marked as an answer

Hi Aki

The #81390 for PIm Sort order of property fields has been planned for Dynamicweb 9.8.10

I would expect this to be out in a few weeks

You will get a notification when ready

Kind Regards
Dynamicweb Support
Kristian K

Votes for this answer: 1
 
Kristian Kirkholt Dynamicweb Employee
Kristian Kirkholt
Reply

Hi Aki

Version 9.8.10 is out now.. Go get it at: http://doc.dynamicweb.com/releases-and-downloads/releases

Or the Dynamicweb.Ecommerce Package version 1.8.92

Please contact Dynamicweb Support if you need any additional help regarding this.

Kind Regards
Dynamicweb Support
Kristian Kirkholt

 

You must be logged in to post in the forum