How do I set default alignment for horizontal controls in Bootstrap-UI 3 for CakePHP 4?
This is a particularly obscure question about the Boostrap-UI plugin for CakePHP but I'm hoping someone might be able to help.
I’m using Bootstrap-UI (https://github.com/FriendsOfCake/bootstrap-ui) version 3.0, so using Bootstrap 4.6.
I’m trying to create a form that has controls that are aligned horizontally with their labels using the example from the readme here -
This works fine except I can’t see how to define the default column distribution ie so that the classes for the label and the control container are something like col-4
and col-8
without any breakpoint defined.
If I try something like -
'align' => [
'left' => 4,
'middle' => 8,
]
The classes created are col-md-4
and col-md-8
ie it seems to default to md as the breakpoint for the columns.
I know this is a bit obscure but does anyone have any idea how to do what I want?
1 answer
-
answered 2022-05-07 10:58
ndm
AFAICT that's currently not supported, meaning you can only generate the default
mb
breakpoint ones, or specify breakpoints yourself.You can open an issue over at GitHub for a feature request. As a workaround you could extend the plugin'S form helper and overwrite
FormHelper::_gridClass()
to modify the generated classlist, something along the lines of this, which would remove the default breakpoint from the generated class string:namespace App\View\Helper; class FormHelper extends \BootstrapUI\View\Helper\FormHelper { protected function _gridClass(string $position, bool $offset = false): string { return str_replace('-md', '', parent::_gridClass($position, $offset)); } }
public function initialize(): void { parent::initialize(); $this->initializeUI(); $this->helpers['Form'] = [ 'className' => \App\View\Helper\FormHelper::class ]; }
See also https://book.cakephp.org/4/en/views/helpers.html#creating-helpers
do you know?
how many words do you know
See also questions close to this topic
-
How to clear user uploaded images if the limit of files exceeded in jquery
I have a simple form where a user can upload multiple images. I only want the user to upload 4 images at once, so I did the following:
$("#myfile").on("change", function() { if ($("#myfile")[0].files.length > 4) { alert("You can select only 4 images"); } });
<input type="file" id="myfile" class="form-control" name="pimage[]" multiple="multiple">
This gives an alert when the user uploads more than 4 images but doesn't stop them from submitting the form.
Can anyone please tell me how to clear the user uploaded images if the limit exceeds or disable the submit button?
-
Setting A $_GET Value From A Previously Defined Variable - PHP
I have a search form in the header of every page on a site that submits info to another page when undertaking a search query via the form's
action
attribute, namely a page calledsearch.php
and it takes the value of the search<input>
field and stores it as a variable calledsearchQuery
. Using PHP this searches a MySQL database. All of this works as expected.I would like the value of the search input field to be placed in the URL of the page the search is processed on, again namely
search.php
.I understand from other questions on SO that you can't add variables to a form's
action
attribute. If I add the key of the query string in the action attribute, the form still works OK:action="search.php?keyword="
From this I thought I would be able to then set the
$_GET
value on thesearch.php
page by using:if(isset($_POST['search-submit'])) { // make this variable available before HTML output $searchQuery = htmlspecialchars($_POST['search']); $_GET['keyword'] = $searchQuery; }
This however does not work, although it doesn't throw any errors in my PHP error logs.
Because I'm running the script on specific page allocated by the action attribute, I don't think I need to use a
$_SESSION
variable?HTML Form
Here is the form that is on every page in the header
<form action="search.php?keyword=" method="POST"> <label for="search">Enter Search</label> <input type="search" name="search" id="search"> <button type="submit" name="search-submit" id="search-submit">Search</button> </form>
-
CakePHP 4.x MissingTemplate Exception when EmailTransport url is defined
Inside
app_local.php
:'EmailTransport' => [ 'default' => [ 'className' => MailTransport::class, /* * The keys host, port, timeout, username, password, client and tls * are used in SMTP transports */ 'host' => 'localhost', 'port' => 25, 'timeout' => 30, /* * It is recommended to set these options through your environment or app_local.php */ //'username' => null, //'password' => null, 'client' => null, 'tls' => false, 'url' => 'myCompany-org.mail.protection.outlook.com' ], ],
Currently, when I set the
url
property to a string, the app crashes with the error below: If the value ofurl
is null then the application does not crash.Fatal error: Type of Cake\View\Exception\MissingTemplateException::$file must be string (as in class Exception) in C:\xampp\htdocs\creative_trak_2\vendor\cakephp\cakephp\src\View\Exception\MissingTemplateException.php on line 23
I thought this could have been a routing issue but I don't know any routes that MailTransport uses. Since I am using React Router, my app is a single page app and my
routes.php
file looks like:$routes->scope('/', function (RouteBuilder $builder) { // Single Page Application $builder->connect('/*', ['controller' => 'Pages', 'action' => 'main']); $builder->connect('/users/{action}', ['controller' => 'Users']); $builder->connect('/pages/*', 'Pages::display'); $builder->fallbacks(); });
I checked my
logs
and there was not no error appearing. Any advice is appreciate on how to further debug this.Thank you.
-
Show default browser 403 HTTP code page for missing controller. CakePHP 4.3
All answers I found do not cover the newest CakePHP version [4.3.8] and only handle how to change the template.
I want to show the default browser page for HTTP code 403 when the controller is missing. How to achieve it in the simplest way? No editing of the HTTP 404 template, just executing this command and that's it:
header("HTTP/1.1 403 Forbidden");
-
Boostrap vertical sizing with different style width and height
I am trying to set verticaly icon on profile photo card inside div to be in the middle in white box(div), but dont know why it doesnt works. When I use
style="width: 300px; height: 300px;
for div square I can center it on horizontaly, but not verticaly :/ Can someone explain me what I am doing wrong?Anyway is there any way how to resize bootstrap icons except display-1???
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css"> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <div class="container-sm offset-md"> <h1 class="p-4 m-4">Nastavení profilu</h1> <div class="row"> <div class="col"> <div class="card p-4 m-4"> Osobní údaje <input type="text" name="name" class="form-control" placeholder="Jméno"> <input type="text" name="surname" class="form-control" placeholder="Příjmení"> <input type="email" name="email" class="form-control" placeholder="E-Mail"> <input type="date" name="name" class="form-control"> </div> </div> <div class="col-4"> <div class="card p-4 m-4 bg-light"> Profilová fotografie <div class=" square text-center border display-1 m-3 bg-white mx-auto"> <i class="bi bi-person-fill align-middle justify-content-center text-secondary"></i> </div> <input type="file" id="customFile" name="file" hidden=""> <div class="text-center"> <button class="btn btn-success" for="customFile">Nahrát</button> <button type="button" class="btn btn-danger">Smazat</button> <p class="text-muted mt-3 mb-0">Poznámka: Minimální velikost 300px x 300px</p> </div> </div> </div> </div> <div class="row"> <div class="col"> <div class="card p-4 m-4"> Změna hesla </div> </div> <div class="col"> <div class="card p-4 m-4"> Zobrazit/skrýt podrobnosti </div> </div> </div> </div>
-
Bootstrap popover content callback called twice on every second click
I'm trying to create a feature that will display the popover with manual click event. My goal is to populate the popover and display newest data through ajax call after every click.
The problem I'm facing is described on the title.
For example:
1st click -> call once 2nd click -> call twice 3rd click -> call once 4th click -> call twice ...
The code look like this:
$popoverButton.popover({ container: 'body', template: `<div></div>`, title: 'title', content: function () { console.log('*'); // this called twice on every second click let id = $(this).attr('data-id'); return initPopover(id); }, html: true, trigger: 'manual', }); function initPopover(id) { let $popover = $('<div class="popover-body"></div>'); $popover.attr({'id': 'popover-body-' + id}); let $spinner = $(`<div class="spinner"><span class="spinner-border"></span></div>`); $popover.append($spinner); let $sellers = $('<div class="sellers"></div>'); $popover.append($sellers); return $popover; }
To open the popover, I declared the click event with these functions:
$popoverButton.on('click', function () { closePopover(); openPopover($(this)); }); closePopover() { $popoverButton.popover('hide'); } openPopover($targetButton) { // hide all opened popovers $('.popover').popover('hide'); $targetButton.popover('show'); getSellersAndAppendData(); }
I'm not sure why this happened. Please help.
-
The "" cache configuration does not exist
I am updating a project from CakePHP 3.5 to 4.0. In one of my models, I am doing this:
public function afterSave(Event $event, EntityInterface $entity) { Cache::clear(false, 'dbResults'); }
This works in the "old" version of my project with CakePHP 3.5, but fails with CakePHP 4.0 with the error
The "" cache configuration does not exist.#0 /var/www/repo/public/vendor/cakephp/cakephp/src/Cache/Cache.php(230): Cake\Cache\Cache::_buildEngine('')
I don't understand why the code tries to search for a configuration with empty string
""
.Here is the relevant part of my
app.php
config file:'Cache' => [ 'default' => [ 'className' => 'File', 'prefix' => 'headless_', 'path' => CACHE, 'url' => env('CACHE_DEFAULT_URL', null), ], '_cake_core_' => [ 'className' => 'File', 'prefix' => 'headless_cake_core_', 'path' => CACHE . 'persistent/', 'serialize' => true, 'duration' => '+2 minutes', 'url' => env('CACHE_CAKECORE_URL', null), ], '_cake_model_' => [ 'className' => 'File', 'prefix' => 'headless_cake_model_', 'path' => CACHE . 'models/', 'serialize' => true, 'duration' => '+2 minutes', 'url' => env('CACHE_CAKEMODEL_URL', null), ], 'permissions' => [ 'className' => 'File', 'prefix' => 'headless_', 'path' => CACHE . 'permissions/', 'url' => env('CACHE_PERMISSIONS_URL', null), ], 'dbResults' => [ 'className' => 'File', 'prefix' => 'headless_', 'path' => CACHE . 'dbResults/', 'url' => env('CACHE_PERMISSIONS_URL', null), 'duration' => '+1440 minutes', ], 'pages' => [ 'className' => 'File', 'prefix' => 'page_', 'path' => CACHE . 'pages/', 'serialize' => true, 'duration' => '+320 minutes', ], 'page_contents' => [ 'className' => 'File', 'prefix' => 'pc_', 'path' => CACHE . 'page_contents/', 'serialize' => true, 'duration' => '+320 minutes', ], ],
In addition to that, in my
bootstrap.php
file I am doingCache::setConfig(Configure::consume('Cache'));
I don't understand why I get this error when everything seems to be properly configured.
-
Add.php Form->control not building the proper <select> for the belongsTo association
I'm trying to learn CakePHP and running into some issues (maybe just my misunderstanding) with the ways associations are handled. I have a RESULTS table with a composite key made of two foreign keys from tables WORKSHEETS and STUDENTS. Here are the relationships between Results, Worksheets and Students.
Results N - 1 Students
Results N - 1 Worksheets
My problem is, the scaffolded ADD page for my RESULTS table doesn't show the
<select>
field for STUDENTS and WORKSHEETS.First, here is the HTML of the results/add.php page, generated by the Form->control. The two inputs for STUDENT and WORKSHEET are not Selects but hidden inputs.
<input type="hidden" name="student_id" options="(object)Cake\Datasource\ResultSetDecorator" id="student-id"/> <input type="hidden" name="worksheet_id" options="(object)Cake\Datasource\ResultSetDecorator" id="worksheet-id"/> <div class="input text"> <label for="result">Result</label> <input type="text" name="result" id="result" maxlength="6"/></div> <button type="submit">Submit</button>
Here is the scaffolded initialize() code for ResultsTable.php:
$this->setTable('results'); $this->setDisplayField(['student_id', 'worksheet_id']); $this->setPrimaryKey(['student_id', 'worksheet_id']); $this->addBehavior('Timestamp'); $this->belongsTo('Students', [ 'foreignKey' => 'student_id', 'joinType' => 'INNER', ]); $this->belongsTo('Worksheets', [ 'foreignKey' => 'worksheet_id', 'joinType' => 'INNER', ]);
Here is the Form Control generation in add.php (the two first lines were not even added during scaffolding).
echo $this->Form->control('student_id', ['options' => $students]); echo $this->Form->control('worksheet_id', ['options' => $worksheets]); echo $this->Form->control('result');
Here is the last part of the add function in the controller:
$students = $this->Results->Students->find('list', ['limit' => 200])->all(); $worksheets = $this->Results->Worksheets->find('list', ['limit' => 200])->all(); $this->set(compact('result', 'students', 'worksheets'));
StudentsTable.php initialize()
$this->setTable('students'); $this->setDisplayField('name'); $this->setPrimaryKey('id'); $this->addBehavior('Timestamp'); $this->belongsTo('Ranks', [ 'foreignKey' => 'rank_id', ]); $this->belongsTo('Grades', [ 'foreignKey' => 'grade_id', 'joinType' => 'INNER', ]); $this->hasMany('Results', [ 'foreignKey' => 'student_id', ]);
WorksheetsTable.php initialize()
$this->setTable('worksheets'); $this->setDisplayField('id'); $this->setPrimaryKey('id'); $this->addBehavior('Timestamp'); $this->belongsTo('Subranks', [ 'foreignKey' => 'subrank_id', 'joinType' => 'INNER', ]); $this->hasMany('Results', [ 'foreignKey' => 'worksheet_id', ]); }
Some hints about why this is happening ?
Let me know if you need any kind of other information or piece of code.
PS: All other tables with belongsTo relationships were scaffolded properly and have the right
<select>
fields.Debug($worksheets) output:
ROOT\templates\Results\add.php (line 8) object(Cake\Datasource\ResultSetDecorator) id:0 { 'count' => (int) 12 }
debug($students) output:
ROOT\templates\Results\add.php (line 10) object(Cake\Datasource\ResultSetDecorator) id:0 { 'count' => (int) 2 }
After removing ->all() from the add method in the controller, getting a query object as follows:
ROOT\templates\Results\add.php (line 10) object(Cake\ORM\Query) id:0 { '(help)' => 'This is a Query object, to get the results execute or iterate it.' 'sql' => 'SELECT Students.id AS Students__id, Students.name AS Students__name FROM students Students LIMIT 200' 'params' => [ ] 'defaultTypes' => [ 'Students__id' => 'integer', 'Students.id' => 'integer', 'id' => 'integer', 'Students__student_number' => 'string', 'Students.student_number' => 'string', 'student_number' => 'string', 'Students__name' => 'string', 'Students.name' => 'string', 'name' => 'string', 'Students__rank_id' => 'integer', 'Students.rank_id' => 'integer', 'rank_id' => 'integer', 'Students__worksheets_count' => 'integer', 'Students.worksheets_count' => 'integer', 'worksheets_count' => 'integer', 'Students__perfects_count' => 'integer', 'Students.perfects_count' => 'integer', 'perfects_count' => 'integer', 'Students__accuracy_rate' => 'integer', 'Students.accuracy_rate' => 'integer', 'accuracy_rate' => 'integer', 'Students__created' => 'date', 'Students.created' => 'date', 'created' => 'date', 'Students__modified' => 'date', 'Students.modified' => 'date', 'modified' => 'date', 'Students__email' => 'string', 'Students.email' => 'string', 'email' => 'string', 'Students__password' => 'string', 'Students.password' => 'string', 'password' => 'string', 'Students__grade_id' => 'integer', 'Students.grade_id' => 'integer', 'grade_id' => 'integer', ] 'decorators' => (int) 0 'executed' => false 'hydrate' => true 'buffered' => true 'formatters' => (int) 1 'mapReducers' => (int) 0 'contain' => [ ] 'matching' => [ ] 'extraOptions' => [ ] 'repository' => object(App\Model\Table\StudentsTable) id:1 { 'registryAlias' => 'Students' 'table' => 'students' 'alias' => 'Students' 'entityClass' => 'App\Model\Entity\Student' 'associations' => [ (int) 0 => 'Ranks', (int) 1 => 'Grades', (int) 2 => 'Results', ] 'behaviors' => [ (int) 0 => 'Timestamp', ] 'defaultConnection' => 'default' 'connectionName' => 'default' } } ROOT\templates\Results\add.php (line 8) object(Cake\ORM\Query) id:0 { '(help)' => 'This is a Query object, to get the results execute or iterate it.' 'sql' => 'SELECT Worksheets.id AS Worksheets__id FROM worksheets Worksheets LIMIT 200' 'params' => [ ] 'defaultTypes' => [ 'Worksheets__id' => 'integer', 'Worksheets.id' => 'integer', 'id' => 'integer', 'Worksheets__subrank_id' => 'integer', 'Worksheets.subrank_id' => 'integer', 'subrank_id' => 'integer', 'Worksheets__link' => 'string', 'Worksheets.link' => 'string', 'link' => 'string', 'Worksheets__created' => 'date', 'Worksheets.created' => 'date', 'created' => 'date', 'Worksheets__modified' => 'date', 'Worksheets.modified' => 'date', 'modified' => 'date', ] 'decorators' => (int) 0 'executed' => false 'hydrate' => true 'buffered' => true 'formatters' => (int) 1 'mapReducers' => (int) 0 'contain' => [ ] 'matching' => [ ] 'extraOptions' => [ ] 'repository' => object(App\Model\Table\WorksheetsTable) id:1 { 'registryAlias' => 'Worksheets' 'table' => 'worksheets' 'alias' => 'Worksheets' 'entityClass' => 'App\Model\Entity\Worksheet' 'associations' => [ (int) 0 => 'Subranks', (int) 1 => 'Results', ] 'behaviors' => [ (int) 0 => 'Timestamp', ] 'defaultConnection' => 'default' 'connectionName' => 'default' } }