Moved to new datetime and date ui element.

This commit is contained in:
Martin Edenhofer 2015-09-19 23:24:11 +02:00
parent a30e31bc80
commit edab5b9197
6 changed files with 448 additions and 782 deletions

View file

@ -226,53 +226,7 @@ class App.ControllerForm extends App.Controller
if App.UiElement[attribute.tag]
item = App.UiElement[attribute.tag].render(attribute, @params, @)
# ticket attribute selection
else if attribute.tag is 'ticket_attribute_selection'
# list of possible attributes
item = $(
App.view('generic/ticket_attribute_manage')(
attribute: attribute
)
)
addShownAttribute = ( key, value ) =>
parts = key.split(/::/)
key = parts[0]
type = parts[1]
if key is 'tickets.number'
attribute_config = {
name: attribute.name + '::tickets.number'
display: 'Number'
tag: 'input'
type: 'text'
null: false
value: value
remove: true
}
else if key is 'tickets.title'
attribute_config = {
name: attribute.name + '::tickets.title'
display: 'Title'
tag: 'input'
type: 'text'
null: false
value: value
remove: true
}
else if key is 'tickets.group_id'
attribute_config = {
name: attribute.name + '::tickets.group_id'
display: 'Group'
tag: 'select'
multiple: true
null: false
nulloption: false
relation: 'Group'
value: value
remove: true
}
###
else if key is 'tickets.owner_id' || key is 'tickets.customer_id'
display = 'Owner'
name = 'owner_id'
@ -332,344 +286,7 @@ class App.ControllerForm extends App.Controller
} )
all
}
else if key is 'tickets.state_id'
attribute_config = {
name: attribute.name + '::tickets.state_id'
display: 'State'
tag: 'select'
multiple: true
null: false
nulloption: false
relation: 'TicketState'
value: value
translate: true
remove: true
}
else if key is 'tickets.priority_id'
attribute_config = {
name: attribute.name + '::tickets.priority_id'
display: 'Priority'
tag: 'select'
multiple: true
null: false
nulloption: false
relation: 'TicketPriority'
value: value
translate: true
remove: true
}
else if key is 'tickets.created_at' && ( type is '<>' || value.count )
attribute_config = {
name: attribute.name + '::tickets.created_at'
display: 'Created (before / last)'
tag: 'time_before_last'
value: value
translate: true
remove: true
}
else if key is 'tickets.created_at' && ( type is '><' || 0 )
attribute_config = {
name: attribute.name + '::tickets.created_at'
display: 'Created (between)'
tag: 'time_range'
value: value
translate: true
remove: true
}
else if key is 'tickets.close_time' && ( type is '<>' || value.count )
attribute_config = {
name: attribute.name + '::tickets.close_time'
display: 'Closed (before / last)'
tag: 'time_before_last'
value: value
translate: true
remove: true
}
else if key is 'tickets.close_time' && ( type is '><' || 0 )
attribute_config = {
name: attribute.name + '::tickets.close_time'
display: 'Closed (between)'
tag: 'time_range'
value: value
translate: true
remove: true
}
else if key is 'tickets.updated_at' && ( type is '<>' || value.count )
attribute_config = {
name: attribute.name + '::tickets.updated_at'
display: 'Updated (before / last)'
tag: 'time_before_last'
value: value
translate: true
remove: true
}
else if key is 'tickets.updated_at' && ( type is '><' || 0 )
attribute_config = {
name: attribute.name + '::tickets.updated_at'
display: 'Updated (between)'
tag: 'time_range'
value: value
translate: true
remove: true
}
else if key is 'tickets.escalation_time' && ( type is '<>' || value.count )
attribute_config = {
name: attribute.name + '::tickets.escalation_time'
display: 'Escalation (before / last)'
tag: 'time_before_last'
value: value
translate: true
remove: true
}
else if key is 'tickets.escalation_time' && ( type is '><' || 0 )
attribute_config = {
name: attribute.name + '::tickets.escalation_time'
display: 'Escatlation (between)'
tag: 'time_range'
value: value
translate: true
remove: true
}
else
attribute_config = {
name: attribute.name + '::' + key
display: 'FIXME!'
tag: 'input'
type: 'text'
value: value
remove: true
}
item.find('select[name=ticket_attribute_list] option[value="' + key + '"]').hide().prop('disabled', true)
itemSub = @formGenItem( attribute_config )
itemSub.find('.glyphicon-minus').bind('click', (e) ->
e.preventDefault()
value = $(e.target).closest('.controls').find('[name]').attr('name')
if value
value = value.replace("#{attribute.name}::", '')
$(e.target).closest('.sub_attribute').find('select[name=ticket_attribute_list] option[value="' + value + '"]').show().prop('disabled', false)
$(@).parent().parent().parent().remove()
)
# itemSub.append('<a href=\"#\" class=\"icon-minus\"></a>')
item.find('.ticket_attribute_item').append( itemSub )
# list of existing attributes
attribute_config = {
name: 'ticket_attribute_list'
display: 'Add Attribute'
tag: 'select'
multiple: false
null: false
# nulloption: true
options: [
{
value: ''
name: '-- Ticket --'
selected: false
disable: true
},
{
value: 'tickets.number'
name: 'Number'
selected: false
disable: false
},
{
value: 'tickets.title'
name: 'Title'
selected: false
disable: false
},
{
value: 'tickets.group_id'
name: 'Group'
selected: false
disable: false
},
{
value: 'tickets.state_id'
name: 'State'
selected: false
disable: false
},
{
value: 'tickets.priority_id'
name: 'Priority'
selected: true
disable: false
},
{
value: 'tickets.owner_id'
name: 'Owner'
selected: true
disable: false
},
#{
# value: 'tickets.created_at::<>'
# name: 'Created (before/last)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.created_at::><'
# name: 'Created (between)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.close_time::<>'
# name: 'Closed (before/last)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.close_time::><'
# name: 'Closed (between)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.updated_at::<>'
# name: 'Updated (before/last)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.updated_at::><'
# name: 'Updated (between)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.escalation_time::<>'
# name: 'Escalation (before/last)'
# selected: true
# disable: false
#},
#{
# value: 'tickets.escalation_time::><'
# name: 'Escalation (between)'
# selected: true
# disable: false
#},
# # {
# value: 'tag'
# name: 'Tag'
# selected: true
# disable: false
# },
# {
# value: 'tickets.created_before'
# name: 'Erstell vor'
# selected: true
# disable: false
# },
# {
# value: 'tickets.created_after'
# name: 'Erstell nach'
# selected: true
# disable: false
# },
# {
# value: 'tickets.created_between'
# name: 'Erstell zwischen'
# selected: true
# disable: false
# },
# {
# value: 'tickets.closed_before'
# name: 'Geschlossen vor'
# selected: true
# disable: false
# },
# {
# value: 'tickets.closed_after'
# name: 'Geschlossen nach'
# selected: true
# disable: false
# },
# {
# value: 'tickets.closed_between'
# name: 'Geschlossen zwischen'
# selected: true
# disable: false
# },
# {
# value: '-a'
# name: '-- ' + App.i18n.translateInline('Article') + ' --'
# selected: false
# disable: true
# },
# {
# value: 'ticket_articles.from'
# name: 'From'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.to'
# name: 'To'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.cc'
# name: 'Cc'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.subject'
# name: 'Subject'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.body'
# name: 'Text'
# selected: true
# disable: false
# },
{
value: '-c'
name: '-- ' + App.i18n.translateInline('Customer') + ' --'
selected: false
disable: true
},
{
value: 'customers.id'
name: 'Customer'
selected: true
disable: false
},
{
value: 'organization.id'
name: 'Organization'
selected: true
disable: false
},
]
default: ''
translate: true
class: 'medium'
add: true
}
list = @formGenItem( attribute_config )
list.find('.glyphicon-plus').bind('click', (e) ->
e.preventDefault()
value = $(e.target).closest('.controls').find('[name=ticket_attribute_list]').val()
addShownAttribute( value, '' )
)
item.find('.ticket_attribute_list').prepend( list )
# list of shown attributes
show = []
if attribute.value
for key, value of attribute.value
addShownAttribute( key, value )
###
else
throw "Invalid UiElement.#{attribute.tag}"
@ -844,88 +461,52 @@ class App.ControllerForm extends App.Controller
# get boolean
if key.substr(0,9) is '{boolean}'
newKey = key.substr( 9, key.length )
param[ newKey ] = param[ key ]
delete param[ key ]
if param[ newKey ] && param[ newKey ].toString() is 'true'
param[ newKey ] = true
newKey = key.substr(9, key.length)
if param[key] && param[key].toString() is 'true'
param[newKey] = true
else
param[ newKey ] = false
param[newKey] = false
delete param[key]
# 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" ]
if lookupForm.find('[data-name = "' + namespace[0] + '"]').hasClass('is-hidden')
param[ namespace[0] ] = null
else if year && month && day && day
newKey = key.substr(6, key.length)
if lookupForm.find("[data-name=\"#{newKey}\"]").hasClass('is-hidden')
param[newKey] = null
else if param[key]
try
time = new Date( Date.parse( "#{param[key]}T00:00:00Z" ) )
format = (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
try
time = new Date( Date.parse( "#{year}-#{format(month)}-#{format(day)}T00:00:00Z" ) )
if time && time.toString() is 'Invalid Date'
throw "Invalid Date #{year}-#{format(month)}-#{format(day)}"
param[ namespace[0] ] = "#{time.getUTCFullYear()}-#{format(time.getUTCMonth()+1)}-#{format(time.getUTCDate())}"
catch err
param[ namespace[0] ] = 'invalid'
console.log('ERR', err)
else
param[ namespace[0] ] = undefined
#console.log('T', time, time.getHours(), time.getMinutes())
delete param[ "#{dateKey}year" ]
delete param[ "#{dateKey}month" ]
delete param[ "#{dateKey}day" ]
if time is 'Invalid Date'
throw "Invalid Date #{param[key]}"
param[newKey] = "#{time.getUTCFullYear()}-#{format(time.getUTCMonth()+1)}-#{format(time.getUTCDate())}"
catch err
param[newKey] = "invalid #{param[key]}"
console.log('ERR', err)
else
param[newKey] = undefined
delete param[key]
# get {datetime}
else if key.substr(0,10) is '{datetime}'
newKey = key.substr( 10, key.length )
namespace = newKey.split '___'
if !param[ namespace[0] ]
datetimeKey = "{datetime}#{namespace[0]}___"
year = param[ "#{datetimeKey}year" ]
month = param[ "#{datetimeKey}month" ]
day = param[ "#{datetimeKey}day" ]
hour = param[ "#{datetimeKey}hour" ]
minute = param[ "#{datetimeKey}minute" ]
if lookupForm.find('[data-name="' + namespace[0] + '"]').hasClass('is-hidden')
param[ namespace[0] ] = null
else if year && month && day && hour && minute
format = (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
try
time = new Date( Date.parse( "#{year}-#{format(month)}-#{format(day)}T#{format(hour)}:#{format(minute)}:00Z" ) )
if time && time.toString() is 'Invalid Date'
throw "Invalid Date #{year}-#{format(month)}-#{format(day)}T#{format(hour)}:#{format(minute)}:00Z"
time.setMinutes( time.getMinutes() + time.getTimezoneOffset() )
param[ namespace[0] ] = time.toISOString()
catch err
param[ namespace[0] ] = 'invalid'
console.log('ERR', err)
else
param[ namespace[0] ] = undefined
#console.log('T', time, time.getHours(), time.getMinutes())
delete param[ "#{datetimeKey}year" ]
delete param[ "#{datetimeKey}month" ]
delete param[ "#{datetimeKey}day" ]
delete param[ "#{datetimeKey}hour" ]
delete param[ "#{datetimeKey}minute" ]
newKey = key.substr(10, key.length)
if lookupForm.find("[data-name=\"#{newKey}\"]").hasClass('is-hidden')
param[newKey] = null
else if param[key]
try
time = new Date( Date.parse( param[key] ) )
if time is 'Invalid Datetime'
throw "Invalid Datetime #{param[key]}"
param[newKey] = time.toISOString().replace(/:\d\d\.\d\d\dZ$/, ':00Z')
catch err
param[newKey] = "invalid #{param[key]}"
console.log('ERR', err)
else
param[newKey] = undefined
delete param[key]
# split :: fields, build objects
inputSelectObject = {}
@ -1027,15 +608,21 @@ class App.ControllerForm extends App.Controller
# show new errors
for key, msg of data.errors
# use native fields
item = lookupForm.find('[name="' + key + '"]').closest('.form-group')
item.addClass('has-error')
item.find('.help-inline').html(msg)
# generic validation
itemGeneric = lookupForm.find('[name="' + key + '"]').closest('.form-group')
itemGeneric.addClass('has-error')
itemGeneric.find('.help-inline').html(msg)
# use meta fields
item = lookupForm.find('[data-name="' + key + '"]').closest('.form-group')
item.addClass('has-error')
item.find('.help-inline').html(msg)
itemMeta = lookupForm.find('[data-name="' + key + '"]').closest('.form-group')
itemMeta.addClass('has-error')
itemMeta.find('.help-inline').html(msg)
# use native fields
itemGeneric = lookupForm.find('[name="' + key + '"]').closest('.form-control')
itemGeneric.trigger('validate')
itemMeta = lookupForm.find('[data-name="' + key + '"]').closest('.form-control')
itemMeta.trigger('validate')
# set autofocus by delay to make validation testable
App.Delay.set(

View file

@ -1,20 +1,23 @@
class App.UiElement.date
@render: (attribute) ->
@render: (attributeOrig) ->
# set data type
if attribute.name
attribute.nameRaw = attribute.name
attribute.name = '{date}' + attribute.name
attribute = _.clone(attributeOrig)
attribute.nameRaw = attribute.name
attribute.name = "{date}#{attribute.name}"
# get time object
if attribute.value
if typeof( attribute.value ) is 'string'
unixtime = new Date( Date.parse( "#{attribute.value}T00:00:00Z" ) )
if typeof attribute.value is 'string'
time = new Date( Date.parse( "#{attribute.value}T00:00:00Z" ) )
else
unixtime = new Date( attribute.value )
year = unixtime.getUTCFullYear()
month = unixtime.getUTCMonth() + 1
day = unixtime.getUTCDate()
hour = unixtime.getUTCHours()
minute = unixtime.getUTCMinutes()
time = new Date( attribute.value )
# time items
year = time.getUTCFullYear()
month = time.getUTCMonth() + 1
day = time.getUTCDate()
# create element
item = $( App.view('generic/date')(
attribute: attribute
year: year
@ -22,118 +25,152 @@ class App.UiElement.date
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" ) )
time.setMinutes( time.getMinutes() + diff + time.getTimezoneOffset() )
else
time = new Date()
time.setMinutes( time.getMinutes() + diff )
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) ->
# start bindings
item.find('.js-today').bind('click', (e) =>
e.preventDefault()
setNewTime(0, @, true)
@setNewTime(item, attribute, 0, true)
@validation(item, attribute)
)
item.find('.js-plus-day').bind('click', (e) ->
item.find('.js-plus-day').bind('click', (e) =>
e.preventDefault()
setNewTime(60 * 24, @)
@setNewTime(item, attribute, 60 * 24)
@validation(item, attribute)
)
item.find('.js-minus-day').bind('click', (e) ->
item.find('.js-minus-day').bind('click', (e) =>
e.preventDefault()
setNewTime(-60 * 24, @)
@setNewTime(item, attribute, -60 * 24)
@validation(item, attribute)
)
item.find('.js-plus-week').bind('click', (e) ->
item.find('.js-plus-week').bind('click', (e) =>
e.preventDefault()
setNewTime(60 * 24 * 7, @)
@setNewTime(item, attribute, 60 * 24 * 7)
@validation(item, attribute)
)
item.find('.js-minus-week').bind('click', (e) ->
item.find('.js-minus-week').bind('click', (e) =>
e.preventDefault()
setNewTime(-60 * 24 * 7, @)
@setNewTime(item, attribute, -60 * 24 * 7)
@validation(item, attribute)
)
item.find('input').bind('keyup blur focus change', (e) =>
@setNewTime(item, attribute, 0)
@validation(item, attribute, true)
)
item.bind('validate', (e) =>
@validation(item, attribute)
)
#setShadowTimestamp()
@setNewTime(item, attribute, 0)
item.find('input').bind('keyup blur focus change', (e) ->
item
# do validation
name = $(@).attr('name')
if name
fieldPrefix = name.split('___')[0]
@format: (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
# remove old validation
item.find('.has-error').removeClass('has-error')
item.closest('.form-group').find('.help-inline').html('')
@setNewTime: (item, attribute, diff, reset = false) ->
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()
# remove old validation
#item.find('.has-error').removeClass('has-error')
#item.closest('.form-group').find('.help-inline').html('')
# validate exists
errors = {}
if !day
if reset
time = new Date()
time.setMinutes( time.getMinutes() + diff )
@setParams(item, attribute, time)
return
params = @getParams(item)
return if params.year is '' && params.month is '' && params.day is '' && params.hour is '' && params.day is ''
time = new Date( Date.parse( "#{params.year}-#{@format(params.month)}-#{@format(params.day)}T00:00:00Z" ) )
time.setMinutes( time.getMinutes() + diff )
return if !time
@setParams(item, attribute, time)
@setShadowTimestamp: (item, attribute, time) ->
timestamp = ''
if time
timestamp = time.toISOString().replace(/T\d\d:\d\d:\d\d\.\d\d\dZ$/, '')
item.find("[name=\"#{attribute.name}\"]").val(timestamp)
@setParams: (item, attribute, time) ->
if time.toString() is 'Invalid Date'
@setShadowTimestamp(item, attribute)
return
day = time.getDate()
month = time.getMonth()+1
year = time.getFullYear()
item.find('[data-item=day]').val(day)
item.find('[data-item=month]').val(month)
item.find('[data-item=year]').val(year)
@setShadowTimestamp(item, attribute, time)
@getParams: (item) ->
params = {}
params.day = item.find('[data-item=day]').val()
params.month = item.find('[data-item=month]').val()
params.year = item.find('[data-item=year]').val()
params
@validation: (item, attribute, runtime) ->
# remove old validation
item.closest('.form-group').removeClass('has-error')
item.find('.has-error').removeClass('has-error')
item.find('.help-inline').html('')
item.closest('.form-group').find('.help-inline').html('')
params = @getParams(item)
# check required attributes
errors = {}
if !runtime && !attribute.null
if params.day is ''
errors.day = 'missing'
if !month
if params.month is ''
errors.month = 'missing'
if !year
if params.year is ''
errors.year = 'missing'
# ranges
if day
daysInMonth = 31
if month && year
daysInMonth = new Date(year, month, 0).getDate();
# ranges
if params.day
daysInMonth = 31
if params.month && params.year
daysInMonth = new Date(params.year, params.month, 0).getDate()
if parseInt(day).toString() is 'NaN'
errors.day = 'invalid'
else if parseInt(day) > daysInMonth || parseInt(day) < 1
errors.day = 'invalid'
if isNaN( Number(params.day) )
errors.day = 'invalid'
else if Number(params.day) > daysInMonth || Number(params.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 params.month
if isNaN( Number(params.month) )
errors.month = 'invalid'
else if Number(params.month) > 12 || Number(params.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 params.year
if isNaN( Number(params.year) )
errors.year = 'invalid'
else if Number(params.year) > 2200 || Number(params.year) < 2001
errors.year = 'invalid'
if !_.isEmpty(errors)
# if field is required, if not do not show error
if year is '' && day is '' && month
if attribute.null
e.preventDefault()
e.stopPropagation()
return
else
item.closest('.form-group').find('.help-inline').text( 'is required' )
#formGroup = item.closest('.form-group')
formGroup = item
if !_.isEmpty(errors)
# show invalid options
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()
# if field is required, if not do not show error
if params.year is '' && params.day is '' && params.month is ''
return if attribute.null
item.closest('.form-group').addClass('has-error')
item.closest('.form-group').find('.help-inline').text( 'is required' )
return
)
item
# show invalid options
for key, value of errors
formGroup.addClass('has-error')
formGroup.find("[data-item=#{key}]").addClass('has-error')
return

View file

@ -1,20 +1,25 @@
class App.UiElement.datetime
@render: (attribute) ->
@render: (attributeOrig) ->
# set data type
if attribute.name
attribute.nameRaw = attribute.name
attribute.name = '{datetime}' + attribute.name
attribute = _.clone(attributeOrig)
attribute.nameRaw = attribute.name
attribute.name = "{datetime}#{attribute.name}"
# get time object
if attribute.value
if typeof( attribute.value ) is 'string'
unixtime = new Date( Date.parse( attribute.value ) )
if typeof attribute.value is 'string'
time = new Date( Date.parse( attribute.value ) )
else
unixtime = new Date( attribute.value )
year = unixtime.getFullYear()
month = unixtime.getMonth() + 1
day = unixtime.getDate()
hour = unixtime.getHours()
minute = unixtime.getMinutes()
time = new Date( attribute.value )
# time items
year = time.getFullYear()
month = time.getMonth() + 1
day = time.getDate()
hour = time.getHours()
minute = time.getMinutes()
# create element
item = $( App.view('generic/datetime')(
attribute: attribute
year: year
@ -24,149 +29,183 @@ class App.UiElement.datetime
minute: minute
) )
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()
hour = item.closest('.form-group').find("[name=\"{datetime}#{name}___hour\"]").val()
minute = item.closest('.form-group').find("[name=\"{datetime}#{name}___minute\"]").val()
format = (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
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" ) )
time.setMinutes( time.getMinutes() + diff + time.getTimezoneOffset() )
else
time = new Date()
time.setMinutes( time.getMinutes() + diff )
#console.log('T', time, time.getHours(), time.getMinutes())
item.closest('.form-group').find("[name=\"{datetime}#{name}___day\"]").val( time.getDate() )
item.closest('.form-group').find("[name=\"{datetime}#{name}___month\"]").val( time.getMonth()+1 )
item.closest('.form-group').find("[name=\"{datetime}#{name}___year\"]").val( time.getFullYear() )
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) ->
# start bindings
item.find('.js-today').bind('click', (e) =>
e.preventDefault()
setNewTime(0, @, true)
@setNewTime(item, attribute, 0, true)
@validation(item, attribute)
)
item.find('.js-plus-hour').bind('click', (e) ->
item.find('.js-plus-hour').bind('click', (e) =>
e.preventDefault()
setNewTime(60, @)
@setNewTime(item, attribute, 60)
@validation(item, attribute)
)
item.find('.js-minus-hour').bind('click', (e) ->
item.find('.js-minus-hour').bind('click', (e) =>
e.preventDefault()
setNewTime(-60, @)
@setNewTime(item, attribute, -60)
@validation(item, attribute)
)
item.find('.js-plus-day').bind('click', (e) ->
item.find('.js-plus-day').bind('click', (e) =>
e.preventDefault()
setNewTime(60 * 24, @)
@setNewTime(item, attribute, 60 * 24)
@validation(item, attribute)
)
item.find('.js-minus-day').bind('click', (e) ->
item.find('.js-minus-day').bind('click', (e) =>
e.preventDefault()
setNewTime(-60 * 24, @)
@setNewTime(item, attribute, -60 * 24)
@validation(item, attribute)
)
item.find('.js-plus-week').bind('click', (e) ->
item.find('.js-plus-week').bind('click', (e) =>
e.preventDefault()
setNewTime(60 * 24 * 7, @)
@setNewTime(item, attribute, 60 * 24 * 7)
@validation(item, attribute)
)
item.find('.js-minus-week').bind('click', (e) ->
item.find('.js-minus-week').bind('click', (e) =>
e.preventDefault()
setNewTime(-60 * 24 * 7, @)
@setNewTime(item, attribute, -60 * 24 * 7)
@validation(item, attribute)
)
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()
hour = item.closest('.form-group').find("[name=\"#{fieldPrefix}___hour\"]").val()
minute = item.closest('.form-group').find("[name=\"#{fieldPrefix}___minute\"]").val()
# validate exists
errors = {}
if !day
errors.day = 'missing'
if !month
errors.month = 'missing'
if !year
errors.year = 'missing'
if !hour
errors.hour = 'missing'
if !minute
errors.minute = '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 hour
if parseInt(hour).toString() is 'NaN'
errors.hour = 'invalid'
else if parseInt(hour) > 23 || parseInt(hour) < 0
errors.hour = 'invalid'
if minute
if parseInt(minute).toString() is 'NaN'
errors.minute = 'invalid'
else if parseInt(minute) > 59
errors.minute = 'invalid'
if !_.isEmpty(errors)
# if field is required, if not do not show error
if year is '' && day is '' && month is '' && hour is '' && minute is ''
if attribute.null
e.preventDefault()
e.stopPropagation()
return
else
item.closest('.form-group').find('.help-inline').text( 'is required' )
# show invalid options
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
item.find('input').bind('keyup blur focus change', (e) =>
@setNewTime(item, attribute, 0)
@validation(item, attribute, true)
)
item.bind('validate', (e) =>
@validation(item, attribute)
)
#setShadowTimestamp()
@setNewTime(item, attribute, 0)
item
@format: (number) ->
if parseInt(number) < 10
number = "0#{number}"
number
@setNewTime: (item, attribute, diff, reset = false) ->
# remove old validation
#item.find('.has-error').removeClass('has-error')
#item.closest('.form-group').find('.help-inline').html('')
if reset
time = new Date()
time.setMinutes( time.getMinutes() + diff )
@setParams(item, attribute, time)
return
params = @getParams(item)
return if params.year is '' && params.month is '' && params.day is '' && params.hour is '' && params.day is ''
time = new Date( Date.parse( "#{params.year}-#{@format(params.month)}-#{@format(params.day)}T#{@format(params.hour)}:#{@format(params.minute)}:00Z" ) )
time.setMinutes( time.getMinutes() + diff + time.getTimezoneOffset() )
return if !time
@setParams(item, attribute, time)
@setShadowTimestamp: (item, attribute, time) ->
timestamp = ''
if time
timestamp = time.toISOString().replace(/\d\d\.\d\d\dZ$/, '00.000Z')
item.find("[name=\"#{attribute.name}\"]").val(timestamp)
@setParams: (item, attribute, time) ->
if time.toString() is 'Invalid Date'
@setShadowTimestamp(item, attribute)
return
day = time.getDate()
month = time.getMonth()+1
year = time.getFullYear()
hour = time.getHours()
minute = time.getMinutes()
item.find('[data-item=day]').val(day)
item.find('[data-item=month]').val(month)
item.find('[data-item=year]').val(year)
item.find('[data-item=hour]').val(hour)
item.find('[data-item=minute]').val(minute)
@setShadowTimestamp(item, attribute, time)
@getParams: (item) ->
params = {}
params.day = item.find('[data-item=day]').val()
params.month = item.find('[data-item=month]').val()
params.year = item.find('[data-item=year]').val()
params.hour = item.find('[data-item=hour]').val()
params.minute = item.find('[data-item=minute]').val()
params
@validation: (item, attribute, runtime) ->
# remove old validation
item.closest('.form-group').removeClass('has-error')
item.find('.has-error').removeClass('has-error')
item.find('.help-inline').html('')
item.closest('.form-group').find('.help-inline').html('')
params = @getParams(item)
# check required attributes
errors = {}
if !runtime && !attribute.null
if params.day is ''
errors.day = 'missing'
if params.month is ''
errors.month = 'missing'
if params.year is ''
errors.year = 'missing'
if params.hour is ''
errors.hour = 'missing'
if params.minute is ''
errors.minute = 'missing'
# ranges
if params.day
daysInMonth = 31
if params.month && params.year
daysInMonth = new Date(params.year, params.month, 0).getDate()
if isNaN( Number(params.day) )
errors.day = 'invalid'
else if Number(params.day) > daysInMonth || Number(params.day) < 1
errors.day = 'invalid'
if params.month
if isNaN( Number(params.month) )
errors.month = 'invalid'
else if Number(params.month) > 12 || Number(params.month) < 1
errors.month = 'invalid'
if params.year
if isNaN( Number(params.year) )
errors.year = 'invalid'
else if Number(params.year) > 2200 || Number(params.year) < 2001
errors.year = 'invalid'
if params.hour
if isNaN( Number(params.hour) )
errors.hour = 'invalid'
else if parseInt(params.hour) > 23 || parseInt(params.hour) < 0
errors.hour = 'invalid'
if params.minute
if isNaN( Number(params.minute) )
errors.minute = 'invalid'
else if Number(params.minute) > 59
errors.minute = 'invalid'
#formGroup = item.closest('.form-group')
formGroup = item
if !_.isEmpty(errors)
# if field is required, if not do not show error
if params.year is '' && params.day is '' && params.month is '' && params.hour is '' && params.minute is ''
return if attribute.null
item.closest('.form-group').addClass('has-error')
item.closest('.form-group').find('.help-inline').text( 'is required' )
return
# show invalid options
for key, value of errors
formGroup.addClass('has-error')
formGroup.find("[data-item=#{key}]").addClass('has-error')
return

View file

@ -1,14 +1,15 @@
<div class="horizontal" data-name="<%= @attribute.nameRaw %>">
<input type="text" maxlength="2" name="<%= @attribute.name %>___day" value="<%= @day %>" placeholder="dd" style="width: 50px;">
<div class="horizontal form-control" style="padding: 0 0 0 4px; line-height: 40px;" data-name="<%= @attribute.nameRaw %>">
<input type="hidden" name="<%= @attribute.name %>" value="<%= @attribute.value %>">
<input type="text" maxlength="2" data-item="day" value="<%= @day %>" placeholder="dd" style="width: 36px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
.
<input type="text" maxlength="2" name="<%= @attribute.name %>___month" value="<%= @month %>" placeholder="mm" style="width: 50px;">
<input type="text" maxlength="2" data-item="month" value="<%= @month %>" placeholder="mm" style="width: 36px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
.
<input type="text" maxlength="4" name="<%= @attribute.name %>___year" value="<%= @year %>" placeholder="yyyy" style="width: 70px;">
<input type="text" maxlength="4" data-item="year" value="<%= @year %>" placeholder="yyyy" style="width: 54px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
</div>
<div>
<a class="js-today"><%- @T('today') %></a>
|
<a class="js-minus-day">-1</a> <a class="js-plus-day">+1</a> <%- @T('day') %>
|
<a class="js-minus-week">-7</a> <a class="js-plus-week">+7</a> <%- @T('days') %>
</div>
<% if !@attribute.disable_feature: %>
<small>
<a href="#" class="js-today"><%- @T('today') %></a> |
<a href="#" class="js-minus-day">-1</a> <a href="#" class="js-plus-day">+1</a> <%- @T('day') %> |
<a href="#" class="js-minus-week">-7</a> <a href="#" class="js-plus-week">+7</a> <%- @T('days') %>
</small>
<% end %>

View file

@ -1,19 +1,19 @@
<div class="horizontal" data-name="<%= @attribute.nameRaw %>">
<input type="text" maxlength="2" name="<%= @attribute.name %>___day" value="<%= @day %>" placeholder="dd" style="width: 44px;">
<div class="horizontal form-control" style="padding: 0 0 0 4px; line-height: 40px;" data-name="<%= @attribute.nameRaw %>">
<input type="hidden" name="<%= @attribute.name %>" value="<%= @attribute.value %>">
<input type="text" maxlength="2" data-item="day" value="<%= @day %>" placeholder="dd" style="width: 36px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
.
<input type="text" maxlength="2" name="<%= @attribute.name %>___month" value="<%= @month %>" placeholder="mm" style="width: 44px;">
<input type="text" maxlength="2" data-item="month" value="<%= @month %>" placeholder="mm" style="width: 36px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
.
<input type="text" maxlength="4" name="<%= @attribute.name %>___year" value="<%= @year %>" placeholder="yyyy" style="width: 70px;">
<input type="text" maxlength="2" name="<%= @attribute.name %>___hour" value="<%= @hour %>" placeholder="00" style="width: 44px;">
<input type="text" maxlength="4" data-item="year" value="<%= @year %>" placeholder="yyyy" style="width: 54px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
<input type="text" maxlength="2" data-item="hour" value="<%= @hour %>" placeholder="00" style="width: 36px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
:
<input type="text" maxlength="2" name="<%= @attribute.name %>___minute" value="<%= @minute %>" placeholder="00" style="width: 44px;">
<input type="text" maxlength="2" data-item="minute" value="<%= @minute %>" placeholder="00" style="width: 36px; padding: 6px 6px; border: 1px solid #ffffff; height: 39px;">
</div>
<div>
<a class="js-today"><%- @T('now') %></a>
|
<a class="js-minus-hour">-1</a> <a class="js-plus-hour">+1</a> <%- @T('hour') %>
|
<a class="js-minus-day">-1</a> <a class="js-plus-day">+1</a> <%- @T('day') %>
|
<a class="js-minus-week">-7</a> <a class="js-plus-week">+7</a> <%- @T('days') %>
</div>
<% if !@attribute.disable_feature: %>
<small>
<a href="#" class="js-today"><%- @T('now') %></a> |
<a href="#" class="js-minus-hour">-1</a> <a href="#" class="js-plus-hour">+1</a> <%- @T('hour') %> |
<a href="#" class="js-minus-day">-1</a> <a href="#" class="js-plus-day">+1</a> <%- @T('day') %> |
<a href="#" class="js-minus-week">-7</a> <a href="#" class="js-plus-week">+7</a> <%- @T('days') %>
</small>
<% end %>

View file

@ -1,4 +1,4 @@
test( "form validation check", function() {
test( 'form validation check', function() {
$('#forms').append('<hr><h1>form params check</h1><form id="form1"></form>')
@ -45,21 +45,19 @@ test( "form validation check", function() {
equal( el.find('[data-name="richtext1"]').val(), '', 'check richtext1 value')
//equal( el.find('[data-name="richtext1"]').prop('required'), true, 'check richtext1 required')
params = App.ControllerForm.params( el )
errors = form.validate(params)
test_errors = {
input1: "is required",
password1: "is required",
textarea1: "is required",
select1: "is required",
selectmulti1: "is required",
autocompletion1: "is required",
richtext1: "is required",
datetime1: "is required",
date1: "is required",
input1: 'is required',
password1: 'is required',
textarea1: 'is required',
select1: 'is required',
selectmulti1: 'is required',
autocompletion1: 'is required',
richtext1: 'is required',
datetime1: 'is required',
date1: 'is required',
}
deepEqual( errors, test_errors, 'validation errors check' )
@ -94,7 +92,7 @@ test( "form validation check", function() {
});
test( "datetime validation check", function() {
test( 'datetime validation check', function() {
$('#forms').append('<hr><h1>datetime validation check</h1><form id="form2"></form>')
@ -119,7 +117,7 @@ test( "datetime validation check", function() {
errors = form.validate(params)
test_errors = {
datetime1: "is required",
datetime1: 'is required',
}
deepEqual( errors, test_errors, 'validation errors check' )
App.ControllerForm.validate( { errors: errors, form: el } )
@ -129,14 +127,14 @@ test( "datetime validation check", function() {
//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')
el.find('[data-name="datetime1"] [data-item="day"]').val(1).trigger('blur')
el.find('[data-name="datetime1"] [data-item="month"]').val(1).trigger('blur')
el.find('[data-name="datetime1"] [data-item="year"]').val(2015).trigger('blur')
el.find('[data-name="datetime1"] [data-item="hour"]').val(12).trigger('blur')
el.find('[data-name="datetime1"] [data-item="minute"]').val(42).trigger('blur')
// check params
timeStamp = new Date( Date.parse("2015-01-01T12:42:00.000Z") )
timeStamp = new Date( Date.parse('2015-01-01T12:42:00.000Z') )
timeStamp.setMinutes( timeStamp.getMinutes() + timeStamp.getTimezoneOffset() )
params = App.ControllerForm.params( el )
test_params = {
@ -153,30 +151,32 @@ test( "datetime validation check", function() {
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')
el.find('[name="{datetime}datetime1___day"]').val('47').blur()
deepEqual( el.find('[name="{datetime}datetime1___day"]').hasClass('has-error'), true )
el.find('[name="{datetime}datetime1___month"]').val('1').blur()
deepEqual( el.find('[name="{datetime}datetime1___month"]').hasClass('has-error'), false )
el.find('[name="{datetime}datetime1___year"]').val('2015').blur()
deepEqual( el.find('[name="{datetime}datetime1___year"]').hasClass('has-error'), false )
el.find('[name="{datetime}datetime1___hour"]').val('12').blur()
deepEqual( el.find('[name="{datetime}datetime1___hour"]').hasClass('has-error'), false )
el.find('[name="{datetime}datetime1___minute"]').val('42').blur()
deepEqual( el.find('[name="{datetime}datetime1___minute"]').hasClass('has-error'), false )
el.find('[data-name="datetime1"] [data-item="day"]').val('47').trigger('blur')
deepEqual( el.find('[data-name="datetime1"] [data-item="day"]').hasClass('has-error'), true )
el.find('[data-name="datetime1"] [data-item="month"]').val('1').trigger('blur')
deepEqual( el.find('[data-name="datetime1"] [data-item="month"]').hasClass('has-error'), false )
el.find('[data-name="datetime1"] [data-item="year"]').val('2015').trigger('blur')
deepEqual( el.find('[data-name="datetime1"] [data-item="year"]').hasClass('has-error'), false )
el.find('[data-name="datetime1"] [data-item="hour"]').val('12').trigger('blur')
deepEqual( el.find('[data-name="datetime1"] [data-item="hour"]').hasClass('has-error'), false )
el.find('[data-name="datetime1"] [data-item="minute"]').val('42').trigger('blur')
deepEqual( el.find('[data-name="datetime1"] [data-item="minute"]').hasClass('has-error'), false )
params = App.ControllerForm.params( el )
errors = form.validate(params)
test_errors = {
datetime1: "invalid",
datetime1: 'is required',
}
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'), true, 'check datetime1 has-error')
equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), 'invalid', 'check datetime1 error message')
equal( el.find('[data-name="datetime1"]').closest('.form-group').hasClass('has-error'), false, 'check datetime1 no has-error')
equal( el.find('[data-name="datetime1"] [data-item="day"]').hasClass('has-error'), true, 'check datetime1 no has-error')
equal( el.find('[data-name="datetime1"] [data-item="month"]').hasClass('has-error'), false, 'check datetime1 no has-error')
equal( el.find('[data-name="datetime1"]').closest('.form-group').find('.help-inline').text(), '', 'check datetime1 error message')
});
test( "date validation check", function() {
test( 'date validation check', function() {
$('#forms').append('<hr><h1>date validation check</h1><form id="form3"></form>')
@ -203,24 +203,23 @@ test( "date validation check", function() {
errors = form.validate(params)
test_errors = {
date1: "is required",
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(), '', 'check date1 error message')
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')
el.find('[data-name="date1"] [data-item="day"]').val('1').trigger('blur')
el.find('[data-name="date1"] [data-item="month"]').val('1').trigger('blur')
el.find('[data-name="date1"] [data-item="year"]').val('2015').trigger('blur')
// check params
params = App.ControllerForm.params( el )
test_params = {
date1: "2015-01-01",
date1: '2015-01-01',
}
deepEqual( params, test_params, 'params check' )
@ -233,29 +232,32 @@ test( "date validation check", function() {
equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), '', 'check date1 error message')
// set invalid values
el.find('[name="{date}date1___day"]').val('47').blur()
deepEqual( el.find('[name="{date}date1___day"]').hasClass('has-error'), true )
el.find('[name="{date}date1___month"]').val('1').blur()
deepEqual( el.find('[name="{date}date1___month"]').hasClass('has-error'), false )
el.find('[name="{date}date1___year"]').val('2015').blur()
deepEqual( el.find('[name="{date}date1___year"]').hasClass('has-error'), false )
el.find('[data-name="date1"] [data-item="day"]').val('47').trigger('blur')
deepEqual( el.find('[data-name="date1"] [data-item="day"]').hasClass('has-error'), true )
el.find('[data-name="date1"] [data-item="month"]').val('1').trigger('blur')
deepEqual( el.find('[data-name="date1"] [data-item="month"]').hasClass('has-error'), false )
el.find('[data-name="date1"] [data-item="year"]').val('2015').trigger('blur')
deepEqual( el.find('[data-name="date1"] [data-item="year"]').hasClass('has-error'), false )
// check params
params = App.ControllerForm.params( el )
test_params = {
date1: 'invalid',
date1: undefined,
}
deepEqual( params, test_params, 'params check' )
// check errors
errors = form.validate(params)
test_errors = {
date1: 'invalid',
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(), 'invalid', 'check date1 error message')
equal( el.find('[data-name="date1"]').closest('.form-group').hasClass('has-error'), false, 'check date1 no has-error')
equal( el.find('[data-name="date1"] [data-item="day"]').hasClass('has-error'), true, 'check date1 no has-error')
equal( el.find('[data-name="date1"] [data-item="month"]').hasClass('has-error'), false, 'check date1 no has-error')
equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), '', 'check date1 error message')
});