netzke-basepack 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG.rdoc +17 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +3 -0
  4. data/TODO.rdoc +1 -4
  5. data/features/form_panel.feature +2 -1
  6. data/features/grid_panel.feature +134 -5
  7. data/features/nested_attributes.feature +4 -1
  8. data/features/paging_form_panel.feature +41 -0
  9. data/features/search_in_grid.feature +20 -7
  10. data/features/step_definitions/form_panel_steps.rb +35 -0
  11. data/features/step_definitions/generic_steps.rb +20 -1
  12. data/features/step_definitions/grid_panel_steps.rb +63 -0
  13. data/features/support/env.rb +4 -0
  14. data/features/validations_in_grid.feature +13 -0
  15. data/features/virtual_attributes.feature +5 -9
  16. data/javascripts/basepack.js +21 -650
  17. data/javascripts/datetimefield.js +24 -0
  18. data/lib/generators/netzke/basepack_generator.rb +10 -0
  19. data/{generators/netzke_basepack/templates/public_assets → lib/generators/netzke/templates/assets}/ts-checkbox.gif +0 -0
  20. data/{generators/netzke_basepack → lib/generators/netzke}/templates/create_netzke_field_lists.rb +0 -0
  21. data/lib/netzke-basepack.rb +3 -41
  22. data/lib/netzke/active_record/attributes.rb +17 -21
  23. data/lib/netzke/basepack.rb +6 -1
  24. data/lib/netzke/basepack/data_accessor.rb +166 -0
  25. data/lib/netzke/basepack/form_panel.rb +69 -20
  26. data/lib/netzke/basepack/form_panel/fields.rb +15 -17
  27. data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +7 -0
  28. data/lib/netzke/basepack/form_panel/javascripts/display_mode.js +6 -0
  29. data/lib/netzke/basepack/form_panel/javascripts/{main.js → form_panel.js} +42 -8
  30. data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +24 -7
  31. data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +52 -0
  32. data/lib/netzke/basepack/form_panel/services.rb +28 -2
  33. data/lib/netzke/basepack/form_panel/stylesheets/readonly_mode.css +14 -0
  34. data/lib/netzke/basepack/grid_panel.rb +151 -181
  35. data/lib/netzke/basepack/grid_panel/columns.rb +122 -84
  36. data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +22 -27
  37. data/lib/netzke/basepack/grid_panel/javascripts/{main.js → grid_panel.js} +182 -108
  38. data/lib/netzke/basepack/grid_panel/record_form_window.rb +7 -2
  39. data/lib/netzke/basepack/grid_panel/services.rb +58 -39
  40. data/lib/netzke/basepack/paging_form_panel.rb +86 -25
  41. data/lib/netzke/basepack/query_builder.rb +105 -0
  42. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +140 -0
  43. data/lib/netzke/basepack/search_panel.rb +61 -44
  44. data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +153 -0
  45. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +64 -0
  46. data/lib/netzke/basepack/search_window.rb +64 -0
  47. data/lib/netzke/basepack/simple_app.rb +1 -1
  48. data/lib/netzke/basepack/simple_app/javascripts/{main.js → simple_app.js} +0 -0
  49. data/lib/netzke/basepack/tab_panel.rb +1 -2
  50. data/lib/netzke/basepack/tab_panel/javascripts/{main.js → tab_panel.js} +0 -0
  51. data/lib/netzke/basepack/version.rb +1 -1
  52. data/locales/en.yml +71 -4
  53. data/netzke-basepack.gemspec +47 -22
  54. data/spec/active_record/attributes_spec.rb +6 -6
  55. data/spec/components/form_panel_spec.rb +2 -13
  56. data/stylesheets/datetimefield.css +54 -0
  57. data/test/rails_app/Gemfile +3 -3
  58. data/test/rails_app/Gemfile.lock +67 -57
  59. data/test/rails_app/README +1 -256
  60. data/test/rails_app/app/components/book_form.rb +1 -3
  61. data/test/rails_app/app/components/book_form_with_custom_fields.rb +20 -0
  62. data/test/rails_app/app/components/book_form_with_nested_attributes.rb +18 -0
  63. data/test/rails_app/app/components/book_grid.rb +3 -1
  64. data/test/rails_app/app/components/book_grid_loader.rb +24 -0
  65. data/test/rails_app/app/components/book_grid_with_custom_columns.rb +28 -0
  66. data/test/rails_app/app/components/book_grid_with_default_values.rb +1 -1
  67. data/test/rails_app/app/components/book_grid_with_virtual_attributes.rb +0 -1
  68. data/test/rails_app/app/components/book_paging_form_panel.rb +3 -2
  69. data/test/rails_app/app/components/book_presentation.rb +3 -3
  70. data/test/rails_app/app/components/book_query_builder.rb +8 -0
  71. data/test/rails_app/app/components/book_search_panel.rb +5 -0
  72. data/test/rails_app/app/components/book_search_panel/javascripts/i18n_de.js +6 -0
  73. data/test/rails_app/app/components/double_book_grid.rb +18 -0
  74. data/test/rails_app/app/components/form_without_model.rb +1 -1
  75. data/test/rails_app/app/components/paging_form_with_search.rb +39 -0
  76. data/test/rails_app/app/components/user_grid.rb +1 -1
  77. data/test/rails_app/app/models/author.rb +1 -0
  78. data/test/rails_app/config/application.rb +6 -1
  79. data/test/rails_app/config/database.yml +7 -5
  80. data/test/rails_app/config/environments/test.rb +1 -1
  81. data/test/rails_app/config/locales/de.yml +35 -0
  82. data/test/rails_app/config/locales/es.yml +84 -8
  83. data/test/rails_app/db/migrate/20101026190021_create_books.rb +2 -2
  84. data/test/rails_app/db/migrate/20110213213050_create_netzke_component_states.rb +20 -0
  85. data/test/rails_app/db/schema.rb +2 -18
  86. data/test/rails_app/public/netzke/basepack/ts-checkbox.gif +0 -0
  87. data/test/unit/active_record_basepack_test.rb +1 -1
  88. metadata +46 -45
  89. data/generators/netzke_basepack/netzke_basepack_generator.rb +0 -13
  90. data/lib/netzke/basepack/grid_panel/search_window.rb +0 -56
  91. data/lib/netzke/data_accessor.rb +0 -113
  92. data/lib/netzke/ext.rb +0 -7
  93. data/lib/netzke/fields_configurator.rb +0 -170
  94. data/lib/netzke/json_array_editor.rb +0 -67
  95. data/lib/netzke/masquerade_selector.rb +0 -53
  96. data/test/rails_app/app/components/some_search_panel.rb +0 -34
  97. data/test/rails_app/db/development_structure.sql +0 -93
  98. data/test/rails_app/db/migrate/20100905214933_create_netzke_preferences.rb +0 -16
