Magento Backendgrid: Click on a data entry and display its data - magento

I used this tutorial (especially Lesson 6 and 7) to create my own backend grid for Magento: http://www.pierrefay.com/magento-developper-guide-howto-tutorial-5
Everything works fine. I can create new data entries for my grid. If I click on an entry the VarienForm is displayed again but all the text fields are empty. This seems as if Magento thinks I want to edit all the text fields. But actually I want it to display the entry data first. But it only shows empty fields.
Can anyone help me out here? Thanks a lot!

There are a lot of things that could be wrong with your implementation, but it's impossible to say without seeing your code. Nevertheless, I'm going to try. That tutorial looks fine to me, but I haven't run the code so I can't be sure. I'm inclined to think you might have just missed something. Working in grids & tabs can be particularly delicate at the best of times.
It does sound to me like it's one of two things. It sounds like either
A) Your model data is not being stored in the registry. That means the problem is in this part of the code:
<?php
class Pfay_Test_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action
{
...
public function editAction()
{
$testId = $this->getRequest()->getParam('id');
$testModel = Mage::getModel('test/test')->load($testId);
if ($testModel->getId() || $testId == 0)
{
Mage::register('test_data', $testModel);
}
What this section of code does is 'registers' the selected model in Magento's registry. Later in the code, you'll see that it calls:
$form->setValues(Mage::registry('test_data')->getData());
to populate your form fields.
Try putting commands like these in the code above:
var_dump($testId);
die();
or
print_r($testModel);
die();
and running it again. Is $testId being set? Is $testModel being loaded? Is the if statement for the registry loading? If not, trace the problem back.
or it might also be
B) Your form is not prepopulating data because the column names are wrong.
Look where the code says:
<?php
class Pfay_Test_Block_Adminhtml_Test_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('test_form', array('legend'=>'ref information'));
$fieldset->addField('nom', 'text',
array(
'label' => 'Nom',
'class' => 'required-entry',
'required' => true,
'name' => 'nom',
)
);
You need to ensure that "nom" is in fact one of your model's attribute names. Did you change the attribute names when you created your test model and forgot to change it here? Change these values accordingly.
I hope that this helps you to solve your problem. Good luck!

Related

Magento getAttributeName / Text

I'm playing arround with magento product attributes.
What i'm trying to do is getting an "Unique Product Number" attached to the same " Unique Video Number" That works perfectly.
The same goes for an Dropdown Attribute using the following code.
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/avembed.js"></script>
<div class="av_videoplayer" data-av-search-ean="<?php echo $_product->getAttributeText('DropDown_Atribute') ?>"></div>
But as soon as i try it with an TextBox or TextField it fails to return an output.
I have been using getAttributeName to make it happen but i can't seem to get it working or find the anwser to do this.
Any tips on what i might be doing wrong here?
Thanks in advance!
Magento provides magic getters and setters, so for most product attributes, you can retrieve them using the attribute name, preceded by get. For example:
$freeShipping = $_product->getFreeShipping();
The alternative to this is the method you are using, getAttributeText.
$freeShipping = $_product->getAttributeText('free_shipping');
HOWEVER, the attribute must be in the product collection, which most custom attributes are not. When you setup your attribute, you need to set the option Visible on Product View Page on Front-end to Yes.
Failing that, you can recreate the product collection (in your own helper, for example) and add your attribute(s) manually as follows:
public function getMyProductCollection( $skuArray ) {
$products = Mage::getResourceSingleton('catalog/product_collection')
->addAttributeToSelect(
array(
'free_shipping',
'list_price',
'manufacturer',
'name',
'price',
'special_price',
'special_from_date',
'special_to_date',
'thumbnail'
)
)
->addAttributeToFilter(
'sku', array( 'in' => $skuArray )
)
->load();
return $products;
}
You can then use the public function as follows:
$_productObj = $this->helper('my_helper')->getMyProductCollection(
$_productSkus
);
Understand that I'm describing the principle, this code is not copy + pastable. Hope that helps.

getAddressesHtmlSelect() Change - Magento

I've been trying to edit the getAddressesHtmlSelect() function (found in code/core/Mage/Checkout/Block/Onepage/abstract.php) in order to enable the "new address" to display first in the dropdpown created.
I've located the place it needs to be changed in, but I can't figure out how to do that. Can anyone help? The code in question is:
$select = $this->getLayout()->createBlock('core/html_select')
->setName($type.'_address_id')
->setId($type.'-address-select')
->setClass('address-select')
->setExtraParams('onchange="'.$type.'.newAddress(!this.value)"')
->setValue($addressId)
->setOptions($options);
$select->addOption('', Mage::helper('checkout')->__('New Address'));
return $select->getHtml();
Look for magento block rewrite.
You need to rewrite Mage_Checkout_Block_Onepage_Billing and Mage_Checkout_Block_Onepage_Shipping
Just rewrite this blocks in your custom module and define new logic for getAddressesHtmlSelect
function
To set "New address" as default one:
Assembled working sample for you.
array_unshift($options, array('value' => '', 'label'=> Mage::helper('checkout')->__('New Address')));
$select = $this->getLayout()->createBlock('core/html_select')
->setName($type.'_address_id')
->setId($type.'-address-select')
->setClass('address-select')
->setExtraParams('onchange="'.$type.'.newAddress(!this.value)"')
->setOptions($options);
return $select->getHtml();

Magento - Can't delete mulitple select value in the product admin

I created a new attribute (multiple select) with some values, everything works fine but when I want to delete all the selected values for a product, I get the message "The product attribute has been saved." but the values are still selected.
Notes:
I press Ctrl + Click to unselect the last value before I save.
I set the parameter Value Required of my attribute to No
If I save a product without any value selected yet, then no values get selected
My Indexes are properly refreshed
See below two screens, on the left the parameters of my attribute and on the right my multiple select.
I'm running out of ideas so thanks for your help.
This is a known (annoying) behaviour of the Magento Adminhtml forms.
The problem is that if no value is selected for the multiselect, no value for that attribute is posted when the form is submitted.
On the server side Magento then loads the model, sets all the posted attribute values on the model and saves it.
Because no value was posted the original value that was loaded on the model wasn't updated.
As a solution for attributes with a custom source model I tend to provide an empty option with a special option value (e.g. -1). That value must not be 0 or an empty string.
Then I specify a backend model for that attribute that checks for that special value in the _beforeSave() method. If it is found the backend model unsets the attribute on the model instance.
Here is an example:
Source Model:
class Your_Module_Model_Entity_Attribute_Source_Example
extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
{
const EMPTY = '-1';
public function getAllOptions()
$options = array(
array('value' => 1, 'label' => 'One'),
array('value' => 2, 'label' => 'Two'),
array('value' => 3, 'label' => 'Three')
);
if ($this->getAttribute()->getFrontendInput() === 'multiselect')
{
array_unshift($options, array('value' => self::EMPTY, 'label' => ''));
}
return $options;
}
}
Backend Model:
class Your_Module_Model_Entity_Attribute_Backend_Example
extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
public function beforeSave($object)
{
$code = $this->getAttribute()->getAttributeCode();
$value = $object->getData($code);
if ($value == Your_Module_Model_Entity_Attribute_Source_Example::EMPTY)
{
$object->unsetData($code);
}
return parent::beforeSave($object);
}
}
If you find a better workaround please let me know.
There is a feature called <can_be_empty> you need to go to your system.xml and add this configuration into your file:
<can_be_empty>1</can_be_empty>
then inspect the element and remove the selected="selected" and hit save, now you can save the multi-select without any values.
Yes I found this a big pain in the bum too BUT it is an improvement on the previous bug which caused drop down attribute selections to be wiped if you tried to update attributes for several products at once.
Anyway, here is my what I do if I want to remove an option from products using a drop down attribute:
Go to Manage attributes
Click Manage Label Options
Add a temporary option to the list
Assign this new attribute option to all the products you want to
change
Delete the temporary attribute option
All solved.
Add a non existent option to html via chrome/firefox developer tool, select that option and save.
eg.
<option value="99999999">Click this to unselect option</option>
Just ran into this problem in Magento 1.7.0.2, my solution :
Use Firefox with Firebug
right-click the multiselect list, choose Inspect with Element and you'll see something like this at the bottom in Firebug :
XLarge
Double-click on selected, right-click, cut, no more selected attribute and just save the page.

