Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Osman Coskun 164 posts 378 karma points
    Aug 26, 2022 @ 16:47
    Osman Coskun
    0

    How to construct the value converter for custom property editor (cascaded dropdown list)

    Hi all,

    I'm working on a website for a real estate company (Umbraco 8.18.5). The client requested cascaded dropdowns for selecting city, town and district in property doctype. I added the tables cities, towns & districts to the database and created a custom property editor named CityTownDistrict.

    I set up the property editor and it works on umbraco backoffice as expected. The editor stores city, town, district as JSON data as follows:

    {
      "city": {
        "Id": 6,
        "Name": "Ankara"
      },
      "town": {
        "Id": 64,
        "Name": "ÇANKAYA"
      },
      "district": {
        "Id": 5086,
        "Name": "ANITTEPE MAHALLESÄ°"
      }
    }
    

    I need to render the city name, town name and district name in razor view. I found a few pages that describe property value converters for simpler data. But couldn't find an example for converting similar JSON data. Can you please guide me creating the value converter? Additionally do you think is it possible to filter the properties by this data?

    Thank you in advance.

    I want to share the code for reference to developers who may need cascaded dropdown list.

    package.manifest

    {
        propertyEditors: [
            {
                alias: "CityTownDistrict",
                name: "City Town District",
                icon: "icon-list",
                group: "Lists",
                editor: {
                    view: "~/App_Plugins/CityTownDistrict/CityTownDistrict.html",
                    valueType: "JSON"
                }
            }
        ]
        ,
        javascript: [
            '~/App_Plugins/CityTownDistrict/CityTownDistrict.resource.js',
            '~/App_Plugins/CityTownDistrict/CityTownDistrict.controller.js'
        ]
    }
    

    CityTownDistrict.html

    <div ng-controller="CityTownDistrictController">
    
        <select ng-model="model.value.city"
                ng-options="item as item.Adi for item in cities track by item.Id"
                ng-change="getTowns()"
                class="form-control"
                ng-required="true"
                id="city">
            <option value="">Select City</option>
        </select>
        <br />
        <select ng-model="model.value.town"
                ng-options="item as item.Ilce for item in towns track by item.Id"
                ng-hide="!model.value.city"
                ng-change="getDistricts()"
                class="form-control"
                ng-required="true"
                id="towns">
            <option value="">Select Town</option>
        </select>
        <br />
        <select ng-model="model.value.district"
                ng-options="item as item.Mahalle for item in districts track by item.Id"
                ng-hide="!model.value.town"
                class="form-control"
                ng-required="true"
                id="towns">
            <option value="">Select District</option>
        </select>
    </div>
    

    CityTownDistrict.resource.js

    angular.module('umbraco.resources').factory('CityTownDistrictResource',
        function ($q, $http, umbRequestHelper) {
            return {
                getCities: function () {
                    return umbRequestHelper.resourcePromise(
                        $http.get("/umbraco/CityTownDistrict/data/getcities"),
                        "Failed to retrieve all cities data");
                },
                getTowns: function (id) {
                    return umbRequestHelper.resourcePromise(
                        $http.get("/umbraco/CityTownDistrict/data/gettowns?id=" + id),
                        "Failed to retrieve all towns data");
                },
                getDistricts: function (id) {
                    return umbRequestHelper.resourcePromise(
                        $http.get("/umbraco/CityTownDistrict/data/getdistricts?id=" + id),
                        "Failed to retrieve all districts data");
                }
            };
        }
    );
    

    CityTownDistrict.controller.js

    angular.module("umbraco").controller("CityTownDistrictController",
        function ($scope, CityTownDistrictResource) {
    
            if ($scope.model.value == "") {
                $scope.model.value = {};
    
            }
    
            CityTownDistrictResource.getCities().then(function (response) {
                $scope.cities = response;
    
                //If the document has city value
                if ($scope.model.value.city.Id != "") {
                    //Get town from document
                    CityTownDistrictResource.getTowns($scope.model.value.city.Id).then(function (response) {
                        $scope.towns = response;
    
                        if ($scope.model.value.town.Id != "") {
                            //Get the district from document
                            CityTownDistrictResource.getDistricts($scope.model.value.town.Id).then(function (response) {
                                $scope.districts = response;
    
                            });
                        }
    
                    });
                }
            });
    
    
            function getTowns() {
                delete $scope.model.value.town;
                delete $scope.model.value.district;
                CityTownDistrictResource.getTowns($scope.model.value.city.Id).then(function (response) {
    
                    $scope.towns = response;
                });
            }
            $scope.getTowns = getTowns;
    
    
            function getDistricts() {
                delete $scope.model.value.district;
                CityTownDistrictResource.getDistricts($scope.model.value.town.Id).then(function (response) {
                    $scope.districts = response;
    
                });
            }
            $scope.getDistricts = getDistricts;
        }
    );
    

    Property editor queries the database using the CityTownDistrictApiController.cs

    using System.Collections.Generic;
    using System.Web;
    using Umbraco.Web.WebApi;
    using Umbraco.Core.Scoping;
    
    [Umbraco.Web.Mvc.PluginController("CityTownDistrict")]
    public class DataController : UmbracoApiController
    {
        public class City
        {
            public int Id { get; set; }
            public string Adi { get; set; } // Adi stands for City
        }
        public class Town
        {
            public int Id { get; set; }
            public string Ilce { get; set; } // Ilce stands for Town
        }
        public class District
        {
            public int Id { get; set; }
            public string Mahalle { get; set; } //Mahalle stands for District
        }
        private readonly IScopeProvider scopeProvider;
    
        public DataController(IScopeProvider scopeProvider)
        {
            this.scopeProvider = scopeProvider;
        }
        public IEnumerable<City> GetCities()
        {
            using (var scope = scopeProvider.CreateScope(autoComplete: true))
            {
                var sql = scope.SqlContext.Sql().Select("*").From("CityTownDistrictCities");
    
                return scope.Database.Fetch<City>(sql);
            }
        }
        public IEnumerable<Town> GetTowns()
        {
            using (var scope = scopeProvider.CreateScope(autoComplete: true))
            {
                //sehkodu stands for cityId foreign key in Towns table
                var sql = scope.SqlContext.Sql().Select("*").From("CityTownDistrictTowns").Where("sehkodu=" + HttpContext.Current.Request.QueryString["id"]);
    
                return scope.Database.Fetch<Town>(sql);
            }
        }
        public IEnumerable<District> GetDistricts()
        {
            using (var scope = scopeProvider.CreateScope(autoComplete: true))
            {
                // ilce_id stands for townId foreign key in Districts table
                var sql = scope.SqlContext.Sql().Select("*").From("CityTownDistrictDistricts").Where("ilce_id=" + HttpContext.Current.Request.QueryString["id"]);
    
                return scope.Database.Fetch<District>(sql);
            }
        }
    }
    
  • Chriztian Steinmeier 2798 posts 8787 karma points MVP 7x admin c-trib
    Aug 27, 2022 @ 08:26
    Chriztian Steinmeier
    0

    Hi Osman,

    I have tried my hands on a couple of PropertyValueConverters for JSON data - maybe it can be of help to you to look at one of them:

    https://github.com/vokseverk/Vokseverk.KeyValueEditor/blob/b192a8518300a5610b147a982887f2c7fb27feb7/src/KeyValuePropertyConverterV8.cs

    I got most of them from other people's code also, so I can't tell you how everything works - but the part I think you need is how to convert the JSON data to "something better"?

    Hope this can help,

    /Chriztian

  • Osman Coskun 164 posts 378 karma points
    Aug 27, 2022 @ 17:48
    Osman Coskun
    0

    Thank you Chriztian, i'll examine your code if i can adapt.

Please Sign in or register to post replies

Write your reply to:

Draft