Ever 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:
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
< %= @datetime %>