Pregunta

Estoy experimentando con el uso de ext_scaffold para generar elementos de la interfaz de usuario para una aplicación web apoyado por los carriles.

Sin embargo, tengo problemas con el comportamiento de los campos booleanos. Por ejemplo, cuando hago

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

Se construye la migración correctamente y genera una interfaz de usuario con una casilla de verificación para el campo booleano.

Al marcar esta casilla, sin embargo, sólo se modifica el objeto si está siendo creado. Si el registro ya existe, el estado de la casilla refleja con precisión el campo. Sin embargo, la edición está fallando -. Es decir, activando o desactivando y guardar el registro no lo cambia

Inmersión en el código, nos encontramos con:

 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' }
    ],

Siento el problema es que cualquiera de los carriles o Ext se confunde a los elementos con nombres idénticos. De cualquier manera, después de un registro se ha creado, haga clic en la casilla de verificación no hace nada (activada o desactivada, el campo sigue siendo '0'.)

Después de jugar un poco con esto, resulta que si colocamos un campo oculto ARRIBA la casilla de verificación, no importa lo que el campo ahora se establece en true después de la edición. No es exactamente el comportamiento deseado, ya sea.

¿Alguien más ha tenido este problema? ¿Hay alguna solución? Gracias.

ACTUALIZACIÓN:

Tenga en cuenta que incluso con la casilla de verificación para el campo está marcado, la solicitud POST envía indica que el campo se establece en false. Todos los demás tipos de campo están siendo actualizados apropiadamente ...

Update2:

De acuerdo, se encontró una gran entrada de blog que describe la solución de este problema Semergence a , pero todavía no estoy del todo capaz de conseguir que esto funcione ... me he adaptado su solución de la siguiente manera:

   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);  
   },

Ahora la alerta es lanzado correctamente, indicando el campo correcto y afirmando que se establece en cero.

Excepto esto no ocurre en la solicitud de cargo que realmente se ha enviado -. De hecho, si la casilla de verificación no está marcada, que no tiene un valor en el POST en absoluto

Puede alguien ayudarme a entender lo que está pasando aquí?

¿Fue útil?

Solución

bien, resulta que esto es un error conocido con el marco Ext. Pasear a los foros ExtJs si va a tener el mismo problema, varias soluciones describen allí. El más simple de implementar es sólo para extender la clase casilla de verificación:

# 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 

Usted también necesitará un poco de CSS para las nuevas casillas de verificación:

.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;
}

Por último, es posible que desee fijar ext-andamio para generar estos nuevos xcheckboxes para booleanos y tampoco para generar el campo oculto. He modificado ext_scaffold_panel.js como sigue:

    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")
%>
    ],

Espero que esto ayude a nadie más que luchan con esto!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top