ExtJS - l'aide personnalisée TriggerField comme un GridEditor

Donc j'ai posté la semaine dernière à la ExtJS forums, mais personne n'a répondu et je vais un peu fou en essayant de le comprendre:

Je suis assez nouveau dans ExtJS (juste appris la semaine dernière pour le travail), mais j'ai travaillé avec d'autres bibliothèques JavaScript pour un certain temps maintenant. Je suis en train de faire un contrôle personnalisé pour l'édition d'une liste d'attributs (actuellement occupé par une JSON demande). Je suis à l'aide de la grille des propriétés personnalisées GridEditor de l' (créé par l'extension de diverses Ext.les champs de formulaire). Tous mes champs personnalisés, sauf un, qui est une répétition de la valeur de l'éditeur. Fondamentalement, le terrain va être passé en 2d simple paire clé/valeur de tableau par le JSON demande, qu'il s'affiche dans une EditorGridPanel (à l'intérieur d'un Poste.La fenêtre que j'ai créé).

Ici est la section du JSON demande qui définit la répétition de la valeur de l'éditeur:

{
    key: 'Repeating',
    type: 'repeating',
    category: 'Category A',
    options: {
        dataArray: [
            {key: 'key A', value: 'value A'}, 
            {key: 'key B', value: 'value B'}, 
            {key: 'key C', value: 'value C'}
        ]
    }
}

La clé est le nom du champ (affiché sur la colonne de gauche de la grille des propriétés).
Le type indique la fonction qui crée l'ensemble de la grille des éditeurs de ce type d'éditeur personnalisé à utiliser.
Le catégorie est utilisé pour déterminer la grille de propriété de la GridEditor est ajouté (j'en ai plusieurs PropertyGird, de tous les contenus dans un groupe avec mise en page: 'acordion').
Rien dans options est ajouté à la prolongation de la Poste.champ de formulaire lorsqu'il est créé.

Donc dataArray est attaché à ma répétition de la valeur de l'éditeur pour la mise en place des premières paires clé/valeur et à stocker le tableau passé à la GridEditor par la Poste.Fenêtre d'édition.

Après quelques tests, j'ai décidé d'utiliser un TriggerField comme le GridEditor pour mon répéter type de valeur. Voici le code pour la définition de la répétition champ de valeur:

Ext.form.customFields = {
    'repeating': Ext.extend(Ext.form.TriggerField, {
        triggerClass: 'x-form-edit-trigger',
        enableKeyEvents: true
    })
};

Et voici le code qui le met en place:

Ext.form.customFields['repeating'] = Ext.extend(Ext.form.customFields['repeating'], {
    onTriggerClick: function()
    {
        this.editorWindow.show();
    },

    listeners: {
        'render': function(field)
        {
            field.editorWindow = new Ext.MultiSelectWindow({
                data: field.dataArray,
                parent: field
            });
        },
        'keydown': function(field, event)
        {
            event.stopEvent();
        },
        'beforerender': function()
        {
            for (i in this.opt) {
                if (i != 'store') {
                    this[i] = this.opt[i];
                }
                else {
                    this.store.loadData(this.opt.store);
                }
            }

            if (this.regex != undefined) {
                this.validator = function(value)
                {
                    return this.regex.test(value);
                };
            }
        }
    }
});

Et enfin, voici le code de la coutume fenêtre de l'éditeur:

Ext.MultiSelectWindow = function(args)
{
var obj = this;
obj.args = args;
obj.KeyValue = new Ext.data.Record.create([{
name: 'key'
}, {
name: 'value'
}]);
obj.gridStore = new Ext.data.Store({
data: obj.args.data,
reader: new Ext.data.JsonReader({}, obj.KeyValue),
autoLoad: true
});
obj.cm = new Ext.grid.ColumnModel([{
id: 'key',
header: "Key",
dataIndex: 'key',
editor: new Ext.form.TextField({
allowBlank: false
}),
hideable: false,
sortable: false,
menuDisabled: true,
css: 'font-weight: bold;'
}, {
id: 'value',
header: "Value",
dataIndex: 'value',
editor: new Ext.form.TextField({}),
hideable: false,
sortable: false,
menuDisabled: true
}]);
obj.gridEditor = new Ext.grid.EditorGridPanel({
cm: obj.cm,
height: 280,
store: obj.gridStore,
autoExpandColumn: 'value',
listeners: {
'render': function()
{
//set up local aliases
obj.a = new Array();
obj.a.grid = obj.gridEditor;
obj.a.store = obj.a.grid.getStore();
obj.a.sel = obj.a.grid.getSelectionModel();
}
},
bbar: [{
text: 'Add',
cls: 'x-btn-text-icon',
icon: '/lib/images/add.png',
listeners: {
'click': function()
{
var kv = new obj.KeyValue({
key: '',
value: ''
});
var row = obj.a.store.data.items.length;
obj.a.grid.stopEditing();
obj.a.store.insert(row, kv);
obj.a.grid.startEditing(row, 0);
}
}
}, {
text: 'Delete',
cls: 'x-btn-text-icon',
icon: '/lib/images/delete.png',
listeners: {
'click': function()
{
if (obj.a.sel.selection) 
obj.a.store.remove(obj.a.sel.selection.record);
}
}
}]
});
obj.panelAll = new Ext.Panel({
border: false,
layout: 'absolute',
items: [new Ext.Panel({
width: 250,
border: false,
x: 0,
y: 0,
items: obj.gridEditor
}), new Ext.Panel({
border: false,
x: 254,
y: 0,
items: [new Ext.Button({
cls: 'x-btn-icon-side',
icon: '/lib/images/arrow_up.png',
listeners: {
'click': function()
{
if (obj.a.sel.selection) {
var row = obj.a.sel.selection.cell[0];
var rec = obj.a.store.getAt(row);
if (row >= 1) {
obj.a.store.remove(rec);
obj.a.store.insert(row - 1, rec);
obj.a.grid.startEditing(row - 1, 0);
}
}
}
}
}), new Ext.Button({
cls: 'x-btn-icon-side',
icon: '/lib/images/arrow_down.png',
listeners: {
'click': function()
{
if (obj.a.sel.selection) {
var row = obj.a.sel.selection.cell[0];
var rec = obj.a.store.getAt(row);
var len = obj.a.store.data.items.length;
if (row < len - 1) {
obj.a.store.remove(rec);
obj.a.store.insert(row + 1, rec);
obj.a.grid.startEditing(row + 1, 0);
}
}
}
}
})]
})]
});
obj.win = new Ext.Window({
title: 'Repeating Value Editor',
layout: 'fit',
closeAction: 'hide',
border: false,
items: obj.panelAll,
width: 300,
height: 350,
resizable: false,
shadow: false,
buttonAlign: 'left',
buttons: [{
text: 'OK',
handler: function()
{
//reset the repeating field data array
obj.args.parent.dataArray = [];
for (r in obj.a.store.data.items) 
obj.args.parent.dataArray[r] = obj.a.store.data.items[r].data;
obj.args.parent.setRawValue(attrValueToString(obj.args.parent.dataArray));
obj.win.hide();
}
}, {
text: 'Cancel',
handler: function()
{
obj.win.hide();
}
}]
});
obj.show = function()
{
obj.win.show();
obj.a.store.loadData(obj.args.parent.dataArray);
}
}

Maintenant, pour mon problème: tout fonctionne bien, sauf pour la 7e ligne de la fenêtre du bouton 'OK' gestionnaire ( obj.args.parent.setRawValue(attrValueToString(obj.args.parent.dataArray)); ).

obj est une auto-alias.
obj.args.parent est un alias pour le champ ouvert à la répétition de la valeur de la fenêtre de l'éditeur.
attrValueToString() est une fonction qui prend un tableau 2d et la convertit en une chaîne avec une mise en forme particulière de sorte qu'il peut être affiché dans un lisible, compréhensible dans le TriggerField de la zone de texte.

Les données est chargé dans le domaine de l'dataArray variable et si vous ouvrez l'éditeur de nouveau, il aura les nouvelles données incluses dans la vue. Je ne peux pas, cependant, de gérer pour obtenir toute sorte de valeur à afficher dans la TriggerField après qu'il a été créé. J'ai essayé les deux obj.args.parent.setValue ("abc") et obj.args.parent.setRawValue('abc') . Aucune exception n'est levée, mais la valeur affichée dans la TriggerField ne change pas. J'ai même essayé de créer une fonction personnalisée pour le réglage de la valeur de l'intérieur de la TriggerField - quelque chose comme cela:

Ext.form.customFields['repeating'] = Ext.extend(Ext.form.customFields['repeating'], {
setFieldValue: function(value){
this.setValue(value);
}
});

Cette fonction personnalisée fonctionne si elle est appelée à partir de l'intérieur de la TriggerField, mais pas quand on l'appelle d'ailleurs (c'est à dire la fenêtre de l'éditeur du bouton 'OK' gestionnaire). La fonction peut être appelée avec succès à partir de n'importe où et ne produisent aucune des exceptions, cependant, elle ne définit la valeur correctement si elle est appelée à partir de l'intérieur de la TriggerField.

Le champ personnalisé fonctionne parfaitement lorsqu'il est instancié qu'une base de champ de formulaire:

var sample = new Ext.form.customFields['repeating']({
renderTo: Ext.getBody(),
dataArray: [
{key: 'key A', value: 'value A'}, 
{key: 'key B', value: 'value B'}, 
{key: 'key C', value: 'value C'}
]
});

J'ai parcouru le ExtJS documentation de l'API et de fait tous les possibles de recherche de google je pense. J'ai trouvé quelques posts sur le forum qui semblent être des gens ayant un problème similaire, mais ils n'obtiennent jamais de réponse claire.

Toute aide à ce sujet serait la plus appréciée, merci d'avance!

  • Vous dites que votre champ personnalisé ne fonctionne pas lorsqu'il est utilisé comme un GridEditor dans la grille des propriétés? Pourriez-vous fournir un exemple, qui illustre l'échec de code, que l'on pourrait, d'exécuter et de déboguer il? Un essai séparé page serait formidable.
InformationsquelleAutor Dan Martens | 2009-06-05