Commit 4149207d authored by jplang's avatar jplang

Use HTML5 date input fields instead of text fields with jquery ui date pickers (#19468).

Patch by Jan Schulz-Hofen.

git-svn-id: https://svn.redmine.org/redmine/trunk@15375 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 6f13ef3e
......@@ -1171,7 +1171,7 @@ module ApplicationHelper
def calendar_for(field_id)
include_calendar_headers_tags
javascript_tag("$(function() { $('##{field_id}').addClass('date').datepicker(datepickerOptions); });")
javascript_tag("$(function() { $('##{field_id}').addClass('date').datepickerFallback(datepickerOptions); });")
end
def include_calendar_headers_tags
......
<p><%= f.text_field(:default_value, :size => 10) %></p>
<p><%= f.date_field(:default_value, :value => @custom_field.default_value, :size => 10) %></p>
<%= calendar_for('custom_field_default_value') %>
<p><%= f.text_field :url_pattern, :size => 50, :label => :label_link_values_to %></p>
......@@ -52,14 +52,14 @@
<% if @issue.safe_attribute? 'start_date' %>
<p id="start_date_area">
<%= f.text_field(:start_date, :size => 10, :required => @issue.required_attribute?('start_date')) %>
<%= f.date_field(:start_date, :size => 10, :required => @issue.required_attribute?('start_date')) %>
<%= calendar_for('issue_start_date') %>
</p>
<% end %>
<% if @issue.safe_attribute? 'due_date' %>
<p id="due_date_area">
<%= f.text_field(:due_date, :size => 10, :required => @issue.required_attribute?('due_date')) %>
<%= f.date_field(:due_date, :size => 10, :required => @issue.required_attribute?('due_date')) %>
<%= calendar_for('issue_due_date') %>
</p>
<% end %>
......
......@@ -147,7 +147,7 @@
<% if @safe_attributes.include?('start_date') %>
<p>
<label for='issue_start_date'><%= l(:field_start_date) %></label>
<%= text_field_tag 'issue[start_date]', '', :value => @issue_params[:start_date], :size => 10 %><%= calendar_for('issue_start_date') %>
<%= date_field_tag 'issue[start_date]', '', :value => @issue_params[:start_date], :size => 10 %><%= calendar_for('issue_start_date') %>
<label class="inline"><%= check_box_tag 'issue[start_date]', 'none', (@issue_params[:start_date] == 'none'), :id => nil, :data => {:disables => '#issue_start_date'} %><%= l(:button_clear) %></label>
</p>
<% end %>
......@@ -155,7 +155,7 @@
<% if @safe_attributes.include?('due_date') %>
<p>
<label for='issue_due_date'><%= l(:field_due_date) %></label>
<%= text_field_tag 'issue[due_date]', '', :value => @issue_params[:due_date], :size => 10 %><%= calendar_for('issue_due_date') %>
<%= date_field_tag 'issue[due_date]', '', :value => @issue_params[:due_date], :size => 10 %><%= calendar_for('issue_due_date') %>
<label class="inline"><%= check_box_tag 'issue[due_date]', 'none', (@issue_params[:due_date] == 'none'), :id => nil, :data => {:disables => '#issue_due_date'} %><%= l(:button_clear) %></label>
</p>
<% end %>
......
......@@ -17,7 +17,7 @@
<span id="time_entry_issue"><%= "#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}" %></span>
<% end %>
</p>
<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
<p><%= f.date_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
<p><%= f.text_field :hours, :size => 6, :required => true %></p>
<p><%= f.text_field :comments, :size => 100, :maxlength => 1024 %></p>
<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
......
......@@ -18,7 +18,7 @@
<p>
<label><%= l(:field_spent_on) %></label>
<%= text_field :time_entry, :spent_on, :size => 10 %><%= calendar_for('time_entry_spent_on') %>
<%= date_field :time_entry, :spent_on, :size => 10 %><%= calendar_for('time_entry_spent_on') %>
</p>
<p>
......
......@@ -6,7 +6,7 @@
<p><%= f.text_field :description, :size => 60 %></p>
<p><%= f.select :status, Version::VERSION_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %></p>
<p><%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %></p>
<p><%= f.text_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
<p><%= f.date_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
<p><%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %></p>
<% @version.custom_field_values.each do |value| %>
......
......@@ -461,12 +461,12 @@ module Redmine
end
def edit_tag(view, tag_id, tag_name, custom_value, options={})
view.text_field_tag(tag_name, custom_value.value, options.merge(:id => tag_id, :size => 10)) +
view.date_field_tag(tag_name, custom_value.value, options.merge(:id => tag_id, :size => 10)) +
view.calendar_for(tag_id)
end
def bulk_edit_tag(view, tag_id, tag_name, custom_field, objects, value, options={})
view.text_field_tag(tag_name, value, options.merge(:id => tag_id, :size => 10)) +
view.date_field_tag(tag_name, value, options.merge(:id => tag_id, :size => 10)) +
view.calendar_for(tag_id) +
bulk_clear_tag(view, tag_id, tag_name, custom_field, value)
end
......
......@@ -185,12 +185,12 @@ function buildFilterRow(field, operator, values) {
case "date":
case "date_past":
tr.find('td.values').append(
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
'<span style="display:none;"><input type="date" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
' <span style="display:none;"><input type="date" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>'
);
$('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions);
$('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions);
$('#values_'+fieldId+'_1').val(values[0]).datepickerFallback(datepickerOptions);
$('#values_'+fieldId+'_2').val(values[1]).datepickerFallback(datepickerOptions);
$('#values_'+fieldId).val(values[0]);
break;
case "string":
......@@ -587,7 +587,7 @@ function beforeShowDatePicker(input, inst) {
}
break;
}
$(input).datepicker("option", "defaultDate", default_date);
$(input).datepickerFallback("option", "defaultDate", default_date);
}
(function($){
......@@ -723,6 +723,33 @@ function toggleDisabledOnChange() {
function toggleDisabledInit() {
$('input[data-disables], input[data-enables]').each(toggleDisabledOnChange);
}
(function ( $ ) {
// detect if native date input is supported
var nativeDateInputSupported = true;
var input = document.createElement('input');
input.setAttribute('type','date');
if (input.type === 'text') {
nativeDateInputSupported = false;
}
var notADateValue = 'not-a-date';
input.setAttribute('value', notADateValue);
if (input.value === notADateValue) {
nativeDateInputSupported = false;
}
$.fn.datepickerFallback = function( options ) {
if (nativeDateInputSupported) {
return this;
} else {
return this.datepicker( options );
}
};
}( jQuery ));
$(document).ready(function(){
$('#content').on('change', 'input[data-disables], input[data-enables]', toggleDisabledOnChange);
toggleDisabledInit();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment