I am using Yii Booster, and one of the widgets is TbTotalSumColumn.
When it renders the total in the footer, it uses the following code:
echo $this->totalValue? $this->evaluateExpression($this->totalValue, array('total'=>$this->total)) : $this->grid->getFormatter()->format($this->total, $this->type);
I have used CFormatter and created a 'currency' type, I have applied the formatting directly in the 'value' attribute, I have gone into the widget and applied the currency formatter there. It seems no matter what I do, I can only get either the values in the column to be formatted as currency, or the footer, never both.
Any help would be greatly appreciated.
I created a new class file in the components folder called TbTotalColumnCurrency.php. Then I call TbTotalSumColumnCurrency in my TbExtendedGridView code.
Yii::import('bootstrap.widgets.TbTotalSumColumn');
class TbTotalSumColumnCurrency extends TbTotalSumColumn
{
protected function renderFooterCellContent()
{
if(is_null($this->total))
return parent::renderFooterCellContent();
echo $this->totalValue? $this->evaluateExpression($this->totalValue, array('total'=>number_format($this->total), 2, '.', '')) : $this->grid->getFormatter()->format(number_format($this->total, 2, '.', ''), $this->type);
}
}
Hope this helps
array(
'name'=>'Total',
'type'=>'text',
'value'=>'number_format($data->price*$data->quantity, 2, \'.\', \'\')',
'class'=>'TbTotalSumColumnCurrency'
),
Related
I'm creating a website using Drupal 8. I want to create a menu item link that I could add HTML/Javascript code in it (I'm trying to display a widget that expands on click in the menu rather than displaying it in its own block next to the menu). The only way I could see to add a menu item is to link to a page.
You could work with a derivative. This lets you customize pretty much everything about it and control what is to be made. An example below:
Note: I am assuming you have a general knowledge of custom modules. If not follow this link
Create the following file in your custom module:
# my_module.links.menu.yml
my_module.custom_links:
deriver: \Drupal\my_module\Plugin\Derivative\CustomLinkDerivative
And now for the derivative class (Located under my_module/src/Plugin/Derivative)
<?php
namespace Drupal\my_module\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class CustomLinkDerivative extends DeriverBase implements ContainerDeriverInterface {
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static();
}
/**
* {#inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$links['custom_menulink'] = [
'title' => t('Custom menulink'),
'menu_name' => 'main',
'route_name' => 'entity.node.canonical',
'parent' => footer,
'route_parameters' => [
'node' => 1,
]
] + $base_plugin_definition;
return $links;
}
}
Note: Derivatives get triggered during rebuild of cache!
This just creates a link in the footer that directs to node 1. You can add all sort of stuff and logic to your liking. Hope this helps you :)
I have pagination with links [1, 2, 3, 4, 5, 6, 7, 8 ... 99, 100] and how can I change limit to display [1, 2, 3, ... 98, 99, 100] ? I have custom paginator class, but I can't find this limit to override in my new class.
By checking the classes I found that you have to override the presenter used by the Paginator.
Its done by calling render($presenter) your presenter must extend BootstrapThreePresenter If you wish to use bootstrap links and you just have to override the constructor and pass number of links you want on each side $this->window = UrlWindow::make($numberOfLinksEachSide)
These are just instructions you'll have to look by yourself, I'm sorry for not being able to provide complete code, I'm on phone.
Please let me know if this worked.
This is my solution to the same problems... In LengthAwarePaginator updated function links:
public function links($view = null, $data = [], $onEachSide = 3)
{
if(!$data){
$data = [];
}
$this->onEachSide = $onEachSide;
return $this->render($view, $data);
}
And in URLWindow function make:
public static function make(PaginatorContract $paginator)
{
return (new static($paginator))->get($paginator->onEachSide);
}
This removes the parameter $onEachSide from function make - which is never passed in anywhere - and allows it to be passed to function links as a parameter.
To use this you need to call this links method like this:
{{ $collection->links('view-to-use'|null, $dataArray|null, 2)}}
Where 2 is the number on each side.
You can do this easily by changing some core fields (although not recommended to change core files).
Find- vendor/laravel/framework/src/Illuminate/Pagination and go to UrlWindow. On this page find some parameters like- $onEachSide, $window. Change and play with these.
I am trying to implement Dashboard widget class (found here: http://harpanet.com/programming/php/codeigniter/dashboard/index#installation) but it is giving me error Unable to load the requested class
I have tried to add this class in autoload as well as menually to my controller $this->load->library('dash') but this also giving the same error.
I have checked dash.php and found below method private function __example__() but can't understand what the developer is saying in comment.
class Dash
{
private function __example__()
{
/*
* This function is purely to show an example of a dashboard method to place
* within your own controller.
*/
// load third_party hArpanet dashboard library
$this->load->add_package_path(APPPATH.'third_party/hArpanet/hDash/');
$dash =& $this->load->library('dash');
$this->load->remove_package_path(APPPATH.'third_party/hArpanet/hDash/');
// configure dashboard widgets - format: type, src, title, cols, alt (for images)
$dash->widgets = array(
array('type'=>'oop', 'src'=>'test_dash', 'title'=>'Test OOP Widget', 'cols'=>3),
// if 'title' is set to FALSE, the title block is omitted entirely
// note: this is an 'html' widget but is being fed content from a local method
array('type'=>'html', 'src'=>self::test_method(), 'title'=>false, 'cols'=>3),
array('type'=>'file', 'src'=>'saf_inv.htm', 'title'=>'Safety Investigation'),
// multi-content widget - set widget title in outer array (also note use of CI anchor to create a link)
array('title'=>anchor('tz', 'TARGET ZERO'),
// sub-content follows same array format as single content widget
// 'img' content can also have an 'alt' text
array('type'=>'img', 'src'=>'saf_tzout.gif', 'alt'=>'Action Completed'),
array('type'=>'file', 'src'=>'saf_tz.htm'),
array('type'=>'file', 'src'=>'ave_close.htm', 'title'=>'Average Time to Close')
),
array('type'=>'file', 'src'=>'saf_meet.htm', 'title'=>'Safety Meeting'),
array('type'=>'file', 'src'=>'saf_acc.htm', 'title'=>'Accident Investigation'),
array('type'=>'file', 'src'=>'saf_hazmat.htm', 'title'=>anchor('hazmat', 'HAZMAT')),
array('type'=>'file', 'src'=>'saf_cont.htm', 'title'=>'Loss of Containment'),
array('type'=>'file', 'src'=>'saf_worksinfo.htm', 'title'=>'Works Information'),
// an action widget - 'clear' will generate a blank widget with a style of clear:both
array('type'=>'clear'),
// multi-content widget - width can be set using the 'cols' param in outer array
array('title'=>'RAG Report', 'cols' => 2,
array('type'=>'file', 'src'=>'saf_rag.htm'),
array('type'=>'img', 'src'=>'ProcSaf.gif')),
array('type'=>'file', 'src'=>'saf_chrom.htm', 'title'=>'Chrome checks'),
);
// populate the view variable
$widgets = $dash->build('safety');
// render the dashboard
$this->load->view('layout_default', $widgets);
}
...................
} // end of Dash class
Installation path is root/application/third_party/hArpanet/hDash/libraries/dash.php
How can I load this class to my system and use widgets?
You have to create a library that initialize the third party class:
for Eg:
--in library create a file named mydash.php --
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MyDash
{
public function __construct()
{
require_once APPPATH.'third_party/hArpanet/hDash/libraries/dash.php';
}
}
load the library using:
$this->load->library('mydash');
then you are able to use the Dash class. Also able to load library in autoload.
Thank you...
Sorry to hear you were having problems, (I've only just noticed this SO entry). Thanks to ReNiSh for his workaround, much appreciated.
You do not however need to use the library approach to implement the 'require_once' of hDash. I have now written a walkthrough for getting hDash installed and running, which you can find here: http://harpanet.com/programming/php/codeigniter/dashboard/walkthrough
Also, note that as of yesterday, 3rd Feb 2014, hDash has been updated to version 1.2.
I am using PDF Parser from http://pdfparser.org/
I create files application/libraries/pdf.php
class Pdf
{
public function __construct()
{
require_once APPPATH."/third_party/pdfparser.php";
}
}
Then I create file application\third_party\pdfparser.php
if (!defined('pdfparser')) {
define('pdfparser', dirname(__FILE__) . '/');
require(pdfparser . 'pdfparser/autoload.php');
}
Last, I include PDF Parser Library in Directory => application\third_party\pdfparser
I am using ZF2 for my project. And this is an e-commerce site. So I am dealing with currencies.
In ZF2 there is a view helper named currencyFormat()
I am from Turkey so my main currency format is TRY (This is the ISO code of Turkish Lira). But in Turkey we do not use TRY as Currency icon. The icons are "$" for USD, € for "EUR" and "TL" for Turkish Lira (TRY).
So when I format a currency for TRY I am doing it like this in view script:
<?php
echo $this->currencyFormat(245.40, 'TRY', 'tr_TR');
?>
The result of this code is "245.40 TRY". But it has to be "245.40 TL"
Is there a way to solve this? I do not want to use replacement function.
I'm guessing when you say I do not want to use replacement function you mean it would be laborious to do a str_replace every time you call the helper. The solution would be to replace the helper with your own. Here's a quick how to
First create a helper of your own which extends the existing helper and handles the replacement if necessary...
<?php
namespace Application\View\Helper;
use Zend\I18n\View\Helper\CurrencyFormat;
class MyCurrencyFormat extends CurrencyFormat
{
public function __invoke(
$number,
$currencyCode = null,
$showDecimals = null,
$locale = null
) {
// call parent and get the string
$string = parent::__invoke($number, $currencyCode, $showDecimals, $locale);
// format to taste and return
if (FALSE !== strpos($string, 'TRY')) {
$string = str_replace('TRY', 'TL', $string);
}
return $string;
}
}
Then in Module.php, implement the ViewHelperProviderInterface, and provide it with details of your helper
//Application/Module.php
class Module implements \Zend\ModuleManager\Feature\ViewHelperProviderInterface
{
public function getViewHelperConfig()
{
return array(
'invokables' => array(
// you can either alias it by a different name, and call that, eg $this->mycurrencyformat(...)
'mycurrencyformat' => 'Application\View\Helper\MyCurrencyFormat',
// or if you want to ALWAYS use your version of the helper, replace the above line with the one below,
//and all existing calls to $this->currencyformat(...) in your views will be using your version
// 'currencyformat' => 'Application\View\Helper\MyCurrencyFormat',
),
);
}
}
As of 1 March 2012 sign for Turkish Lira is TRY. http://en.wikipedia.org/wiki/Turkish_lira
So ZF outputs it right I think.
I have rewritten the app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php
with app/code/local/Mage/Adminhtml/Block/Sales/Order/Grid.php
& have created a renderer to display customer's email column in grid.
Here is my renderer file:
class Mage_Adminhtml_Block_Renderer_Customer extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
$model = Mage::getModel('customer/customer')->load($row->getCustomerId());
return $model->getEmail();
}
}
& here is my Grid changes (I just added a column, & I intend to make it search-able)
$this->addColumn('billing_name', array(
'header' => Mage::helper('sales')->__('Bill to Name'),
'index' => 'billing_name',
));
// this is new col.
$this->addColumn('customer_email', array(
'header' => Mage::helper('sales')->__('Customer Email'),
'renderer' => 'adminhtml/renderer_customer',
));
I am getting what I want. But this col/ has a lot of whitespace both leading & trailing
due to this I think this col. is not search-able.
Can Anybody suggest what can be done in order to remove these white spaces
Many thanks in advance
EDIT
After few days I have figured out that these white spaces are common in the grid & it has nothing to do with the search-able option.
Can anybody suggest that how to make a custom column in search-able that has been added to a grid by using a renderer ???
Thanks
2 EDIT
Guys According to the clockworkgeek I have customized
my _prepareCollection() method of the overwritten grid as follows
protected function _prepareCollection()
{
// 'sales/order_collection' is changed from 'sales/order_grid_collection'
$collection = Mage::getResourceModel('sales/order_collection');
$collection->addAttributeToSelect('*')
->joinAttribute('billing_firstname', 'order_address/firstname', 'billing_address_id', null, 'left')
->joinAttribute('billing_lastname', 'order_address/lastname', 'billing_address_id', null, 'left')
->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
->joinAttribute('billing_fax', 'order_address/fax', 'billing_address_id', null, 'left')
->joinAttribute('billing_telephone', 'order_address/telephone', 'billing_address_id', null, '')
->addExpressionAttributeToSelect('billing_name',
'CONCAT({{billing_firstname}}, " ", {{billing_lastname}})',
array('billing_firstname', 'billing_lastname'))
->addExpressionAttributeToSelect('shipping_name',
'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
array('shipping_firstname', 'shipping_lastname'));
$this->setCollection($collection);
return parent::_prepareCollection();
}
I also have investigated that for Grid Magento obtains data from sales_flat_order_grid table not from sales_flat_order this is the reason it was reporting error of unknow column as per the clockworkgeek first solution
THe issue with current implementation is Magento reports an error Fatal error: Call to undefined method Mage_Sales_Model_Mysql4_Order_Collection::addExpressionAttributeToSelect()
as Mage_Sales_Model_Mysql4_Order_Collection does not have addExpressionAttributeToSelect method instead it has addExpressionFieldToSelect method
Now I need help to write a proper syntax for addExpressionAttributeToSelect method. Changing the method name only is not helping me. I also have referred the docs
Add 'index' => 'email' to your addColumn() in the Grid.php and then try something like this:
$emailaddress = trim($row->getData($this->getColumn()->getIndex()));
return ''.$emailaddress.'';
That way you strip the whitespace and also provide a clickable link for your admin users :)
In response to the second part of your question may I offer this little trick.
Adminhtml grid columns can take an extra filter_condition_callback parameter which takes a standard PHP callback type. In your case you might modify the grid like this:
protected function _prepareColumns() {
// ...
$this->addColumn('customer_email', array(
'header' => Mage::helper('sales')->__('Customer Email'),
'renderer' => 'adminhtml/renderer_customer',
'filter_condition_callback' => array($this, 'addCustomerEmailFilter'),
));
}
public function addCustomerEmailFilter(Mage_Eav_Model_Entity_Collection_Abstract $collection, Mage_Adminhtml_Block_Widget_Grid_Column $column) {
$collection->addAttributeToFilter('customer_email', $column->getFilter()->getValue());
}
But all that still feels a bit messy, especially if the attribute is not a first class column. For those unusual cases you can combine the output processing and searching in the collection class...
protected function _initSelect() {
parent::_initSelect();
// email is existing column, customer_email is generated column
$this->addExpressionAttributeToSelect(
'customer_email',
'TRIM({{email}})',
array('email')
);
return $this;
}
The addExpressionAttributeToSelect() method temporarily stores the SQL expression as a mapped field so that when a grid tries to search for customer_email it gets substituted by the expression instead.