Silverstripe 3.4 gridfieldextensions GridFieldEditableColumns - php

I am using gridfieldextensions and GridFieldEditableColumns on a GridFieldConfig_RelationEditor.
How can the GridField - Actions be moved to the right?
[![enter image description here][1]][1]
class StaffCatObject extends DataObject
private static $many_many = array(
'Staffs' => 'Staff'
);
private static $many_many_extraFields = array(
'Staffs' => array(
'SortOrder' => 'Int',
'Display' => 'Boolean(1)'
),
);
public function getCMSFields() {
$fields = parent::getCMSFields();
.......
$GridFieldConfig = GridFieldConfig_RelationEditor::create();
$GridFieldConfig->removeComponentsByType('GridFieldPaginator');
$GridFieldConfig->addComponent(new GridFieldPaginator(20));
$GridFieldConfig->addComponent(new GridFieldEditableColumns());
$GridFieldConfig->addComponent( new GridFieldDeleteAction());
$items = $this->Staffs();
if (class_exists('GridFieldOrderableRows') && !$items instanceof UnsavedRelationList) {
$GridFieldConfig->addComponent(new GridFieldOrderableRows('SortOrder'));
}
$gridfield = new GridField("Staff", $this->StaffCatTitle, $this->Staffs()->sort('SortOrder'), $GridFieldConfig); //->sort('SortOrder')
$gridfield->getConfig()->getComponentByType('GridFieldEditableColumns')->setDisplayFields(array(
'Display' => array(
'callback' => function ($record, $column, $gridfield) {
return new CheckboxField('Display');
},
'title' => 'Display'
),
'AdImpressum' => array(
'title' => 'Ad Impressum',
'field' => 'CheckboxField'
)
));
$fields->addFieldToTab('Root.Main', $gridfield);
return $fields;
class Staff extends DataObject
private static $belongs_many_many = array(
'StaffCatObjects' => 'StaffCatObject'
);
static $summary_fields = array(
'Thumbnail' => 'Thumbnail',
'StaffTitle' => 'Name',
'Email' => 'Email',
'CheckDisplay' => 'wird angezeigt in'
);

You are appending the end of the GridField. One solution is to empty the Actions column with the following code:
$config->removeComponentsByType('GridFieldDeleteAction');
$config->removeComponentsByType('GridFieldEditButton');
Just after creating the GridField, and then readd them after adding GridFieldEditableColumns with the following code:
$config->addComponent(new GridFieldEditButton());
$config->addComponent(new GridFieldDeleteAction());
Hint:
Your first initialization is unnecessary:
$GridFieldConfig = GridFieldConfig_RelationEditor::create();
$GridFieldConfig->removeComponentsByType('GridFieldPaginator');
$GridFieldConfig->addComponent(new GridFieldPaginator(20));
$GridFieldConfig->addComponent(new GridFieldEditableColumns());
$GridFieldConfig->addComponent( new GridFieldDeleteAction());
It can be done with just:
$GridFieldConfig = GridFieldConfig_RelationEditor::create(20);
More info here: https://github.com/silverstripe/silverstripe-framework/blob/3.4.5/forms/gridfield/GridFieldConfig.php#L232

Related

Use setQueriedColumns on GridField

I have a dataobject which I want to use on a GridField on a page but I want to limit the columns displayed. I used setQueriedColumns() to list the fields I wanted but it is still displaying the default $summary_fields from the dataobject.
MyActivity dataobject:
class MyActivity extends DataObject{
private static $db = array(
'Title' => 'Varchar(255)',
'URLSegment' => 'Varchar(512)',
'IsPublished' => 'Boolean',
'IsPublic' => 'Boolean',
'IsBooked' => 'Boolean',
'MaxDuration' => 'Int',
'PricePoint' => 'Int',
'Summary' => 'HTMLText',
'Body' => 'HTMLText',
'Sort' => 'Int'
);
private static $has_one = array(
'FileAttachment' => 'File'
);
private static $summary_fields = array(
'Title' => 'Name',
'URLSegment' => 'URLSegment',
'IsPublished' => 'Published',
'IsBooked' => 'Booked',
'Events.Count' => 'List of Events',
'Categories.Count' => ' of Categories'
);
static $has_many = array(
'Events' => 'MyEvent'
);
static $belongs_many_many = array(
'Categories' => 'MyCategory'
);
...
}
MyActivityPage:
class MyActivityPage extends Page{
public function getCMSFields(){
$fields = parent::getCMSFields();
$GridFieldConfig = GridFieldConfig_RecordEditor::create();
$fields->addFieldToTab('Root.Courses',
GridField::create(
'FileAttachment',
'Activity List',
MyActivity::get()->filter(['IsPublished' => 1])
->setQueriedColumns([
'Title',
'URLSegment',
'IsPublished'
]),
$GridFieldConfig
)
);
return $fields;
}
...
}
After thorough searching, I got what I'm looking for. Apparently, we can set the columns using GridFieldConfig then limit the fields by overriding the $summary_fields using the setDisplayFields() method in the GridFieldDataColumns object.
This could be handy to people who are looking for similar solution.
$gridField = GridField::create(
'FileAttachment',
'Activity List',
MyActivity::get()->filter(['IsPublished' => 1]),
$GridFieldConfig
)
$gridField->getConfig()
->getComponentByType('GridFieldDataColumns')
->setDisplayFields([
'Title' => 'Title',
'URLSegment' => 'URLSegment',
'IsPublished' => 'IsPublished'
]);
$fields->addFieldToTab('Root.Courses',$gridField);`

How to combine a fields_list + .tpl view in 1 admincontroller?

I can't figure out how to display, in my custom admin controller, 1 fields_list + content of a .tpl file. The goal is to display my product keys in stock + some extra features below (content from a tpl file).
I can display either the fields list OR the message from the .tpl file. But not combined... I found a tutorial online and this comes very close, but not working.
<?php
require_once(_PS_MODULE_DIR_ . 'avanto_key/classes/AvantoStock.php');
class AdminAvantokeyStockController extends ModuleAdminController
{
protected $position_identifier = 'id_avanto_keys';
public function __construct()
{
//$this->fields_form = $this->fieldForm();
$this->bootstrap = true;
$this->table = 'avanto_keys'; // DB table name where your object data stored
$this->className = "AvantoStock"; // The class name of my object
//$this->identifier = 'id_avanto_keys';
//$this->list_id = 'id_avanto_keys';
$this->_defaultOrderBy = 'id_avanto_keys';
//$this->lang = FALSE;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?')), );
//Shop::addTableAssociation($this->table, array('type' => 'shop'));
parent::__construct();
$this->_select = 'pl.`name` as product_name, a.`serial_key` as serial_display';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang`
= '.(int)$this->context->language->id.')';
}
public function renderView()
{
$tpl = $this->context->smarty->createTemplate(
dirname(__FILE__).
'/../../views/templates/admin/view.tpl');
return $tpl->fetch();
}
public function renderList()
{
$this->toolbar_title = $this->l('Stock Management');
$this->toolbar_btn['new'] = null;
$this->fields_list = array(
'id_avanto_keys' => array(
'title' => $this->l('ID Key'),
'width' => 140,
),
'id_product' => array(
'title' => $this->l('Product ID'),
'width' => 140,
),
'serial_key' => array(
'title' => $this->l('Serial Keys'),
'width' => 140,
),
'product_name' => array(
'title' => $this->l('Product Name'),
'width' => 140,
),
);
return parent::renderList();
}
public function init()
{
parent::init();
}
public function initContent()
{
$this->context->smarty->assign(array(
'form' => $form,
'base_dir' => _PS_MODULE_DIR_,
));
$this->setTemplate('stock.tpl');
$lists = parent::initContent();
$this->renderList();
$lists .= parent::initContent();
return $lists;
}
public function renderForm()
{
$this->display = 'edit';
$this->initToolbar();
$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->l('Edit product key'),
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Key ID'),
'name' => 'id_product',
),
array(
'type' => 'text',
'label' => $this->l('Product ID'),
'name' => 'id_avanto_keys',
),
array(
'type' => 'text',
'label' => $this->l('Serial Key'),
'required' => true,
'name' => 'serial_key',
),
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
);
return parent::renderForm();
}
}
?>
The code above only displays the message hello world and not my product listing.
Anyone has an idea how to combine this?
Thanks in advance!!!
It's a little bit confused, we have to make some tidy :):
First:
The fields of the list it's better to declare in the __construct so:
public function __construct()
{
$this->module = 'YourModuleName'; // Here you have to put your module name
$this->bootstrap = true;
$this->table = 'avanto_keys'; // DB table name where your object data stored
$this->className = "AvantoStock"; // The class name of my object
//$this->identifier = 'id_avanto_keys';
//$this->list_id = 'id_avanto_keys';
$this->_defaultOrderBy = 'id_avanto_keys';
//$this->lang = FALSE;
$this->explicitSelect = true; // This if you do a select manually after
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?')), );
//Shop::addTableAssociation($this->table, array('type' => 'shop'));
$this->_select = 'pl.`name` as product_name, a.`serial_key` as serial_display';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang`
= '.(int)$this->context->language->id.')';
$this->fields_list = array(
'id_avanto_keys' => array(
'title' => $this->l('ID Key'),
'width' => 140,
),
'id_product' => array(
'title' => $this->l('Product ID'),
'width' => 140,
),
'serial_key' => array(
'title' => $this->l('Serial Keys'),
'width' => 140,
),
'product_name' => array(
'title' => $this->l('Product Name'),
'width' => 140,
),
);
parent::__construct();
}
Second
The parent renderList method make other stuff, let's separate that from what do you want to display:
public function renderList()
{
// Here we retrieve the list (without doing any strange thing)
$list = parent::renderList();
// Assign some vars to pass to our custom tpl
$this->context->smarty->assign(
array(
'var1' => "Test",
'var2' => "Test2"
)
);
// Get the custom tpl rendered
$content = $this->context->smarty->fetch(_PS_MODULE_DIR_ . "avanto_key/views/templates/admin/avantokeystock/customcontent.tpl");
// return the list plus your content
return $list . $content;
}
Third
Leave the parent initContent as is, do not override, because he make a lot of stuffs
I guess that is a great point to start :)
Try this way and let me know ;)

Render helper form from prestashop admin controller

I am trying to add a helper form that lets the user upload images for two languages that the user can select.
However I am stuck with the form and cannot render it in the view. Here is my controller code:
<?php
class AdminWineoHeaderImgController extends ModuleAdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->lang = (!isset($this->context->cookie) ||
!is_object($this->context->cookie)) ? intval(Configuration::get('PS_LANG_DEFAULT')) : intval($this->context->cookie->id_lang);
parent::__construct();
}
public function display()
{
parent::display();
}
public function renderList()
{
$this->renderForm();
$return = $this->context->smarty->fetch(_PS_MODULE_DIR_.'wineoheaderimg/views/templates/hook/adminwineoimg.tpl');
return $return;
}
public function renderForm()
{
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->module->l('Wineo Header Img Configuration'),
'icon' => 'icon-envelope',
),
'input' => array(
array(
'type' => 'file',
'label' => $this->module->l('Add images'),
'name' => 'enable_grades',
'id' => 'uploadwineoheaderimg',
'required' => false,
'desc' => $this->module->l('Choose images that will appear on the front page.'),
),
array(
'type' => 'select',
'label' => $this->l('Languages:'),
'name' => 'category',
'required' => true,
'options' => array(
'query' => $options = array(
array(
'id_option' => 1, // The value of the 'value' attribute of the <option> tag.
'name' => 'EN', // The value of the text content of the <option> tag.
),
array(
'id_option' => 2,
'name' => 'BG',
),
),
'id' => 'id_option',
'name' => 'name',
),
),
),
'submit' => array('title' => $this->module->l('Save')),
),
);
$helper = new HelperForm();
$helper->table = 'wineoheaderimg';
$helper->default_form_language = (int) Configuration::get('PS_LANG_DEFAULT');
$helper->allow_employee_form_lang = (int) Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG');
$helper->submit_action = 'wineo_header_img_pc_form';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->module->name.'&tab_module='.$this->module->tab.'&module_name='.$this->module->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => array(
'wineo_header_img' => Tools::getValue('enable_grades', Configuration::get('WINEO_HEADER_IMG')),
),
'languages' => $this->context->controller->getLanguages(),
);
return $helper->generateForm(array($fields_form));
}
}
Where should I call the method renderForm()? I have tried in the admin hooks and basically everywhere I could imagine.
Any help will be appreciated!
Well you are calling renderForm() inside renderList(), (I assume you want the form to display by default when you open controller page) but you don't assign the form to template.
public function renderList()
{
$form = $this->renderForm();
// To load form inside your template
$this->context->smarty->assign('form_tpl', $form);
return $this->context->smarty->fetch(_PS_MODULE_DIR_.'wineoheaderimg/views/templates/hook/adminwineoimg.tpl');
// To return form html only
return $form;
}
So if you want the form inside your adminwineoimg.tpl
{* Some HTML *}
{$form_tpl}
{* Some HTML *}

Silverstripe 3.1 - Export Dataobject with all relations?

I need to export the whole data of an dataobject. Database fields and relations.
private static $db = array (
'URLSegment' => 'Varchar(255)',
'SKU' => 'Text',
'Title' => 'Text',
'Price' => 'Text',
'Content' => 'HTMLText',
'ItemConfig' => 'Int',
'Priority' => 'Int'
);
private static $has_one = array (
'Visual' => 'Image'
);
private static $has_many = array (
'Sizes' => 'ShopItem_Size',
'Colors' => 'ShopItem_Color'
);
private static $many_many = array (
'Visuals' => 'Image',
'Categories' => 'ShopCategory'
);
I added everything to getExportFields(). But as expected the result for the relations is "ManyManyList" or "HasManyList"
public function getExportFields() {
return array(
'SKU' => 'SKU',
'Title' => 'Title',
'Price' => 'Price',
'Content' => 'Content',
'ItemConfig' => 'ItemConfig',
'Visual' => 'Visual',
'Visuals' => 'Visuals',
'Sizes' => 'Sizes',
'Colors' => 'Colors',
'Categories' => 'Categories'
);
}
Is it possible to create such an export?
Thank you in advance
You can use any method name instead of a field/relation name in the exportFields array.
In your ModelAdmin class
public function getExportFields() {
return array(
'SKU' => 'SKU',
'Title' => 'Title',
'CategoryNames' => 'Categories'
);
}
and just have a method with that name on the DataObject, returning the relation data as a string:
public function CategoryNames(){
$catNames = array();
foreach($this->Categories() as $cat){
$catNames[] = $cat->getField('Title');
}
//use a separator that won't break the CSV file
return join("; ", $catNames);
}
I think this is even way better than the modeladmin creating magic fields in your CSV file,
that would make it inconsistent...

Using yii with dynamic data and highcharts

Hi everybody thanks for reading i was wandering how you can insert dynamic data into the highcharts extension for example i have the highcharts extension as follows (location of code =>Reprting/index):
$this->Widget('ext.highcharts.HighchartsWidget', array(
'options'=>array(
'credits' => array('enabled' => false),
'title' => array('text' => $graphTitle),
'xAxis' => array(
'categories' => array('Apples', 'Bananas', 'Oranges')
),
'yAxis' => array(
'title' => array('text' => 'Fruit eaten')
),
'series' => array(
array('name' => 'Jane', 'data' => array(3, 6, 7)),
array('name' => 'John', 'data' => array(5, 7, 3))
) )));
And i have the following code in the controller :
public function actionIndex()
{
$model= $this->loadModel();
$dataProvider=new CActiveDataProvider('Reporting');
$graphTitle= 'Price Per Product';
$this->render('index',array(
'dataProvider'=>$dataProvider, 'graphTitle'=>$graphTitle, 'model'=>$model,
));
}
And the following code is the model :
class Reporting extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return '{{price}}';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('id_product, id_channel', 'required'),
array('id_product, id_channel', 'numerical', 'integerOnly'=>true),
array('price_min, price_max', 'numerical'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id_price, id_product, id_channel, price_min, price_max', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'idChannel' => array(self::BELONGS_TO, 'Channel', 'id_channel'),
'idProduct' => array(self::BELONGS_TO, 'Product', 'id_product'),
);
}
public function attributeLabels()
{
return array(
'id_price' => __('Id Price'),
'id_product' => __('Id Product'),
'id_channel' => __('Id Channel'),
'price_min' => __('Price Min'),
'price_max' => __('Price Max'),
);
}
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('id_price',$this->id_price);
$criteria->compare('id_product',$this->id_product);
$criteria->compare('id_channel',$this->id_channel);
$criteria->compare('price_min',$this->price_min);
$criteria->compare('price_max',$this->price_max);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
How do i put this all together to achieve a dynamically driven graph
One sample for you:
<?php
$xAxis = array(1,2,3);
$yAxis = array(4,5,6);
$this->Widget('ext.highcharts.HighchartsWidget',
array(
'id' => 'something',
'options'=> array(
'chart' => array(
'defaultSeriesType' => 'bar',
'style' => array(
'fontFamily' => 'Verdana, Arial, Helvetica, sans-serif',
),
),
'title' => array(
'text' => 'title',
),
'xAxis' => array(
'title' => array(
'text' => 'xTitle,
),
'categories' => $xAxis,
'labels' => array(
'step' => 1,
'rotation' => 0,
'y' => 20,
),
),
'yAxis' => array(
'title' => array(
'text' => 'yTitle,
),
),
'series' => array(
array(
'name' => 'seriesName',
'data' => $yAxis,
'shadow' => false,
)
)
)
)
);
?>
To customize it, you'll have to build your own $yAxis, $xAxis arrays, and modify title and settings. For more info, take a look at the official Highcharts doc.

Categories