More in this section
Forums / Project Feather / Ability to sort custom content type in designer

Ability to sort custom content type in designer

The forums are in read-only mode. In case that you want to directly contact the Progress Sitefinity team use the support center. In our Google Plus group you can find more than one thousand Sitefinity developers discussing different topics. For the Stack Overflow threads don’t forget to use the “Sitefinity” tag.
4 posts, 0 answered
  1. Hooman
    Hooman avatar
    19 posts
    Registered:
    24 Jun 2016
    03 Aug 2016
    Link to this post

    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.

  2. Hooman
    Hooman avatar
    19 posts
    Registered:
    24 Jun 2016
    04 Aug 2016
    Link to this post

    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: http://www.sitefinity.com/developer-network/forums/project-feather/multiple-content-item-selector-for-dynamic-items-in-widget-designer 

  3. Hooman
    Hooman avatar
    19 posts
    Registered:
    24 Jun 2016
    04 Aug 2016
    Link to this post

    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.

     

     

  4. Hooman
    Hooman avatar
    19 posts
    Registered:
    24 Jun 2016
    04 Aug 2016 in reply to Hooman
    Link to this post

    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
              
              
           }        
       }

     

4 posts, 0 answered