Also add this to other layout files, if you're using them., (*15)
Bake JS Controllers
You can bake JS Controllers for your controller actions by using the bake shell. Just pass the controller name and the camelized action name., (*16)
bin/cake bake js_controller Posts addPost
This command will create the JavaScript-controller file and if necessary the directory structure for it., (*17)
You can also bake JS controllers into your plugins by using the --plugin option., (*18)
Code Examples
Use the following example code snippets to get a better understanding of the FrontendBridge Plugin and its useful features. Note that you might need to include further Plugins for these., (*19)
1.) Access view variables in js_controller
Use the following basic setup to pass data from the Backend to the Frontend via FrontendBridge., (*20)
YourController.php (CakeController), (*21)
action() {
$this->FrontendBridge->setJson(
'varName',
'this is sample text');
}
action.ctp (Cake View file), (*22)
display content of json var
<span class="findMe"></span>
startup: function() {
var varName = this.getVar('varName');
$('findMe').text(varName);
}
Be sure to play close attention to the naming convention, especially regarding the action_controller.js. Following the example shown above, its exact path should be /webroot/js/app/controllers/your/action_controller.js, (*24)
The data you passed from the Controller to the Frontend in the variable varName should now be rendered in the view., (*25)
2.) Use modal dialog windows for editing forms
This example uses the following additional Plugins:, (*26)
Use the following basic setup to use a modal view element as an edit form that passes the change-request data to the Backend via FrontendBridge. For this example, we will use a basic Users-Model as well as a modal form-element, embedded in the regular view page for a User-Entity to edit and save some of its attributes., (*27)
UsersController.php (CakeController), (*28)
public function editModal ($id = null) {
$user = $this->Users->get($id);
if ($this->request->is(['patch', 'post', 'put'])) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
// prevent redirecting or reloading of the current page
$this->FrontendBridge->setJson('success', true);
}
}
$this->set(compact('user'));
}
view.ctp (regular Cake View file; edit_modal.ctp in front of it), (*29)
// CkTools button
<?=$this->CkTools->button('edit_label', [
'controller' => 'Users',
'action' => 'editModal',
$user->id
],
// block interaction with the view file 'behind' the modal element
['additionalClasses' => 'modal-form']
)?>
edit_modal.ctp (View file which will be the content of the modal form), (*30)
startup: function() {
// add an EventListener to element with class 'modal-form'
this.$('.modal-form').on('click', function(e) {
// callback function when Listener is triggered
e.preventDefault();
App.Main.Dialog.loadDialog($(e.currentTarget).attr('href'), {
modalTitle: 'Modal title',
preventHistory: false
});
});
}
3.) Generate custom AJAX requests
Use the following setup to generate custom AJAX requests. Using FrontendBridge's 'request' action, we will pass JSON data from the Backend to the Frontend., (*32)
YourController.php (CakeController), (*33)
public function getJsonData()
{
$code = ApiReturnCode::SUCCESS;
return $this->Api->response($code, [
'foo' => 'bar',
'more' => 'json-data'
]); // JSON data which will be logged in your browser console
}
App.Controllers.YourIndexController = Frontend.AppController.extend({
startup: function() {
this.$('.ajax-json-demo').click(function() {
var url = {
controller: 'Your',
action: 'getJsonData'
};
// if postData is null, a GET request will be made
var postData = null;
App.Main.request(url, postData, function (response) {
alert('Response Code ' + response.code + ' - see console for details');
console.log(response.data);
});
}.bind(this));
}
});
4.) Load content dynamically using AJAX
Use the following setup to make custom HTML requests via AJAX. Using FrontendBridge's loadJsonAction and request, we will implement a very basic livesearch., (*36)
This example assumes a Table called Users with a field username in your database., (*37)
SearchController.php (CakeController), (*38)
public function index() {
// renders index.ctp
}
public function search() {
$users = null;
if ($this->request->is(['patch', 'post', 'put']) && !empty($this->request->data['search'])) {
// search UsersTable for entities that contain
// request->data['search'] in field 'username'
$users = TableRegistry::get('Users')->find()
->where(['username LIKE' => '%' . $this->request->data['search'] . '%'])
->all();
}
$this->set(compact('users'));
}
index.ctp (Cake View file), (*39)
<!-- input field -->
<div class="input-group">
<input type="text" class="form-control" id="search">
</div>
<br />
<!-- search results (search.ctp) will be rendered here -->
<div class="results"></div>
search.ctp (Cake View file), (*40)
<?php if(!empty($users)) : ?>
<?php foreach($users as $user) : ?>
<?= h($user->username) ?><br />
<?php endforeach; ?>
<?php else : ?>
no results to display
<?php endif; ?>
App.Controllers.SearchIndexController = Frontend.AppController.extend({
startup: function() {
// set KeyUp-EventListener to field with id 'search' in index.ctp
this.$('#search').keyup(this._search.bind(this));
},
// called at eatch keyup-event in 'search'
_search: function() {
var $renderTarget = this.$('.results');
var url = {
controller: 'Search',
action: 'search'
}
// create a custom AJAX request with the user input included in the post-data
App.Main.loadJsonAction(url, {
data: {
search: this.$('#search').val()
},
target: $renderTarget, // render the HTML into this selector
});
}
});
Functionality Overview
loadJsonAction, (*42)
Allows dynamically loading content in the view using AJAX according to user interaction. Uses request., (*43)
request, (*44)
Allows generating custom AJAX requests.
Also supports FormData (except IE <= 9) as request data., (*45)