Domanda

sto sperimentando con l'utilizzo di ext_scaffold per generare elementi dell'interfaccia utente di un'applicazione web Rails-backed.

Comunque, sto sperimentando problemi con il comportamento dei campi booleani. Per esempio, quando faccio

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

Si costruisce la migrazione correttamente e genera un interfaccia utente con una casella di controllo per il campo booleano.

Selezionando questa casella, tuttavia, modifica la sola oggetto se è stato creato. Se il record esiste già, lo stato della casella di controllo riflette correttamente il campo. Tuttavia, la modifica di esso sta fallendo -. Vale a dire, selezionando o deselezionando e salvare il record non cambiarlo

Immersione nel codice, troviamo:

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

ho la sensazione che il problema è che o Rails o Ext è confuso presso gli elementi con nomi identici. In entrambi i casi, dopo un record è stato creato, cliccando sulla casella di controllo non fa nulla (verificate e non, il campo rimane '0'.)

Dopo aver giocato un po 'con questo, si scopre se poniamo che campo nascosto SOPRA la casella di controllo, non importa quale sia il campo ora viene impostata su true dopo la modifica. Non esattamente desiderato comportamento sia.

Ha chiunque altrimenti sperimentato questo problema? Esistono soluzioni alternative? Grazie.

UPDATE:

Si noti che anche con la casella di controllo per il campo controllato, la richiesta POST inviato indica che il campo è impostato su false. Tutti gli altri tipi di campo sono sempre aggiornati in modo appropriato ...

UPDATE2:

Va bene, ha trovato un grande post sul blog che descrive la soluzione di Semergence a questo problema , ma sono ancora non del tutto in grado di farlo funzionare ... ho adattato la sua soluzione come segue:

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

Ora l'allarme si butta correttamente, indicando il campo corretto e affermando che sarà impostato a zero.

A parte questo non si verifica verso il basso nella richiesta POST che in realtà viene inviato -. Infatti, se la casella di controllo non è selezionata, non ha un valore nel POST a tutti

Qualcuno può aiutarmi a capire cosa sta succedendo qui?

È stato utile?

Soluzione

OK, scopre questo è un bug noto con il quadro Ext. Vagare ai forum ExtJS se hai lo stesso problema, diverse soluzioni delineate lì. Il più semplice da implementare è solo quello di estendere la classe casella di controllo:

# 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 

Avrete anche bisogno di un po 'di CSS per le nuove caselle di controllo:

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

Infine, si consiglia di fissare ext-impalcatura per generare questi nuovi xcheckboxes per booleani e, inoltre, non per generare il campo nascosto. Ho modificato ext_scaffold_panel.js come segue:

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

Spero che questo aiuti chiunque altro alle prese con questo!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top