How to make Yii CButtonColumn custom button global? - php

I was using Yii's CGridView(actually it's yiistrap's TbGridView), I created a custom CButtonColumn template with a listen button, everything works fine until I found myself copy this code every where I need a listen button for the table list.
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
'template'=>'{listen}{delete}',
'buttons'=>array(
'listen'=>array(
'label'=>'listen',
'options' => array('class'=>'view headphones'),
'icon' => 'icon-headphones',
'url' => '#',
'visible' => '$data->filename_32',
),
),
),
Is there something I can do to make this little piece of code globally configured? Such as:
array(
'template'=>'{listen}{delete}',
'buttons'=>array(
'listen' => 'xxxx.widgets.buttons.Listen',
)
)
Something like this.

You can! In your config/main.php, add:
'components' => array(
'widgetFactory' => array(
'widgets' => array(
'bootstrap.widgets.TbButtonColumn' => array(
'template' => '{listen}{delete}',
'buttons' => array(
'listen' => 'xxxx.widgets.buttons.Listen',
)
),
)
)
),
This method is mainly used to pre-configure internal widgets though, in situations where you can't control the exact class of the widget that'll be loaded. In your case it looks like you specify the widget classname manually though, so simply overriding the TbButtonColumn widget could be an easier and cleaner solution:
class MyTbButtonColumn extends TbButtonColumn {
public $template = '{listen}{delete}';
public $buttons = array(
'listen' => 'xxxx.widgets.buttons.Listen',
);
}
array(
'class' => 'MyTbButtonColumn',
),

Related

How to remove route on overrided module?

I added zfcUser module to my project via Composer and overrided it in the module ZfcUserOverride. I want trailing slash work, so I added route in overrided module.
zfcUserOverride file module.config.php contents below:
<?php
$config = array(
'view_manager' => array(
'template_path_stack' => array(
'zfcuser' => __DIR__ . '/../view',
),
),
'controllers' => array(
'invokables' => array(
'zfcuser' => 'ZfcUserOverride\Controller\UserController',
),
)
);
$config['router']['routes']['zfcuser']['child_routes']['trailing_slash'] = array(
'type' => 'Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'zfcuser',
'action' => 'index',
),
),
);
return $config;
I added new path, everythin is working correct.
But what if I want remove route? How to do this? I need somethink like:
$config['router']['routes']['zfcuser']['child_routes']['login'] = null;
Help please. Thank you.
In zfcUserOverride you will need to override the route config rather than add a new one.
This can easily be done by using the same array key when defining the routes.
For example; should I wish to modify the login route to allow the extra slash I would use this:
// zfcUserOverride/config/module.config.php
'router' => array(
'routes' => array(
'zfcuser' => array(
'child_routes' => array(
'login' => array(
'type' => 'Segment',
'options' => array(
'route' => '/login[/]',
),
),
),
),
),
);
Internally ZF2 will combine/merge all module configuration into one complete array using array_replace_recursive(). Matching configuration keys will therefore be replaced by modules that have loaded after.
So you will also need to ensure that you have it correctly configured in application.config.php
array(
'modules' => array(
//...
'ZfcUser',
'ZfcUserOverride', // Loads after
// ...
),
);
Here the answer.
#Sharikov Vladislav, I want to say something to you.
In this question I answered to your question and you choose the correct answer to somebody that just update his answer with my content 10 hours later.
I do not want to start a flame war, what I ask is just to be correct to whom used its time to help you.
And also I think you must use search engines prior to post here, you are asking a question for every single step of your development process and it is clear you are putting no effort on searching a solution by yourself.
Just sayin..

How to make three gridviews in the same page using tabs in Yii framework

