Frage

Ich experimentiere mit ext_scaffold mit UI-Elemente für eine Rails-backed Web-Anwendung zu erzeugen.

Allerdings erlebe ich Probleme mit dem Verhalten von Booleschen Feldern. Zum Beispiel, wenn ich

./script/generate ext_scaffold product name:string description:text sku:integer available:boolean

Es baut die Migration ordnungsgemäß und erzeugt eine Benutzeroberfläche mit einem Kontrollkästchen für das boolean Feld.

Wenn dieses Feld aktiviert, jedoch ändert nur das Objekt, wenn es erstellt wird ist. Wenn der Datensatz bereits vorhanden ist, spiegelt der Zustand der Checkbox genau das Feld. Es ist jedoch versagt Bearbeitung - d. H, die Überprüfung oder es und speichern Sie die Aufzeichnung unchecking es nicht ändern

Dipping in den Code, finden wir:

 items: [
    { fieldLabel: scaffoldPanel.labels['product[name]'], name: 'product[name]', xtype: 'textfield' },
    // ... other fields ...
    { fieldLabel: scaffoldPanel.labels['product[available]'], name: 'product[available]', xtype: 'checkbox', inputValue: '1' }, { xtype: 'hidden', name: 'product[available]', value: '0' }
    ],

Ich habe das Gefühl das Problem ist, dass entweder Rails oder Ext bei den identisch genannten Elementen verwechselt wird. So oder so, nachdem ein Datensatz erstellt wurde, klicken Sie das Kontrollkästchen tut nichts (aktiviert oder deaktiviert, das Feld bleibt ‚0‘).

Nachdem sie mit dieser ein wenig herum zu spielen, stellt sich heraus, wenn wir setzen, dass versteckte Feld über dem Kontrollkästchen, egal, was das Feld nun auf true gesetzt wird nach der Bearbeitung. Nicht gerade Verhalten entweder gewünscht wird.

Hat jemand dieses Problem erfahren? Gibt es Workarounds? Danke.

UPDATE:

Hinweis

, dass auch mit dem Kontrollkästchen für das Feld überprüft, schickte die POST-Anforderung anzeigt, wird das Feld auf false gesetzt. Alle anderen Feldtypen werden immer entsprechend aktualisiert ...

UPDATE2:

In Ordnung, fand eine große Blog-Post Semergence Lösung für dieses Problem beschreiben, aber ich bin noch nicht ganz in der Lage zu bekommen dies funktioniert ... ich habe seine Lösung wie folgt angepasst:

   onOk: function() { 

      // ....

      if (scaffoldPanel.getFormPanel().currentMode == 'edit') {
        // set up request for Rails create action
        submitOptions.params._method = 'PUT';
        submitOptions.url = submitOptions.url + '/' + selected.data.id;
      }

  // ----- checkbox serializer ------
     var serializedForm = scaffoldPanel.getFormPanel().getForm();

 // because unchecked checkboxes do not submit values, manually force a value of 0  
     serializedForm.items.each(function(f) {  
        //alert("Checking \"" + f.getName() "\" field...");
        if (f.isFormField && f.getXType() == 'checkbox' && !f.getValue()) {  
            alert("Auto setting \"" + f.getName() + "\" field to 0...");
            serializedForm.getValues()[f.getName()] = '0';  
        }
      });
// ------- end serializer -------

     serializedForm.submit(submitOptions);
     //scaffoldPanel.getFormPanel().getForm().submit(submitOptions);  
   },

Nun wird die Warnung richtig geworfen, das richtige Feld angibt, und behauptet wird es auf Null gesetzt werden.

Außer dies nicht der Fall nach unten in der Post-Anforderung, die tatsächlich bekommt geschickt -. In der Tat, wenn das Kontrollkästchen nicht markiert ist, es keinen Wert in der POST überhaupt haben

Kann mir jemand helfen, zu verstehen, was hier vor sich geht?

War es hilfreich?

Lösung

OK, stellt sich heraus, das ist ein bekannter Fehler mit dem Ext-Framework. Schlendern Sie über den ExtJS Foren, wenn Sie das gleiche Problem haben sollten, mehrere Lösungen gibt skizziert. Die einfachste zu implementieren, ist nur die Checkbox Klasse zu erweitern:

