JQuery Date/Datetime picker

Posted April 18, 2010

I recently ran across this helpful post on a Merb Datetime picker and it was good, that is until I wanted to use the JQuery Date picker. Well a bit of hacking later we have this:

<%= form_for @person %>
  <%= jquery_date_field :birth_date :label => 'Birthdate' %>
  <%= jquery_datetime_field :birth_date_and_time, :label => 'Birthdate and time' %>
<% end =%>
module Merb
  module GlobalHelpers
    # Jquery date picker
    module Merb::Helpers::Form
      def jquery_date_field(*args)
        if bound?(*args)
          current_form_context.jquery_bound_date_field(*args)
        else
          current_form_context.jquery_unbound_date_field(*args)
        end
      end

      def jquery_datetime_field(*args)
        if bound?(*args)
          current_form_context.jquery_bound_datetime_field(*args)
        else
          current_form_context.jquery_unbound_datetime_field(*args)
        end
      end

      module Builder
        class Base
          def jquery_bound_date_field(method, attrs = {})
            name = control_name(method)
            update_bound_controls(method, attrs, nil)
            jquery_unbound_date_field({:name => name}.merge(attrs))
          end

          def jquery_bound_datetime_field(method, attrs = {})
            name = control_name(method)
            update_bound_controls(method, attrs, nil)
            jquery_unbound_datetime_field({:name => name}.merge(attrs))
          end

          def jquery_unbound_date_field(attrs)
            if attrs[:name] =~ /\[(.*)\]/
              date = @obj.send($1)
            end
            date ||= attrs[:value] || Time.now

            date_attrs = attrs.merge(
                :class => 'jquery_date_picker',
                :value => date.to_date.to_s,
                :name => attrs[:name].to_s + '[date]',
                :id => attrs[:id] + '_input',
                :label => attrs[:label]
            )
            hidden_attrs = attrs.merge(
                :value => '',
                :label => nil
            )
            unbound_text_field( date_attrs ) +
              unbound_hidden_field( hidden_attrs.merge(:name => attrs[:name].to_s + '[year]', :id => attrs[:id] + '_year', :value => date.year) ) +
              unbound_hidden_field( hidden_attrs.merge(:name => attrs[:name].to_s + '[month]', :id => attrs[:id] + '_month', :value => date.month) ) +
              unbound_hidden_field( hidden_attrs.merge(:name => attrs[:name].to_s + '[day]', :id => attrs[:id] + '_day', :value => date.day) ) +
              "<script type=\"text/javascript\">
              $(function() {
                  $(\"##{date_attrs[:id]}\").datepicker({
                    dateFormat: 'yy-mm-dd',
                    onSelect: function(dateText, inst) {
                      var myDatesSplit = $(\"##{attrs[:id]}_input\")[0].value.split( '-' );
                      $(\"##{attrs[:id]}_year\")[0].value = myDatesSplit[0];
                      $(\"##{attrs[:id]}_month\")[0].value = myDatesSplit[1];
                      $(\"##{attrs[:id]}_day\")[0].value = myDatesSplit[2];
                    }
                  });
                });
              </script>"
          end

          def jquery_unbound_datetime_field(attrs)
            if attrs[:name] =~ /\[(.*)\]/
              date = @obj.send($1)
            end
            date ||= attrs[:value] || Time.now

            hour_attrs = attrs.merge(
              :class => "date hour",
              :selected => date.hour.to_s,
              :name => attrs[:name].to_s + '[hour]',
              :id => attrs[:id] + '_hour',
              :collection => (0..24).map{|i|[i, i.to_s]},
              :label => nil
            )

            minute_attrs = attrs.merge(
              :class => "date minutes",
              :selected => date.min.to_s,
              :name => attrs[:name].to_s + '[min]',
              :id => attrs[:id] + '_min',
              :collection => %w[00 05 10 15 20 25 30 35 40 45 50 55].map{|i|[i.to_i, i]},
              :value_method => :first,
              :text_method => :last,
              :label => nil
            )

            jquery_unbound_date_field(attrs) + ' ' + unbound_select(hour_attrs) + ':' + unbound_select(minute_attrs)
          end
        end
      end
    end
    # end Jquery date picker
  end
end

Comments

There are no comments for this post.

No comments found

Add comment