Question

J'expérimente l'utilisation ext_scaffold pour générer des éléments de l'interface utilisateur pour une application Web soutenu par Rails.

Cependant, je rencontre des problèmes avec le comportement des champs booléens. Par exemple, quand je fais

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

Il construit la migration correctement et génère une interface utilisateur avec une case à cocher pour le champ booléen.

Si vous cochez cette case, cependant, ne modifie l'objet si elle est en cours de création. Si l'enregistrement existe déjà, l'état de la case à cocher reflète avec précision le champ. Cependant, l'éditer échoue -. À savoir, la vérification ou décochant et sauvegarde de l'enregistrement ne change pas

trempant dans le code, nous trouvons:

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

Je sens le problème est que soit Rails ou Ext est confondu les éléments nommés de manière identique. De toute façon, après un enregistrement a été créé, cliquez sur la case à cocher ne fait rien (enregistré ou non, le champ reste « 0 »).

Après avoir joué un peu avec cela, il se trouve si l'on place ce champ Cachée la case à cocher, quel que soit le champ se maintenant à true après l'édition. Pas exactement soit le comportement souhaité.

Quelqu'un at-il rencontré ce problème? Y a-t-il des solutions de contournement? Merci.

Mise à jour:

Notez que même avec la case à cocher pour le champ cochée, la requête POST envoyée indique que le champ est défini sur false. Tous les autres types de champs sont mis à jour de façon appropriée se ...

MAJ2:

D'accord, a trouvé un grand blog décrivant la solution à ce problème Semergence , mais je ne suis toujours pas tout à fait en mesure d'obtenir ce travail ... Je l'ai adapté sa solution comme suit:

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

Maintenant, l'alerte est jeté correctement, indiquant le champ approprié et d'affirmer qu'il sera mis à zéro.

Sauf que cela ne se produit pas dans la demande de poste qui obtient effectivement envoyé -. En fait, si la case est cochée, il n'a pas de valeur dans le POST du tout

Quelqu'un peut-il me aider à comprendre ce qui se passe ici?

Était-ce utile?

La solution

OK, se c'est un bug connu avec le framework Ext. Promenez-vous sur les forums ExtJS si vous rencontrez le même problème, plusieurs solutions qui y sont décrites. Le plus simple à mettre en œuvre est juste pour étendre la classe de case à cocher:

# 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 

Vous aurez également besoin d'css pour les nouvelles cases à cocher:

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

Enfin, vous pouvez fixer poste-échafaudage pour générer ces nouveaux xcheckboxes pour booléens et aussi de ne pas générer le champ caché. Je modifié ext_scaffold_panel.js comme suit:

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

Espérons que cela aide tout le monde en difficulté d'autre avec cela!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top