Is it good practice to add own file in lib/Varien/Data/Form/Element folder

I need to create module in Magento which will have few database tables. One of the function of the module is adding multiple images.
For example while being on the "Add new item" or "Edit item" page in the admin, from the left side I have tabs, one of them is "Item Images". When being clicked I want the content of this tab to be my own custom one.
After digging into the code, found out that the way it renders this content, Magento is using one of the Varien_Data_Form_Element classes for each element in the full form. I want to add my own class here that will render form elements the way I want.
Is this a good practice to do so, or there is some other more elegant way of adding own content in the admin forms?
EDIT: I must add that none of the existing classes is helping my problem.
SOLUTION EDIT:
I have a controller in my custom module that is in Mypackage/Mymodule/controllers/Adminhtml/Item.php. In the editAction() method which I am using for adding and creating new items, I am creating 2 blocks, one for the form and one left for the tabs:
$this->_addContent($this->getLayout()->createBlock('item/adminhtml_edit'))
->_addLeft($this->getLayout()->createBlock('item/adminhtml_edit_tabs'));
$this->renderLayout();
The Block/Adminhtml/Edit/Tabs.php block is creating 2 tabs on the left: General Info and Item Images, each of them are rendering different content on the right side using Block classes.
protected function _beforeToHtml()
{
$this->addTab('item_info', array(
'label' => Mage::helper('mymodule')->__('Item Info'),
'content'=> $this->getLayout()->createBlock('item/adminhtml_edit_tab_form')->toHtml(),
));
$this->addTab('item_images', array(
'label' => Mage::helper('mymodule')->__('Item Images'),
'active' => ( $this->getRequest()->getParam('tab') == 'item_images' ) ? true : false,
'content' => $this->getLayout()->createBlock('item/adminhtml_images')->toHtml(),
));
return parent::_beforeToHtml();
}
I wanted the tab item_images to render my own form elements and values, not the default varien form elements.
class Mypackage_Mymodule_Block_Adminhtml_Images extends Mage_Core_Block_Template
{
public function __construct()
{
parent::__construct();
$this->setTemplate('item/images.phtml'); //This is in adminhtml design
}
public function getPostId()
{
return $this->getRequest()->getParam('id');
}
public function getExistingImages()
{
return Mage::getModel('mymodule/item')->getImages($this->getPostId());
}
}
Then in the template app/design/adminhtml/default/default/template/item/images.phtml you can use these values:
//You can add your own custom form fields here and all of them will be included in the form
foreach($this->getExistingImages() as $_img):
//Do something with each image
endforeach;
//You can add your own custom form fields here and all of them will be included in the form
No, it's not. You should never edit or add to files that provided by a vendor. If you absolutely must replace a class file you should use the local code pool. For example, if you wanted to change the behavior of a text field,
lib/Varien/Data/Form/Element/Text.php
You should place a file in the local or community code pool
app/code/local/Varient/Data/Form/Element/Text.php
However, doing the replaces the class, and it becomes your responsibility to maintain compatibility with future versions. That means if Magento Inc. changes lib/Varien/Data/Form/Element/Text.php, you need to update your version to be compatible.
Based on what you said I'd look into creating a class rewrite for the Block class that renders the form.

Change template after user login in joomla 1.5

Anybody ever tried to change joomla 1.5 template in code? Don't know how to do it on current version. I just wanted to change the template after the user login.
So, i wrote code like this :
$mainframe->setTemplate('newtemplate');
But it doesn't works. WHen i see the joomla application.php, whoops, there is no setTemplate function there, but it used to be there before 1.5 (based on my search on the web).
Anyone know how to do it?
Update :
seems that we can set user state and just read that user state, then render. But I don't know where joomla render the template, since I put a code in library/joomla/application.php, insite render(), but it didn't get executed. This is what i did :
function render()
{
$params = array(
'template' => $this->getTemplate(),
'file' => 'index.php',
'directory' => JPATH_THEMES
);
// I added this code, where i set the user state $option.template somewhere else
$template = $mainframe->getUserState( "$option.template", 'FoxySales01VIP' );
if(!empty($template)){
$params['template'] = $template;
}
$document =& JFactory::getDocument();
$data = $document->render($this->getCfg('caching'), $params );
JResponse::setBody($data);
}
Never mind, i solved it.
Just change the code in core library (JDocument Class) to read the template from session, works fine.
Thanks

Resources