# patch.js -- include before creating any checkboxes
Ext.ns('Ext.ux.form');
Ext.ux.form.XCheckbox = Ext.extend(Ext.form.Checkbox, {
 offCls:'xcheckbox-off'
,onCls:'xcheckbox-on'
,disabledClass:'xcheckbox-disabled'
,submitOffValue:'false'
,submitOnValue:'true'
,checked:false

,onRender:function(ct) {
    // call parent
    Ext.ux.form.XCheckbox.superclass.onRender.apply(this, arguments);

    // save tabIndex remove & re-create this.el
    var tabIndex = this.el.dom.tabIndex;
    var id = this.el.dom.id;
    this.el.remove();
    this.el = ct.createChild({tag:'input', type:'hidden', name:this.name, id:id});

    // update value of hidden field
    this.updateHidden();

    // adjust wrap class and create link with bg image to click on
    this.wrap.replaceClass('x-form-check-wrap', 'xcheckbox-wrap');
    this.cbEl = this.wrap.createChild({tag:'a', href:'#', cls:this.checked ? this.onCls : this.offCls});

    // reposition boxLabel if any
    var boxLabel = this.wrap.down('label');
    if(boxLabel) {
        this.wrap.appendChild(boxLabel);
    }

    // support tooltip
    if(this.tooltip) {
        this.cbEl.set({qtip:this.tooltip});
    }

    // install event handlers
    this.wrap.on({click:{scope:this, fn:this.onClick, delegate:'a'}});
    this.wrap.on({keyup:{scope:this, fn:this.onClick, delegate:'a'}});

    // restore tabIndex
    this.cbEl.dom.tabIndex = tabIndex;
} // eo function onRender

,onClick:function(e) {
    if(this.disabled || this.readOnly) {
        return;
    }
    if(!e.isNavKeyPress()) {
        this.setValue(!this.checked);
    }
} // eo function onClick

,onDisable:function() {
    this.cbEl.addClass(this.disabledClass);
    this.el.dom.disabled = true;
} // eo function onDisable

,onEnable:function() {
    this.cbEl.removeClass(this.disabledClass);
    this.el.dom.disabled = false;
} // eo function onEnable

,setValue:function(val) {
    if('string' == typeof val) {
        this.checked = val === this.submitOnValue;
    }
    else {
        this.checked = !(!val);
    }

    if(this.rendered && this.cbEl) {
        this.updateHidden();
        this.cbEl.removeClass([this.offCls, this.onCls]);
        this.cbEl.addClass(this.checked ? this.onCls : this.offCls);
    }
    this.fireEvent('check', this, this.checked);

} // eo function setValue

,updateHidden:function() {
    this.el.dom.value = this.checked ? this.submitOnValue : this.submitOffValue;
} // eo function updateHidden

,getValue:function() {
    return this.checked;
} // eo function getValue

}); // eo extend

// register xtype
Ext.reg('xcheckbox', Ext.ux.form.XCheckbox);

 // eo file 

Sie werden auch einige CSS für das neue Kontrollkästchen müssen:

.xcheckbox-wrap {
 line-height: 18px;
 padding-top:2px;
}
.xcheckbox-wrap a {
 display:block;
 width:16px;
 height:16px;
 float:left;
}
.x-toolbar .xcheckbox-wrap {
 padding: 0 0 2px 0;
}
.xcheckbox-on {
 background:transparent url(../javascripts/ext/resources/images/default/menu/checked.gif) no-repeat 0 0;
}
.xcheckbox-off {
 background:transparent url(../javascripts/ext/resources/images/default/menu/unchecked.gif) no-repeat 0 0;
}
.xcheckbox-disabled {
 opacity: 0.5;
 -moz-opacity: 0.5;
 filter: alpha(opacity=50);
 cursor:default;
}

Schließlich können Sie ext-Gerüst zu beheben, diese neuen xcheckboxes für booleans zu erzeugen und auch das versteckte Feld nicht zu erzeugen. Ich veränderte ext_scaffold_panel.js wie folgt:

    baseParams: scaffoldPanel.baseParams,
    items: [
<%= attributes.inject([]) do |items, a|
 item =  "        { fieldLabel: scaffoldPanel.labels['#{class_name.demodulize.underscore}[#{a.name}]']"
 item << ", name: '#{class_name.demodulize.underscore}[#{a.name}]'"
 item << case a.field_type
   when :text_field      then [:integer, :float, :decimal].include?(a.type) ? ", xtype: 'numberfield'" : ", xtype: 'textfield'"
   when :text_area       then ", xtype: 'textarea'"
   when :date_select     then ", xtype: 'xdatefield'"
   when :datetime_select then ", xtype: 'xdatetime'"
   when :check_box       then ", xtype: 'xcheckbox', inputValue: '1' //// }, { xtype: 'hidden', name: '#{class_name.demodulize.underscore}[#{a.name}]', value: '0'"
 end
 item << " }"
 items << item
end.join(",\n")
%>
    ],

Hope, das hilft jemand anderes mit diesem zu kämpfen!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top