diff --git a/app/assets/javascripts/custom_netzke_helpers.js b/app/assets/javascripts/custom_netzke_helpers.js index b46baa7..443ea9e 100644 --- a/app/assets/javascripts/custom_netzke_helpers.js +++ b/app/assets/javascripts/custom_netzke_helpers.js @@ -3,3 +3,150 @@ Ext.Ajax.on('requestexception', function(conn, response, options) { if (response.status === 401) { window.location = '/users/sign_in'; } }, this); +Ext.define('Ext.ux.form.field.ColorCombo', { + extend:'Ext.form.FieldContainer', + mixins:{ + field:'Ext.form.field.Field' + }, + alias: 'widget.xcolorcombo', + + //configurables + combineErrors: true, + msgTarget: 'under', + layout: 'hbox', + readOnly: false, + + // properties + colorValue: null, + /** + * @property dateField + * @type Ext.form.field.Date + */ + colorField: null, + + initComponent: function(){ + var me = this + ,i = 0 + ,key + ,tab; + + me.items = me.items || []; + + me.colorField = Ext.create('Ext.form.field.Trigger', { + flex:1, + isFormField:false, //exclude from field query's + submitValue:false, + readOnly: me.readOnly, + onTriggerClick: function() { + //needs to be called twice because? + me.picker.alignTo(me.colorField.inputEl); + me.picker.show(); + me.picker.alignTo(me.colorField.inputEl); + me.picker.show(); + } + }); + me.items.push(me.colorField); + + me.picker = Ext.create('Ext.picker.Color', { + renderTo: document.body, + floating: true, + hidden: true, + style: { + backgroundColor: "#fff" + }, + listeners: { + scope:this, + select: function(field, value, opts){ + me.setValue(value); + me.picker.hide(); + } + } + }); + me.items.push(me.picker); + + for (; i < me.items.length; i++) { + me.items[i].on('focus', Ext.bind(me.onItemFocus, me)); + me.items[i].on('blur', Ext.bind(me.onItemBlur, me)); + me.items[i].on('specialkey', function(field, event){ + key = event.getKey(); + tab = key == event.TAB; + + if (tab && me.focussedItem == me.dateField) { + event.stopEvent(); + me.timeField.focus(); + return; + } + + me.fireEvent('specialkey', field, event); + }); + } + + me.callParent(); + + // this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not + this.inputEl = { + dom: document.createElement('div'), + swallowEvent:function(){} + }; + + me.initField(); + }, + focus:function(){ + this.callParent(arguments); + this.colorField.focus(); + var me = this; + }, + + onItemFocus:function(item){ + if (this.blurTask){ + this.blurTask.cancel(); + } + this.focussedItem = item; + }, + + onItemBlur:function(item, e){ + var me = this; + if (item != me.focussedItem){ return; } + // 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field + me.blurTask = new Ext.util.DelayedTask(function(){ + me.picker.hide(); + me.fireEvent('blur', me, e); + }); + me.blurTask.delay(100); + }, + + getValue: function(){ + var value = null + ,color = this.colorField.getSubmitValue(); + + if (color){ + value = this.colorField.getValue(); + } + return value; + }, + + getSubmitValue: function(){ +// var value = this.getValue(); +// return value ? Ext.Date.format(value, this.dateTimeFormat) : null; + + var me = this + ,value = me.getValue(); + + return value; + }, + + setValue: function(value){ + this.colorField.setValue(value); + }, + // Bug? A field-mixin submits the data from getValue, not getSubmitValue + getSubmitData: function(){ + var me = this + ,data = null; + + if (!me.disabled && me.submitValue && !me.isFileUpload()) { + data = {}; + data[me.getName()] = '' + me.getSubmitValue(); + } + return data; + } +}); diff --git a/app/components/bikes.rb b/app/components/bikes.rb index 9897742..225c70d 100644 --- a/app/components/bikes.rb +++ b/app/components/bikes.rb @@ -16,7 +16,8 @@ class Bikes < Netzke::Basepack::Grid end } }, - :color, + #needs to have type :action or else won't work in grid, because... netzke + { :name => "color", :text => "Frame Color", :type => :action, :editor => { :xtype => "xcolorcombo"}, :renderer => :color_block}, { :name => :bike_style__style, :text => 'Style' }, { :name => :seat_tube_height, :text => 'Seat Tube (in)'}, { :name => :top_tube_length, :text => 'Top Tube (in)'}, @@ -32,6 +33,23 @@ class Bikes < Netzke::Basepack::Grid ] end + def default_fields_for_forms + [ + { :name => :shop_id, :field_label => 'Shop ID'}, + :serial_number, + { :name => :bike_brand__brand, :field_label => 'Brand' }, + { :name => :bike_model__model, :field_label => 'Model'}, + { :name => "color", :xtype => "xcolorcombo"}, + { :name => :bike_style__style, :field_label => 'Style' }, + { :name => :seat_tube_height, :field_label => 'Seat Tube (in)'}, + { :name => :top_tube_length, :field_label => 'Top Tube (in)'}, + { :name => :wheel_size, :field_label => 'Wheel Size (in)'}, + :value, + { :name => :bike_condition__condition, :field_label => 'Condition'}, + { :name => :bike_status__status, :field_label => 'Status'} + ] + end + #override with nil to remove actions def default_bbar [ :apply, :add_in_form, :search ] diff --git a/app/components/bikes/javascripts/init_component.js b/app/components/bikes/javascripts/init_component.js index 402ef15..e152db1 100644 --- a/app/components/bikes/javascripts/init_component.js +++ b/app/components/bikes/javascripts/init_component.js @@ -9,5 +9,8 @@ // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! this.selectBikeBrand({bike_brand_id: record.get('bike_brand__brand')}); }, this); + }, + colorBlock: function(value){ + return Ext.String.format('
{1}
', value, value); } }