pass value from jquery to Cakephp controller - cakephp-2.0

I am beginner to CakePHP and trying the send the textbox value during change function to my controller action using ajax.
Can someone help to how to pass the value form jquery to cakephp controller. If there is example code could great.

Let's say you want to send your data to a method called 'ajax_process' in the users controller. Here's how I do it:
in your view .ctp (anywhere)
<?php
echo $this->Form->textarea('text_box',array(
'id' => 'my_text',
));
?>
<div id="ajax_output"></div>
In the same view file - the jquery function to call on an event trigger:
function process_ajax(){
var post_url = '<?php echo $this->Html->url(array('controller' => 'users', 'action' => 'ajax_process')); ?>';
var text_box_value = $('#my_text').val();
$.ajax({
type : 'POST',
url : post_url,
data: {
text : text_box_value
},
dataType : 'html',
async: true,
beforeSend:function(){
$('#ajax_output').html('sending');
},
success : function(data){
$('#ajax_output').html(data);
},
error : function() {
$('#ajax_output').html('<p class="error">Ajax error</p>');
}
});
}
In the UsersController.php
public function ajax_process(){
$this->autoRender = false; //as not to render the layout and view - you dont have to do this
$data = $this->request->data; //the posted data will come as $data['text']
pr($data); //Debugging - print to see the data - this value will be sent back as html to <div id="ajax_output"></div>
}
Disable cake's security for the ajax_process method, in AppController.php:
public function beforeFilter() {
$this->Security->unlockedActions = array('ajax_process');
}
I haven't tested any of this code but it should give you what you need

Related

CakePHP 3 Rss error

i want do a rss, I followed this http://book.cakephp.org/3.0/en/views/helpers/rss.html. But the things not working correctly, because when access the router of the rss, it returns a controller error, saying that controller does not exists. My route is this:
/posts/index.rss
When do this request, it return a error of the controller not found.
The action index.rss is not defined in PostsController
I declared that "app" to accepts rss..My complete config/routes.php
use Cake\Core\Plugin;
use Cake\Routing\Router;
Router::defaultRouteClass('Route');
Router::scope('/', function ($routes) {
Router::extensions(['json', 'xml', 'rss']);
$routes->connect('/', ['controller' => 'Fronts', 'action' => 'index']);
$routes->connect('/contact', ['controller' => 'Fronts', 'action' => 'contact']);
$routes->connect(
'/:controller/:action/:id-:slug',
[],
[
'pass' => ['id', 'slug'],
'id' => '[0-9]+',
'routeClass' => 'DashedRoute'
]
);
$routes->fallbacks('InflectedRoute');
});
Plugin::routes();
I also made the LoadComponent in :: initialize () of the controller
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
And my controller
class PostsController extends AppController
{
...
public function index()
{
...
if($this->RequestHandler->isRss()) :
$_rss = $this->Posts->find()->limit(20);
$this->set(compact('_rss'));
return;
endif;
...
}
}
Whats is wrong?
Thankss..!!!
You're defining the extension the wrong way, Router::extensions() is ment to define global extensions for all routes that are being connected after Router::extensions() has been invoked.
So, inside a scope, the call to Router::extensions() is too late, as it's the Router::scope() method, that, when invoked, reads the global extensions and passes them into the scope.
Either invoke Router::extensions() outside of the scope
Router::extensions(['json', 'xml', 'rss']);
Router::scope('/', function ($routes) {
// ...
});
or use RouterBuilder::extensions() inside of the scope (note that this overrides the global extensions that the scope might have been inherited)
Router::scope('/', function (\Cake\Routing\RouteBuilder $routes) {
$routes->extensions(['json', 'xml', 'rss']);
// ...
});
See also Cookbook > Routing > Routing File Extensions

Calling a JavaScript method before rendering

