How-to: AJAX DateTime picker in Rhodes (Rhomobile)

ajax-datetime-picker-rhodesEver desired a method to handle a DateTime picker in Rhodes without reloading the page? The ideal solution would be to tap the datetime input field to popup the DateTime picker, choose a date and/or time and tap ‘Done’. This would automatically display the selection into the input field.

We were able to achieve this using 2 AJAX calls. Read on and get the full code to do this!

This is the proposed method (in the official Rhodes example) to use the DateTime picker:

    • tap a ‘choose’ link (next to the datetime input field)
    • choose the date and/or time and tap ‘Done’ button to hide the DateTime picker
    • tap ‘Save’ button (which would reload the form) to display the selected date and/or time into the input field

    Not only this is a tedious way to select a date and/or time, but it makes it difficult to manage a form (from the programming point of view).

    The desired method is the following: tap the datetime input field to popup the DateTime picker, choose a date and/or time and tap ‘Done’ (this would automatically display the selection into the input field). We were able to achieve this using 2 AJAX calls:

    • the first AJAX call pops up the native iPhone DateTime picker
    • the second AJAX call is initiated every 0.3 seconds to check if a datetime was selected and to display it

    The above code belongs to the view.

    Here are the functions to add in application.js:

    function displaySelectedDateTime(dom_id) {
      $(document).ready(function() {
        setInterval(function(){
          $.get('/app/Datetime/selection', {field_key: dom_id}, function(data){
            $('#'+dom_id).val(data);
          });
          return false;
        }, 300);
      });
    }
    
    function popupDateTimePicker(flag, title, field_key) {
      $.get('/app/Datetime/popup', { flag: flag, title: title, field_key: field_key });
      return false;
    }

    You’ll also need to add the following files:

    /app/Datetime/controller.rb
    require 'rho/rhocontroller'
    require 'dateME'
    
    class DatetimeController < Rho::RhoController
      $date_time = {}
    
      def popup
        flag = @params['flag']
        if ['0', '1', '2'].include?(flag)
          DateTimePicker.choose url_for(:action => :callback), @params['title'], Time.new, flag.to_i, Marshal.dump({:flag => flag, :field_key => @params['field_key']})
        end
      end
    
      def selection
        @datetime = $date_time[@params['field_key']] ? $date_time[@params['field_key']] : ''
        render :action => :selection, :layout => false, :use_layout_on_ajax => false
      end
    
      def callback
        if @params['status'] == 'ok'
          datetime_vars = Marshal.load(@params['opaque'])
          format = case datetime_vars[:flag]
            when "0" then '%F %T'
            when "1" then '%F'
            when "2" then '%T'
            else '%F %T'
          end
          $date_time[datetime_vars[:field_key]] = Time.at(@params['result'].to_i).strftime(format)
          WebView::refresh
        end
      end
    end
    /app/Datetime/selection.erb
    < %= @datetime %>