Copied to clipboard

Flag this post as spam?

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


  • Maria 34 posts 128 karma points
    Aug 05, 2016 @ 07:46
    Maria
    0

    Custom Property Editor Dropdown needs to save both value and text of option

    I have a custom dropdown editor (it is important for me to have control over both the value and the text of an option) and it saves values without problem.

    I need to save the value of an option for integrating with an external service and the text to show on the page. Ideally as a key:value pairs.

    I can write both text and value into the value attribute and trimm it as needed. I can concatinate value and text in my controller and save is as a string to database and then again trim it so that it bindes in Umbraco and shows the chosen option.

    But is there a smart angular/Umbraco way to save it to the database as a key:value pair or an object so that I can than use item.GetProperty() and retrive text and value separately?

  • David Peck 687 posts 1863 karma points c-trib
    Aug 05, 2016 @ 08:06
    David Peck
    0

    Hi Maria,

    $scope.model.value doesn't have to just be a string, it can be an object. So $scope.model.value = { key: key, value: value };

    I assume you've already got your angular controller setup, so all you really need to do is to listen to the change event on your dropdown and then set that object as your value. In your Razor view you'll be returned some JSON so you can either work with it is a dynamic, deserialize it to an object. (e.g. var propVal = JsonConvert.DeserializeObject<KeyValuePair<string,string>>(content.GetPropertyValue<string>("myVal"));) or setup a property value converter.

  • Maria 34 posts 128 karma points
    Aug 05, 2016 @ 09:26
    Maria
    0

    Hey David,

    your solution sounds logical but I can only get it to work halfway. Here is what I've got:

    Dropdown:

    <select ng-model="model.value" ng-options="key as value for (key , value) in data" ng-controller="DDMakeController"></select>
    

    Controller:

    angular.module("umbraco")
    .controller("DDMakeController", function($scope){
    
    
        $scope.data = {
            "key1": "val1",
            "key2": "val2",
            "key3": "val3",
        };
    
        $scope.model.value = { a: $scope.model.value, b: $scope.data[$scope.model.value] }
    
        console.log($scope.model);
    

    });

    Razor:

     var propVal = JsonConvert.DeserializeObject<KeyValuePair<string, string>>(Model.Content.GetPropertyValue<string>("test"));
    

    console.log from controller shows me that I end up with Object that has a value where a: "key1" and b: "val1" (or whichever I choose).

    So far so good.

    However when I use Model.Content.GetPropertyValue("test") it only contains key1 and your line of code with JsonConvert returns an error:

    Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: U. Path '', line 0, position 0.

    And it makes sense if the value contains only "key1"

    Any ideas?

  • Maria 34 posts 128 karma points
    Aug 05, 2016 @ 10:12
    Maria
    0

    Ok. I got it working but now I have another problem, namely how to make sure that backoffice shows the value that was last selected. Here is my code again:

    Controller:

       angular.module("umbraco")
        .controller("DDMakeController", function($scope){
        $scope.makes = {
            "key1": "val1",
            "key2": "val2",
            "key3": "val3",
        };
    
        $scope.saveKeyValue = function () {
            $scope.model.value = { key: $scope.model.value, value: $scope.makes[$scope.model.value] }
            console.log($scope.model.value);
        };
    });
    

    Select:

       <select ng-model="model.value" ng-options="key as value for (key , value) in makes" ng-controller="DDMakeController" ng-change="saveKeyValue()"></select>
    

    I tried to use "track by":

    <select ng-model="model.value" ng-options="key as value for (key , value) in makes track by model.value.key" ng-controller="DDMakeController" ng-change="saveKeyValue()"></select>
    

    But that stops it from filling in values and I get "Object {key: undefined, value: undefined}" from my console.log. Any idea what to do?

  • David Peck 687 posts 1863 karma points c-trib
    Aug 05, 2016 @ 10:31
    David Peck
    2

    Ok so you've reminded me that ng-options can select an object so perhaps if you do something like this:

    $scope.myOptions = [
        { id: "key1", label: "va1A"},
        { id: "key2", label: "va1B"},
    ];
    

    Then you should be able to structure your ng-options directive to actually select one of those objects as your value. Something like:

    <select ng-model="model.value" ng-options="item as item.label for item in myOptions track by item.id" ng-controller="DDMakeController"></select>
    

    Then you should find that $scope.value = { id: "key1", label: "va1A"} (or other option)

  • Maria 34 posts 128 karma points
    Aug 05, 2016 @ 11:20
    Maria
    100

    Hey David,

    thanks for your help. This solution work with some changes to razor part.

    Here is the full functioning code if anyone ever needs it.

    Controller:

    angular.module("umbraco")
    .controller("DDMakeController", function($scope){
    
        $scope.makes = [
            { id: "key1", label: "val1" },
            { id: "key2", label: "val2" },
            { id: "key3", label: "val3" }
        ];});
    

    View:

    <select ng-model="model.value" ng-options="item as item.label for item in makes track by item.id" ng-controller="DDMakeController" ng-change="saveKeyValue()"></select>
    

    Razor:

    @{
                        var type = new { id = "", label = "" };
                        var trData = Model.Content.GetProperty("test");
                        if (trData != null)
                        {
                            var propVal = JsonConvert.DeserializeAnonymousType(trData.Value.ToString(), type);
                            <h1>@propVal</h1>
                            <h1>@propVal.id</h1>
                            <h1>@propVal.label</h1>
                        }
    
                    }
    
  • David Peck 687 posts 1863 karma points c-trib
    Aug 05, 2016 @ 11:54
    David Peck
    0

    Great stuff. Well done.

    Can you mark the topic as resolved please?

Please Sign in or register to post replies

Write your reply to:

Draft