@@ -25,6 +25,10 @@ require 'capybara/cucumber'
25
25
  require 'capybara/session'
26
26
  require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
27
27
 
28
+ Capybara.register_driver :selenium do |app|
29
+ Capybara::Driver::Selenium.new(app, {:profile => 'selenium' } )
30
+ end
31
+
28
32
  # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
29
33
  # order to ease the transition to Capybara we set the default here. If you'd
30
34
  # prefer to use XPath just remove this line and adjust any selectors in your
@@ -0,0 +1,13 @@
1
+ Feature: Validations in grid
2
+ In order to value
3
+ As a role
4
+ I want feature
5
+
6
+ # @javascript
7
+ # Scenario: Multi-editing in grid with some records invalid
8
+ # Given an author exists with first_name: "Vladimir", last_name: "Nabokov"
9
+ # And a book exists with title: "Lolita", author: that author
10
+ # And an author exists with first_name: "Carlos", last_name: "Castaneda"
11
+ # And a book exists with title: "Luzhin Defence", author: that author
12
+ # When I go to the BookGridWithCustomColumns test page
13
+ #
@@ -4,17 +4,13 @@ Feature: Window component loader
4
4
  I want feature
5
5
 
6
6
  @javascript
7
- Scenario: Columns and fields with custom setter/getter methods should work as expected
7
+ Scenario: Creating an author on the fly with BookGridWithVirtualAttributes
8
8
  Given an author exists with first_name: "Victor"
