Added date widget.

This commit is contained in:
Martin Edenhofer 2015-01-26 22:55:23 +01:00
parent 47a822583a
commit 54550e5bf2
3 changed files with 255 additions and 33 deletions

View file

@ -282,14 +282,133 @@ class App.ControllerForm extends App.Controller
# date
else if attribute.tag is 'date'
attribute.type = 'text'
#item.datetimepicker({
# format: 'Y.m.d'
#});
# set data type
if attribute.name
attribute.nameRaw = attribute.name
attribute.name = '{date}' + attribute.name
if attribute.value
if typeof( attribute.value ) is 'string'
unixtime = new Date( Date.parse( "#{attribute.value}T00:00:00Z" ) )
else
unixtime = new Date( attribute.value )
year = unixtime.getYear() + 1900
month = unixtime.getMonth() + 1
day = unixtime.getDate()
hour = unixtime.getHours()
minute = unixtime.getMinutes()
item = $( App.view('generic/date')(
attribute: attribute
year: year
month: month
day: day
) )
setNewTime = (diff, el, reset) ->
name = $(el).closest('.form-group').find('[data-name]').attr('data-name')
# remove old validation
item.find('.has-error').removeClass('has-error')
item.closest('.form-group').find('.help-inline').html('')
day = item.closest('.form-group').find("[name=\"{date}#{name}___day\"]").val()
month = item.closest('.form-group').find("[name=\"{date}#{name}___month\"]").val()
year = item.closest('.form-group').find("[name=\"{date}#{name}___year\"]").val()
format = (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
if !reset && (year isnt '' && month isnt '' && day isnt '')
time = new Date( Date.parse( "#{year}-#{format(month)}-#{format(day)}T00:00:00Z" ) )
else
time = new Date()
time.setMinutes( time.getMinutes() + diff + time.getTimezoneOffset() )
item.closest('.form-group').find("[name=\"{date}#{name}___day\"]").val( time.getDate() )
item.closest('.form-group').find("[name=\"{date}#{name}___month\"]").val( time.getMonth()+1 )
item.closest('.form-group').find("[name=\"{date}#{name}___year\"]").val( time.getFullYear() )
item.find('.js-today').bind('click', (e) ->
e.preventDefault()
setNewTime(0, @, true)
)
item.find('.js-plus-day').bind('click', (e) ->
e.preventDefault()
setNewTime(60 * 24, @)
)
item.find('.js-minus-day').bind('click', (e) ->
e.preventDefault()
setNewTime(-60 * 24, @)
)
item.find('.js-plus-week').bind('click', (e) ->
e.preventDefault()
setNewTime(60 * 24 * 7, @)
)
item.find('.js-minus-week').bind('click', (e) ->
e.preventDefault()
setNewTime(-60 * 24 * 7, @)
)
item.find('input').bind('keyup blur focus change', (e) ->
# do validation
name = $(@).attr('name')
if name
fieldPrefix = name.split('___')[0]
# remove old validation
item.find('.has-error').removeClass('has-error')
item.closest('.form-group').find('.help-inline').html('')
day = item.closest('.form-group').find("[name=\"#{fieldPrefix}___day\"]").val()
month = item.closest('.form-group').find("[name=\"#{fieldPrefix}___month\"]").val()
year = item.closest('.form-group').find("[name=\"#{fieldPrefix}___year\"]").val()
# validate exists
errors = {}
if !day
errors.day = 'missing'
if !month
errors.month = 'missing'
if !year
errors.year = 'missing'
# ranges
if day
daysInMonth = 31
if month && year
daysInMonth = new Date(year, month, 0).getDate();
if parseInt(day).toString() is 'NaN'
errors.day = 'invalid'
else if parseInt(day) > daysInMonth || parseInt(day) < 1
errors.day = 'invalid'
if month
if parseInt(month).toString() is 'NaN'
errors.month = 'invalid'
else if parseInt(month) > 12 || parseInt(month) < 1
errors.month = 'invalid'
if year
if parseInt(year).toString() is 'NaN'
errors.year = 'invalid'
else if parseInt(year) > 2100 || parseInt(year) < 2001
errors.year = 'invalid'
if !_.isEmpty(errors)
for key, value of errors
item.closest('.form-group').addClass('has-error')
item.closest('.form-group').find("[name=\"#{fieldPrefix}___#{key}\"]").addClass('has-error')
#item.closest('.form-group').find('.help-inline').text( value )
e.preventDefault()
e.stopPropagation()
return
)
# date
else if attribute.tag is 'datetime'
attribute.type = 'text'
# set data type
if attribute.name
@ -313,20 +432,14 @@ class App.ControllerForm extends App.Controller
hour: hour
minute: minute
) )
item.find('.js-today').bind('click', (e) ->
e.preventDefault()
name = $(@).closest('.form-group').find('[data-name]').attr('data-name')
today = new Date();
item.closest('.form-group').find("[name=\"{datetime}#{name}___day\"]").val( today.getDate() )
item.closest('.form-group').find("[name=\"{datetime}#{name}___month\"]").val( today.getMonth()+1 )
item.closest('.form-group').find("[name=\"{datetime}#{name}___year\"]").val( today.getFullYear() )
item.closest('.form-group').find("[name=\"{datetime}#{name}___hour\"]").val( today.getHours() )
item.closest('.form-group').find("[name=\"{datetime}#{name}___minute\"]").val( today.getMinutes() )
)
setNewTime = (diff, el) ->
setNewTime = (diff, el, reset) ->
name = $(el).closest('.form-group').find('[data-name]').attr('data-name')
# remove old validation
item.find('.has-error').removeClass('has-error')
item.closest('.form-group').find('.help-inline').html('')
day = item.closest('.form-group').find("[name=\"{datetime}#{name}___day\"]").val()
month = item.closest('.form-group').find("[name=\"{datetime}#{name}___month\"]").val()
year = item.closest('.form-group').find("[name=\"{datetime}#{name}___year\"]").val()
@ -336,8 +449,10 @@ class App.ControllerForm extends App.Controller
if parseInt(number) < 10
number = "0#{number}"
number
#console.log('ph', diff, "#{year}-#{format(month)}-#{format(day)}T#{format(hour)}:#{format(minute)}:00Z")
time = new Date( Date.parse( "#{year}-#{format(month)}-#{format(day)}T#{format(hour)}:#{format(minute)}:00Z" ) )
if !reset && (year isnt '' && month isnt '' && day isnt '' && hour isnt '' && day isnt '')
time = new Date( Date.parse( "#{year}-#{format(month)}-#{format(day)}T#{format(hour)}:#{format(minute)}:00Z" ) )
else
time = new Date()
time.setMinutes( time.getMinutes() + diff + time.getTimezoneOffset() )
#console.log('T', time, time.getHours(), time.getMinutes())
item.closest('.form-group').find("[name=\"{datetime}#{name}___day\"]").val( time.getDate() )
@ -346,6 +461,10 @@ class App.ControllerForm extends App.Controller
item.closest('.form-group').find("[name=\"{datetime}#{name}___hour\"]").val( time.getHours() )
item.closest('.form-group').find("[name=\"{datetime}#{name}___minute\"]").val( time.getMinutes() )
item.find('.js-today').bind('click', (e) ->
e.preventDefault()
setNewTime(0, @, true)
)
item.find('.js-plus-hour').bind('click', (e) ->
e.preventDefault()
setNewTime(60, @)
@ -371,7 +490,7 @@ class App.ControllerForm extends App.Controller
setNewTime(-60 * 24 * 7, @)
)
item.find('input').bind('keyup blur focus', (e) ->
item.find('input').bind('keyup blur focus change', (e) ->
# do validation
name = $(@).attr('name')
@ -406,7 +525,6 @@ class App.ControllerForm extends App.Controller
daysInMonth = 31
if month && year
daysInMonth = new Date(year, month, 0).getDate();
console.log('222', month, year, daysInMonth)
if parseInt(day).toString() is 'NaN'
errors.day = 'invalid'
@ -2173,6 +2291,35 @@ class App.ControllerForm extends App.Controller
else
param[ newKey ] = false
# get {date}
else if key.substr(0,6) is '{date}'
newKey = key.substr( 6, key.length )
namespace = newKey.split '___'
if !param[ namespace[0] ]
dateKey = "{date}#{namespace[0]}___"
year = param[ "#{dateKey}year" ]
month = param[ "#{dateKey}month" ]
day = param[ "#{dateKey}day" ]
timezone = (new Date()).getTimezoneOffset()/60
if year && month && day
format = (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
try
time = new Date( Date.parse( "#{year}-#{format(month)}-#{format(day)}T00:00:00Z" ) )
time.setMinutes( time.getMinutes() + time.getTimezoneOffset() )
param[ namespace[0] ] = time.toISOString()
catch err
console.log('ERR', err)
#console.log('T', time, time.getHours(), time.getMinutes())
delete param[ "#{dateKey}year" ]
delete param[ "#{dateKey}month" ]
delete param[ "#{dateKey}day" ]
# get {datetime}
else if key.substr(0,10) is '{datetime}'
newKey = key.substr( 10, key.length )

View file

@ -1 +1,14 @@
<input id="<%= @attribute.id %>" type="<%= @attribute.type %>" class="form-control <%= @attribute.class %>" placeholder="<%= @attribute.placeholder %>" name="<%= @attribute.name %>" value="<%= @attribute.value %>" <%= @attribute.required %>>
<div class="horizontal" data-name="<%= @attribute.nameRaw %>">
<input type="text" maxlength="2" name="<%= @attribute.name %>___day" value="<%= @day %>" placeholder="dd" style="width: 50px;">
.
<input type="text" maxlength="2" name="<%= @attribute.name %>___month" value="<%= @month %>" placeholder="mm" style="width: 50px;">
.
<input type="text" maxlength="4" name="<%= @attribute.name %>___year" value="<%= @year %>" placeholder="yyyy" style="width: 70px;">
</div>
<div>
<a class="js-today"><%- @T('today') %></a>
|
<a class="js-minus-day"><%- @T('-1') %></a> <a class="js-plus-day"><%- @T('+1') %></a> <%- @T('day') %>
|
<a class="js-minus-week"><%- @T('-7') %></a> <a class="js-plus-week"><%- @T('+7') %></a> <%- @T('days') %>
</div>

View file

@ -8,15 +8,16 @@ test( "form validation check", function() {
el: el,
model: {
configure_attributes: [
{ name: 'input1', display: 'Input1', tag: 'input', type: 'text', limit: 100, null: false },
{ name: 'password1', display: 'Password1', tag: 'input', type: 'password', limit: 100, null: false },
{ name: 'textarea1', display: 'Textarea1', tag: 'textarea', rows: 6, limit: 100, null: false, upload: true },
{ name: 'select1', display: 'Select1', tag: 'select', null: false, nulloption: true, options: { true: 'internal', false: 'public' } },
{ name: 'selectmulti1', display: 'SelectMulti1', tag: 'select', null: false, nulloption: true, multiple: true, options: { true: 'internal', false: 'public' } },
{ name: 'autocompletion1', display: 'AutoCompletion1', tag: 'autocompletion', null: false, options: { true: 'internal', false: 'public' }, source: [ { label: "Choice1", value: "value1", id: "id1" }, { label: "Choice2", value: "value2", id: "id2" }, ], minLength: 1 },
{ name: 'richtext1', display: 'Richtext1', tag: 'richtext', maxlength: 100, null: false, type: 'richtext', multiline: true, upload: true, default: defaults['richtext1'] },
{ name: 'datetime1', display: 'Datetime1', tag: 'datetime', null: false, default: defaults['datetime1'] },
{ name: 'active1', display: 'Active1', tag: 'boolean', type: 'boolean', default: defaults['active1'], null: false },
{ name: 'input1', display: 'Input1', tag: 'input', type: 'text', limit: 100, null: false },
{ name: 'password1', display: 'Password1', tag: 'input', type: 'password', limit: 100, null: false },
{ name: 'textarea1', display: 'Textarea1', tag: 'textarea', rows: 6, limit: 100, null: false, upload: true },
{ name: 'select1', display: 'Select1', tag: 'select', null: false, nulloption: true, options: { true: 'internal', false: 'public' } },
{ name: 'selectmulti1', display: 'SelectMulti1', tag: 'select', null: false, nulloption: true, multiple: true, options: { true: 'internal', false: 'public' } },
{ name: 'autocompletion1', display: 'AutoCompletion1', tag: 'autocompletion', null: false, options: { true: 'internal', false: 'public' }, source: [ { label: "Choice1", value: "value1", id: "id1" }, { label: "Choice2", value: "value2", id: "id2" }, ], minLength: 1 },
{ name: 'richtext1', display: 'Richtext1', tag: 'richtext', maxlength: 100, null: false, type: 'richtext', multiline: true, upload: true, default: defaults['richtext1'] },
{ name: 'datetime1', display: 'Datetime1', tag: 'datetime', null: false, default: defaults['datetime1'] },
{ name: 'date1', display: 'Date1', tag: 'date', null: false, default: defaults['date1'] },
{ name: 'active1', display: 'Active1', tag: 'boolean', type: 'boolean', default: defaults['active1'], null: false },
],
},
params: defaults,
@ -58,6 +59,7 @@ test( "form validation check", function() {
autocompletion1: "is required",
richtext1: "is required",
datetime1: "is required",
date1: "is required",
}
deepEqual( errors, test_errors, 'validation errors check' )
@ -87,6 +89,9 @@ test( "form validation check", function() {
equal( el.find('[data-name="datetime1"]').closest('.form-group').hasClass('has-error'), true, 'check datetime1 has-error')
equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), 'is required', 'check datetime1 error message')
equal( el.find('[data-name="date1"]').closest('.form-group').hasClass('has-error'), true, 'check date1 has-error')
equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), 'is required', 'check date1 error message')
});
test( "datetime validation check", function() {
@ -99,7 +104,7 @@ test( "datetime validation check", function() {
el: el,
model: {
configure_attributes: [
{ name: 'datetime1', display: 'Datetime1', tag: 'datetime', null: false, default: defaults['datetime1'] },
{ name: 'datetime1', display: 'Datetime1', tag: 'datetime', null: false, default: defaults['datetime1'] },
],
},
params: defaults,
@ -115,18 +120,20 @@ test( "datetime validation check", function() {
equal( el.find('[data-name="datetime1"]').closest('.form-group').hasClass('has-error'), true, 'check datetime1 has-error')
equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), 'is required', 'check datetime1 error message')
//equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), '', 'check datetime1 error message')
// set new values
el.find('[name="{datetime}datetime1___day"]').val('1')
el.find('[name="{datetime}datetime1___month"]').val('1')
el.find('[name="{datetime}datetime1___year"]').val('2015')
el.find('[name="{datetime}datetime1___hour"]').val('12')
el.find('[name="{datetime}datetime1___minute"]').val('42')
params = App.ControllerForm.params( el )
errors = form.validate(params)
test_errors = undefined
// datetime1: "invalid",
// }
deepEqual( errors, test_errors, 'validation errors check' )
App.ControllerForm.validate( { errors: errors, form: el } )
equal( el.find('[data-name="datetime1"]').closest('.form-group').hasClass('has-error'), false, 'check datetime1 has-error')
equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), '', 'check datetime1 error message')
@ -146,4 +153,59 @@ test( "datetime validation check", function() {
equal( el.find('[data-name="datetime1"]').closest('.form-group').hasClass('has-error'), true, 'check datetime1 has-error')
equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), '', 'check datetime1 error message')
});
test( "date validation check", function() {
$('#forms').append('<hr><h1>date validation check</h1><form id="form3"></form>')
var el = $('#form3')
var defaults = {}
var form = new App.ControllerForm({
el: el,
model: {
configure_attributes: [
{ name: 'date1', display: 'Date1', tag: 'date', null: false, default: defaults['time1'] },
],
},
params: defaults,
});
params = App.ControllerForm.params( el )
errors = form.validate(params)
test_errors = {
date1: "is required",
}
deepEqual( errors, test_errors, 'validation errors check' )
App.ControllerForm.validate( { errors: errors, form: el } )
equal( el.find('[data-name="date1"]').closest('.form-group').hasClass('has-error'), true, 'check date1 has-error')
equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), 'is required', 'check date1 error message')
// set new values
el.find('[name="{date}date1___day"]').val('1')
el.find('[name="{date}date1___month"]').val('1')
el.find('[name="{date}date1___year"]').val('2015')
params = App.ControllerForm.params( el )
errors = form.validate(params)
test_errors = undefined
deepEqual( errors, test_errors, 'validation errors check' )
App.ControllerForm.validate( { errors: errors, form: el } )
equal( el.find('[data-name="date1"]').closest('.form-group').hasClass('has-error'), false, 'check date1 has-error')
equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), '', 'check date1 error message')
el.find('[name="{date}date1___day"]').val('47')
el.find('[name="{date}date1___month"]').val('1')
el.find('[name="{date}date1___year"]').val('2015')
params = App.ControllerForm.params( el )
errors = form.validate(params)
test_errors = {
date1: "is required",
}
deepEqual( errors, test_errors, 'validation errors check' )
App.ControllerForm.validate( { errors: errors, form: el } )
});