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 4026 posts 15837 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

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies