Hallo Zusammen, analog zu dem Developers Guide Beispiel habe ich die Backendmaske Artikel-Details um einen Tab erweitert um dort zwei erweiterte Attribute zu verwalten. Die Datenbank wurde erfolgreich beim installieren des Plugins wie folgt erfoglreich erweitert: $shopware\_obj-\>Application()-\>Models()-\>addAttribute('s\_articles\_attributes', 'ezi', 'issos\_art\_nr','varchar(24)',true,null); $shopware\_obj-\>Application()-\>Models()-\>addAttribute('s\_articles\_attributes', 'ezi', 'stock\_names','varchar(255)',true,null); Shopware()-\>Models()-\>generateAttributeModels(array('s\_articles\_attributes'));
Die Webmaske wurde ebenfalls erfolgreich erweitert (inkl. Snippsets), ich sehe den neuen Tab und die zwei neuen Felder, diese wurde wie folgt definiert: me.eziIssosArtNr = Ext.create('Ext.form.field.Text', { name:'attribute[eziIssosArtNr]', fieldLabel:'{s name=ezi\_detail/issos\_art\_nr}ISSOS-article-no{/s}', allowBlank: true,anchor:'95%',labelWidth:150,minWidth:250 }); me.eziStockNames = Ext.create('Ext.form.field.Text', { name:'attribute[eziStockNames]', fieldLabel:'{s name=ezi\_detail/stock\_names}ISSOS-stock-name{/s}', allowBlank: true,anchor:'95%',labelWidth:100,minWidth:250 });
âShopware.apps.Article.model.Attributeâ wurde erweitert. Das die Zeilen an der richtigen Stelle landen, kann ich z.B. mit Firebug Debugger feststellen Ext.define('Shopware.apps.Article.model.Attribute', { extend: 'Ext.data.Model', fields: [{ name:'eziIssosArtNr', type:'string' }, { name:'eziStockNames', type:'string' }, { name: 'id', type: 'int' }, { name: 'articleId', type: 'int', useNull : true }, ...
Ich sehe auch in â\templates_default\backend\article\model\article.jsâ, das die erwartete Assoziation vorhanden ist: { type: 'hasMany', model: 'Shopware.apps.Article.model.Attribute', name: 'getAttribute', associationKey: 'attribute' },
In den Feldern geschriebene Inhalte werden beim Speichern aber nicht in die DB gespeichert, bzw. in die DB manuell eingetragene auch nicht dort angezeigt. Sie werden also nicht âautomatisch befĂŒlltâ. Stehen die erweiterten Artikel-Attribute hier nicht zur VerfĂŒgung? Oder habe ich irgendwo was ĂŒberlesen/missverstanden? Vielen Dank im voraus.
Wenn das das ist was ich meine, dann mĂŒssen die Freifelder auch die richtigen Namen attr1 attr2 usw⊠haben
Jein, attr1 attr2 usw. sind auch Teil von âShopware.apps.Article.model.Attributeâ und sie stehen in der Datenbank in der selben Tabelle (s_articles_attributes). Die genannten Tabelle wurde (wie im erstem Codeabschnitt gezeigt) erweitert durch 2 weitere Attribute. Mittels folgendem Code //{block name="backend/article/model/attribute/fields" append} { name:'eziIssosArtNr', type:'string' }, { name:'eziStockNames', type:'string' }, //{/block}
wird aber die Field-Definition aus â\templates_default\backend\article\model\attribute.jsâ erweitert, so dass im Webbrowser folgendes zu sehen ist (4+5 Zeile): Ext.define('Shopware.apps.Article.model.Attribute', { extend: 'Ext.data.Model', fields: [{ name:'eziIssosArtNr', type:'string' }, { name:'eziStockNames', type:'string' }, { name: 'id', type: 'int' }, { name: 'articleId', type: 'int', useNull : true }, { name: 'articleDetailId', type: 'int', useNull : true }, { name: 'attr1', type: 'string' }, ... { name: 'attr20', type: 'string' }] });
Laut dem Wiki Beitrag hĂ€tte ich daher erwartet, dass die Felder nun âautomatisch befĂŒlltâ wĂŒrden, Zitat: âDieses Vorgehen ist bei Formularen unbedingt empfehlenswert, da nur so das automatische Setzen und Lesen von Models durch ExtJS genutzt werden kann.â Aber auch wenn ich attr1 oder attr2 statt der neuen Tabellen-Spalten-Namen eingeben - laden und speichern der Werte aus/in die DB funktioniert hier trotzdem nicht. Daher der verdacht, dass diese Attribute hier gar nicht geladen und somit nicht beachtet werden. Die Assoziation ist zwar da, ich finde aber nirgends, dass sie tatsĂ€chlich aufgerufen wĂŒrde. Wie kann ich also auf die Attribute zugreifen (lesend/schreibend)?
Ok, bin nun ein StĂŒck weiter. Habe mich durchgesucht im Code bis â\templates_default\backend\article\controller\main.jsâ. Dort finde ich folgenden Code: openExistingArticle: function(id) { var me = this; // Create main window me.openMainWindow(); //the batch store is responsible to load all required stores for the detail page in one request me.batchStore = me.getStore('Batch'); me.batchStore.getProxy().extraParams.articleId = id; me.batchStore.load({ callback: function(records, operation) { var storeData = records[0]; me.subApplication.fireEvent('batchStoreLoaded', storeData, operation, true); } }); },
Wenn ich an Zeile 14 stoppe und storeData.raw.article[0].attribute[âeziIssosArtNrâ] abfrage, so sehe ich den Inhalt der in der Datenbank steht. Geladen werden die Werte also⊠Feld mir nur noch der Grund wieso der nun sichtlich geladene Wert nicht im Feld angezeigt (und auch gespeichert) wird. Kann mir jemand weiterhelfen? Ist die Art und weiĂe ich ich ânameâ definiert habe falsch? Liegt das Problem daran, dass das Feld in einem Neuen Tab angezeigt wird und nicht direkt im Reiter âStammdatenâ?
Leider hatte ich immer noch kein erfolgt. Hat jemand irgend ein Vorschlag machen wie ich die Datenbank-Werte in die Felder lade und die Ănderung in die Datenbank speichern kann? Auch Links zu Ă€hnlichen Themen wĂŒrde weiterhelfen, denn noch bin ich am Anfang meiner Einarbeitung in der Shopware Programmierung⊠Aber irgendwie wie fehlt mir hier der konzeptionelle Hintergrund von ExtJS um zu wissen wo ich nun weiter suchen kann. Vielen Dank im voraus.
Hallo ich habe dein Posting gesehen und wollte mal fragen ob du schon eine Lösung gefunden hast? Ich stehe nÀmlich vor dem selben Problem und denke das hier mehr im Argen ist.
Hallo Almare, nein, stehe leider immer noch an der selben Stelle. Wie mir scheint wurde das laden/setzen/auslesen der Erweiterten Attribute in Artikel-Details vergessen. Wenn man weiĂ wo, dann ist dies vermutlich ein Einzeiler⊠Leider weiĂ ich inzwischen nicht mehr wo ich noch suchen könnte. Bin aber fĂŒr jeden Hinweis offen.
Haha in der Tat ich habe es gerade herausgefunden. MIch hat dieser Scheià echt den letzten Nerv geraubt!!! Also ich will mal versuchen es zu erklÀren. 1 Schritt : Die Daten aus den Attributen auslesen (Bei mir sind diese in einem weiteren Tab untergebracht) createMeinTab: function(article, stores, eOpts) { var me = this, tab = eOpts.tab; tab.add(me.createMeineComponents()); // Variablen zuweisen me.MEIN\_FELD1.setValue(article.getAttributeStore.data.items[0].data.MEIN\_ATTRIBUT\_FELD\_1); me.MEIN\_FELD2.setValue(article.getAttributeStore.data.items[0].data.MEIN\_ATTRIBUT\_FELD\_2); tab.setDisabled(article.get('id') === null); },
Das gleiche muss in die Funktion wenn das Tab einen neuen Artikel lÀdt articleChange: function(article, tabConfig) { var me = this; // Variablen zuweisen me.MEIN\_FELD\_1.setValue(article.getAttributeStore.data.items[0].data.MEIN\_ATTRIBUT\_FELD\_1); me.MEIN\_FELD\_2.setValue(article.getAttributeStore.data.items[0].data.MEIN\_ATTRIBUT\_FELD\_2); },
Nun werden die Felder angezeigt und befĂŒllt!!! Weiter im Context. Das Speichern der neuen Werte. Es muss ein event in deinem Controller erzeugt werden das auf den Namen saveArticle reagiert. Dieser Event ist im Main Window der Artikel definiert. Hier fĂŒgen wir wieder unsere Werte dem Store hinzu. onSaveArticle:function(win, article, options){ var me = this, mainController = me.getController('Main'), mainWindow = mainController.mainWindow; article = mainWindow.article; article.getAttributeStore.data.items[0].data.MEIN\_ATTRIBUTE\_FELD\_1 = Ext.getCmp('MEIN\_FELD\_1').getValue(); article.getAttributeStore.data.items[0].data.MEIN\_ATTRIBUTE\_FELD\_2 = Ext.getCmp('MEIN\_FELD\_2').getValue(); }
Das war es auch schon. Hier ist allerdings keine Validierung eingebaut. Es gibt sicher noich eine bessere Lösung aber es funktioniert zumindest. Eine Woche und sĂ€mtliche Tutorials haben mich nicht weitergebracht. Bin offen fĂŒr Verbesserungen. Dies soll zumindest der Anfang sein. Feedback willkommen
Hm, wie mir scheint hast du genau das gemacht wovon im Developer Guide beschrieben wird, dass man sich das sparen kann: [quote]âŠDurch die Namensgebung, die sich am jeweiligen ExtJS-Model orientiert, können wir uns die Logik zum Laden und Speichern des Inhalts der Eingabefelder komplett sparen: ExtJS besorgt dies automatisch⊠Um unsere Eingabefelder automatisch befĂŒllen zu lassen, können wir einfach die gewĂŒnschten Feldnamen des Models als Name des Eingabefeldes nutzen⊠Dieses Vorgehen ist bei Formularen unbedingt empfehlenswert, da nur so das automatische Setzen und Lesen von Models durch ExtJS genutzt werden kann. [/quote] Die angesprochene Namensgebung ist âattribute[MEIN_FELD]â. Das hab ich auch so gemacht. Wie mir scheint sind aber die Erweiterten Attribute der Artikel nichts als âstoresâ abgebildet, vermutlich daher auch nicht automatisch gesetzt/gespeichert. Zu allen anderen Werten finde ich dazu eine âbindStore()â Anweisung. Sofern diese Anweisung (und der anderen dazugehörigen) vergessen wurden, dann ist es ein Bug. Sofern sie bewusst nicht gemacht wurden, dann ist es zumindest ein Konzeptbruch - wenn man weiĂ, dass dieses Konzept nur fĂŒr den einen oder anderen Bereich gilt, dann wĂŒrde man sich ja nicht wundern, dass man es dort âzu FuĂâ machen muss. Aufgrund das es im Wiki hieĂ, man kann sich die eigene Logik sparen hatte ich bisher noch keinen eigenen Controller implementiert. Dieser ist aber Voraussetzung fĂŒr deine beschrieben Logik. Kann jemand sagen ob dieses Konzept nur fĂŒr die Kundendetails gilt und es fĂŒr die Artikel bewusst nicht?
Richtig, das habe ich aucbh gelesen. Leider hat dies aber hier anscheinend noch niemand geschafft es so umzusetzen. Bei mir und wie bei allen anderen hat es anscheinend nicht funktioniert. Daher lieber eine âschlechteâ Lösung die lĂ€uft, als eine die gar nicht funktioniert bzw. wir nicht wissen wie sie korrekt angewendet wird. Ich persönlich wĂŒrde auch die genannte Lösung bevorzugen, allerdings geht sie nicht. Bug? Das kann ich leider nicht bestĂ€tigen, daher mĂŒsste man erstmal wissen was wir falsch gemacht haben.
So ich habs herausgefunden. Das hat mich echt jetzt genervt. Die Lösung um Store Variablen den Feldern zuzuweisen lĂ€uft ĂŒber .loadRecord( ) Funktion. Doku: http://docs.sencha.com/extjs/4.0.7/#!/a ⊠oadRecords Ein kleines Beispiel hier noch: onTabActivated: function(window) { var me = this; window.MEINStore.load({ callback: function(records, operation) { if (!operation.wasSuccessful()) { return; } if (records.length \> 0) { me.record = records[0]; me.getMEIN\_REF\_MIT\_FORMULAR().loadRecord(me.record); } else { // Create a new, empty record me.record = Ext.create('Shopware.apps.Article.model.MEIN.MODEL'); // Do not pass empty record here: This way the components' default values will be used me.getMEIN\_REF\_MIT\_FORMULAR().loadRecord(); } } }); },
Ich hoffe das hilft weiter
Hallo Ich sehe, dass dieser Beitrag ein Bisschen Àlter ist. Jedoch möchte ich gerne ein Plugin auf Version 5.0.2 erstellen, welches meine ErwAttribute in einem selbststÀndigen Tab bei Artikeldetails im Backend anzeigt. Ich habe noch nicht viel Erfahrung und kann diesem Beitrag nicht ganz folgen, da nicht gesagt wird welches File gerade angesprochen wird. Ist es möglich, wenn beschrieben wird welche Events man subscriben muss und welche Views erstellt/bearbeitet werden sollen? Vielen Dank
Hallo Ich bin nun schon viel weiter gekommen. Ich habe nun folgende Schritte gemacht: Bootstrap.php //Event subscriben $this-\>subscribeEvent( 'Enlight\_Controller\_Action\_PostDispatch\_Backend\_Article', 'onEnlightControllerActionPostDispatchBackendArticle' ); //Meine Views registrieren public function onEnlightControllerActionPostDispatchBackendArticle(Enlight\_Event\_EventArgs $arguments) { $arguments-\>getSubject()-\>View()-\>addTemplateDir( $this-\>Path() . 'Views/' ); //Hier lĂ€dst du alle Javascript Dateien die ein Override enthalten. if ($arguments-\>getRequest()-\>getActionName() === 'load') { $arguments-\>getSubject()-\>View()-\>extendsTemplate( 'backend/article/view/detail/my\_window.js' ); } //Hier erweiterst du die APP.JS um eigene Komponenten (Models, Views, Stores, Controllers) hinzuzufĂŒgen if ($arguments-\>getRequest()-\>getActionName() === 'index') { $arguments-\>getSubject()-\>View()-\>extendsTemplate( 'backend/article/my\_app.js' ); } }
my_window.js //{block name="backend/article/view/detail/window" append} Ext.define('Shopware.apps.Article.view.detail.Window', { override:'Shopware.apps.Article.view.detail.Window', /\*\* \* Creates the main tab panel which displays the different tabs for the article sections. \* To extend the tab panel this function can be override. \* \* @return Ext.tab.Panel \*/ createMainTabPanel: function() { var me = this; var formTab = me.callParent(arguments); //Der Container fĂŒr das Tab =\> Der Tab selber me.testTab = Ext.create('Ext.container.Container', { title: 'Test Tab', disabled: true, name: 'test-tab', layout: 'border' }); me.mainTab.insert(me.testTab); return formTab; }, //Der Inhalt des Tabs createTestContent: function() { var me = this; me.testContent = Ext.create('Shopware.apps.Article.view.test.Test', { height: '100%', width: '100%', autoScroll:true, margin: 10 }); return me.testContent; }, onStoresLoaded: function(article, stores) { var me = this; me.callParent(arguments); me.testTab.add(me.createKmudoContent()); me.testTab.setDisabled(false); }, }); //{/block}
test.js //{namespace name=backend/article/view/main} //{block name="backend/article/view/test/test"} Ext.define('Shopware.apps.Article.view.test.Test', { /\*\* \* Define that the category drop zone is an extension of the Ext.panel.Panel \* @string \*/ extend:'Ext.form.FieldSet', /\*\* \* List of short aliases for class names. Most useful for defining xtypes for widgets. \* @string \*/ alias:'widget.article-test-test', /\*\* \* Set css class for this component \* @string \*/ cls: Ext.baseCSSPrefix + 'article-test-test', /\*\* \* Layout for the component \*/ layout: 'anchor', /\*\* \* Defaults for the panel items \* @object \*/ defaults: { anchor: '100%' }, /\*\* \* The initComponent template method is an important initialization step for a Component. \* It is intended to be implemented by each subclass of Ext.Component to provide any needed constructor logic. \* The initComponent method of the class being created is called first, \* with each initComponent method up the hierarchy to Ext.Component being called thereafter. \* This makes it easy to implement and, if needed, override the constructor logic of the Component at any step in the hierarchy. \* The initComponent method must contain a call to callParent in order to ensure that the parent class' initComponent method is also called. \* \* @return void \*/ initComponent:function () { var me = this; me.items = me.createContent(); me.callParent(arguments); }, /\*\* \* Creates the content \* @return Ext.container.Container \*/ createContent: function() { var me = this; return Ext.create('Ext.container.Container', { anchor: '100%', focusable: false, margin: 10, items: [{ xtype: 'checkbox', name: 'mein\_erstes\_feld', fieldLabel: 'Sehenswert', boxLabel: 'Ob Artikel sehenswert ist', inputValue: true, uncheckedValue:false }, { xtype: 'textfield', name: 'mein\_zweites\_feld', allowBlank: false, fieldLabel: 'BegrĂŒndung', supportText: 'Warum denn?' }] }); } }); //{/block}
Mit diesen Anpassungen hier hat man ein neues Tab und Inhalt. Nun jedoch meine Frage: Ich habe in der Datenbank die Felder âmein_erstes_feldâ und âmein_zweites_feldâ und möchte diese in meinem Tab auslesen und speichern können. Ich weiss, dass ich im File my_app.js die Views, Controller, Store und Model einbinden muss, aber diese Version hier funktioniert nicht⊠(Alle gefundenen Beispiele Shopware Version 4) //{block name="backend/article/application" append} //{include file="backend/article/controller/test.js"} //{include file="backend/article/model/test.js"} //{include file="backend/article/store/test.js"} //{include file="backend/article/view/test/test.js"} //{/block}
Was ist der korrekte Weg im Shopware 5? Und wie muss der Controller, Model und Store aussehen, dass ich die Felder von s_articles_attributes auslesen kann? Vielen Dank
Hallo Ich bin wieder einen Schritt weiter gekommen, benötige aber immer noch Hilfe. Wenn ich im my_app.js wie oben die Files âeinfĂŒgeâ werden sie geladen, aber an der falschen Stelle. Wenn ich das original app.js nehme und dies gĂ€nzlich ĂŒberschreibe und mein View, Store und Controller in die gegebenen Felder hinzufĂŒge werden sie an den korrekten Stellen geladen. Das aber kann ja nicht der Weg sein, wenn man Plugins entwickelt⊠Beim Model habe ich nun attribute.js folgendermassen appended: //{block name="backend/article/model/attribute/fields" append} { name : 'mein\_erstes\_feld', type: 'boolean' }, { name : 'mein\_zweites\_feld', type: 'string' }, //{/block}
Wie muss ich nun den Controller, View und Store einrichten damit mein Tab die Daten erhÀlt?
Hallo kmudo, [quote=âkmudoâ][âŠ] Beim Model habe ich nun attribute.js folgendermassen appended: //{block name="backend/article/model/attribute/fields" append} { name : 'mein\_erstes\_feld', type: 'boolean' }, { name : 'mein\_zweites\_feld', type: 'string' }, //{/block}
[âŠ][/quote] ohne den Code oben angesehen zu haben ( sorry aber den kann man so nicht lesen bitte benutze das âcodeâ Tag ) fĂ€llt mir gleich auf, dass du im Model die Felder falsch gemappt hast. Diese werden von Shopware in die âCamelâ-Schreibweise umgewandelt. So wird der Article ExtJS App deine Werte nicht richtig zuordnen. So sollte das gehen: //{block name="backend/article/model/attribute/fields" append} { name : 'meinErstesFeld', type: 'boolean' }, { name : 'meinZweitesFeld', type: 'string' }, //{/block}
Die ExtJS Anwendung erweiterst du mit âoverrideâ. Du musst aber nur die Dateien ĂŒberschreiben, die du auch Ă€ndern willst ( nicht die gesamte ExtJS Anwendung ). Hier gibt es ein gutes Tutorial dazu. Viele GrĂŒĂe edit: Ich sehe gerade, dass das Code Tag nicht funktioniert *facepalm* Dann könntest du den Code ja vielleicht hier mal reinstellen: http://gist.github.com