I'm new to Yii framework. Currently I have three models test1,test2,test3. I created admin pages for all the three models. So I can view gridview for each model individually.
Now , I want to use single page for all the three gridview. i.e I want to create three tabs in that page. Each tab should open a gridview of that corresponding model name.
How can I do this.
I'v passed $model and $form which is my active form to each tab by rendering it partially,
put your grids in 'view/_form_firstPart' and 'view/_form_second'
$this->widget('bootstrap.widgets.TbTabs', array(
'id' => 'tabs',
'type' => 'tabs', // '', 'tabs', 'pills' (or 'list')
'tabs' => array(
array(
'label' => 'someLabel',
'content' => $this->renderPartial('_form_firstPart', array(
'model' => $model,
'form' => $form,
)
,true),
'active' => true,
),
array(
'label' => 'anotherLabel',
'content' => $this->renderPartial('_form_second', array(
'model' => $model,
'form' => $form,
) ,true),
),
)));
If you are not using bootstrap,than you can use cjuitabs,
$this->widget('zii.widgets.jui.CJuiTabs', array(
'tabs'=>array(
'first model' =>array('content'=>$tab_1),
'second model' =>array('content'=>$tab_2),
),
// additional javascript options for the tabs plugin
'options'=>array(
'collapsible'=>true,
),
));

How to use AssetManager filter for Zend Framework 2?

I'm trying to use AssetManager module with Zend Framework 2.
I have a problem with using filter. At the moment I can combine css files with following (in module.config.php):
'resolver_configs' => array(
'collections' => array(
'css/combined.css' => array(
'css/a.css',
'css/b.css'
),
'paths' => array(
__DIR__ . '/../public'
),
),
),
The problem is I cannot minify a css file with following:
'filters' => array(
'css/combined.css' => array(
array(
'filter' => 'UglifyCss'
),
),
),
I have also tried CssMin filter, but it doesn't minify either.
There is the documentation about filter, and the filter does not work out of the box and it needs to provide dependencies. If the filters like UglifyCss and CssMin need dependencies, then how do I know what dependencies are needed and how do I provide them?
The filters don't work on collections. They can only be applied to individual assets. If you wish to minify a stylesheet collection you'll have to minify the individual components inside of the collection.
Considering the following configuration:
'resolver_configs' => array(
'collections' => array(
'css/combined.css' => array(
'css/a.css',
'css/b.css'
),
'paths' => array(
__DIR__ . '/../public'
),
),
),
You'll need these filters:
'filters' => array(
'css/a.css' => array(
array(
'filter' => 'UglifyCss'
),
),
'css/b.css' => array(
array(
'filter' => 'UglifyCss'
),
),
),
As to supplying the dependencies for filters, you can look inside of the filters themselves. They usually contain a link to the required file(s): https://github.com/kriswallsmith/assetic/blob/master/src/Assetic/Filter/JSMinFilter.php#L21

Extending ZfcUser with Zend Framework 2