9
- And a book exists with title: "Lolita", exemplars: "5", author: that author
9
+ And a book exists with author: that author, title: "Lolita"
10
10
  And I am on the BookGridWithVirtualAttributes test page
11
11
  Then I should see "Victor"
12
- And I should see "YES"
13
12
 
14
- When I select first row in the grid
15
- And I press "Edit in form"
16
- And I fill in "Author first name" with "Vladimir"
17
- And I fill in "Exemplars" with "3"
18
- And I press "OK"
13
+ When I edit row 1 of the grid with author__first_name: "Vladimir"
14
+ And I press "Apply"
15
+ And I wait for the response from the server
19
16
  Then I should see "Vladimir"
20
- And I should see "NO"
@@ -10,33 +10,36 @@ Ext.netzke.PassField = Ext.extend(Ext.form.TextField, {
10
10
  });
11
11
  Ext.reg('passfield', Ext.netzke.PassField);
12
12
 
13
+ Ext.override(Ext.ux.form.DateTimeField, {
14
+ format: "Y-m-d",
15
+ timeFormat: "g:i:s",
16
+ picker: {
17
+ minIncremenet: 15
18
+ }
19
+ });
20
+
13
21
  // ComboBox that gets options from the server (used in both grids and panels)
14
22
  Ext.netzke.ComboBox = Ext.extend(Ext.form.ComboBox, {
15
- displayField : 'id',
16
- valueField : 'id',
23
+ valueField : 'field1',
24
+ displayField : 'field2',
17
25
  triggerAction : 'all',
18
26
  typeAhead : true,
19
27
 
20
28
  initComponent : function(){
21
- var row = Ext.data.Record.create([{name:'id'}]);
29
+ var row = Ext.data.Record.create(['field1', 'field2']); // defaults for local ComboBox; makes testing easier
22
30
  var store = new Ext.data.Store({
23
- proxy : new Ext.data.HttpProxy({url: Ext.getCmp(this.parentId).endpointUrl("get_combobox_options"), jsonData:{column:this.name}}),
31
+ proxy : new Ext.data.DirectProxy({directFn: Netzke.providers[this.parentId].getComboboxOptions}),
24
32
  reader : new Ext.data.ArrayReader({root:'data', id:0}, row)
25
33
  });
34
+ store.proxy.on('beforeload', function (self, params) {
35
+ params.column = this.name;
36
+ },this);
26
37
 
27
- Ext.apply(this, {
28
- store : store
29
- });
30
-
31
- Ext.netzke.ComboBox.superclass.initComponent.apply(this, arguments);
38
+ if (this.store) store.loadData({data: this.store});
32
39
 
33
- this.on('blur', function(cb){
34
- cb.setValue(cb.getRawValue());
35
- });
40
+ this.store = store;
36
41
 
37
- this.on('specialkey', function(cb, event){
38
- if (event.getKey() == 9 || event.getKey() == 13) {cb.setValue(cb.getRawValue());}
39
- });
42
+ Ext.netzke.ComboBox.superclass.initComponent.apply(this, arguments);
40
43
 
41
44
  var parent = Ext.getCmp(this.parentId);
42
45
  // Is parent a grid?
@@ -50,7 +53,7 @@ Ext.netzke.ComboBox = Ext.extend(Ext.form.ComboBox, {
50
53
  store.on('beforeload',function(store, options){
51
54
  if (parent.getSelectionModel) {
52
55
  var selected = parent.getSelectionModel().getSelected();
53
- if (selected) options.params.id = selected.get('id');
56
+ if (selected) options.params.id = selected.id;
54
57
  } else {
55
58
  // TODO: also for the FormPanel
56
59
  }
@@ -58,7 +61,7 @@ Ext.netzke.ComboBox = Ext.extend(Ext.form.ComboBox, {
58
61
  }
59
62
  });
60
63
 
61
- Ext.reg('combobox', Ext.netzke.ComboBox);
64
+ Ext.reg('netzkeremotecombo', Ext.netzke.ComboBox);
62
65
 
63
66
  Ext.util.Format.mask = function(v){
64
67
  return "********";
@@ -82,639 +85,6 @@ Ext.netzke.JsonField = Ext.extend(Ext.form.TextField, {
82
85
 
83
86
  Ext.reg('jsonfield', Ext.netzke.JsonField);
84
87
 
85
- /**
86
- * @class Ext.ux.form.DateTime
87
- * @extends Ext.form.Field
88
- *
89
- * DateTime field, combination of DateField and TimeField
90
- *
91
- * @author Ing. Jozef Sak�lo�
92
- * @copyright (c) 2008, Ing. Jozef Sak�lo�
93
- * @version 2.0
94
- * @revision $Id: Ext.ux.form.DateTime.js 513 2009-01-29 19:59:22Z jozo $
95
- *
96
- * @license Ext.ux.form.DateTime is licensed under the terms of
97
- * the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
98
- * that the code/component(s) do NOT become part of another Open Source or Commercially
99
- * licensed development library or toolkit without explicit permission.
100
- *
101
- * <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html"
102
- * target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p>
103
- *
104
- * @forum 22661
105
- */
106
-
107
- Ext.ns('Ext.ux.form');
108
-
109
- /**
110
- * @constructor
111
- * Creates new DateTime
112
- * @param {Object} config The config object
113
- */
114
- Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
115
- /**
116
- * @cfg {String/Object} defaultAutoCreate DomHelper element spec
117
- * Let superclass to create hidden field instead of textbox. Hidden will be submittend to server
118
- */
119
- defaultAutoCreate:{tag:'input', type:'hidden'}
120
- /**
121
- * @cfg {Number} timeWidth Width of time field in pixels (defaults to 100)
122
- */
123
- ,timeWidth:80
124
- /**
125
- * @cfg {String} dtSeparator Date - Time separator. Used to split date and time (defaults to ' ' (space))
126
- */
127
- ,dtSeparator:' '
128
- /**
129
- * @cfg {String} hiddenFormat Format of datetime used to store value in hidden field
130
- * and submitted to server (defaults to 'Y-m-d H:i:s' that is mysql format)
131
- */
132
- ,hiddenFormat:'Y-m-d H:i:s'
133
- /**
134
- * @cfg {Boolean} otherToNow Set other field to now() if not explicly filled in (defaults to true)
135
- */
136
- ,otherToNow:true
137
- /**
138
- * @cfg {Boolean} emptyToNow Set field value to now on attempt to set empty value.
139
- * If it is true then setValue() sets value of field to current date and time (defaults to false)
140
- */
141
- /**
142
- * @cfg {String} timePosition Where the time field should be rendered. 'right' is suitable for forms
143
- * and 'below' is suitable if the field is used as the grid editor (defaults to 'right')
144
- */
145
- ,timePosition:'right' // valid values:'below', 'right'
146
- /**
147
- * @cfg {String} dateFormat Format of DateField. Can be localized. (defaults to 'm/y/d')
148
- */
149
- ,dateFormat:'m/d/y'
150
- /**
151
- * @cfg {String} timeFormat Format of TimeField. Can be localized. (defaults to 'g:i A')
152
- */
153
- ,timeFormat:'g:i A'
154
- /**
155
- * @cfg {Object} dateConfig Config for DateField constructor.
156
- */
157
- /**
158
- * @cfg {Object} timeConfig Config for TimeField constructor.
159
- */
160
-
161
- // {{{
162
- /**
163
- * @private
164
- * creates DateField and TimeField and installs the necessary event handlers
165
- */
166
- ,initComponent:function() {
167
- // call parent initComponent
168
- Ext.ux.form.DateTime.superclass.initComponent.call(this);
169
-
170
- // create DateField
171
- var dateConfig = Ext.apply({}, {
172
- id:this.id + '-date'
173
- ,format:this.dateFormat || Ext.form.DateField.prototype.format
174
- ,width:this.timeWidth
175
- ,selectOnFocus:this.selectOnFocus
176
- ,listeners:{
177
- blur:{scope:this, fn:this.onBlur}
178
- ,focus:{scope:this, fn:this.onFocus}
179
- }
180
- }, this.dateConfig);
181
- this.df = new Ext.form.DateField(dateConfig);
182
- this.df.ownerCt = this;
183
- delete(this.dateFormat);
184
-
185
-
186
- // create TimeField
187
- var timeConfig = Ext.apply({}, {
188
- id:this.id + '-time'
189
- ,format:this.timeFormat || Ext.form.TimeField.prototype.format
190
- ,width:this.timeWidth
191
- ,selectOnFocus:this.selectOnFocus
192
- ,listeners:{
193
- blur:{scope:this, fn:this.onBlur}
194
- ,focus:{scope:this, fn:this.onFocus}
195
- }
196
- }, this.timeConfig);
197
- this.tf = new Ext.form.TimeField(timeConfig);
198
- this.tf.ownerCt = this;
199
- delete(this.timeFormat);
200
-
201
- // relay events
202
- this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);
203
- this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);
204
-
205
- } // eo function initComponent
206
- // }}}
207
- // {{{
208
- /**
209
- * @private
210
- * Renders underlying DateField and TimeField and provides a workaround for side error icon bug
211
- */
212
- ,onRender:function(ct, position) {
213
- // don't run more than once
214
- if(this.isRendered) {
215
- return;
216
- }
217
-
218
- // render underlying hidden field
219
- Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);
220
-
221
- // render DateField and TimeField
222
- // create bounding table
223
- var t;
224
- if('below' === this.timePosition || 'bellow' === this.timePosition) {
225
- t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
226
- {tag:'tr',children:[{tag:'td', style:'padding-bottom:1px', cls:'ux-datetime-date'}]}
227
- ,{tag:'tr',children:[{tag:'td', cls:'ux-datetime-time'}]}
228
- ]}, true);
229
- }
230
- else {
231
- t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
232
- {tag:'tr',children:[
233
- {tag:'td',style:'padding-right:4px', cls:'ux-datetime-date'},{tag:'td', cls:'ux-datetime-time'}
234
- ]}
235
- ]}, true);
236
- }
237
-
238
- this.tableEl = t;
239
- // this.wrap = t.wrap({cls:'x-form-field-wrap'});
240
- this.wrap = t.wrap();
241
- this.wrap.on("mousedown", this.onMouseDown, this, {delay:10});
242
-
243
- // render DateField & TimeField
244
- this.df.render(t.child('td.ux-datetime-date'));
245
- this.tf.render(t.child('td.ux-datetime-time'));
246
-
247
- // workaround for IE trigger misalignment bug
248
- if(Ext.isIE && Ext.isStrict) {
249
- t.select('input').applyStyles({top:0});
250
- }
251
-
252
- this.on('specialkey', this.onSpecialKey, this);
253
- this.df.el.swallowEvent(['keydown', 'keypress']);
254
- this.tf.el.swallowEvent(['keydown', 'keypress']);
255
-
256
- // create icon for side invalid errorIcon
257
- if('side' === this.msgTarget) {
258
- var elp = this.el.findParent('.x-form-element', 10, true);
259
- this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
260
-
261
- this.df.errorIcon = this.errorIcon;
262
- this.tf.errorIcon = this.errorIcon;
263
- }
264
-
265
- // setup name for submit
266
- this.el.dom.name = this.hiddenName || this.name || this.id;
267
-
268
- // prevent helper fields from being submitted
269
- this.df.el.dom.removeAttribute("name");
270
- this.tf.el.dom.removeAttribute("name");
271
-
272
- // we're rendered flag
273
- this.isRendered = true;
274
-
275
- // update hidden field
276
- this.updateHidden();
277
-
278
- } // eo function onRender
279
- // }}}
280
- // {{{
281
- /**
282
- * @private
283
- */
284
- ,adjustSize:Ext.BoxComponent.prototype.adjustSize
285
- // }}}
286
- // {{{
287
- /**
288
- * @private
289
- */
290
- ,alignErrorIcon:function() {
291
- this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
292
- }
293
- // }}}
294
- // {{{
295
- /**
296
- * @private initializes internal dateValue
297
- */
298
- ,initDateValue:function() {
299
- this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
300
- }
301
- // }}}
302
- // {{{
303
- /**
304
- * Calls clearInvalid on the DateField and TimeField
305
- */
306
- ,clearInvalid:function(){
307
- this.df.clearInvalid();
308
- this.tf.clearInvalid();
309
- } // eo function clearInvalid
310
- // }}}
311
- // {{{
312
- /**
313
- * @private
314
- * called from Component::destroy.
315
- * Destroys all elements and removes all listeners we've created.
316
- */
317
- ,beforeDestroy:function() {
318
- if(this.isRendered) {
319
- // this.removeAllListeners();
320
- this.wrap.removeAllListeners();
321
- this.wrap.remove();
322
- this.tableEl.remove();
323
- this.df.destroy();
324
- this.tf.destroy();
325
- }
326
- } // eo function beforeDestroy
327
- // }}}
328
- // {{{
329
- /**
330
- * Disable this component.
331
- * @return {Ext.Component} this
332
- */
333
- ,disable:function() {
334
- if(this.isRendered) {
335
- this.df.disabled = this.disabled;
336
- this.df.onDisable();
337
- this.tf.onDisable();
338
- }
339
- this.disabled = true;
340
- this.df.disabled = true;
341
- this.tf.disabled = true;
342
- this.fireEvent("disable", this);
343
- return this;
344
- } // eo function disable
345
- // }}}
346
- // {{{
347
- /**
348
- * Enable this component.
349
- * @return {Ext.Component} this
350
- */
351
- ,enable:function() {
352
- if(this.rendered){
353
- this.df.onEnable();
354
- this.tf.onEnable();
355
- }
356
- this.disabled = false;
357
- this.df.disabled = false;
358
- this.tf.disabled = false;
359
- this.fireEvent("enable", this);
360
- return this;
361
- } // eo function enable
362
- // }}}
363
- // {{{
364
- /**
365
- * @private Focus date filed
366
- */
367
- ,focus:function() {
368
- this.df.focus();
369
- } // eo function focus
370
- // }}}
371
- // {{{
372
- /**
373
- * @private
374
- */
375
- ,getPositionEl:function() {
376
- return this.wrap;
377
- }
378
- // }}}
379
- // {{{
380
- /**
381
- * @private
382
- */
383
- ,getResizeEl:function() {
384
- return this.wrap;
385
- }
386
- // }}}
387
- // {{{
388
- /**
389
- * @return {Date/String} Returns value of this field
390
- */
391
- ,getValue:function() {
392
- // create new instance of date
393
- return this.dateValue ? new Date(this.dateValue) : '';
394
- } // eo function getValue
395
- // }}}
396
- // {{{
397
- /**
398
- * @return {Boolean} true = valid, false = invalid
399
- * @private Calls isValid methods of underlying DateField and TimeField and returns the result
400
- */
401
- ,isValid:function() {
402
- return this.df.isValid() && this.tf.isValid();
403
- } // eo function isValid
404
- // }}}
405
- // {{{
406
- /**
407
- * Returns true if this component is visible
408
- * @return {boolean}
409
- */
410
- ,isVisible : function(){
411
- return this.df.rendered && this.df.getActionEl().isVisible();
412
- } // eo function isVisible
413
- // }}}
414
- // {{{
415
- /**
416
- * @private Handles blur event
417
- */
418
- ,onBlur:function(f) {
419
- // called by both DateField and TimeField blur events
420
-
421
- // revert focus to previous field if clicked in between
422
- if(this.wrapClick) {
423
- f.focus();
424
- this.wrapClick = false;
425
- }
426
-
427
- // update underlying value
428
- if(f === this.df) {
429
- this.updateDate();
430
- }
431
- else {
432
- this.updateTime();
433
- }
434
- this.updateHidden();
435
-
436
- // fire events later
437
- (function() {
438
- if(!this.df.hasFocus && !this.tf.hasFocus) {
439
- var v = this.getValue();
440
- if(String(v) !== String(this.startValue)) {
441
- this.fireEvent("change", this, v, this.startValue);
442
- }
443
- this.hasFocus = false;
444
- this.fireEvent('blur', this);
445
- }
446
- }).defer(100, this);
447
-
448
- } // eo function onBlur
449
- // }}}
450
- // {{{
451
- /**
452
- * @private Handles focus event
453
- */
454
- ,onFocus:function() {
455
- if(!this.hasFocus){
456
- this.hasFocus = true;
457
- this.startValue = this.getValue();
458
- this.fireEvent("focus", this);
459
- }
460
- }
461
- // }}}
462
- // {{{
463
- /**
464
- * @private Just to prevent blur event when clicked in the middle of fields
465
- */
466
- ,onMouseDown:function(e) {
467
- if(!this.disabled) {
468
- this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
469
- }
470
- }
471
- // }}}
472
- // {{{
473
- /**
474
- * @private
475
- * Handles Tab and Shift-Tab events
476
- */
477
- ,onSpecialKey:function(t, e) {
478
- var key = e.getKey();
479
- if(key === e.TAB) {
480
- if(t === this.df && !e.shiftKey) {
481
- e.stopEvent();
482
- this.tf.focus();
483
- }
484
- if(t === this.tf && e.shiftKey) {
485
- e.stopEvent();
486
- this.df.focus();
487
- }
488
- }
489
- // otherwise it misbehaves in editor grid
490
- if(key === e.ENTER) {
491
- this.updateValue();
492
- }
493
-
494
- } // eo function onSpecialKey
495
- // }}}
496
- // {{{
497
- /**
498
- * @private Sets the value of DateField
499
- */
500
- ,setDate:function(date) {
501
- this.df.setValue(date);
502
- } // eo function setDate
503
- // }}}
504
- // {{{
505
- /**
506
- * @private Sets the value of TimeField
507
- */
508
- ,setTime:function(date) {
509
- this.tf.setValue(date);
510
- } // eo function setTime
511
- // }}}
512
- // {{{
513
- /**
514
- * @private
515
- * Sets correct sizes of underlying DateField and TimeField
516
- * With workarounds for IE bugs
517
- */
518
- ,setSize:function(w, h) {
519
- if(!w) {
520
- return;
521
- }
522
- if('below' === this.timePosition) {
523
- this.df.setSize(w, h);
524
- this.tf.setSize(w, h);
525
- if(Ext.isIE) {
526
- this.df.el.up('td').setWidth(w);
527
- this.tf.el.up('td').setWidth(w);
528
- }
529
- }
530
- else {
531
- this.df.setSize(w - this.timeWidth - 4, h);
532
- this.tf.setSize(this.timeWidth, h);
533
-
534
- if(Ext.isIE) {
535
- this.df.el.up('td').setWidth(w - this.timeWidth - 4);
536
- this.tf.el.up('td').setWidth(this.timeWidth);
537
- }
538
- }
539
- } // eo function setSize
540
- // }}}
541
- // {{{
542
- /**
543
- * @param {Mixed} val Value to set
544
- * Sets the value of this field
545
- */
546
- ,setValue:function(val) {
547
- if(!val && true === this.emptyToNow) {
548
- this.setValue(new Date());
549
- return;
550
- }
551
- else if(!val) {
552
- this.setDate('');
553
- this.setTime('');
554
- this.updateValue();
555
- return;
556
- }
557
- if ('number' === typeof val) {
558
- val = new Date(val);
559
- }
560
- else if('string' === typeof val && this.hiddenFormat) {
561
- val = Date.parseDate(val, this.hiddenFormat)
562
- }
563
- val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
564
- var da, time;
565
- if(val instanceof Date) {
566
- this.setDate(val);
567
- this.setTime(val);
568
- this.dateValue = new Date(val);
569
- }
570
- else {
571
- da = val.split(this.dtSeparator);
572
- this.setDate(da[0]);
573
- if(da[1]) {
574
- if(da[2]) {
575
- // add am/pm part back to time
576
- da[1] += da[2];
577
- }
578
- this.setTime(da[1]);
579
- }
580
- }
581
- this.updateValue();
582
- } // eo function setValue
583
- // }}}
584
- // {{{
585
- /**
586
- * Hide or show this component by boolean
587
- * @return {Ext.Component} this
588
- */
589
- ,setVisible: function(visible){
590
- if(visible) {
591
- this.df.show();
592
- this.tf.show();
593
- }else{
594
- this.df.hide();
595
- this.tf.hide();
596
- }
597
- return this;
598
- } // eo function setVisible
599
- // }}}
600
- //{{{
601
- ,show:function() {
602
- return this.setVisible(true);
603
- } // eo function show
604
- //}}}
605
- //{{{
606
- ,hide:function() {
607
- return this.setVisible(false);
608
- } // eo function hide
609
- //}}}
610
- // {{{
611
- /**
612
- * @private Updates the date part
613
- */
614
- ,updateDate:function() {
615
-
616
- var d = this.df.getValue();
617
- if(d) {
618
- if(!(this.dateValue instanceof Date)) {
619
- this.initDateValue();
620
- if(!this.tf.getValue()) {
621
- this.setTime(this.dateValue);
622
- }
623
- }
624
- this.dateValue.setMonth(0); // because of leap years
625
- this.dateValue.setFullYear(d.getFullYear());
626
- this.dateValue.setMonth(d.getMonth(), d.getDate());
627
- // this.dateValue.setDate(d.getDate());
628
- }
629
- else {
630
- this.dateValue = '';
631
- this.setTime('');
632
- }
633
- } // eo function updateDate
634
- // }}}
635
- // {{{
636
- /**
637
- * @private
638
- * Updates the time part
639
- */
640
- ,updateTime:function() {
641
- var t = this.tf.getValue();
642
- if(t && !(t instanceof Date)) {
643
- t = Date.parseDate(t, this.tf.format);
644
- }
645
- if(t && !this.df.getValue()) {
646
- this.initDateValue();
647
- this.setDate(this.dateValue);
648
- }
649
- if(this.dateValue instanceof Date) {
650
- if(t) {
651
- this.dateValue.setHours(t.getHours());
652
- this.dateValue.setMinutes(t.getMinutes());
653
- this.dateValue.setSeconds(t.getSeconds());
654
- }
655
- else {
656
- this.dateValue.setHours(0);
657
- this.dateValue.setMinutes(0);
658
- this.dateValue.setSeconds(0);
659
- }
660
- }
661
- } // eo function updateTime
662
- // }}}
663
- // {{{
664
- /**
665
- * @private Updates the underlying hidden field value
666
- */
667
- ,updateHidden:function() {
668
- if(this.isRendered) {
669
- var value = this.dateValue instanceof Date ? this.dateValue.format(this.hiddenFormat) : '';
670
- this.el.dom.value = value;
671
- }
672
- }
673
- // }}}
674
- // {{{
675
- /**
676
- * @private Updates all of Date, Time and Hidden
677
- */
678
- ,updateValue:function() {
679
-
680
- this.updateDate();
681
- this.updateTime();
682
- this.updateHidden();
683
-
684
- return;
685
- } // eo function updateValue
686
- // }}}
687
- // {{{
688
- /**
689
- * @return {Boolean} true = valid, false = invalid
690
- * calls validate methods of DateField and TimeField
691
- */
692
- ,validate:function() {
693
- return this.df.validate() && this.tf.validate();
694
- } // eo function validate
695
- // }}}
696
- // {{{
697
- /**
698
- * Returns renderer suitable to render this field
699
- * @param {Object} Column model config
700
- */
701
- ,renderer: function(field) {
702
- var format = field.editor.dateFormat || Ext.ux.form.DateTime.prototype.dateFormat;
703
- format += ' ' + (field.editor.timeFormat || Ext.ux.form.DateTime.prototype.timeFormat);
704
- var renderer = function(val) {
705
- var retval = Ext.util.Format.date(val, format);
706
- return retval;
707
- };
708
- return renderer;
709
- } // eo function renderer
710
- // }}}
711
-
712
- }); // eo extend
713
-
714
- // register xtype
715
- Ext.reg('xdatetime', Ext.ux.form.DateTime);
716
-
717
- // eof
718
88
  Ext.grid.HeaderDropZone.prototype.onNodeDrop = function(n, dd, e, data){
719
89
  var h = data.header;
720
90
  if(h != n){
@@ -736,6 +106,7 @@ Ext.grid.HeaderDropZone.prototype.onNodeDrop = function(n, dd, e, data){
736
106
  return false;
737
107
  };
738
108
 
109
+
739
110
  Ext.ns('Ext.ux.form');
740
111
  Ext.ux.form.TriCheckbox = Ext.extend(Ext.form.Checkbox, {
741
112
  checked: null,