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

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

Ability to sort custom content type in designer

4 posts, 0 answered
  1. Hooman
    Hooman avatar
    19 posts
    Registered:
    24 Jun 2016
    03 Aug
    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
    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
    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 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