Yii2 ActiveForm custom template for checkbox field - templates

I'm looking to use a template for my checkboxList.
That's the properties i want to apply
class="switch" checked data-on-text="ON" data-off-text="OFF" data-on-color="teal"
<?php $form = ActiveForm::begin(); ?>
<ul class="list-unstyled">
<li>
<?= $form->field($modelUserPermission, 'id_permission')->checkboxList(ArrayHelper::map(Permission::find()->all(),'id', 'code')) ?>
</li><br>
</ul>
<div class="form-group">
<?= Html::submitButton($modelUserPermission->isNewRecord ? 'Create' : 'Update', ['class' => $modelUserPermission->isNewRecord ? 'btn btn-success' : 'btn btn-primary', 'value'=>'Create', 'name'=>'submit']) ?>
</div>
<?php ActiveForm::end(); ?>

<?= $form->field($model, 'recomended_by_user', ['template'=>'<div class="control-group">
<label class="control control--checkbox checkbox-small-text">Recomended by user
{input}
<div class="control__indicator"></div>
</label>
</div>'])->textInput(['class'=>"",'type'=>'checkbox'])?>
Use like this for custom Checkbox template

Answer provided by Bizley is correct, but here is one more alternate way you can try if you want.
<?php
$items_array = ArrayHelper::map(Permission::find()->all(),'id', 'code');
echo $form->field($model, 'id_permission')->checkboxList($items_array, [
'items' =>
function ($index, $label, $name, $checked, $value) {
return Html::checkbox($name, $checked, [
'value' => $value,
'label' => '<label for="' . $label . '">' . $label . '</label>',
'labelOptions' => [
// you can set label options here ],
],
]);
}, 'itemOptions' => ['class' => 'switch',
'data-on-text' => 'ON', 'data-off-text' => 'OFF', 'data-on-color' => 'teal'],
'separator' => false,]);
?>

If you want these properties in every checkbox (like Insane Skull asked) use itemOptions option.
<?= $form->field($modelUserPermission, 'id_permission')->checkboxList(
ArrayHelper::map(Permission::find()->all(),'id', 'code'),
[
'itemOptions' => [
'class' => 'switch',
'data' => [
'on-text' => 'ON',
'off-text' => 'OFF',
'on-color' => 'teal'
],
],
]
) ?>
Since it's ActiveField widget in order to get all checkboxes checked you have to pass array to $modelUserPermission->id_permission with all the IDs.

Related

How to hook event of validation error in livewire 2?

Reading how validations work at https://laravel-livewire.com/docs/2.x/input-validation
I did not find if there is a way in livewire 2 when I have
validation error to hook event as I need to send dispatchBrowserEvent event
to show message with toastr ?
My form is rather big and val;idation field can be out of screen
and I want to pay attention of user that there are validation errors...
Updated Block # 1:
You propose to get rid of livewire validate method and use laravel validate methods, which are written here
https://laravel.com/docs/8.x/validation, like :
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
...
In my conmponent I define all variables under 1 variable $form :
public $form
= [
'name' => '',
'state_id' => '',
...
public function firstStepSubmit()
{
$rules = [
'name' => 'required',
'state_id' => 'required',
];
$validation = Validator::make( $this->form, $rules, Hostel::getValidationMessagesArray());
$failed = $validation->fails();
if ($failed) {
$errorMsg = $validation->getMessageBag();
$focus_field = array_key_first($errorMsg->getMessages());
$this->dispatchBrowserEvent('PersonalPageMessageWarning', [
'title' => 'Personal Hostel',
'message' => 'Your hostel has invalid data !',
'focus_field' => str_replace('form.', '', $focus_field ),
]);
$validation->validate(); // What for this line ? Looks like we really need it ?
return;
}
$this->currentStep = 2;
} // public function firstStepSubmit()
// What for is
$validation->validate();
line inside of failed block ? Do we really need it ?
2) moving to laravel original methods sems for me as step back... Are there some livewire hooks/methods for it ?
Thanks in advance!
I got a solution to that. Let's say you have next:
// in blade
<div class="col-md-6 flex-row">
<label for="name">Name</label>
<input id="name" type="text" class="form-control flex-row" wire:model="name">
#error('name') <span class="error" style="color: #ff0000">{{ $message }}</span> #enderror
</div>
<div class="col-md-6 flex-row">
<label for="last_name">Name</label>
<input id="last_name" type="text" class="form-control flex-row" wire:model="last_name">
#error('last_name') <span class="error" style="color: #ff0000">{{ $message }}</span> #enderror
</div>
.... // all the rest of elements
//in component
public $name, $last_name;
// the rest of properies
public function store()
{
$validation = Validator::make([
'name' => $this->name,
'last_name' => $this->last_name,
.....
], $this->rules());
if ($validation->fails()) {
$errorMsg = $validation->getMessageBag();
$this->dispatchBrowserEvent('focusErrorInput',['field' => array_key_first($errorMsg->getMessages())]);
$validation->validate();
}
//... other code
now, if validation fails, the above validation checks dispatch and event with all the non-validated fields and in the blade's script tag handle the element focus in order of the error bag field. So, if the element is out of windows this will be focused
<script>
window.addEventListener('focusErrorInput', event => {
var $field = '#' + event.detail.field;
$($field).focus()
})
</script>

Opencart check if product has options

Currently my Opencart site only lets me 'Add to Cart' on the categories page, however if a product has options like 'colour' etc I want it to say 'View Product' instead.
Does anyone know how this can be achieved? I have tried editing the category.php controller to check if a product has options but cannot seem to get it working properly.
Thanks.
Update
So far I have added:
$options = $this->model_catalog_product->getProductOptions($result['product_id']);
Above this array $this->data['products'] = array(); in catalog>controller>product>category.php
This was my attempt to check if a product has options or not. Then I added in catalog>view>theme>mytheme>template>product>category.tpl
<?php if ($product['options']) { ?>
<a href="<?php echo $product['href']; ?>" class="button" />View Product</a>
<?php } else { // EO CATALOGUE MODE ?>
<input type="button" value="<?php echo $button_cart; ?>" onclick="addToCart('<?php echo $product['product_id']; ?>');" class="button" />
<?php } ?>
But it is not quite cutting the mustard.
You need to add the options to the $products array which is what you are checking in category.tpl:
Look for:
$this->data['products'][] = array(
'product_id' => $result['product_id'],
and add the options as an index to each product array
$this->data['products'][] = array(
'product_id' => $result['product_id'],
'options' => $this->model_catalog_product->getProductOptions($result['product_id']),

Cakephp 3 multiple custom template formhelpers

So I'm at work (working with sensitive data might I add for posterity's sake), and the powers that be decide we need to use the all powerful and least documented new tool by Cakephp 3.0 (beta at this time).
Edit: My goal is to create several different templates for forms to call through the formhelper template or input methods. There really isn't much of an a good example for this.
Customizing the Templates FormHelper Uses:
As seen in the book(and nowhere else on the internet anywhere) the very short documentation is thus:
http://book.cakephp.org/3.0/en/core-libraries/helpers/form.html#customizing-the-templates-formhelper-uses
The site says you can use the template method and then give a vague "use":
$myTemplates = [
'inputContainer' => '<div class="form-control">{{content}}</div>',
];
$this->Form->templates($myTemplates);
Then it says you can use the input() method for which it gives no example.
And last but not least the custom template FormHelper should allow you to "make" or "create" as many of these custom formhelpers as you wish, but they give no example use of how to do that!? lulwut?
I can easily use it once like their example, but where's the power in a single custom template? That doesn't do me anygood.
So by a new possible solution I try and get a new error.
I get this error(within my view)(from the following code):
Fatal Error
Error: Class 'Configure' not found
//within bootstrap.php
Configure::write('templates', [
'shortForm' => [
'formstart' => '<form class="" {{attrs}}>',
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>',
'input' => '<div class="col-md-4"><input type="{{type}}" name="{{name}}" {{attrs}} /></div>',
'select' => '<div class="col-md-4"><select name="{{name}}"{{attrs}}>{{content}}</select> </div>',
'inputContainer' => '<div class="form-group {{required}}" form-type="{{type}}">{{content}} </div>',
'checkContainer' => '',],
'longForm' => [
'formstart' => '<form class="" {{attrs}}>',
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>',
'input' => '<div class="col-md-6"><input type="{{type}}" name="{{name}}" {{attrs}} /></div>',
'select' => '<div class="col-md-6"><select name="{{name}}"{{attrs}}>{{content}}</select> </div>',
'inputContainer' => '<div class="form-group {{required}}" form-type="{{type}}">{{content}} </div>',
'checkContainer' => '',],
'fullForm' => [
'formstart' => '<form class="" {{attrs}}>',
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>',
'input' => '<div class="col-md-10"><input type="{{type}}" name="{{name}}" {{attrs}} /> </div>',
'select' => '<div class="col-md-10"><select name="{{name}}"{{attrs}}>{{content}}</select> </div>',
'inputContainer' => '<div class="form-group {{required}}" form-type="{{type}}">{{content}} </div>',
'checkContainer' => '',]
]);
//within my view
<?php
$this->Form->templates(Configure::read('templates.shortForm'));
?>
Old Update: I added
use "Cake\Core\Configure;"
in my view and everything works great, but I would like to add this to the appropriate file in the hierarchy so that I don't have to add that to every view,
that is unless of course it causes efficacy issues for the entire app as a whole. Does anyone know which file it should go in? Regards and TIA!
Newest Update: I just figured it out. So simple! check my answer below! Hope this helped someone
What this fix does is allow you to have custom template forms (from cakephp 3!!!!) using bootstrap. If you want to set sizes using the form helper and all of it's goodness (security and what not).
Jose Zap of Cakephp told me to try bootstrap plugins and widgets and what not, but the real way to do this should have been this:
Step 1: Create config/templatesConfig.php and add your custom form stuff.
<?php
$config = [
'Templates'=>[
'shortForm' => [
'formStart' => '<form class="" {{attrs}}>',
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>',
'input' => '<div class="col-md-4"><input type="{{type}}" name="{{name}}" {{attrs}} /></div>',
'select' => '<div class="col-md-4"><select name="{{name}}"{{attrs}}>{{content}}</select></div>',
'inputContainer' => '<div class="form-group {{required}}" form-type="{{type}}">{{content}}</div>',
'checkContainer' => '',],
'longForm' => [
'formStart' => '<form class="" {{attrs}}>',
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>',
'input' => '<div class="col-md-6"><input type="{{type}}" name="{{name}}" {{attrs}} /></div>',
'select' => '<div class="col-md-6"><select name="{{name}}"{{attrs}}>{{content}}</select></div>',
'inputContainer' => '<div class="form-group {{required}}" form-type="{{type}}">{{content}}</div>',
'checkContainer' => '',],
'fullForm' => [
'formStart' => '<form class="" {{attrs}}>',
'label' => '<label class="col-md-2 control-label" {{attrs}}>{{text}}</label>',
'input' => '<div class="col-md-10"><input type="{{type}}" name="{{name}}" {{attrs}} /></div>',
'select' => '<div class="col-md-10"><select name="{{name}}"{{attrs}}>{{content}}</select></div>',
'inputContainer' => '<div class="form-group {{required}}" form-type="{{type}}">{{content}}</div>',
'checkContainer' => '',]
]
];
Step 2: From your controller inside the method for the correct view call this line.
Don't forget add this on the top of your controller
use Cake\Core\Configure;
$this->set('form_templates', Configure::read('Templates'));
Step 3: Add this within the bootstrap.php file
// Load an environment local configuration file.
// You can use this file to provide local overrides to your
// shared configuration.
Configure::load('templatesConfig','default'); //fixed
Step 4(finally): Add this line with the template name you want Bam!.
<?php $this->Form->templates($form_templates['shortForm']); ?>
Let's say you need all inputs to use a custom markup in a form to show the label after the input (default is before) and a different class for the hardcoded error-message for errors:
$this->Form->create($entity, ['templates' => [
'formGroup' => '{{input}}{{label}}',
'error' => '<div class="error">{{content}}</div>'
]]);
If you want to only customize a single input, pass the same 'templates' key to the FormHelper::input() options like so:
$this->Form->input('fieldname', ['templates' => [
'formGroup' => '{{input}}{{label}}',
'error' => '<div class="error">{{content}}</div>'
]]);
If you need to define multiple templates and re-use them whenever you want, here's something you can try (mind I am writing it here, never used it before):
// in bootstrap (as this is a config i believe
Configure::write('templates', [
'foo' => [....],
'bar' => [....]
]);
// in any view
$this->Form->templates(Configure::read('templates.foo'));
$this->Form->create(...);
....
You could also create your own helper and define the templates there, etc.
It really all depends on what you want to achieve but that should give you a good understanding of how templates work (not just in forms by the way).

How to print ex tax amount on featured, bestseller and related module?

How to print ex-tax amount on featured, bestseller and related module? I tried with $product array but there is no key for ex-tax amount.
Open your bestseller controller file (catalog/controller/module/bestseller.php), and modify this part:
$this->data['products'][] = array(
'product_id' => $result['product_id'],
'thumb' => $image,
'name' => $result['name'],
'price' => $price,
'special' => $special,
'rating' => $rating,
'reviews' => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
'href' => $this->url->link('product/product', 'product_id=' . $result['product_id']),
);
... by declaring 2 new variables, called price_ex_tax and special_ex_tax in the products array:
$this->data['products'][] = array(
'product_id' => $result['product_id'],
'thumb' => $image,
'name' => $result['name'],
'price' => $price,
'price_ex_tax' => $this->currency->format($result['price']),
'special' => $special,
'special_ex_tax' => $this->currency->format($result['special'],
'rating' => $rating,
'reviews' => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
'href' => $this->url->link('product/product', 'product_id=' . $result['product_id']),
);
Then you could access the new variables in the bestseller view file (catalog/view/theme/your_theme_name/template/module/bestseller.tpl). Look for this part:
<?php if ($product['price']) { ?>
<div class="price">
<?php if (!$product['special']) { ?>
<?php echo $product['price']; ?>
<?php } else { ?>
<span class="price-old"><?php echo $product['price']; ?></span> <span class="price-new"><?php echo $product['special']; ?></span>
<?php } ?>
</div>
<?php } ?>
... and replace with:
<?php if ($product['price']) { ?>
<div class="price">
<?php if (!$product['special']) { ?>
<?php echo $product['price'] . "(" . $product['price_ex_tax'] . ")"; ?>
<?php } else { ?>
<span class="price-old"><?php echo $product['price'] . "(" . $product['price_ex_tax'] . ")"; ?></span> <span class="price-new"><?php echo $product['special'] . "(" . $product['special_ex_tax'] . ")"; ?></span>
<?php } ?>
</div>
<?php } ?>
You could repeat the same steps for the featured module as well (controller file: catalog/controller/module/featured.php - view file: catalog/view/theme/your_theme_name/template/module/featured.tpl). You can find the related products in the product controller file (catalog/controller/product/product.php), and you can display it in the product view file (catalog/view/theme/your_theme_name/product/product.tpl). I hope this helped.
For me it worked when I added this to the controller file: catalog/controller/module/featured.php
Just above the $this->data['products'][] = array( add the following line:
$extax = $this->currency->format($product_info['price']);
Then within the array( add:
'extax' => $extax,
Finally go to catalog/view/theme/your_theme_name/template/module/featured.tpl and add:
<?php echo $product['extax']; ?> where you wish to display the price without tax or
<?php echo $product['price'] . "(" . $product['extax'] . ")"; ?> to show both inc and exc, hope that helps.

Creating Pagination With CakePHP For Custom Template Links

I've following custom template for pagination links
<li class="prev">prev</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>...</li>
<li>30</li>
<li class="next">next</li>
I've tried it by using following code(cakephp 2.3 version) but not getting the result as required.
<?php
echo $this->Paginator->prev('<', array( 'class' => '', 'tag' => 'li' ), null, array('class' => 'prev', 'tag' => 'li'));
echo $this->Paginator->numbers(array('tag' => 'li', 'separator' => '', 'currentClass' => 'active', 'currentTag' => 'a' ));
echo $this->Paginator->next('>', array('class' => 'next', 'tag' => 'li' ), null, array( 'class' => 'next', 'tag' => 'li'));
?>
Please help me out to get it done.. Thanks in advance.
This is just a sample of my custom template for pagination links, that I made for use with bootstrap. You can modify it accordingly to your needs
<ul>
<?php
echo $this->Paginator->first('‹', array('tag' => 'li', 'title' => __('First page'), 'escape' => false));
echo $this->Paginator->prev('«', array('tag' => 'li', 'title' => __('Previous page'), 'disabledTag' => 'span', 'escape' => false), null, array('tag' => 'li', 'disabledTag' => 'span', 'escape' => false, 'class' => 'disabled'));
echo $this->Paginator->numbers(array('separator' => false, 'tag' => 'li', 'currentTag' => 'span', 'currentClass' => 'active'));
echo $this->Paginator->next('»', array('tag' => 'li', 'disabledTag' => 'span', 'title' => __('Next page'), 'escape' => false), null, array('tag' => 'li', 'disabledTag' => 'span', 'escape' => false, 'class' => 'disabled'));
echo $this->Paginator->last('›', array('tag' => 'li', 'title' => __('First page'), 'escape' => false));
?>
</ul>
The ellipsis ... is created automatically by Paginator::numbers() according to the CakeBook, but you can change it to whatever you want.
I hope it works out for you