How can I add a font awsome animated icon ( like fa fa-reload fa-spin) inside an input using $this->form->input(code)
<div class="input-wrapper">
<input id="stuff">
<label id ="spin" for="stuff" class="fa fa-spinner fa-spin input-icon">
</label>
</div>
and for css
.input-icon{ position: relative; right: 20px; }
input{ padding-right: 20px; }
.input-wrapper{ position: relative; }
I don't know if what you're trying to do it's right from a css point of view
Don't even know if it is the right way to use fontAwesome (You're applying the fa classes to the label instead o using in a <i> as usually done)
So I'm just going to show you how to replicate your exact html using cakephp
if you want to do using just one command you have to leverage on templates. You can change the form templates just for one form, for your whole application or just for a single control.
In my exhample I'm changing the templates just for this control
echo $this->form->control(
'my_input_name',
[
'label' => [
'text' => '',
'id' => 'spin',
'class' => "fa fa-spinner fa-spin input-icon"
],
'templates' => [
'inputContainer' => '<div class="input-wrapper">{{content}}</div>',
'formGroup' => '{{input}}{{label}}',
]
]
)
Related
I need to set an input range on a form to create and update. In the October CMS documentation, I found a list solution, but in the register there is no "range" field.
<input type="range" min="0" max="100" step="1">
I'm using the "Builder Plugin".The closest thing to the solution was the "macros" feature, but the documentation about the feature didn't help much. Has anyone found a solution for creating their own input types or range?
October CMS is very extendable platform. You can extend each and every aspect of it.
Same goes for builder plugin you can extend it as per your needs.
Please hold on this answer will be long but You will find it lot of useful.
Final Results
It will add control to control list so you can easily add it and reuse it for other fields as well.
Configurable - you don't need to edit any file/partial to change its values. its all inside builder plugin. your values [min, max, step] field-name etc.. all you can edit/update from builder plugin.
Its automatic. means labels and field-name all will work like other controls you don't need to specify anything else. all will be dynamic.
So lets start extending builder plugin :)
add this code to your plugin boot method plugin.php, it will basically add the control to builder plugin control list. [1st image]
public function boot() {
\Backend\Widgets\Form::extend(function($widget) {
$widget->addViewPath(\File::symbolizePath('~/plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider/field_partials'));
});
\Event::listen('pages.builder.registerControls', function($controlLibrary) {
$properties = [
'min' => [
'title' => 'Min',
'type' => 'string',
'default' => '0',
'ignoreIfEmpty' => false,
'sortOrder' => 81
],
'max' => [
'title' => 'Max',
'type' => 'string',
'default' => '100',
'ignoreIfEmpty' => false,
'sortOrder' => 82
],
'step' => [
'title' => 'Step',
'type' => 'string',
'default' => '10',
'ignoreIfEmpty' => false,
'sortOrder' => 83,
]
];
$controlLibrary->registerControl(
'my_range',
'Range Field',
'Custom Range Field',
\RainLab\Builder\Classes\ControlLibrary::GROUP_STANDARD,
'icon-arrows-h',
$controlLibrary->getStandardProperties(['stretch'], $properties),
\HardikSatasiya\SoTest\Classes\CustomDesignTimeProvider::class
);
});
.... your extra code ...
now you need to create/add required dependent files plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider.php , plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider/partials/_control-my_range.htm and plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider/field_partials/_field_my_range.htm'
plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider.php
<?php namespace HardikSatasiya\SoTest\Classes;
use File;
use RainLab\Builder\Classes\ControlDesignTimeProviderBase;
class CustomDesignTimeProvider extends ControlDesignTimeProviderBase {
public function renderControlBody($type, $properties, $formBuilder)
{
return $this->makePartial('control-'.$type, [
'properties'=>$properties,
'formBuilder' => $formBuilder
]);
}
public function renderControlStaticBody($type, $properties, $controlConfiguration, $formBuilder)
{
$partialName = 'control-static-'.$type;
$partialPath = $this->getViewPath('_'.$partialName.'.htm');
if (!File::exists($partialPath)) {
return null;
}
return $this->makePartial($partialName, [
'properties'=>$properties,
'controlConfiguration' => $controlConfiguration,
'formBuilder' => $formBuilder
]);
}
public function controlHasLabels($type)
{
return true;
}
}
plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider/partials/_control-my_range.htm
<div class="builder-blueprint-control-text">
<i class="icon-arrows-h"></i> Range Field
</div>
while above steps will add our custom control to the plugin builder list, next step will be adding form field partial. [3rd image]
plugins/hardiksatasiya/sotest/classes/CustomDesignTimeProvider/field_partials/_field_my_range.htm
<!-- Range -->
<?php if ($this->previewMode): ?>
<span class="form-control"><?= $field->value ? e($field->value) : ' ' ?></span>
<?php else: ?>
<div style="display: flex;">
<span style="width: 30px; margin-right: 20px;" id="<?= $field->getId() ?>_val">
<?= $field->value ?>
</span>
<span>
[<?= $field->getConfig('min') ?>]
</span>
<input
type="range"
name="<?= $field->getName() ?>"
id="<?= $field->getId() ?>"
value="<?= e($field->value) ?>"
min="<?= $field->getConfig('min') ?>"
max="<?= $field->getConfig('max') ?>"
step="<?= $field->getConfig('step') ?>"
oninput="(function(input) { document.getElementById('<?= $field->getId() ?>_val').innerText = input.value; })(this)"
<?= $field->getAttributes() ?>
/>
<span>
[<?= $field->getConfig('max') ?>]
</span>
</div>
<?php endif ?>
This html files are just html markup so can edit them and add css/style according to your need.
Once you did following steps you will able to see your custom range control in form builder's control list. now you can add it update it just like any other default control.
Its fully dynamic you can choose field-name, min, max, step and it will be applied.
Note: Just make sure you replace author-name and plugin-name according to your setup in provided code.
if you have any doubts please comment.
Well this was unique and after some research and testing I came up with a way to do this. I will remark that there isn't any reason that I have personally found to justify a range slider in a form. So I understand why OctoberCMS doesn't have one natively.
Inside the builder plugin you need to add the input field of the value you want to be stored and change the setting to be read only.
Inside the builder plugin you will want to add a partial. I called my partial something.htm for testing purposes. The whole path to the partial is: $/dle/test/models/products/something.htm Note the $ is just to evoke the starting point of the search.
Not inside the something.htm partial I have this: The label and input of the range. Natively the range element doesn't show the amount but with javascript and jquery we can connect this range to the price field.
<label for="priceRange">Price Range</label>
<input id="priceRange" type="range" min="0" max="10" step=".25" onchange="updateTextInput(this.value);">
Now you have to go to your create.htm and update.htm pages under controller. IE: author/plugin/controllers/controller/create.htm. Here I have entered the javascript / jquery to connect the range to the input field.
<script>
function updateTextInput(val) {
document.getElementById('Form-field-Products-price').value=val;
}
var value = $('#Form-field-Products-price').val();
$('#priceRange').val(value);
</script>
I have a div with x images in it aligned horizontally. The div is only showing one image at a time. When I press a button I want to animate the items until the next image is visible. I tried using animation triggers but since I could have unknown number of images I don't know how to change the translate variable within the trigger. When I set state to 'in' it animates once to -100% but I want it to continue to animate to the next image when I click the button again. So for the third image I would need to change the translateX to -200%.
Is there a way to do it, or another way to handle this kind of animation?
trigger('animateX', [
state('in', style({ transform: 'translateX(-100%)' })),
transition('start => in', [
style({
transform: 'translateX(0%)'
}),
animate('0.2s ease-in')
])
])
The template....
<div class="carousel">
<ul class="images">
<li [#animateX]="state">
<img src="myImage1" />
</li>
<li [#animateX]="state">
<img src="myImage2" />
</li>
<li [#animateX]="state">
<img src="myImage3" />
</li>
<ul >
[UPDATE] I would like to add a forward and back buttons which animate the carousel into the corresponding direction. So far I have the following trigger and it works ok except for two cases:
If I press next and then I press the back button the new item appears correctly but the current item leaves into the wrong direction. If I press back again then it is ok. It's only when switching the states from next to prev and vice versa.
When showing the carousel initially I don't want any animation to occur. The carousel should simply show the first item.
Here is the trigger code and below it a plunkr from #micronyks
trigger('animateX', [
state('next', style({})),
transition('* => next', [
style({ transform: 'translatex(100%)' }),
animate(300)
]),
transition('next => void', [
animate(300, style({ transform: 'translateX(-100%)' }))
]),
state('prev', style({})),
transition('* => prev', [
style({ transform: 'translatex(-100%)' }),
animate(300)
]),
transition('prev => void', [
animate(300, style({ transform: 'translateX(100%)' }))
])
])
http://plnkr.co/edit/SS3nb7bkl3YBMoViDsRz?p=preview
inside a gridview i have a css based inline graph. everything is working fine untill i filter something and the gridview gets updated. then css is not registering inside the grid anymore. anyone knows a solution? to be honest i don't even know what to try in this situation. css is not one of my strong points.
this is the element before ajaxupdate:
This is after the ajax update
.stat-block .stat-graph {
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #D7D7D7;
border-radius: 3px;
margin-right: 10px;
padding: 10px 10px 8px;
text-align: center;
width: auto;
}
as far as i can see first time the grid is generated css generates a canvas tag like so
<canvas style="display: inline-block; width: 29px; height: 20px; vertical-align: top;" width="29" height="20"></canvas>
but after the ajax update and the refresh of the gridview that tag won't appear anymore.
i have tried to put the graph data inside the canvas tag whit no success.
here is the gridview code:
this->widget('zii.widgets.grid.CGridView', array(
'id' => 'cartuse-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'afterAjaxUpdate' => 'reinstallDatePicker',
'columns' => array(
array(
'id' => 'autoId',
'class' => 'CCheckBoxColumn',
'selectableRows' => '50',
),
// 'id',
array(
'name'=>'client',
'type'=>'raw',
'value'=>'client($data->client)',
'htmlOptions' => array(
'align'=>'center',
//'width'=>'35%'
)
here is the client function:
function client($client) {
...
return '<div class="stat-block" id="graph">
<ul>
<li class="stat-graph inlinebar" id="activitate-lunara">
'.$data.'
</li>
<li class="stat-count">
<span>'.$data['0'].'
</span>
</li>
<li class="stat-percent">
<span class="text-info stat-percent">'.$target.'</span>
</li>
</ul>
</div>';
}
Edit 1 :
as recomended in answer 1 i used the removeClass() and addClass() functions to refresh css after ajax update. nothing hapens, the canvas tag still won't appear.
i tryed to use replaceWith() and just insert the canvas tag that way but then it will brake the filtering.
here's the reinstallDatePicker function
<?php Yii::app()->clientScript->registerScript('re-install-date-picker', "
function reinstallDatePicker(id, data) {
$('#datepicker_min').datepicker({ dateFormat: 'yy-mm-dd',
showOtherMonths: true,
selectOtherMonths: true,
changeYear: true,
changeMonth: true,
});
$('#datepicker_max').datepicker({ dateFormat: 'yy-mm-dd',
showOtherMonths: true,
selectOtherMonths: true,
changeYear: true,
changeMonth: true,
});
$( \"#activitate-lunara\" ).removeClass( \"stat-graph inlinebar\" );
$( \"#graph\" ).removeClass( \"stat-block\" );
$( \"#graph\" ).addClass( \"stat-block\" );
$( \"#activitate-lunara\" ).addClass( \"stat-graph inlinebar\" );
}"); ?>
Edit 2:
i wasn't using renderPartial as column content. just a function that returned the content i wanted. after exhausting All posible ideeas i moved to renderpartial and with renderpartial + registering scripts / css in the partialview and removeclass / addclass everything is working fine now.
I have this issue sometimes as well.
First thing: If you're using partial views, include the CSS in the partial view as well.
If not, you will probably have to re-apply the style after each ajax update.
I see that you are using "afterAjaxUpdate"=>"reinstallDatePicker" so one way to fix your problem is to add that CSS to .stat-block .stat-graph inside that function. You can use jquery functions like css(), addClass() and many others.
But the important thing is that you style your elements after each ajax update. Since your function reinstallDatePicker is being called after each ajax update, you can just add some code to this function to do what you want (that is, re-style the elements).
i have tried everything i can think of without success. the only way i could get it to work was to store my filter data in my session and then afterajaxupdate force a reload. (not really recommended because if your query's are not optimized i guess it could slow down your page)
i'm just posting this here in case someone else has this problem and want to get it working before someone else finds a correct solution
so now in my controller i have this
public function actionAdmin()
{
$model=new Cartuse('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Cartuse']))
$_SESSION['filterData'][$this->id][$this->action->id] = $_GET['Cartuse'];
$model->attributes=$_SESSION['filterData'][$this->id][$this->action->id];
if (isset($_GET['pageSize'])) {
Yii::app()->user->setState('pageSize',(int)$_GET['pageSize']);
unset($_GET['pageSize']);
}
$this->render('admin',array(
'model'=>$model,
));
}
and in my gridview
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'cartuse-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'afterAjaxUpdate' => 'reinstallDatePicker',
'columns' => array(/*
.....
)
));
and the reinstall datepicker (for some reason if i put the location.reload () directly in the afterajaxupdate field my datepickers won't register (not even first time) and filtering stops working. so i put it in the reinstalldatepicker function. no problems till now.
<?php Yii::app()->clientScript->registerScript('re-install-date-picker', "
function reinstallDatePicker(id, data) {
location.reload();
$('#datepicker_min').datepicker({ dateFormat: 'yy-mm-dd',
showOtherMonths: true,
selectOtherMonths: true,
changeYear: true,
changeMonth: true,
});
$('#datepicker_max').datepicker({ dateFormat: 'yy-mm-dd',
showOtherMonths: true,
selectOtherMonths: true,
changeYear: true,
changeMonth: true,
});
$.datepicker.setDefaults($.datepicker.regional['ro']);
}
");
this is not really a solution, its jut a cheap workaround so if anyone has a solution i'll be waiting for it.
My code right now:
<?php echo anchor('admin/delete_msg/'.$obj->id, 'DELETE MESSAGE', array('onclick' => 'return confirm(\'Are you sure?\');', 'class' => 'delete-button')); ?>
But Iwould liek to use something like:
<?php echo anchor('admin/delete_msg/'.$obj->id, '', array('onclick' => 'return confirm(\'Are you sure?\');', 'class' => 'delete-button')); ?>
So there is no "DELETE MESSAGE" text and I can use image instead.
But if I leave the single quotes empty the link will show up e.g. http://localhost/project
Any advice how to solve that within anchor function and not going via <a href="...?
You could use CSS to hide the text and pull in a background image:
.delete-button{
display: inline-block;
width: 80px; /* fits background-img width */
height: 40px; /* fits background-img height */
text-indent: -9999px;
background: url('path/to/image') top left no-repeat;
}
I have solved it using space like:
<?php echo anchor('admin/delete_msg/'.$obj->id, ' ', array('onclick' => 'return confirm(\'Are you sure?\');', 'class' => 'delete-button')); ?>
Don't use the anchor helper. Just pass $obj to the view(html.php)
<a rel="nofollow" onclick="return confirm()" class="btn btn-delete-icon" href="<?php echo site_url('admin/delete_msg/'.$obj->id.'')?>"> </a>
I am new to CakePHP. I have two problem with the view.
There is line break between text field name and text field area. I have tried to pass 'div' => false but that didn't work. How can I remove line break and display both on same line?
I have added validation rule to this textfield but when I click save Error message doesn't show up. Do I need to do something else beside adding validates in my model?
Here is my view input.ctp
echo $this->Form->input('fileId', array(
'type'=>'text',
'style' => 'width: 200px; height: 15px'
));
echo $this->Form->end('Save Post');
Here is my model:
var $validate = array(
'fileId' => 'notEmpty',
'message' => 'Should not be empty'
);
Controller:
if ($this->request->is('post')) {
$data = $this->request->data;
if ($data) {
// saving the data
}
}
If you are not using save then you need to manually validate the data using validates. In such case you also need to set the data. For e.g. in your controller
$this->ModelName->set($data);
$this->Modelname->validates();
For validate your data, you should have something like this:
public $validate = array(
'fileId' => array(
'rule' => 'notEmpty',
'message' => 'Should not be empty'
)
);
And your Controller:
if ($this->request->is('post')) {
if ($this->Model->save($this->request->data)) {
// saved
}
}
If you can not save, the error will be shown near the corresponding field. Or you can customize your error using $this->Model->validationErrors array.
For the line break question, make sure that 200px does the automatic line break because of where these elements are positioned.
validation errors appear when validates() or save() was called.
setup your action completely.
If you're not using FormHelper::input, which outputs the field, label and error, you need to manually output the error as well using $this->Form->error('fileId').
And for the form try this:
add this to your css
label { float: left;
width: 150px;
display: block;
clear: none;
text-align: left;
vertical-align: middle;
padding-right: 0px;}
.xg {
display: block;
float:left;
}
echo $this->Form->input('fileId', array('div'=>'xg','type'=>'text', 'style' => 'width: 200px; height: 15px'));
echo $this->Form->end('Save Post');
you can customize your output by following method:
<tr>
<td><label>Username</label></td>
<td>
<?php echo $this->Form->input('username',array('label'=>false,'div'=>false,'error'=>false)); ?>
</td>
<td><?php echo $this->Form->error('username'); ?></td>
</tr>
This method will give you output in same line.