Hi I am trying to write a user registration form using ZfcUser module for Zend Framwork 2 and would like some advice on best practices when adding more user fields.
So far I have created my own module called "WbxUser" and as outlined in the modules wiki pages I have added a custom field called "userlastname" to ZfcUser's registration form by using the Event Manager in my modules bootstrap function like so.
Code:
//WbxUser.Module.php
namespace WbxUser;
use Zend\Mvc\MvcEvent;
class Module {
public function onBootstrap(MvcEvent $e){
$events = $e->getApplication()->getEventManager()->getSharedManager();
$events->attach('ZfcUser\Form\Register','init', function($e) {
$form = $e->getTarget();
$form->add(array(
'name' => 'userlastname',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Last Name',
),
));
// Do what you please with the form instance ($form)
});
$events->attach('ZfcUser\Form\RegisterFilter','init', function($e) {
$filter = $e->getTarget();
$filter->add(array(
'name' => 'userlastname',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'min' => 3,
'max' => 255,
),
),
),
));
});
}
public function getConfig(){
return array();
}
public function getAutoloaderConfig(){
return array();
}
}
But after this I have got a bit lost on where/how to write the code to save the extra data that my new fields are gathering.
Is this the event where I can fire off save routines for the additional fields https://github.com/ZF-Commons/ZfcUser/wiki/How-to-perform-a-custom-action-when-a-new-user-account-is-created
Should I be writing my own WbxUser model that extends ZfcUser\Entity\User.php to add my new fields
I am a bit of a ZF and MVC noob so would be very great-full for a nudge in the write direction.
this one seems to be a bit more intuitive
http://juriansluiman.nl/en/article/117/use-3rd-party-modules-in-zend-framework-2
You can override the module configurations. The most elegant way is to use the zfcuser.global.php.dist in the autoload folder. Copy this file to your appliction autoload folder and change the filename to zfcuser.global.php. In here you're able to change whatever option you can find in here. This option can be used to override the zfcUser entity: 'user_entity_class' => 'ZfcUser\Entity\User'.
Then again, you may find yourself in a situation where you need to change things that cannot be changed in the configuration file. In this case you could create your own user module ( You may want to just clone the entire zfcuser module until you're sure about what files you want to replace.
After cloning the user module (and changed the namespaces accordingly) add your module to application.config.php. Make sure your module is loaded after zfcuser. Or alternatively you could remove zfcuser from the config file and put the following in module.php:
public function init($moduleManager)
{
$moduleManager->loadModule('ZfcUser');
}
Now you can override ZfcUser module configurations.
The following snippet could be used to override the template folder and UserController.
<?php
// Note most routes are managed in zfcUser config file.
// All settings here either overrides or extend that functionality.
return array(
'view_manager' => array(
'template_path_stack' => array(
// 'zfcuser' => __DIR__ . '/../view', Override template path
),
'template_map' => array(
// You may want to use templates from the original module without having to copy - paste all of them.
),
),
'controllers' => array(
'invokables' => array(
// 'zfcuser' => 'YourModule\Controller\IndexController', // Override ZfcUser controller.
),
),
'router' => array(
'routes' => array(
'zfcuser' => array(
'type' => 'Literal',
'priority' => 2500,
'options' => array(
'route' => '/user',
'defaults' => array(
// Use original ZfcUser controller.
// It may be a good idea to use original code where possible
'controller' => 'ZfcUser\Controller\UserController',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'authenticate' => array(
'type' => 'Literal',
'options' => array(
'route' => '/authenticate',
'defaults' => array(
// Invoke YourModule\Controller\IndexController
'controller' => 'zfcuser',
'action' => 'authenticate',
),
),
),
),
),
),
),
);
Also you can override ZfcUser services in module.php. ;-)
Altering a third party module don't really appeal to me because at times it unsettle a lot of functionality. I always try do something outside the module because if there is an update in the module i easily incorporate into my application without haven to rewrite anything.
To do something like you are trying to do I would create another table in my application and add a foreign key that extend the zfcuser table that way i can relate the information to each zf2user in my application.
It just a suggestion as i am also new in zf2.

Access to the $data variable from buttons in cgridview

Is the any way, to access model located in $data variable from CButtonColumn?
Below code is not working.
array(
'class' => 'CButtonColumn',
'template' => '{test}',
'buttons' => array(
'test' => array(
'label' => 'Select',
'click' => 'js:function() { <b>alert($data->_id);</b> return false;}',
),
),
),
It is possible to access visible attributes from jquery:
'click'=>'js:function(){alert("first element in cgridview is"+$(this).parent().parent().children(":nth-child(1)").text());}'
The only field where $data is allowed in CButtonColumn class is url, imageUrl and visible. To pass id to the javascript click event you may place such id in the url and grab it from the DOM. This is very rude hack but easy implementation.
array(
'class' => 'CButtonColumn',
'template' => '{test}',
'buttons' => array(
'test' => array(
'label' => 'Select',
/* set id */
'url' => $data->id,
/* retrieve id from this DOM element (jQuery) */
'click' => 'function() { alert( $(this).attr("href"); return false;}',
),
),
),
If you are looking for a more clear coding you could work in CDataColumn class
It looks like _id is a private variable (according to Yii's coding "standards"). You can not access private variables (and methods) outside of an object. Create a getter-method like this in your model:
public function getId() {
return $this->_id;
}
and then change your code to:
array(
'class' => 'CButtonColumn',
'template' => '{test}',
'buttons' => array(
'test' => array(
'label' => 'Select',
'click' => 'js:function() { alert($data->id); return false;}',
),
),
),
You need to customize the CButtonColumn class. Have a look this post:
http://www.yiiframework.com/wiki/714/yii-1-1-cgridview-use-special-variable-data-in-the-options-of-a-button-i-e-evaluate-options-attribute/
You can do that by custom function, as we can derived a $data variable inside it so that we can utilize better php as well as yii itself.
Try like this :
'test' => array(
'label' => 'Select',
'click' => function($data) {
$id = $data->id;
return "js:function() { alert($id); return false;}";
},
),

Categories