Ability to sort custom content type in designer - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Ability to sort custom content type in designer

  • Ability to sort custom content type in designer
  • I have a custom widget that displays a list of custom content types (products).  I want to give the ability for the user to set the display order in the widget designer.  So for example i have product1, product2, product3, and product4.  In the designer I would like a sortable list of the products and the user can ideally drag and and move the products around to set their order as desired.  I see this functionality in various parts of Sitefinity (such as related data section of a content).  How to do this in the widget designer?

    Using Feather 9.1.

  • Update: I think I can accomplish this via the  sf-list-selector.  I have the tag below in the designer.  However I am getting an exception in the log file when i press save in the designer:

    End element 'PropertyValue' from namespace '' expected. Found element 'item' from namespace ''.   I don't have a view JSON or JS file.

     

    <sf-list-selector sf-dynamic-items-selector sf-provider="properties.ProductProviderName.PropertyValue" sf-item-type="properties.ProductType.PropertyValue" sf-multiselect="true" sf-sortable="true" sf-master="true" sf-selected-ids="properties.ProductIds.PropertyValue" />

     

    See same issue reported here: www.sitefinity.com/.../multiple-content-item-selector-for-dynamic-items-in-widget-designer 

  • Making a little progress.  It turns out the value for the sf-selected-ids attribute needs to be in JSON array format. e.g. [ productId1, productId2, productId3].  Otherwise the backend service throws that exception.  However, the selector by itself creates the string as product1, product2, product3.  I.e. without the brackets.

    So from what i gather, I need to create a JS file for designer that'll do that mapping back and forth.   Will report back on progress.

     

     

  • OK, got it going finally.  Here is the selector in the designer view (DesignerView.Simple.cshtml):

    <sf-list-selector sf-dynamic-items-selector sf-provider="properties.ProductProviderName.PropertyValue" sf-item-type="properties.ProductType.PropertyValue" sf-multiselect="true" sf-sortable="true" sf-master="true" sf-selected-ids="productIds" />

    As mentioned above, you'll need the designer JS file to do the JSON conversion back and forth.  So I save this in the MVC/Scripts/[WidgetName]/designer-simple.json:  (Simple is the name of the designer view)

    (function ($)
     
        var designerModule = angular.module('designer');
        angular.module('designer').requires.push('sfSelectors');
     
        designerModule.controller('SimpleCtrl', ['$scope', 'propertyService', function ($scope, propertyService)
             
            $scope.feedback.showLoadingIndicator = true;
            propertyService.get().then(function (data)
                if (data)
                    $scope.properties = propertyService.toAssociativeArray(data.Items);
                
            ,
            function (data)
                $scope.feedback.showError = true;
                if (data)
                    $scope.feedback.errorMessage = data.Detail;
            ).finally(function ()
                $scope.feedback.showLoadingIndicator = false;
            );
          
            $scope.$watch('properties.ProductIds.PropertyValue', function (newValue, oldValue)
                if (newValue)                
                    $scope.productIds = JSON.parse(newValue);
                
            );
     
            $scope.$watch('productIds', function (newValue, oldValue)
                if (newValue)                
                    $scope.properties.ProductIds.PropertyValue = JSON.stringify(newValue);
                
            );
     
        ]);
        
    )(jQuery);

    Lastly I added a DesignerView.Simple.json file in the same folder as DesignerView.Simple.cshtml:

        "priority": 1,
        "scripts": [     
            "client-components/selectors/common/sf-selected-items-view.js"
        ],
        "components" : ["sf-dynamic-items-selector"]

     

    Now the widget controller has a ProductIds property.  It's values will be in format [productId1, productId2, etc.].  I used a JSON deserializer to get an array of products for the controller Index action:

    public class ProductServicesWidgetController : Controller
       
           private string productProviderName = WebConfigurationManager.AppSettings["productProviderName"];
           private string productTypeName = WebConfigurationManager.AppSettings["productTypeName"];
     
           public string ProductIds get; set;
     
           public string ProductType
           
               get return productTypeName;
               set productTypeName = value;
           
     
           public string ProductProviderName
           
               get return productProviderName;
               set productProviderName = value;
           
     
           public ActionResult Index()
           
               var selectedProducts = string.IsNullOrEmpty(this.ProductIds) ? new Guid[0] : JsonConvert.DeserializeObject<Guid[]>(this.ProductIds);
     
             // ... rest of your controller index action