【问题标题】:Rails Auto-populate form field based off of date inputRails 根据日期输入自动填充表单字段
【发布时间】:2014-07-12 19:05:56
【问题描述】:

我有一个 Rails 3.2.18 应用程序,在我的表单中,我有一个年龄 (int) 和出生日期 (datetime) 字段。我将使用一个简单的 jQuery 日期选择器来选择 DOB。

这就是我想要发生的事情。

第一个字段是 DOB(出生日期)。我想选择它,一旦选择它,我想计算年龄并根据该选择自动填充年龄字段。

我想我可以通过在模型上创建一个计算年龄的方法来以某种方式做到这一点,但我不确定如何在年龄字段中填充它。也许是一些 Javascript 或什么的?

任何帮助将不胜感激。

下面是我为另一个基于 DOB 计算年龄并且可以在视图中使用的应用编写的方法:

def age(dob)
    now = Time.zone.now.to_date
    now.year - patient_dob.year - ((now.month > patient_dob.month || (now.month == patient_dob.month && now.day >= patient_dob.day)) ? 0 : 1)
  end

【问题讨论】:

    标签: ruby ruby-on-rails-3 forms datetime activerecord


    【解决方案1】:

    这是一种更客户端的 javascript 方法,可以使用服务器实现日期准确性。

    加载父页面时在 Rails 视图中

    <%= javascript_tag do%>
        var currDate = new Date('<%= Date.today%>');
    <%end%>
    

    在您的 js 文件中(我假设日期选择器是使用日期选择器选择的输入。)

    function calcAge(dateString) {
        var birthDate = new Date(#('date_picker').val());
        var age = currDate.getFullYear() - birthDate.getFullYear();
        var m = currDate.getMonth() - birthDate.getMonth();
        if (m < 0 || (m === 0 && currDate.getDate() < birthDate.getDate())) {
            age--;
        }
        return age;
    }
    

    然后只需要调用 calcAge on date selected event 和

    return age; 
    

    可以更改为输入字段的设置值

    $('#ageField').val(age);
    

    【讨论】:

    • 他仍然需要从出生日期字段计算服务器上的年龄。所以发回服务器日期似乎是做作的,你不觉得吗?我认为它不会有任何好处,除非用户的系统日期不同步好几个月。
    • 那仍然没有回答问题。在服务器上设置日期是多余的。它实现了什么?拥有这个丑陋的内联 JS var currDate = new Date('&lt;%= Date.today%&gt;') 比简单的 new Date() 好在什么方面?
    • 我的意思是,您只需要服务器上的服务器日期,即可将表单中发送的日期字符串转换为年龄。发回服务器日期是没有意义的,也没用。
    • “在任何情况下你都不需要存储年龄”onBlur 上。然后,在服务器上使用 DOB 安全地计算年龄。问题解决了。
    • 至于@Mohamad 想知道为什么以var currDate = new Date('&lt;%= Date.today%&gt;'); 开头:我觉得在这种情况下使用服务器日期甚至是不正确的,因为从用户的时区角度来看,服务器的日期可能提前一天或落后一天.我觉得在我生日那天填写表格时看到我的年龄计算错误会很奇怪,就像服务器生活在不同的时区一样。
    【解决方案2】:

    你的建议在 Ruby 中是不可能的。您可以使用 JavaScript。

    如果不先到达服务器,计算年龄,然后将结果呈现给客户端,就无法根据用户输入计算年龄。该模型不知道用户输入的日期;当然,除非您提交表单。

    可以通过 Ajax 提交表单。例如,有些网站让您填写邮政编码,然后他们会为您预先填写地址。真正发生的是,在幕后,浏览器正在向返回地址的服务器发送 ajax 请求。

    在您的情况下,您不必这样做,因为在 JavaScript 中计算年龄非常容易。在客户端上执行此操作也更快,因为它可以节省您到服务器的往返行程。

    看看this answer,它向您展示了如何根据输入日期计算一个人的年龄。

    如果您使用 Rails,您可能会使用 jQuery。在这种情况下,您可以执行以下操作:

    $('#date_input').on('change', function () {
      date = $(this).val();
      age = getAge(date);
      $('#age_input').val(age);
    });
    
    # This is taken directly from this answer: https://stackoverflow.com/a/7091965/276959
    function getAge(dateString) {
        var today = new Date();
        var birthDate = new Date(dateString);
        var age = today.getFullYear() - birthDate.getFullYear();
        var m = today.getMonth() - birthDate.getMonth();
        if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
            age--;
        }
        return age;
    }
    

    然后,您可能需要在服务器上重新计算年龄,然后再将数据保存到数据库中。这是因为没有什么能阻止用户直接提交虚假年龄。要么填写,要么修改 DOM。

    class Person
      before_save :set_age
    
    private
    
      def set_age
        self.age = # Calculate age here.
      end
    end
    

    See this answer 关于如何使用 Ruby 计算年龄,这看起来与您问题中的代码相同。

    【讨论】:

    • 这似乎可以工作,但 jQuery 会抛出各种错误并使应用程序崩溃。
    • @teknull 在没有任何细节的情况下诊断问题有点困难,但这可能是因为您的应用程序中有一些语法错误或加载错误。此代码仍然需要在正确的位置正确设置,并且如果您正在使用它,则需要使其与 Turbolinks 一起使用。但要让它发挥作用,所有这些都是微不足道的。
    • 这个人给出了一个不正确的答案,然后在下面复制了我的答案然后发表评论以使其看起来我的答案存在典型的堆栈黑客问题......嘘他
    • @JetAbe,Mohamad 于 5 月 29 日发布了上述内容(并很好地归功于 another answer),8 分钟后编辑添加了关于服务器验证的注释,然后是 days later on June 4th you came along and posted yours。你为什么抱怨抄袭?
    • @Mohamad 我能够让它工作。当我将功能添加到我的 application.js 文件时,我的 JS 语法似乎是错误的。感谢您的帮助,效果很好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2018-01-17
    • 2018-02-19
    相关资源
    最近更新 更多