Git Product home page Git Product logo

Comments (9)

jhpyle avatar jhpyle commented on August 26, 2024

I think you were on the right track by triggering change on the hidden element. I got it to work with:

$(document).on("daPageLoad", function () {
  $('input[type="date"]').each(function () {
    var dateElement = this;
    $(dateElement).attr("type", "hidden");
    var parentElement = $('<div class="row px-1">');
    var monthParent = $('<div class="col-sm-5 px-0">');
    var dayParent = $('<div class="col-sm-4 px-0">');
    var yearParent = $('<div class="col-sm-3 px-0">');
    var monthElement = $('<select class="form-select">');
    var dayElement = $('<select class="form-select">');
    var yearElement = $('<select class="form-select">');
    var today = new Date();
    var dateEntered;
    if ($(dateElement).val()) {
      var utcDate = new Date($(dateElement).val());
      dateEntered = new Date(
        utcDate.getUTCFullYear(),
        utcDate.getUTCMonth(),
        utcDate.getUTCDate()
      );
    } else {
      dateEntered = null;
    }
    var opt = $("<option>");
    opt.val("");
    opt.text("Month");
    monthElement.append(opt);
    for (var month = 0; month < 12; month++) {
      opt = $("<option>");
      if (month < 9) {
        opt.val("0" + (month + 1));
      } else {
        opt.val(month + 1);
      }
      var dt = new Date(1970, month, 15);
      opt.text(dt.toLocaleString("default", { month: "long" }));
      if (dateEntered && month == dateEntered.getMonth()) {
        opt.attr("selected", "selected");
      }
      monthElement.append(opt);
    }
    opt = $("<option>");
    opt.val("");
    opt.text("Day");
    dayElement.append(opt);
    for (var day = 1; day <= 31; day++) {
      var opt = $("<option>");
      if (day < 10) {
        opt.val("0" + day);
      } else {
        opt.val(day);
      }
      opt.text(day);
      if (dateEntered && day == dateEntered.getDate()) {
        opt.attr("selected", "selected");
      }
      dayElement.append(opt);
    }
    opt = $("<option>");
    opt.val("");
    opt.text("Year");
    yearElement.append(opt);
    for (
      var year = today.getFullYear();
      year > today.getFullYear() - 50;
      year--
    ) {
      opt = $("<option>");
      opt.val(year);
      opt.text(year);
      if (dateEntered && year == dateEntered.getFullYear()) {
        opt.attr("selected", "selected");
      }
      yearElement.append(opt);
    }
    function updateDate() {
      if (
        $(yearElement).val() != "" &&
        $(monthElement).val() != "" &&
        $(dayElement).val() != ""
      ) {
        $(dateElement).val(
          $(yearElement).val() +
            "-" +
            $(monthElement).val() +
            "-" +
            $(dayElement).val()
        );
        $(dateElement).trigger("change");
      }
    }
    $(dateElement).before(parentElement);
    $(monthParent).append(monthElement);
    $(parentElement).append(monthParent);
    $(dayParent).append(dayElement);
    $(parentElement).append(dayParent);
    $(yearParent).append(yearElement);
    $(parentElement).append(yearParent);
    yearElement.on("change", updateDate);
    monthElement.on("change", updateDate);
    dayElement.on("change", updateDate);
    updateDate();
  });
});

and

features:
  javascript: datereplace.js
---
question: |
  When were you born?
fields:
  - Date of birth: date_of_birth
    datatype: date
  - "Do you remember the dinosaurs?": remembers_dinosaurs
    datatype: yesnoradio
    js show if: |
      val('date_of_birth') && Date.parse(val('date_of_birth')) < Date.parse('1980-01-01')
---
mandatory: True
question: |
  You were born on ${ date_of_birth }.

The Bootstrap classes in the JavaScript file were out of date so I changed them.

from docassemble.

myaptad avatar myaptad commented on August 26, 2024

Hello, Thanks alot for looking into this. I confirm this issue to have been fixed. I am marking this ticket to closed. Much appreciated. Thanks!

from docassemble.

myaptad avatar myaptad commented on August 26, 2024

Hello,

  • I am not sure if there is a quick workaround to pass min & max attributes to custom datepicker from the hidden control? The getAttribute function inside .js does not catch any values set in .yml for the hidden date field for min/max attributes.

  • Alternatively, is it possible for user to type the date instead of using date picker as only input option on android devices. Default date picker seems to be somewhat confusing in that it does not lend well for the dates such as date-of-birth which are far back. Although it allows quick year selection but year drop down initiation is not obvious to the user on android.

These are related to the date control so re-opening the ticket instead of new issue.

Thanks

from docassemble.

jhpyle avatar jhpyle commented on August 26, 2024

The min and max validators work for me when I add them to the recipe.

question: |
  When were you born?
fields:
  - Date of birth: date_of_birth
    datatype: date
    min: 1970-01-01
    max: 2020-01-01

The validators work via the jQuery Validation plugin, so the max and min values aren't in the <input> element itself. They are in daValidator.settings.rules.

You could write JavaScript that detects if the device is Android and then converts the field to text:

$(document).on("daPageLoad", function () {
  var isAndroid = // your code here;
  if (isAndroid){
    $('input[type="date"]').each(function () {
      $(this).attr('type', 'text');
    });
  }
});

so that the browser treats the field as plain text.

from docassemble.

myaptad avatar myaptad commented on August 26, 2024

Thank you for reverting back on this. I should have been bit more clear earlier. Let's see if I can clarify further:

  • min and max do work on default "date" type. However, with datereplace.js included in the interview, there does seem to be break in this functionality as there is no mechanism for the hidden control to enforce these min and max for validation on the nameless control.
  • yes that is doable, however, changing the field to simple text will remove other benefits such as validation etc of having type as "date". It seems like behavior of datepicker is different on desktop than how it is on android (mobile devices). On desktop, datepicker shows up only when user clicks on the calendar icon, however, in mobile version datepicker shows up on click anywhere in the input box. I guess, the functionality as on desktop works great as it allows user to choose how they want to enter the date. Having the same behavior for date entry field on mobile devices, if possible, will allow for best of both worlds.

from docassemble.

jhpyle avatar jhpyle commented on August 26, 2024

I am not seeing what you are seeing. When I use my datereplace.js, the standard docassemble input validation functionality based on the jQuery Validation plugin works as normal, and I get the warning messages if the date is outside the min or max. Also when I use JavaScript to change the type of the input element to text, the jQuery Validation plugin makes sure that I enter a valid date.

from docassemble.

myaptad avatar myaptad commented on August 26, 2024

Hello there, I can confirm that setting the field to text in javascript does work along with its proper validation.

However, after playing around a bit, it seems like there is a usage specific behavior or possibly a bug in the code. We can see the behavior using code below which has minor changes to your example. The validation stops working when the last field is commented/removed as shown. Do you see some issue with usage as such?

features:
  javascript: datereplace.js
---
question: |
  When were you born?
fields:
  - Date of birth: date_of_birth
    datatype: date
    max: ${ today() }
  # - "Do you remember the dinosaurs?": remembers_dinosaurs
  #   datatype: yesnoradio
  #   js show if: |
  #     val('date_of_birth') && Date.parse(val('date_of_birth')) < Date.parse('1980-01-01')
---
mandatory: True
question: |
  You were born on ${ date_of_birth }.

from docassemble.

jhpyle avatar jhpyle commented on August 26, 2024

In 1.4.27 I changed the jQuery Validation Plugin settings so that this will work more consistently.

from docassemble.

myaptad avatar myaptad commented on August 26, 2024

Works now, thank you!

from docassemble.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.