4

I am creating a standard Magento widget. In the options tab for the widget I have a field. This field is for filters in the form of key:'value' pairs. I would like the user to be able to dynamically create as many filters as they need.

So, ideally the user clicks a button 'Add new Filter' and a new field is generated below the original field.

widget options

I have an idea that I can use a custom <source_model>, but I am not sure what javascript methods or Mage classes already handle dynamic buttons such as this. I'm thinking there has to be an easy way.

My widget.xml file looks like this:

<?xml version="1.0"?>
    <widgets>
      <namespace_module type="module/links">
        <name>Widget Name</name>
    <description>Display a gizmo</description>
    <parameters>        
      <filters>
        <label>Filters</label>
        <visible>1</visible>
        <required>0</required>
        <type>text</type>
        <source_model>module/filters</source_model>        
      </filters>
    </parameters>
    </namespace_module>
    </widgets>

Then I have app/code/community/Namespace/Module/Model/Filters.php

which looks like:

class Namespace_Module_Model_Filters {

  public function toOptionArray() {
    return array(
      array('value' => 'val', 'val' => '1'),
      array('value' => 'val2', 'val2' => '2'),
      array('value' => 'val3', 'val3' => '3'),
    );
  }

  // Can I do anything here to generate dynamic fields?

}

Perhaps this is not the correct way to go about this? Is it possible to create a custom <type> and generate the buttons there? Maybe I just need more coffee ["])

UPDATE: I'm now looking at the <type>multiline</type> parameter, to see if I can use that. However, I think I'm still going to need to create a custom multiline. The reason is that Varien_Data_Form_Element_Multiline has the line count hardcoded:

public function __construct($attributes=array())
    {
        parent::__construct($attributes);
        $this->setType('text');
        $this->setLineCount(2); // hardcoded
    }
  • The user must be able to click a button 'add new field', which generates a new field and updates the <line_count> attribute, which is currently hardcoded in core. – Tim Hallman May 30 '15 at 14:28
  • Well, looks like it's going to be wasted bounty. – Tim Hallman Jun 1 '15 at 18:19
  • yes u may need some more coffee and also increase the bounty to attract someone to help you :) – MTM Jun 2 '15 at 7:57
  • Maybe it's the lack of coffee again (lol), but I cannot seem to figure out how to award more bounty. – Tim Hallman Jun 2 '15 at 12:49
6
+50

I've not got much experience with widgets, but if this works like any other admin panel form you could make use of Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract and store your filters as a serialised array?

Have a look at Mage_CatalogInventory_Block_Adminhtml_Form_Field_Minsaleqty for an implementation of it.

It should allow you to add dynamic rows and store them all under one serialised attribute, kind of like how this picture shows.

enter image description here

  • Thanks, Luke! It seems Magento widgets don't behave like most admin panels, however the block you quoted is certainly valid as that is where I was monkeying around in the beginning. I'll delve into this some later today and let you know my results. – Tim Hallman Jun 2 '15 at 12:48
  • Good luck! These array inputs are a bit of a paint, just have a delve through how they're implemented in the core and try and recreate. – Luke Rodgers Jun 2 '15 at 13:56
  • I haven't put it together yet, but briefly looking I'm positive you've provided the correct answer. Thanks! – Tim Hallman Jun 2 '15 at 20:23
  • 1
    Cool, good luck with the implementation. The render for these array inputs are a massive pain, but should definitely allow you to do what you want! – Luke Rodgers Jun 3 '15 at 8:44
2

I needed exactly this function and came up with my own widget extension. You can find it on GitHub. But for the impatient here's how to use it:

In your widget.xml you can use this extension as a helper block:

<!-- Widget XML definition -->

        <items>
            <visible>1</visible>
            <label>Items</label>
            <type>array</type> <!-- Use "array" type -->
            <helper_block>
                <type>mp_widgetarray/adminhtml_widget_array</type>
                <data>
                    <columns>
                        <text translate="label">
                            <label>Text</label>
                        </text>
                        <col2 translate="label">
                            <label>Col 2</label>
                        </col2>
                        <!-- Add more columns as needed. -->
                        <!-- Node name will become field name. -->
                    </columns>
                </data>
            </helper_block>
        </items>

<!-- Widget XML definition -->

The values are stored as a base64 AND json_encoded string, so in your widget block class you need to use base64_decode and json_decode.

<?php

class Namespace_Module_Block_Widget_YourWidget
extends Mage_Core_Block_Template
implements Mage_Widget_Block_Interface
{
    /**
     * Get items
     *
     * @return array
     */
    public function getItems()
    {
        $b64 = $this->getData('items');
        $json = base64_decode($b64);

        return json_decode($json, true);
    }

This will yield something like this:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.