netzke-basepack 0.7.3 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +9 -1
- data/javascripts/xdatetime.js +195 -0
- data/lib/netzke/active_record/attributes.rb +2 -2
- data/lib/netzke/basepack.rb +1 -2
- data/lib/netzke/basepack/data_accessor.rb +1 -3
- data/lib/netzke/basepack/form_panel.rb +1 -10
- data/lib/netzke/basepack/form_panel/fields.rb +3 -7
- data/lib/netzke/basepack/grid_panel.rb +3 -0
- data/lib/netzke/basepack/grid_panel/columns.rb +4 -4
- data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +31 -9
- data/lib/netzke/basepack/grid_panel/services.rb +2 -0
- data/lib/netzke/basepack/search_window.rb +1 -0
- data/lib/netzke/basepack/version.rb +1 -1
- data/lib/netzke/basepack/window/javascripts/window.js +7 -5
- data/netzke-basepack.gemspec +12 -26
- data/test/basepack_test_app/Gemfile.lock +48 -49
- data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +2 -1
- data/test/basepack_test_app/app/components/window_component_loader.rb +1 -1
- data/test/basepack_test_app/db/seeds.rb +4 -0
- data/test/basepack_test_app/features/form_panel.feature +13 -4
- data/test/basepack_test_app/features/grid_panel.feature +10 -4
- data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +17 -1
- data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +9 -1
- metadata +10 -10
- data/javascripts/datetimefield.js +0 -24
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
= 0.7.4 - 2012-03-05
|
2
|
+
* bug fix
|
3
|
+
* :enable_pagination is now respected in GridPanel
|
4
|
+
* Virtual columns are not sortable by default now
|
5
|
+
* Datetime column now works
|
6
|
+
* Make Window respect persistence: false
|
7
|
+
* Disable persistence for search window in GridPanel
|
8
|
+
|
1
9
|
= 0.7.3 - 2011-10-23
|
2
10
|
* bug fix
|
3
|
-
* :sorting_scope
|
11
|
+
* :sorting_scope is now respected in GridPanel
|
4
12
|
* regression: filtering on association column is fix (covered with tests)
|
5
13
|
|
6
14
|
= 0.7.2 - 2011-10-20
|
@@ -0,0 +1,195 @@
|
|
1
|
+
/**
|
2
|
+
* @class Ext.ux.form.field.DateTime
|
3
|
+
* @extends Ext.form.FieldContainer
|
4
|
+
* @version 0.2 (July 20th, 2011)
|
5
|
+
* @author atian25 (http://www.sencha.com/forum/member.php?51682-atian25)
|
6
|
+
* @author ontho (http://www.sencha.com/forum/member.php?285806-ontho)
|
7
|
+
* @author jakob.ketterl (http://www.sencha.com/forum/member.php?25102-jakob.ketterl)
|
8
|
+
* @link http://www.sencha.com/forum/showthread.php?134345-Ext.ux.form.field.DateTime
|
9
|
+
*/
|
10
|
+
Ext.define('Ext.ux.form.field.DateTime', {
|
11
|
+
extend:'Ext.form.FieldContainer',
|
12
|
+
mixins:{
|
13
|
+
field:'Ext.form.field.Field'
|
14
|
+
},
|
15
|
+
alias: 'widget.xdatetime',
|
16
|
+
|
17
|
+
//configurables
|
18
|
+
|
19
|
+
combineErrors: true,
|
20
|
+
msgTarget: 'under',
|
21
|
+
layout: 'hbox',
|
22
|
+
readOnly: false,
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @cfg {String} dateFormat
|
26
|
+
* Convenience config for specifying the format of the date portion.
|
27
|
+
* This value is overridden if format is specified in the dateConfig.
|
28
|
+
* The default is 'Y-m-d'
|
29
|
+
*/
|
30
|
+
dateFormat: 'Y-m-d',
|
31
|
+
/**
|
32
|
+
* @cfg {String} timeFormat
|
33
|
+
* Convenience config for specifying the format of the time portion.
|
34
|
+
* This value is overridden if format is specified in the timeConfig.
|
35
|
+
* The default is 'H:i:s'
|
36
|
+
*/
|
37
|
+
timeFormat: 'H:i:s',
|
38
|
+
// /**
|
39
|
+
// * @cfg {String} dateTimeFormat
|
40
|
+
// * The format used when submitting the combined value.
|
41
|
+
// * Defaults to 'Y-m-d H:i:s'
|
42
|
+
// */
|
43
|
+
// dateTimeFormat: 'Y-m-d H:i:s',
|
44
|
+
/**
|
45
|
+
* @cfg {Object} dateConfig
|
46
|
+
* Additional config options for the date field.
|
47
|
+
*/
|
48
|
+
dateConfig:{},
|
49
|
+
/**
|
50
|
+
* @cfg {Object} timeConfig
|
51
|
+
* Additional config options for the time field.
|
52
|
+
*/
|
53
|
+
timeConfig:{},
|
54
|
+
|
55
|
+
|
56
|
+
// properties
|
57
|
+
|
58
|
+
dateValue: null, // Holds the actual date
|
59
|
+
/**
|
60
|
+
* @property dateField
|
61
|
+
* @type Ext.form.field.Date
|
62
|
+
*/
|
63
|
+
dateField: null,
|
64
|
+
/**
|
65
|
+
* @property timeField
|
66
|
+
* @type Ext.form.field.Time
|
67
|
+
*/
|
68
|
+
timeField: null,
|
69
|
+
|
70
|
+
initComponent: function(){
|
71
|
+
var me = this
|
72
|
+
,i = 0
|
73
|
+
,key
|
74
|
+
,tab;
|
75
|
+
|
76
|
+
me.items = me.items || [];
|
77
|
+
|
78
|
+
me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
|
79
|
+
format:me.dateFormat,
|
80
|
+
flex:1,
|
81
|
+
isFormField:false, //exclude from field query's
|
82
|
+
submitValue:false
|
83
|
+
}, me.dateConfig));
|
84
|
+
me.items.push(me.dateField);
|
85
|
+
|
86
|
+
me.timeField = Ext.create('Ext.form.field.Time', Ext.apply({
|
87
|
+
format:me.timeFormat,
|
88
|
+
flex:1,
|
89
|
+
isFormField:false, //exclude from field query's
|
90
|
+
submitValue:false
|
91
|
+
}, me.timeConfig));
|
92
|
+
me.items.push(me.timeField);
|
93
|
+
|
94
|
+
for (; i < me.items.length; i++) {
|
95
|
+
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
|
96
|
+
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
|
97
|
+
me.items[i].on('specialkey', function(field, event){
|
98
|
+
key = event.getKey();
|
99
|
+
tab = key == event.TAB;
|
100
|
+
|
101
|
+
if (tab && me.focussedItem == me.dateField) {
|
102
|
+
event.stopEvent();
|
103
|
+
me.timeField.focus();
|
104
|
+
return;
|
105
|
+
}
|
106
|
+
|
107
|
+
me.fireEvent('specialkey', field, event);
|
108
|
+
});
|
109
|
+
}
|
110
|
+
|
111
|
+
me.callParent();
|
112
|
+
|
113
|
+
// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
|
114
|
+
this.inputEl = {
|
115
|
+
dom:{},
|
116
|
+
swallowEvent:function(){}
|
117
|
+
};
|
118
|
+
|
119
|
+
me.initField();
|
120
|
+
},
|
121
|
+
|
122
|
+
focus:function(){
|
123
|
+
this.callParent();
|
124
|
+
this.dateField.focus();
|
125
|
+
},
|
126
|
+
|
127
|
+
onItemFocus:function(item){
|
128
|
+
if (this.blurTask){
|
129
|
+
this.blurTask.cancel();
|
130
|
+
}
|
131
|
+
this.focussedItem = item;
|
132
|
+
},
|
133
|
+
|
134
|
+
onItemBlur:function(item){
|
135
|
+
var me = this;
|
136
|
+
if (item != me.focussedItem){ return; }
|
137
|
+
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
|
138
|
+
me.blurTask = new Ext.util.DelayedTask(function(){
|
139
|
+
me.fireEvent('blur', me);
|
140
|
+
});
|
141
|
+
me.blurTask.delay(100);
|
142
|
+
},
|
143
|
+
|
144
|
+
getValue: function(){
|
145
|
+
var value = null
|
146
|
+
,date = this.dateField.getSubmitValue()
|
147
|
+
,time = this.timeField.getSubmitValue()
|
148
|
+
,format;
|
149
|
+
|
150
|
+
if (date){
|
151
|
+
if (time){
|
152
|
+
format = this.getFormat();
|
153
|
+
value = Ext.Date.parse(date + ' ' + time, format);
|
154
|
+
} else {
|
155
|
+
value = this.dateField.getValue();
|
156
|
+
}
|
157
|
+
}
|
158
|
+
return value;
|
159
|
+
},
|
160
|
+
|
161
|
+
getSubmitValue: function(){
|
162
|
+
// var value = this.getValue();
|
163
|
+
// return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
|
164
|
+
|
165
|
+
var me = this
|
166
|
+
,format = me.getFormat()
|
167
|
+
,value = me.getValue();
|
168
|
+
|
169
|
+
return value ? Ext.Date.format(value, format) : null;
|
170
|
+
},
|
171
|
+
|
172
|
+
setValue: function(value){
|
173
|
+
if (Ext.isString(value)){
|
174
|
+
value = Ext.Date.parse(value, this.getFormat()); //this.dateTimeFormat
|
175
|
+
}
|
176
|
+
this.dateField.setValue(value);
|
177
|
+
this.timeField.setValue(value);
|
178
|
+
},
|
179
|
+
|
180
|
+
getFormat: function(){
|
181
|
+
return (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeField.submitFormat || this.timeField.format);
|
182
|
+
},
|
183
|
+
|
184
|
+
// Bug? A field-mixin submits the data from getValue, not getSubmitValue
|
185
|
+
getSubmitData: function(){
|
186
|
+
var me = this
|
187
|
+
,data = null;
|
188
|
+
|
189
|
+
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
|
190
|
+
data = {};
|
191
|
+
data[me.getName()] = '' + me.getSubmitValue();
|
192
|
+
}
|
193
|
+
return data;
|
194
|
+
}
|
195
|
+
});
|
@@ -184,7 +184,7 @@ module Netzke
|
|
184
184
|
end
|
185
185
|
|
186
186
|
# a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
|
187
|
-
v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone
|
187
|
+
v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone].include?(v.class)
|
188
188
|
|
189
189
|
v
|
190
190
|
end
|
@@ -242,4 +242,4 @@ module Netzke
|
|
242
242
|
|
243
243
|
end
|
244
244
|
end
|
245
|
-
end
|
245
|
+
end
|
data/lib/netzke/basepack.rb
CHANGED
@@ -17,10 +17,9 @@ module Netzke
|
|
17
17
|
|
18
18
|
# Called from netzke-basepack.rb
|
19
19
|
def init
|
20
|
-
|
20
|
+
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/xdatetime.js"
|
21
21
|
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/basepack.js"
|
22
22
|
|
23
|
-
Netzke::Core.ext_stylesheets << "#{File.dirname(__FILE__)}/../../stylesheets/datetimefield.css"
|
24
23
|
Netzke::Core.ext_stylesheets << "#{File.dirname(__FILE__)}/../../stylesheets/basepack.css"
|
25
24
|
end
|
26
25
|
|
@@ -23,7 +23,7 @@ module Netzke
|
|
23
23
|
|
24
24
|
if assoc.klass.column_names.include?(assoc_method)
|
25
25
|
# apply query
|
26
|
-
relation = relation.where(
|
26
|
+
relation = relation.where(["#{assoc_method} like ?", "%#{query}%"]) if query.present?
|
27
27
|
relation.all.map{ |r| [r.id, r.send(assoc_method)] }
|
28
28
|
else
|
29
29
|
relation.all.map{ |r| [r.id, r.send(assoc_method)] }.select{ |id,value| value =~ /^#{query}/ }
|
@@ -43,8 +43,6 @@ module Netzke
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
return res
|
46
|
-
|
47
|
-
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -106,16 +106,7 @@ module Netzke
|
|
106
106
|
|
107
107
|
# A hash of record data including the meta field
|
108
108
|
def js_record_data
|
109
|
-
|
110
|
-
|
111
|
-
# HACK: a dirty hack cutting off the time part from the datetime string to please the form's datefield - until we have a real datetimefield
|
112
|
-
hsh.each_pair do |k,v|
|
113
|
-
if v && [:datetime, :date].include?(fields[k.to_sym].try(:fetch, :attr_type, nil))
|
114
|
-
hsh[k] = v.split.first
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
hsh
|
109
|
+
record.to_hash(fields).merge(:_meta => meta_field).literalize_keys
|
119
110
|
end
|
120
111
|
|
121
112
|
def record
|
@@ -101,9 +101,8 @@ module Netzke
|
|
101
101
|
set_default_read_only(field)
|
102
102
|
|
103
103
|
# temporal datetime setup, while we don't have real datetime field
|
104
|
-
if field[:attr_type] == :
|
105
|
-
field[:format] ||= "Y-m-d"
|
106
|
-
field[:submit_format] = "Y-m-d"
|
104
|
+
if field[:attr_type] == :date
|
105
|
+
field[:format] ||= "Y-m-d"
|
107
106
|
end
|
108
107
|
|
109
108
|
# provide our special combobox with our id
|
@@ -187,10 +186,7 @@ module Netzke
|
|
187
186
|
:integer => :numberfield,
|
188
187
|
:boolean => config[:multi_edit] ? :tricheckbox : :checkboxfield,
|
189
188
|
:date => :datefield,
|
190
|
-
|
191
|
-
# :datetime => :datetimefield,
|
192
|
-
:datetime => :datefield,
|
193
|
-
|
189
|
+
:datetime => :xdatetime,
|
194
190
|
:text => :textarea,
|
195
191
|
:json => :jsonfield,
|
196
192
|
:string => :textfield
|
@@ -40,6 +40,7 @@ module Netzke
|
|
40
40
|
# * +enable_edit_in_form+ - (defaults to true) provide buttons into the toolbar that activate editing/adding records via a form
|
41
41
|
# * +enable_extended_search+ - (defaults to true) provide a button into the toolbar that shows configurable search form
|
42
42
|
# * +enable_context_menu+ - (defaults to true) enable rows context menu
|
43
|
+
# * +context_menu+ - an array of actions (e.g. [:edit.action, "-", :del.action] - see the Actions section) or +false+ to disable the context menu
|
43
44
|
# * +enable_rows_reordering+ - (defaults to false) enable reordering of rows with drag-n-drop; underlying model (specified in +model+) must implement "acts_as_list"-compatible functionality
|
44
45
|
# * +enable_pagination+ - (defaults to true) enable pagination
|
45
46
|
# * +rows_per_page+ - (defaults to 30) number of rows per page (ignored when +enable_pagination+ is set to +false+)
|
@@ -74,6 +75,8 @@ module Netzke
|
|
74
75
|
# }
|
75
76
|
# end
|
76
77
|
#
|
78
|
+
# * +format+ - the format to display data in case of date and datetime columns, e.g. 'Y-m-d g:i:s'.
|
79
|
+
#
|
77
80
|
# Besides these options, a column can receive any meaningful config option understood by Ext.grid.column.Column.
|
78
81
|
#
|
79
82
|
# == One-to-many association support
|
@@ -214,7 +214,8 @@ module Netzke
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def set_default_sortable(c)
|
217
|
-
|
217
|
+
# this *has* to be set to false if we don't want the column to be sortable (it's sortable by default in Ext)
|
218
|
+
c[:sortable] = !(c[:virtual] && !c[:sorting_scope]) if c[:sortable].nil?
|
218
219
|
end
|
219
220
|
|
220
221
|
def set_default_filterable(c)
|
@@ -309,8 +310,7 @@ module Netzke
|
|
309
310
|
:integer => :numberfield,
|
310
311
|
:boolean => :checkbox,
|
311
312
|
:date => :datefield,
|
312
|
-
|
313
|
-
:datetime => :datefield,
|
313
|
+
:datetime => :xdatetime,
|
314
314
|
:text => :textarea,
|
315
315
|
:string => :textfield
|
316
316
|
}
|
@@ -321,7 +321,7 @@ module Netzke
|
|
321
321
|
# :integer => :numbercolumn, # don't like the default formatter
|
322
322
|
:boolean => :checkcolumn,
|
323
323
|
:date => :datecolumn,
|
324
|
-
|
324
|
+
#:datetime => :datecolumn # TODO: replace with datetimepicker
|
325
325
|
}
|
326
326
|
end
|
327
327
|
|
@@ -23,13 +23,27 @@
|
|
23
23
|
// Run through columns and set up different configuration for each
|
24
24
|
Ext.each(this.columns, function(c, i){
|
25
25
|
|
26
|
+
this.normalizeRenderer(c);
|
27
|
+
|
26
28
|
// Build the field configuration for this column
|
27
29
|
var fieldConfig = {name: c.name, defaultValue: c.defaultValue};
|
28
30
|
|
29
31
|
if (c.name !== '_meta') fieldConfig.type = this.fieldTypeForAttrType(c.attrType); // field type (grid editors need this to function well)
|
30
32
|
|
31
|
-
if (c.attrType == 'datetime'
|
33
|
+
if (c.attrType == 'datetime') {
|
32
34
|
fieldConfig.dateFormat = 'Y-m-d g:i:s'; // in this format we receive dates from the server
|
35
|
+
|
36
|
+
if (!c.renderer) {
|
37
|
+
c.renderer = Ext.util.Format.dateRenderer(c.format || fieldConfig.dateFormat); // format in which the data will be rendered
|
38
|
+
}
|
39
|
+
};
|
40
|
+
|
41
|
+
if (c.attrType == 'date') {
|
42
|
+
fieldConfig.dateFormat = 'Y-m-d'; // in this format we receive dates from the server
|
43
|
+
|
44
|
+
if (!c.renderer) {
|
45
|
+
c.renderer = Ext.util.Format.dateRenderer(c.format || fieldConfig.dateFormat); // format in which the data will be rendered
|
46
|
+
}
|
33
47
|
};
|
34
48
|
|
35
49
|
fields.push(fieldConfig);
|
@@ -45,7 +59,6 @@
|
|
45
59
|
// c.editor = {xtype: "combobox", options: c.comboboxOptions.split('\\n')}
|
46
60
|
// }
|
47
61
|
|
48
|
-
this.normalizeRenderer(c);
|
49
62
|
|
50
63
|
// Set rendeder for association columns (the one displaying associations by the specified method instead of id)
|
51
64
|
if (c.assoc) {
|
@@ -163,14 +176,23 @@
|
|
163
176
|
this.plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {pluginId: 'celleditor'}));
|
164
177
|
}
|
165
178
|
|
166
|
-
//
|
179
|
+
// Toolbar
|
167
180
|
this.dockedItems = this.dockedItems || [];
|
168
|
-
this.
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
181
|
+
if (this.enablePagination) {
|
182
|
+
this.dockedItems.push({
|
183
|
+
xtype: 'pagingtoolbar',
|
184
|
+
dock: 'bottom',
|
185
|
+
store: this.store,
|
186
|
+
items: this.bbar && ["-"].concat(this.bbar) // append the old bbar. TODO: get rid of it.
|
187
|
+
});
|
188
|
+
} else if (this.bbar) {
|
189
|
+
this.dockedItems.push({
|
190
|
+
xtype: 'toolbar',
|
191
|
+
dock: 'bottom',
|
192
|
+
items: this.bbar
|
193
|
+
});
|
194
|
+
}
|
195
|
+
|
174
196
|
|
175
197
|
delete this.bbar;
|
176
198
|
|
@@ -5,14 +5,16 @@
|
|
5
5
|
this.callParent();
|
6
6
|
|
7
7
|
// set the move and resize events after window is shown, so that they don't fire at initial rendering
|
8
|
-
this.
|
9
|
-
this.on("
|
10
|
-
|
11
|
-
|
8
|
+
if (this.persistence) {
|
9
|
+
this.on("show", function(){
|
10
|
+
this.on("move", this.onMoveResize, this);
|
11
|
+
this.on("resize", this.onMoveResize, this);
|
12
|
+
}, this);
|
13
|
+
}
|
12
14
|
},
|
13
15
|
|
14
16
|
onMoveResize: function(){
|
15
17
|
var x = this.getPosition()[0], y = this.getPosition()[1], w = this.getSize().width, h = this.getSize().height;
|
16
18
|
this.setSizeAndPosition({x:x, y:y, w:w, h:h}); // API call
|
17
19
|
}
|
18
|
-
}
|
20
|
+
}
|
data/netzke-basepack.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.7.
|
7
|
+
s.name = "netzke-basepack"
|
8
|
+
s.version = "0.7.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
11
|
+
s.authors = ["Sergei Kozlov"]
|
12
|
+
s.date = "2012-03-05"
|
13
|
+
s.description = "A set of full-featured extendible Netzke components (such as FormPanel, GridPanel, Window, BorderLayoutPanel, etc) which can be used as building block for your RIA"
|
14
|
+
s.email = "sergei@playcode.nl"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
17
|
"README.md"
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"init.rb",
|
30
30
|
"install.rb",
|
31
31
|
"javascripts/basepack.js",
|
32
|
-
"javascripts/
|
32
|
+
"javascripts/xdatetime.js",
|
33
33
|
"lib/generators/netzke/basepack_generator.rb",
|
34
34
|
"lib/generators/netzke/templates/assets/ts-checkbox.gif",
|
35
35
|
"lib/generators/netzke/templates/create_netzke_field_lists.rb",
|
@@ -269,25 +269,11 @@ Gem::Specification.new do |s|
|
|
269
269
|
"test/unit/tab_panel_test.rb",
|
270
270
|
"uninstall.rb"
|
271
271
|
]
|
272
|
-
s.homepage =
|
273
|
-
s.post_install_message =
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
Don't forget to run "rails generate netzke:baspack" to copy necessary
|
279
|
-
assets to your public folder!
|
280
|
-
|
281
|
-
Netzke home page: http://netzke.org
|
282
|
-
Netzke Google Groups: http://groups.google.com/group/netzke
|
283
|
-
Netzke tutorials: http://blog.writelesscode.com
|
284
|
-
|
285
|
-
========================================================================
|
286
|
-
|
287
|
-
}
|
288
|
-
s.require_paths = [%q{lib}]
|
289
|
-
s.rubygems_version = %q{1.8.6}
|
290
|
-
s.summary = %q{Pre-built Rails + ExtJS components for your RIA}
|
272
|
+
s.homepage = "http://netzke.org"
|
273
|
+
s.post_install_message = "\n========================================================================\n\n Thanks for installing netzke-basepack!\n\n Don't forget to run \"rails generate netzke:baspack\" to copy necessary\n assets to your public folder!\n\n Netzke home page: http://netzke.org\n Netzke Google Groups: http://groups.google.com/group/netzke\n Netzke tutorials: http://blog.writelesscode.com\n\n========================================================================\n\n"
|
274
|
+
s.require_paths = ["lib"]
|
275
|
+
s.rubygems_version = "1.8.10"
|
276
|
+
s.summary = "Pre-built Rails + ExtJS components for your RIA"
|
291
277
|
|
292
278
|
if s.respond_to? :specification_version then
|
293
279
|
s.specification_version = 3
|
@@ -44,54 +44,53 @@ GEM
|
|
44
44
|
acts_as_list (0.1.4)
|
45
45
|
addressable (2.2.6)
|
46
46
|
arel (2.2.1)
|
47
|
-
bcrypt-ruby (3.0.
|
47
|
+
bcrypt-ruby (3.0.1)
|
48
48
|
builder (3.0.0)
|
49
|
-
capybara (1.1.
|
49
|
+
capybara (1.1.2)
|
50
50
|
mime-types (>= 1.16)
|
51
51
|
nokogiri (>= 1.3.3)
|
52
52
|
rack (>= 1.0.0)
|
53
53
|
rack-test (>= 0.5.4)
|
54
54
|
selenium-webdriver (~> 2.0)
|
55
55
|
xpath (~> 0.1.4)
|
56
|
-
childprocess (0.2.
|
56
|
+
childprocess (0.2.8)
|
57
57
|
ffi (~> 1.0.6)
|
58
|
-
cucumber (1.
|
58
|
+
cucumber (1.1.4)
|
59
59
|
builder (>= 2.1.2)
|
60
60
|
diff-lcs (>= 1.1.2)
|
61
|
-
gherkin (~> 2.
|
61
|
+
gherkin (~> 2.7.1)
|
62
62
|
json (>= 1.4.6)
|
63
|
-
term-ansicolor (>= 1.0.
|
64
|
-
cucumber-rails (1.
|
65
|
-
capybara (>= 1.
|
66
|
-
cucumber (
|
67
|
-
nokogiri (>= 1.
|
68
|
-
database_cleaner (0.
|
63
|
+
term-ansicolor (>= 1.0.6)
|
64
|
+
cucumber-rails (1.2.1)
|
65
|
+
capybara (>= 1.1.2)
|
66
|
+
cucumber (>= 1.1.3)
|
67
|
+
nokogiri (>= 1.5.0)
|
68
|
+
database_cleaner (0.7.0)
|
69
69
|
diff-lcs (1.1.3)
|
70
70
|
erubis (2.7.0)
|
71
|
-
factory_girl (2.
|
72
|
-
|
73
|
-
|
71
|
+
factory_girl (2.3.2)
|
72
|
+
activesupport
|
73
|
+
ffi (1.0.11)
|
74
|
+
gherkin (2.7.2)
|
74
75
|
json (>= 1.4.6)
|
75
76
|
hike (1.2.1)
|
76
77
|
i18n (0.6.0)
|
77
|
-
json (1.
|
78
|
-
json_pure (1.5.4)
|
79
|
-
spruz (~> 0.2.8)
|
78
|
+
json (1.6.4)
|
80
79
|
launchy (2.0.5)
|
81
80
|
addressable (~> 2.2.6)
|
82
81
|
mail (2.3.0)
|
83
82
|
i18n (>= 0.4.0)
|
84
83
|
mime-types (~> 1.16)
|
85
84
|
treetop (~> 1.4.8)
|
86
|
-
mime-types (1.
|
87
|
-
multi_json (1.0.
|
88
|
-
mysql2 (0.3.
|
85
|
+
mime-types (1.17.2)
|
86
|
+
multi_json (1.0.4)
|
87
|
+
mysql2 (0.3.11)
|
89
88
|
nokogiri (1.5.0)
|
90
|
-
pickle (0.4.
|
89
|
+
pickle (0.4.10)
|
91
90
|
cucumber (>= 0.8)
|
92
91
|
rake
|
93
|
-
polyglot (0.3.
|
94
|
-
rack (1.3.
|
92
|
+
polyglot (0.3.3)
|
93
|
+
rack (1.3.6)
|
95
94
|
rack-cache (1.0.3)
|
96
95
|
rack (>= 0.4)
|
97
96
|
rack-mount (0.8.3)
|
@@ -115,44 +114,44 @@ GEM
|
|
115
114
|
rake (>= 0.8.7)
|
116
115
|
rdoc (~> 3.4)
|
117
116
|
thor (~> 0.14.6)
|
118
|
-
rake (0.9.2)
|
119
|
-
rdoc (3.
|
120
|
-
|
121
|
-
|
122
|
-
rspec-
|
123
|
-
rspec-
|
124
|
-
|
125
|
-
rspec-
|
117
|
+
rake (0.9.2.2)
|
118
|
+
rdoc (3.12)
|
119
|
+
json (~> 1.4)
|
120
|
+
rspec (2.8.0)
|
121
|
+
rspec-core (~> 2.8.0)
|
122
|
+
rspec-expectations (~> 2.8.0)
|
123
|
+
rspec-mocks (~> 2.8.0)
|
124
|
+
rspec-core (2.8.0)
|
125
|
+
rspec-expectations (2.8.0)
|
126
126
|
diff-lcs (~> 1.1.2)
|
127
|
-
rspec-mocks (2.
|
128
|
-
rspec-rails (2.
|
129
|
-
actionpack (
|
130
|
-
activesupport (
|
131
|
-
railties (
|
132
|
-
rspec (~> 2.
|
133
|
-
rubyzip (0.9.
|
134
|
-
selenium-webdriver (2.
|
135
|
-
childprocess (>= 0.2.
|
136
|
-
ffi (
|
137
|
-
|
127
|
+
rspec-mocks (2.8.0)
|
128
|
+
rspec-rails (2.8.1)
|
129
|
+
actionpack (>= 3.0)
|
130
|
+
activesupport (>= 3.0)
|
131
|
+
railties (>= 3.0)
|
132
|
+
rspec (~> 2.8.0)
|
133
|
+
rubyzip (0.9.5)
|
134
|
+
selenium-webdriver (2.16.0)
|
135
|
+
childprocess (>= 0.2.5)
|
136
|
+
ffi (~> 1.0.9)
|
137
|
+
multi_json (~> 1.0.4)
|
138
138
|
rubyzip
|
139
139
|
spork (0.8.5)
|
140
|
-
sprockets (2.0.
|
140
|
+
sprockets (2.0.3)
|
141
141
|
hike (~> 1.2)
|
142
142
|
rack (~> 1.0)
|
143
|
-
tilt (
|
144
|
-
|
145
|
-
sqlite3 (1.3.4)
|
143
|
+
tilt (~> 1.1, != 1.3.0)
|
144
|
+
sqlite3 (1.3.5)
|
146
145
|
sqlite3-ruby (1.3.3)
|
147
146
|
sqlite3 (>= 1.3.3)
|
148
|
-
term-ansicolor (1.0.
|
147
|
+
term-ansicolor (1.0.7)
|
149
148
|
thor (0.14.6)
|
150
149
|
tilt (1.3.3)
|
151
150
|
treetop (1.4.10)
|
152
151
|
polyglot
|
153
152
|
polyglot (>= 0.3.1)
|
154
|
-
tzinfo (0.3.
|
155
|
-
will_paginate (3.0.
|
153
|
+
tzinfo (0.3.31)
|
154
|
+
will_paginate (3.0.2)
|
156
155
|
xpath (0.1.4)
|
157
156
|
nokogiri (~> 1.3)
|
158
157
|
|
@@ -7,12 +7,14 @@
|
|
7
7
|
# Mayor.create(:name => 'Daley', :city => cities.first)
|
8
8
|
|
9
9
|
Role.delete_all
|
10
|
+
puts "Creating roles..."
|
10
11
|
Role.create([
|
11
12
|
{:name => "writer"},
|
12
13
|
{:name => "reader"}
|
13
14
|
])
|
14
15
|
|
15
16
|
User.delete_all
|
17
|
+
puts "Creating users..."
|
16
18
|
User.create([
|
17
19
|
{:first_name => "Mark", :last_name => "Twain", :role => Role.find_by_name("writer")},
|
18
20
|
{:first_name => "Carlos", :last_name => "Castaneda", :role => Role.find_by_name("writer")},
|
@@ -21,6 +23,7 @@ User.create([
|
|
21
23
|
])
|
22
24
|
|
23
25
|
Author.delete_all
|
26
|
+
puts "Creating authors..."
|
24
27
|
Author.create([
|
25
28
|
{:first_name => "Carlos", :last_name => "Castaneda"},
|
26
29
|
{:first_name => "Herman", :last_name => "Hesse"}
|
@@ -30,6 +33,7 @@ Book.delete_all
|
|
30
33
|
|
31
34
|
hesse = Author.find_by_last_name("Hesse")
|
32
35
|
castaneda = Author.find_by_last_name("Castaneda")
|
36
|
+
puts "Creating books..."
|
33
37
|
Book.create([
|
34
38
|
{:title => "Journey to Ixtlan", :author => castaneda},
|
35
39
|
{:title => "The Tales of Power", :author => castaneda},
|
@@ -13,9 +13,9 @@ Scenario: UserForm should be rendered properly along with the data for the first
|
|
13
13
|
|
14
14
|
@javascript
|
15
15
|
Scenario: A form should be rendered properly along with the data for the specified record
|
16
|
-
Given a book exists with title: "Great Book", last_read_at: "2005-01-23"
|
16
|
+
Given a book exists with title: "Great Book", last_read_at: "2005-01-23 11:12:13"
|
17
17
|
When I go to the BookFormWithDefaults test page
|
18
|
-
Then the form should show title: "Great Book", last_read_at: "2005-01-23"
|
18
|
+
Then the form should show title: "Great Book", last_read_at: "2005-01-23 11:12:13"
|
19
19
|
|
20
20
|
@javascript
|
21
21
|
Scenario: Editing the record
|
@@ -115,7 +115,16 @@ Scenario: Editing and immediately submitting the form
|
|
115
115
|
Scenario: Setting date
|
116
116
|
Given a book exists with title: "Some Title"
|
117
117
|
When I go to the BookFormWithDefaults test page
|
118
|
-
Then I fill in "
|
118
|
+
Then I fill in "Published on" with "2005-01-23"
|
119
119
|
And I press "Apply"
|
120
120
|
And I wait for the response from the server
|
121
|
-
Then a book should exist with
|
121
|
+
Then a book should exist with published_on: "2005-01-23"
|
122
|
+
|
123
|
+
@javascript
|
124
|
+
Scenario: Setting datetime
|
125
|
+
Given a book exists with title: "Some Title"
|
126
|
+
When I go to the BookFormWithDefaults test page
|
127
|
+
Then I fill in Ext field "Last read at" with "2005-01-23 11:12:13"
|
128
|
+
And I press "Apply"
|
129
|
+
And I wait for the response from the server
|
130
|
+
Then a book should exist with last_read_at: "2005-01-23 11:12:13"
|
@@ -4,13 +4,13 @@ Feature: Grid panel
|
|
4
4
|
I want feature
|
5
5
|
|
6
6
|
@javascript
|
7
|
-
Scenario:
|
7
|
+
Scenario: BookGrid should correctly display data
|
8
8
|
Given an author exists with first_name: "Vladimir", last_name: "Nabokov"
|
9
|
-
And a book exists with author: that author, title: "Lolita", last_read_at: "2011-12-13", published_on: "2005-01-30"
|
9
|
+
And a book exists with author: that author, title: "Lolita", last_read_at: "2011-12-13 11:12:13", published_on: "2005-01-30"
|
10
10
|
|
11
11
|
When I go to the BookGrid test page
|
12
12
|
Then I should see "Nabokov, Vladimir"
|
13
|
-
And I should see "12
|
13
|
+
And I should see "2011-12-13 11:12:13"
|
14
14
|
And I should see "01/30/2005"
|
15
15
|
|
16
16
|
@javascript
|
@@ -235,6 +235,12 @@ Scenario: GridPanel with overridden columns
|
|
235
235
|
Then I should see "LOLITA"
|
236
236
|
And I should see "Nabokov, Vladimir"
|
237
237
|
|
238
|
+
@javascript
|
239
|
+
Scenario: Virtual attributes should not be sortable
|
240
|
+
Given a book exists with title: "Some Title"
|
241
|
+
When I go to the BookGridWithVirtualAttributes test page
|
242
|
+
Then the grid's column "In abundance" should not be sortable
|
243
|
+
|
238
244
|
@javascript
|
239
245
|
Scenario: Virtual attributes should not be editable
|
240
246
|
Given a book exists with title: "Some Title"
|
@@ -248,4 +254,4 @@ Scenario: GridPanel with overridden columns
|
|
248
254
|
And I click the "Delete row" action icon
|
249
255
|
And I press "Yes"
|
250
256
|
Then I should see "Deleted 1 record(s)"
|
251
|
-
And a book should not exist with title: "Some Title"
|
257
|
+
And a book should not exist with title: "Some Title"
|
@@ -23,8 +23,24 @@ Then /the form should show #{capture_fields}$/ do |fields|
|
|
23
23
|
var form = Ext.ComponentQuery.query('form')[0].getForm();
|
24
24
|
var values = {#{fields}};
|
25
25
|
for (var fieldName in values) {
|
26
|
-
|
26
|
+
var field = form.findField(fieldName);
|
27
|
+
|
28
|
+
if (field.getXType() == 'xdatetime') {
|
29
|
+
// Treat xdatetime specially
|
30
|
+
var oldValue = field.getValue();
|
31
|
+
field.setValue(values[fieldName]);
|
32
|
+
return oldValue == field.getValue();
|
33
|
+
} else {
|
34
|
+
return (field.getValue() == values[fieldName] || field.getRawValue() == values[fieldName]);
|
35
|
+
}
|
27
36
|
}
|
28
37
|
return true;
|
29
38
|
JS
|
30
39
|
end
|
40
|
+
|
41
|
+
Then /^I fill in Ext field "([^"]*)" with "([^"]*)"$/ do |field_label, value|
|
42
|
+
page.driver.browser.execute_script <<-JS
|
43
|
+
var field = Ext.ComponentQuery.query("[fieldLabel='#{field_label}']")[0];
|
44
|
+
field.setValue("#{value}");
|
45
|
+
JS
|
46
|
+
end
|
@@ -165,6 +165,14 @@ Then /^the grid should have records sorted by "([^"]*)"\s?(asc|desc)?$/ do |colu
|
|
165
165
|
JS
|
166
166
|
end
|
167
167
|
|
168
|
+
Then /^the grid's column "([^"]*)" should not be sortable$/ do |column_name|
|
169
|
+
column = column_name.downcase.gsub(' ', '_')
|
170
|
+
page.driver.browser.execute_script(<<-JS).should_not be_true
|
171
|
+
var col = Ext.ComponentQuery.query('gridcolumn[name="#{column}"]')[0];
|
172
|
+
return col.sortable;
|
173
|
+
JS
|
174
|
+
end
|
175
|
+
|
168
176
|
Then /^the grid's column "([^"]*)" should not be editable$/ do |column_name|
|
169
177
|
column = column_name.downcase.gsub(' ', '_')
|
170
178
|
page.driver.browser.execute_script(<<-JS).should be_true
|
@@ -175,4 +183,4 @@ end
|
|
175
183
|
|
176
184
|
When /^I click the "([^"]*)" action icon$/ do |action_name|
|
177
185
|
find("img[data-qtip='#{action_name}']").click
|
178
|
-
end
|
186
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netzke-basepack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: netzke-core
|
16
|
-
requirement: &
|
16
|
+
requirement: &70335624108560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.7.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70335624108560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: will_paginate
|
27
|
-
requirement: &
|
27
|
+
requirement: &70335624108080 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.0.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70335624108080
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: acts_as_list
|
38
|
-
requirement: &
|
38
|
+
requirement: &70335624107600 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 0.1.4
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70335624107600
|
47
47
|
description: A set of full-featured extendible Netzke components (such as FormPanel,
|
48
48
|
GridPanel, Window, BorderLayoutPanel, etc) which can be used as building block for
|
49
49
|
your RIA
|
@@ -66,7 +66,7 @@ files:
|
|
66
66
|
- init.rb
|
67
67
|
- install.rb
|
68
68
|
- javascripts/basepack.js
|
69
|
-
- javascripts/
|
69
|
+
- javascripts/xdatetime.js
|
70
70
|
- lib/generators/netzke/basepack_generator.rb
|
71
71
|
- lib/generators/netzke/templates/assets/ts-checkbox.gif
|
72
72
|
- lib/generators/netzke/templates/create_netzke_field_lists.rb
|
@@ -329,7 +329,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
329
329
|
version: '0'
|
330
330
|
requirements: []
|
331
331
|
rubyforge_project:
|
332
|
-
rubygems_version: 1.8.
|
332
|
+
rubygems_version: 1.8.10
|
333
333
|
signing_key:
|
334
334
|
specification_version: 3
|
335
335
|
summary: Pre-built Rails + ExtJS components for your RIA
|
@@ -1,24 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Ext.ux.DateTimePicker & Ext.ux.form.DateTimeField
|
3
|
-
* http://www.sencha.com/forum/showthread.php?98292-DateTime-field-again-and-again-)
|
4
|
-
* Copyright(c) 2011, Andrew Pleshkov andrew.pleshkov@gmail.com
|
5
|
-
*
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
11
|
-
* furnished to do so, subject to the following conditions:
|
12
|
-
*
|
13
|
-
* The above copyright notice and this permission notice shall be included in
|
14
|
-
* all copies or substantial portions of the Software.
|
15
|
-
*
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
* THE SOFTWARE.
|
23
|
-
*/
|
24
|
-
Ext.namespace("Ext.ux");(function(){var a=Ext.ux;a.BaseTimePicker=Ext.extend(Ext.Panel,{timeFormat:"g:i A",header:true,nowText:"Now",doneText:"Done",hourIncrement:1,minIncrement:1,hoursLabel:"Hours",minsLabel:"Minutes",cls:"ux-base-time-picker",width:210,layout:"form",labelAlign:"top",initComponent:function(){this.addEvents("select");this.hourSlider=new Ext.slider.SingleSlider({increment:this.hourIncrement,minValue:0,maxValue:23,fieldLabel:this.hoursLabel,listeners:{change:this._updateTimeValue,scope:this},plugins:new Ext.slider.Tip()});this.minSlider=new Ext.slider.SingleSlider({increment:this.minIncrement,minValue:0,maxValue:59,fieldLabel:this.minsLabel,listeners:{change:this._updateTimeValue,scope:this},plugins:new Ext.slider.Tip()});this.setCurrentTime(false);this.items=[this.hourSlider,this.minSlider];this.bbar=[{text:this.nowText,handler:this.setCurrentTime,scope:this},"->",{text:this.doneText,handler:this.onDone,scope:this}];a.BaseTimePicker.superclass.initComponent.call(this)},setCurrentTime:function(b){this.setValue(new Date(),!!b)},onDone:function(){this.fireEvent("select",this,this.getValue())},setValue:function(c,b){this.hourSlider.setValue(c.getHours(),b);this.minSlider.setValue(c.getMinutes(),b);this._updateTimeValue()},_extractValue:function(){var b=new Date();b.setHours(this.hourSlider.getValue());b.setMinutes(this.minSlider.getValue());return b},getValue:function(){return this._extractValue()},_updateTimeValue:function(){var b=this._extractValue().format(this.timeFormat);if(this.rendered){this.setTitle(b)}},afterRender:function(){a.BaseTimePicker.superclass.afterRender.call(this);this._updateTimeValue()},destroy:function(){this.purgeListeners();this.hourSlider=null;this.minSlider=null;a.BaseTimePicker.superclass.destroy.call(this)}});Ext.reg("basetimepicker",a.BaseTimePicker)})();Ext.namespace("Ext.ux");(function(){var a=Ext.ux;var c="ux-date-time-picker";a.DateTimePicker=Ext.extend(Ext.BoxComponent,{timeLabel:"Time",timeFormat:"g:i A",changeTimeText:"Change...",doneText:"Done",initComponent:function(){a.DateTimePicker.superclass.initComponent.call(this);this.addEvents("select");this.timePickerButton=new Ext.Button({text:this.changeTimeText,handler:this._showTimePicker,scope:this});this._initDatePicker();this.timeValue=new Date();if(this.value){this.setValue(this.value);delete this.value}},_initTimePicker:function(){if(!this.timeMenu){var d=this.initialConfig.timeMenu;if(d&&d.xtype){this.timeMenu=Ext.create(d)}else{var e=Ext.create(Ext.applyIf(this.initialConfig.timePicker||{},{timeFormat:this.timeFormat}),"basetimepicker");this.timeMenu=new b(e,d||{})}if(!Ext.isFunction(this.timeMenu.getPicker)){throw"Your time menu must provide the getPicker() method"}this.timeMenu.on("timeselect",this.onTimeSelect,this)}},_initDatePicker:function(){var e=this.initialConfig.datePicker||{};e.internalRender=this.initialConfig.internalRender;Ext.applyIf(e,{format:this.dateFormat||Ext.DatePicker.prototype.format});var d=this.datePicker=Ext.create(e,"datepicker");d.update=d.update.createSequence(function(){if(this.el!=null&&this.datePicker.rendered){var f=this.datePicker.el.getWidth();this.el.setWidth(f+this.el.getBorderWidth("lr")+this.el.getPadding("lr"))}},this)},_renderDatePicker:function(g){var e=this.datePicker;e.render(g);var j=e.getEl().child(".x-date-bottom");var f=j.getSize(true);var h=["position: absolute","bottom: 0","left: 0","overflow: hidden","width: "+f.width+"px","height: "+f.height+"px"].join(";");var i=g.createChild({tag:"div",cls:"x-date-bottom",style:h,children:[{tag:"table",cellspacing:0,style:"width: 100%",children:[{tag:"tr",children:[{tag:"td",align:"left"},{tag:"td",align:"right"}]}]}]});if(e.showToday){var d={};Ext.each(["text","tooltip","handler","scope"],function(k){d[k]=e.todayBtn.initialConfig[k]});this.todayBtn=new Ext.Button(d).render(i.child("td:first"))}this.doneBtn=new Ext.Button({text:this.doneText,handler:this.onDone,scope:this}).render(i.child("td:last"))},_getFormattedTimeValue:function(d){return d.format(this.timeFormat)},_renderValueField:function(f){var e=c+"-value-ct";var d=!Ext.isEmpty(this.timeLabel)?'<span class="'+e+'-value-label">'+this.timeLabel+":</span> ":"";var h=f.insertFirst({tag:"div",cls:[e,"x-date-bottom"].join(" ")});var g=h.createChild({tag:"table",cellspacing:0,style:"width: 100%",children:[{tag:"tr",children:[{tag:"td",align:"left",cls:e+"-value-cell",html:'<div class="'+e+'-value-wrap">'+d+'<span class="'+e+'-value">'+this._getFormattedTimeValue(this.timeValue)+"</span></div>"},{tag:"td",align:"right",cls:e+"-btn-cell"}]}]});this.timeValueEl=g.child("."+e+"-value");this.timeValueEl.on("click",this._showTimePicker,this);this.timePickerButton.render(g.child("td:last"))},onRender:function(e,d){this.el=e.createChild({tag:"div",cls:c,children:[{tag:"div",cls:c+"-inner"}]},d);a.DateTimePicker.superclass.onRender.call(this,e,d);var f=this.el.first();this._renderDatePicker(f);this._renderValueField(f)},_updateTimeValue:function(d){this.timeValue=d;if(this.timeValueEl!=null){this.timeValueEl.update(this._getFormattedTimeValue(d))}},setValue:function(d){this._updateTimeValue(d);this.datePicker.setValue(d.clone())},getValue:function(){var d=this.datePicker.getValue();var e=this.timeValue.getElapsed(this.timeValue.clone().clearTime());return new Date(d.getTime()+e)},onTimeSelect:function(f,d,e){this._updateTimeValue(e)},_showTimePicker:function(){this._initTimePicker();this.timeMenu.getPicker().setValue(this.timeValue,false);if(this.timeMenu.isVisible()){this.timeMenu.hide()}else{this.timeMenu.show(this.timePickerButton.el,null,this.parentMenu)}},onDone:function(){this.fireEvent("select",this,this.getValue())},destroy:function(){Ext.destroy(this.timePickerButton);this.timePickerButton=null;if(this.timeValueEl){this.timeValueEl.remove();this.timeValueEl=null}Ext.destroy(this.datePicker);this.datePicker=null;if(this.timeMenu){Ext.destroy(this.timeMenu);this.timeMenu=null}if(this.todayBtn){Ext.destroy(this.todayBtn);this.todayBtn=null}if(this.doneBtn){Ext.destroy(this.doneBtn);this.doneBtn=null}this.parentMenu=null;a.DateTimePicker.superclass.destroy.call(this)}});Ext.reg("datetimepicker",a.DateTimePicker);var b=a.DateTimePicker.Menu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:false,plain:true,showSeparator:false,constructor:function(e,d){d=d||{};if(d.picker){delete d.picker}this.picker=Ext.create(e);b.superclass.constructor.call(this,Ext.applyIf({items:this.picker},d));this.addEvents("timeselect");this.picker.on("select",this.onTimeSelect,this)},getPicker:function(){return this.picker},onTimeSelect:function(d,e){this.hide();this.fireEvent("timeselect",this,d,e)},destroy:function(){this.purgeListeners();this.picker=null;b.superclass.destroy.call(this)}})})();Ext.namespace("Ext.ux.form");(function(){var c=Ext.ux.form;var a=Ext.isIE7&&Ext.isStrict;var b=Ext.extend(Ext.menu.Menu,{enableScrolling:false,plain:true,showSeparator:false,hideOnClick:true,pickerId:null,cls:"x-date-menu x-date-time-menu",constructor:function(e,d){b.superclass.constructor.call(this,Ext.applyIf({items:e},d||{}));this.primaryPicker=e;e.parentMenu=this;this.on("beforeshow",this.onBeforeShow,this);this.strict=a;if(this.strict){this.on("show",this.onShow,this,{single:true,delay:20})}this.picker=e.datePicker;this.relayEvents(e,["select"]);this.on("show",e.focus,e);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}},onBeforeShow:function(){if(this.picker){this.picker.hideMonthPicker(true)}},onShow:function(){var d=this.picker.getEl();d.setWidth(d.getWidth())},destroy:function(){this.primaryPicker=null;this.picker=null;b.superclass.destroy.call(this)}});c.DateTimeField=Ext.extend(Ext.form.DateField,{timeFormat:"g:i A",defaultAutoCreate:{tag:"input",type:"text",size:"22",autocomplete:"off"},initComponent:function(){c.DateTimeField.superclass.initComponent.call(this);this.dateFormat=this.dateFormat||this.format;var d=this._createPicker();this.format=this.dateFormat+" "+this.timeFormat;this.menu=new b(d,{hideOnClick:false})},_createPicker:function(){var d=this.initialConfig.picker||{};Ext.apply(d,{ctCls:"x-menu-date-item",internalRender:a||!Ext.isIE});Ext.applyIf(d,{dateFormat:this.dateFormat,timeFormat:this.timeFormat});return Ext.create(d,"datetimepicker")},onTriggerClick:function(){c.DateTimeField.superclass.onTriggerClick.apply(this,arguments);this.menu.primaryPicker.setValue(this.getValue()||new Date())}});Ext.reg("datetimefield",c.DateTimeField)})();
|