Copied to clipboard

Flag this post as spam?

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


  • Mike Taylor 155 posts 353 karma points
    May 29, 2018 @ 13:40
    Mike Taylor
    0

    How to bind <umb-editor> date picker values inside an ng-repeat?

    Hi there,

    I'm creating a custom property editor that can store multiple prices for an item based on a date range.

    The JSON for the value looks like this:

    {
      "prices": [
      {
         "dateFrom": "2018-01-01T00:00:00Z",
         "dateTo": "2018-01-31T00:00:00Z",
         "price": 100
      },
      {
         "dateFrom": "2018-02-01T00:00:00Z",
         "dateTo": "2018-04-30T00:00:00Z",
         "price": 120
      },
      {
         "dateFrom": "2018-05-01T00:00:00Z",
         "dateTo": "2018-07-31T00:00:00Z",
         "price": 150
      }
      ]
    }
    

    Here's my dateprices.editor.html file:

    <div ng-controller="MT.DatePricesController">
    
        <table class="date-prices">
        <thead>
            <tr>
                <th scope="col">From</th>
                <th scope="col">To</th>
                <th scope="col">Price</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="priceItem in model.value.prices">
                <td>{{ priceItem.dateFrom }}</td>
                <td>{{ priceItem.dateTo }}</td>
                <td><input ng-model="priceItem.price" type="number" class="clr-number"/></td>
            </tr>
        </tbody>
        </table>
    
    </div>
    

    I'd really like to use the Umbraco date picker for the dateFrom and dateTo fields, but I can't work out how to bind it up from inside an ng-repeater block like this.

    For simple situations, it looks like it can be connected up like this:

    <umb-editor model="datePickerSingle"></umb-editor>
    

    With the "datePickerSingle" model defined in the controller:

    $scope.datePickerSingle = {
            view: "datepicker",
            config: {
                pickDate: true,
                pickTime: false,
                pick12HourFormat: false,
                format: "D MMM YYYY"
            },
            value: $scope.model.value.myDate
        };
    

    But for my example, I want to bind multiple date pickers to the values inside my ng-repeat block.

    Anyone got any tips or examples of this being done?

    Thanks,

    Mike

  • Marcel van Helmont 68 posts 259 karma points c-trib
    May 29, 2018 @ 16:56
    Marcel van Helmont
    0

    Hi Mike,

    I think you can better use umbDateTimePicker if you wanne use a umbraco styled date picker. and make your change event generic so he can update your model.

    https://our.umbraco.org/apidocs/ui/#/api/umbraco.directives.directive:umbDateTimePicker

  • Mike Taylor 155 posts 353 karma points
    Jun 12, 2018 @ 14:47
    Mike Taylor
    0

    Thanks Marcel.

    I'm looking at the umbDateTimePicker, but I'm still not sure how to manage the situation where the picker is inside an ng-repeat loop.

    Each iteration of the ng-repeat loop has two dates, and I'm trying to work out how to bind these "From" and "To" dates for each row to date pickers:

    Date picker inside an ng-repeat loop

    Is this possible? I can only find examples that bind a single date value to a date picker; nothing with multiple values inside an ng-repeat loop.

    Thanks,

    Mike

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Sep 04, 2018 @ 13:48
    Lee Kelleher
    1

    Hi Mike,

    Only a week or so delayed response to your tweet ... hopefully I can try to help. Although I suspect something details may get lost in translation, e.g. prepare yourself, as I doubt this will be a copy-n-paste solution.

    OK, you can use the <umb-date-time-picker options="..." /> directive, like so...

    <tbody>
        <tr ng-repeat="priceItem in prices">
            <td>
                <umb-date-time-picker options="priceItem.dateFrom" />
            </td>
            <td>
                <umb-date-time-picker options="priceItem.dateTo" />
            </td>
            <td>
                <input ng-model="priceItem.price" type="number" class="clr-number" />
            </td>
        </tr>
    </tbody>
    

    ... but it requires a bit of extra fiddly config in the values ... e.g.

    {
        dateFrom: {
            defaultDate: new Date("2018-04-30T12:34:56Z"),
            pickDate: true,
            pickTime: false,
            useSeconds: false,
            format: "D MMM YYYY",
            icons: {
                time: "icon-time",
                date: "icon-calendar",
                up: "icon-chevron-up",
                down: "icon-chevron-down"
            }
        },
        dateTo: /* snipped for brevity */,
        price: 100
    }
    

    The date picker is using the Bootstrap DateTimePicker library; the full config options for it can be seen here: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web.UI.Client/lib/datetimepicker/bootstrap-datetimepicker.js#L1412-L1435
    Make note, that the defaultDate is the one that is used. I'd have expected it to be called value, but I dunno.

    To be honest, you wont want to keep duplicating the datetimepicker config, so you could whack that in a variable and extend it, like so...

    var defaultDateTimeConfig = {
        pickDate: true,
        pickTime: false,
        useSeconds: false,
        format: "D MMM YYYY",
        icons: {
            time: "icon-time",
            date: "icon-calendar",
            up: "icon-chevron-up",
            down: "icon-chevron-down"
        }
    };
    
    ...
    
    dateFrom: angular.extend({ defaultDate: new Date("2018-04-30T12:34:56Z") }, defaultDateTimeConfig)
    

    but that's just a suggestion

    The reason I've used new Date("") instead of a string, is that in Bootstap DateTimePicker, it checks if the value is a Date object, if it's a string, then it will attempt to parse it using the date-format provided, see here:

    https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web.UI.Client/lib/datetimepicker/bootstrap-datetimepicker.js#L1297

    Meaning that if your date/string value is "2018-04-30T12:34:56Z" and your format is "D MMM YYYY", then it just ain't gonna work. Better to work with actual Date objects.


    Now, when I said this wouldn't be a copy-n-paste solution, the issue is how to persist all these values back to $scope.model.value? ... and that's the bit that take a LOT of trial & error. aka, I don't have a solid answer for that, sorry.

    There are various things you can do with angularjs watchers or the formSubmitting event ... they are all a bit hacky. Feel free to take a look at how I tackled this for my Property List editor...

    https://github.com/umco/umbraco-property-list/blob/develop/src/Our.Umbraco.PropertyList/Web/UI/App_Plugins/PropertyList/js/propertylist.js#L119-L133


    I hope some of this helps?

    Cheers,
    - Lee

  • Mike Taylor 155 posts 353 karma points
    Sep 04, 2018 @ 14:40
    Mike Taylor
    0

    Thanks so much Lee - I'll give this a whirl. Really appreciate you taking the time.

    Mike

  • Marcel van Helmont 68 posts 259 karma points c-trib
    Jun 12, 2018 @ 14:59
    Marcel van Helmont
    0

    @Mike,

    I am currently on holiday but will try to make a sample to use it!

    Marcel

  • Marcel van Helmont 68 posts 259 karma points c-trib
    Jun 16, 2018 @ 14:30
    Marcel van Helmont
    0

    Hi Mike,

    I've looked at the current implementation of the umb datetimepicker and unfortunately i don't see a way of passing the value. I think building your own directive is your best bett.

    Here is some inspiration: https://gist.github.com/jamiepollock/ad1d1be07453cd1d7509

Please Sign in or register to post replies

Write your reply to:

Draft