I have one-page app where header, footer and top navigation are static and the "pages" are opened with Ajax.
Example:
Element from the main navigation:
Something
JavaScript:
$('body').on('click', '[data-open-dynamic]', function () {
var url = $(this).data('openDynamic');
openDynamic(url);
})
function openDynamic(url)
{
$.ajax({
url: url,
async: true,
success: function (data) {
//some other logic
$('.content').html(data).fadeIn();
}
})
}
The problem is that I need to open these pages from direct URLs also. Now if I try to open domain.com/controllerName/actionName the design is broken as the layout is set to ajax in the controller:
public function initialize()
{
parent::initialize();
$this->layout = 'ajax';
}
I tried to do something with beforeFilter(), beforeRender(), shutdown() but it seems the JavaScript file containing the method openDynamic() is not loaded yet and I can't call it.
public function beforeRender(\Cake\Event\Event $event)
{
parent::beforeRender($event);
$url = $event->subject->request->here; // the URL is correct
echo 'openDynamic("' . $url . '");';
$this->response->stop();
}
Also I'm not sure if the header, footer and navigation will be loaded properly in this way. How can I achieve this?
How about only setting the layout to be ajax if the page is requested via AJAX? You can test this using $this->request->is('ajax'):-
public function beforeRender(\Cake\Event\Event $event)
{
parent::beforeRender($event);
if ($this->request->is('ajax')) {
$this->layout = 'ajax';
}
}
This would be cleaner than mixing JavaScript with PHP in your code.

Call CI Controller from ExtJs

I am creating controller in Code Igniter and make form in ExtJs 4.2.1 now from where i call control and how?
i used url property of form and put controller name there but nothing happen
Update
I think i am not clearing my question actually i want to post data through submit function in which i pass data to php file in my server side i use Code Igniter Rest Api so here i want pass data to specific controller
ExtJs is a javascript framework and is executed on the client side. It has its own MCV system.
It makes no sense to mix up a php controller with a javascript view.
Be sure to read the introduction to MVC in ExtJS.
Also in ExtJS you don't call the controller. On initialisation of the app, all controllers get lloaded. In the controller you define what it has to control, and from then on the magic hhappens: The events defined in the controller are fired whenever needed.
In ExtJS 3.3.1
In login form put the buttons and call function submit_login();
buttons: [{
text: 'Login',
handler: function() {
submit_login();
}
}]
Submit_login() code is, I used Ext.Ajax.request to submit login parameters
You can debug the message with alert(response.responseText):
function submit_login() {var useridx = Ext.getCmp('useridx').getValue();var userpasswordx = Ext.getCmp('userpasswordx').getValue();Ext.Ajax.request({url:'".$url."', method:'POST',
params :{useridx:useridx,userpasswordx:userpasswordx},
success:function(response){
//alert(response.responseText);
//return;
var jsonData = Ext.util.JSON.decode(response.responseText);
var resultMessage = jsonData.Message;
var isLogin = jsonData.isLogin;
if (isLogin)
{
window.location = '';
}
else
{
Ext.Msg.alert('Info',resultMessage);
}
},
failure: function(){
Ext.Msg.alert('Not OK');
}
});
}
variable $url is:
$url = "index.php/apps/login";
You can create Apps controller
and create function login
public function login()
{
$this->load->view('login');
}
Create login.php in view
if ($i==1) {
//session_start();
$this->session->set_userdata('userid',$useridx); echo '{"success" : true, "isLogin": true,"Message" : "User Successfully Login"}';
} else {
echo '{"success" : true, "isLogin": false, "Message" : "Salah User: '.$useridx.' dan Password "}';
}
You also do this in Ext JS 4.2.1 with same code.
This is works for me
Andrex Maulana

CakePHP: JQuery submit() returns a blank page

