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;}";
},
),
Related
I am creating a module in prestashop 1.7 to save my settings.
Also I created a form to display my settings. Form sample is shown below:-
//display form function
public function renderCustomerForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Customer Settings'),
'icon' => 'icon-time'
),
'input'=>array(
array(
'type' => 'text',
'label' => $this->l('BusinessCustomerFlag'),
'name' => 'C_BUSINESS_FLAG',
'lang' => false,
'required' => true
),
),
'submit' => array(
'title' => $this->l('Save'),
'name' => 'submitCustomer',
'icon' => 'process-icon-save'
)
);
I am saving this values in configuration table using configuration class functions.
I know how to retrieve it but don't know how to show in the form. Please some one guide on this will be really helpful.
Add this line to helper on your module (before generateForm):
$helper->fields_value = $this->getFormValues();
and add function to define values:
public function getFormValues()
{
$fields_value = array();
$fields_value['C_BUSINESS_FLAG'] = "some data or retrieved data";
return $fields_value;
}
I'm trying to change the element value using Jquery but it's not working...
This is my widget where I have my element 'tag' which i want to change it to textField on edit...
$this->widget('EditableGrid', array(
'dataProvider' => $dataProvider->searchbyID($invoice_id),
'template' => '{items}{buttonCreateRow}{pager} ',
'id' => 'InvoiceLine-grid',
'rowTemplate' => $row_template,
'columns' => array(
array(
'class' => 'EditableGridColumn',
'header' => '',
'name' => 'InvoiceLine_{gridNum}_{rowNum}_edit',
'imageurl'=> Yii::app()->request->baseUrl.'/images/update.png',
'tag' => 'button',
'tagHtmlOptions' => array(
'onclick'=>'editline(this)',
)
),
array(
'class' => 'EditableGridColumn',
'header' => 'StentysRef',
'name' => '[{gridNum}][{rowNum}]stentysproductref',
'tag' => 'laabel',
'tagHtmlOptions' => array(
'style'=>'background-color:#FFF;border-color:#FFF',
'onkeyup'=>'stentysref(this)',
'readonly'=>true
)
),
My Jquery is,
(as you can see the removeAttr works but attr doesn't)
function editline(obj){
$("#InvoiceLine_1_"+row+"_stentysproductref").attr("tag","textField");
$("#InvoiceLine_1_"+row+"_stentysproductref").removeAttr("readonly");
}
Use .prop() and removeProp() which is added in jQuery 1.6, as the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior.
function editline(obj){
$("#InvoiceLine_1_"+row+"_stentysproductref").prop("tag","textField");
$("#InvoiceLine_1_"+row+"_stentysproductref").removeProp("readonly");
}
API Doc for .prop()
If you are using EditableGrid widget without pointing AR model, then the row id looks like
$('#_1_'+row+'stentysproductref').
I'll take it into consideration for the future updates. Thank you.
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',
),
What I'm trying to accomplish with the following code is when the 'roleSelector' dropdown is changed, it fires a ajax request to the 'admin/permissions/assign' url which in turn, sets a state for the role selected. I need it as a state so I can use it in the CLinkColumn column within the CGridView. However, when the success javascript fires and the grid view reloads the content of the cgridview does not update, while the summary does (it shows the number of results that should be in the grid view).
I'm not sure why either but this seems to be the only CGridView that I've had to use the 'ajaxUrl' property in order for the $.fn.yiiGridView.update() call to work. If I omit the url property it returns an error stating it could not find the url which I don't recall having to set in the past.
The Action:
class AssignAction extends CAction {
// Used in the url to determine if we are assigning or revoking permissions
const FLAG_APPLY = 'apply';
const FLAG_REVOKE = 'revoke';
// Identifier to the user saved state of the role selected
const STATE_ROLE = 'roleSelected';
public function run($name='', $action='') {
// Get the role the user selected
if (isset($_POST['roleSelector'])) {
$roleSelected = $_POST['roleSelector'];
Yii::app()->user->setState(self::STATE_ROLE, $roleSelected);
Yii::app()->end();
}
// Get all of the roles from the system
$roleSelected = Yii::app()->user->getState(self::STATE_ROLE);
$roles = AuthItem::model()->byTypes(array(CAuthItem::TYPE_ROLE))->findAll();
$authItemProvider = new CActiveDataProvider('AuthItem', array(
'criteria' => array(
'condition' => (!$roleSelected) ? '1=0' : '',
),
'pagination' => array(
'pageSize' => 30,
)
));
$this->getController()->render('assign', array(
'roles' => $roles,
'roleSelected' => $roleSelected,
'authItemProvider' => $authItemProvider,
));
}
}
The View:
<div id="content-header">
<h1 class="p-mt10">Assign Permissions</h1>
<div class="p-fr p-pb10">
<?php
$roleList = CHtml::listData($roles, 'name', 'label');
echo CHtml::dropDownList('roleSelector', $roleSelected, $roleList, $htmlOptions=array(
'empty' => 'Select a Role',
'ajax' => array(
'type' => 'POST',
'url' => $this->createUrl('/admin/permissions/assign'),
'data' => array('roleSelector' => 'js: $(this).val()'),
'success' => 'js: function() { $.fn.yiiGridView.update("GridView-AuthItem") }',
),
));
?>
</div>
</div>
<div id="content-body">
<table>
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'GridView-AuthItem',
'dataProvider' => $authItemProvider,
'columns' => array(
'label:properCase',
'typeName:properCase',
'description',
'bizrule',
array(
'class' => 'CLinkColumn',
'label' => 'Assign',
'urlExpression' => 'array("/admin/permissions/assign",
"name" => $data->name,
"action" => (AuthItemChild::model()->byParentAndChild(Yii::app()->user->getState(AssignAction::STATE_ROLE), $data->name)->find()
? AssignAction::FLAG_REVOKE : AssignAction::FLAG_APPLY),
)',
'htmlOptions' => array(
'style' => 'text-align: center',
),
'linkHtmlOptions' => array(
'class' => 'button gray icon i_stm_edit',
),
),
),
));
?>
</table>
</div>
I forgot I left the table tags in there since it originally was a CListView. Removing those tags seems to have fixed my problem.
Having just arrived at Prestashop 1.5, I am making a very simple module: a video of the week, associated with multiple products that need to appear right next to it.
I decided to start from the Backoffice. Right now, I can view, add, edit and remove all the Video entries but I'm a bit lost on how to map the N-N association between a video and its related products... The lack of documentation isn't helping either.
Any ideas how to pull this off?
Here's a bit of my code, the Video class is defined by:
class Video extends ObjectModel {
public $id_video;
public $title;
public $url;
public $active;
public static $definition = array(
'table' => 'video',
'primary' => 'id_video',
'multilang' => false,
'fields' => array(
'id_video' => array(
'type' => ObjectModel :: TYPE_INT
),
'title' => array(
'type' => ObjectModel :: TYPE_STRING,
'required' => true
),
'url' => array(
'type' => ObjectModel :: TYPE_STRING,
'required' => true
),
'active' => array(
'type' => ObjectModel :: TYPE_BOOL,
'required' => true
)
),
);
(...)
and the AdminVideo class is here:
class AdminVideoController extends ModuleAdminController {
public function __construct()
{
$this->table = 'video';
$this->className = 'Video';
$this->lang = false;
$this->fields_list['id_video'] = array(
'title' => $this->l('ID'),
'align' => 'center',
);
$this->fields_list['title'] = array(
'title' => $this->l('Title'),
'width' => 'auto'
);
$this->fields_list['url'] = array(
'title' => $this->l('URL'),
'width' => 'auto'
);
$this->fields_list['active'] = array(
'title' => $this->l('Active'),
'width' => '70',
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'orderby' => false
);
parent::__construct();
}
public function postProcess()
{
parent::postProcess();
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->addRowAction('details');
return parent::renderList();
}
public function renderForm()
{
if (!($obj = $this->loadObject(true)))
return;
$this->fields_form = array(
'legend' => array(
'title' => $this->l('This weeks video'),
'image' => '../img/admin/world.gif'
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Nome'),
'name' => 'title',
'size' => 33,
'required' => true,
'desc' => $this->l('Title')
),
array(
'type' => 'text',
'label' => $this->l('URL'),
'name' => 'url',
'size' => 33,
'required' => true,
'desc' => $this->l('Video URL')
),
array(
'type' => 'radio',
'label' => $this->l('Active:'),
'name' => 'active',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Disabled')
)
),
'desc' => $this->l('Only one video can be active at any given time')
),
)
);
if (Shop::isFeatureActive())
{
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->l('Shop association:'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->l(' Save '),
'class' => 'button'
);
if (!($obj = $this->loadObject(true)))
return;
return parent::renderForm();
}
}
One other thing: would it be possible to add a preview of the video inside the backoffice? I tried to echo YouTube's embed code, but it gets inserted even before the header. Is there a clean way of doing this or do I have to use some jQuery trickery? I was basically doing an echo of YT's embed code just before the end of postProcess().
Thanks in advance!
The simplest way to associate the videos to the products is by adding a "products" text field in your "video" table to store a comma separated list of the ids of the associated products (eg.: 1,10,27). Even if it's a bit rudimentary, it should work.
Alternatively, you could use a table like this:
create table video_product (
id_association int not null auto_increment,
id_video int,
id_product int,
primary key (id_association)
);
The problem with this solution is that the PrestaShop ObjectModel core does not provide any method to automatically update or delete the related tables (at least as far as I know), so you have to insert the code to manage the "video_product" table in your "Video" class.
If you want an example of how to do this, you should look at the classes/Product.php script, which manages the product table and all its related tables (categories, tags, features, attachments, etc.).
To have an idea of how the Prestashop database is structured, have a look at the docs/dbmodel.mwb file, which contains the schema of the database; this file can be viewed by using the MySQL Workbench application.