I create a function in CakePHP controller class to process AJAX request. But I found different result when using CakePHP function and simple (Non-MVC) PHP code. My problem is when it goes to submit() process. When using CakePHP function it returns blank page.
Here is the AJAX request code that I use:
var userdata = {username : $("#UserUsername").val()};
$.ajax({
type:'POST',
url: 'http://localhost/mycakephp/users/login',
data: userdata,
success: function(data){
if(data==0){
alert("empty");
} else {
$("#UserLoginForm").submit();
}
}
});
But when I pointed the url to external site like this:
url: 'http://localhost/test/test.php'
Which test.php is a simple PHP code to handle request, submit process works fine.
Sorry, but your code looks bizarre to me: There you have a login form, you send using ajax your username calling the Controller "UsersController" / function "login", and when you have an answer from this function, then you submit again another form ("#UserLoginForm") and send it again to the controller? You are sending two forms! Most probably this is not what you want. Correct me if I am wrong.
I guess what you want is just submit the UserLoginForm and wait for an answer, whatever it is OK or NotOK, and finally show this result.
You have two options to do this: either CakePHP way or your own ajax code using JQuery. I like to use both, depending on the user experience I want to get.
1. CakePHP way
Include JS Helper in the controler using the public $helpers = array('Js'); and then create a Form in the view, using the submit from the JsHelper.
View
<?php
echo $this->Form->create();
echo $this->Form->input('username');
echo $this->Form->input('whatever');
// use the Js submit from JsHelper
echo $this->Js->submit('Send', array(
'url'=> array('controller' => 'users', 'action' => 'login'),
'update' => '#update_ajax_div',
));
echo $this->Form->end();
// Next line is actually very important in order
// to print the automatically created ajax code from JsHelper.
echo $this->Js->writeBuffer();
?>
<div id="update_ajax_div">
this will be overwritten after submit.
</div>
Controller
In the controller all the data in the form will be sent in the $this->data[] array. For example $this->data['Users'] if this is the Model being used in the Form->create().
The code is pretty standard, except the layout, which must be set to ajax.
public function login(){
// print the data being sent
$dataFromAjaxLink = $this->data[];
$v = var_export($dataFromAjaxLink, true);
$this->log("Ajax log: ".$v, 'debug');
if(isset($this->data['User'])){
$user_name = $this->data['User']['username'];
...
// do your stuff
}
// the answer must be ajax layout
$this->layout = "ajax";
// I like to use elements when using ajax, it keeps the folders clean
// in this example /app/View/Elements/display_ajax_result.ctp
$this->render('/elements/display_ajax_result');
}
The content of this element will be printed in the div "update_ajax_div"
2. Pure Ajax way
The second version is done by manually typing ajax code in <script> tags. This solution gives you more freedom, allowing you to do more complex stuff, but the code is not so clean!
The following JQuery code must be inside some button/div/whatever event...
$(document).ready(function(){
$(".someButton").click(function() {
// create the json data to be sent
var username = $(....).val();
var dataString = ...
// call ajax
$.ajax({
type: "POST",
// never type full paths as in your example. They are sources of errors!
url: "<?php echo $this->Html->url(array(
"controller" => "users",
"action" => "login")); ?>,
data: dataString,
cache: false,
success: function(html){
$("#update_ajax_div").html(html);
}
});
...
The controller is the same as the CakePHP way. Remember to add ajax layout.
I hope it helps you.
According to your comment, if you use the SecurityComponent, you could disable POST validation on the login action. In your UsersController, add this:
function beforeFilter()
{
parent :: beforeFilter();
switch($this->request->params['action'])
{
case 'login':
$this->Security->validatePost = false;
$this->Security->csrfCheck = false;
break;
}
}
But off course you loose the value added by the SecurityComponent on the login action.

Updating multiple divs

I am using the following code to update a div
echo $this->Js->link($station["Company"]["name"],
array('action' => 'station_users','company_id'=>$station["Company"]["id"]),
array('id'=>'team_member'.$x, 'update' => '#myDIV')
);
But now I have a need to update multiple divs. How do I go about it? I want to update multiple divs by clicking on that link.
You can directly use jQuery instead of JsHelper. JsHelper will also render it as jQuery script.
You can add the following type of code in your view in a script block.
jQuery("#id").bind('click', function(event) {
jQuery.ajax({
beforeSend : function(XMLHttpRequest) {
jQuery("#sending").show();
},
data : jQuery("#id").closest("form").serialize(),
dataType : "html",
success : function(data, textStatus) {
updateMultipleDivs(data, textStatus);
},
type : "post",
url : "\/AppName\/ControllerName\/Method"
});
return false;
});
function updateMultipleDivs(data, textStatus) {
jQuery('#Div1toUpdate').before(data);
jQuery("#Div2toUpdate").hide();
}

Resources