Use ajax/json in yii framework - php

Im trying to make a webshop in Yii framework. Now i want to unset a session when a user clicks on a icon.
I currently have it working that is sends a json call to a file, but the url in the json call is being rewrited by my htaccess i think.
JSON call:
$(document).ready(function(){
$('.glyphicon-trash').click(function(){
$.getJSON("ajax/load.php?action=unset&element="+$(this).parent(), function(data) {
alert(data.message);
});
});
});
Error i get:
GET http://mydomain.nl/my/path/to/site/ajax/load 404 (Not Found)
But it's not load, its load.php! But my htaccess rewrites that url..
.htaccess
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
Other ways of implementing ajax calls in Yii are also good, only i need alot of explanation then.

You can achieve these by core yii-ajax but if you want much work with ajax then you can use the core YII library with "renderPartial" ajax and widgets.
This is the core ajax call with yii
Add below line in your view.
<input type="hidden" id="baseUrl" value="<?php echo Yii::app()->getBaseUrl(true);?>">
Add below line in your js file.
function changeData(val1){
var baseUrl = $('#baseUrl').val();
var urlCI = baseUrl+'/Controller/actionMethod/;
$.ajax({
type: "GET",
url: urlCI,
data:{
'action':'unset',
'element' : 'someValue'
},
success: function(response) {
if(response!=''){
//do whatever work you want
return true;
}
else{
return false;
}
}
});
}

Okay i got this working now, i made a file under site view. Now i call it like:
$(document).ready(function(){
$('.glyphicon-trash').click(function(){
var session = 'session';
$.getJSON("<?php echo Yii::app()->baseurl; ?>/load?action=unset&session="+session, function(data) {
location.reload(true); //<---- this one does not work tho...
});
setInterval(function(){location.reload(true);}, 500);
});
});

You must not hardcode url's. You must use createUrl() or createAbsoluteUrl() as #Grimv01k recommends you. When in view or in controller you can do this by
$this->createUrl( 'foo/bar',array('id'=>321) )
Other ways:
Yii::app()->controller->createUrl('/baz/foo/bar'); // will use current controller
or
Yii::app()->createUrl('/baz/foo/bar')
Edited
So if you want
to unset a session when a user clicks on a icon
you can do this in following way.
echo CHtml::ajaxLink(
'click me to destroy session, mua-ha-ha',
Yii::app()->createUrl( '/session/destroy' ),
array(
'type' => 'post',
'dataType' => 'json',
'data' => array(
'foo' => 'bar',
),
'beforeSend' => 'js:function(){
console.log( $(this) );
return false;
}',
'success' => 'js:function(data){
console.log(data);
}',
)
);
in SessionController:
public function actionDestroy () {
if ( isset( $_POST['foo'] ) ) {
Yii::app()->session->destroy();
if ( Yii::app()->request->isAjaxRequest ) {
$response = array(
'status' => !Yii::app()->session->sessionID
) ;
echo CJSON::encode( (object) $response );
Yii::app()->end();
}
}
}

Related

how to specify redirect url with ajax jQuery redirect

I have a form that when I submit the form, it would redirect to the url that I've specified from the controller (function controller as action form). I've made a function controller to process the form, and I have several difference conditions that could make 2 redirect from json result when I submit the form. But I want the ajax to redirect to one of the redirect from the json result.
How could I redirect to the specific redirect from the json result?
the json result :
{"result":"ok","message":"Failed!!! ","redirect":"http:\/\/localhost\/myproject\/approval\/detail\/21?status=approve_failed"}
{"result":"ok","message":"Success!!!","redirect":"http:\/\/localhost\/myproject\/approval\/detail\/21?status=approve_success"}
this is how I redirect when I submit the form :
var frm = $('#form-process');
frm.submit(function(e) {
e.preventDefault();
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
dataType: "json",
success: function(res) {
if (res.result == "ok") {
if (res.redirect) {
window.location.href = res.redirect;
}
$.notify("Success. Data saved.", "success");
$('#modalDateEst').modal('hide');
table.ajax.reload();
} else {
$.notify("System gone wrong's. Please contact Administrator", "error");
}
},
error: function(data) {
}
});
});
I've found the solution. Here's what I do.
I make a variable $redirect in the function that I use in the controller. Then I make some the conditions.
Inside the condition should be :
if (//condition) {
$arred = array(
"result" => "ok",
"message" => "Success!!! ",
'redirect' => base_url(//my url for the redirect)
);
$redirect = $arred;
}
so in my function controller would be like :
function something() {
$redirect = "";
if (//condition) {
//do something
$arred = array(
"result" => "ok",
"message" => "Success!!! ",
'redirect' => base_url(//my url for the redirect)
);
$redirect = $arred;
}
if (//condition2) {
//do something
$arred = array(
"result" => "ok",
"message" => "Success!!! ",
'redirect' => base_url(//my url for the redirect)
);
$redirect = $arred;
}
//make the json
echo json_encode($redirect);
}
note : this solution is only making your jquery redirect to the latest redirect that fill the $redirect variable. So if you got multiply redirect, the only redirect that would be used is the latest one. In this case, I just need the latest redirect. So this is my solution.

Posting to CakePHP controller using jquery ajax

I want to post data to a controller in CakePHP, but posting with JQuery always results in"POST http//localhost/SA/myController/editUserData/1 400 (Bad Request)" error and I can't figure out why.
In my view I have the following method, that posts the data to the controller page
$scope.saveUser = function() {
$.ajax({
type: 'POST',
url: '<?php echo Router::url(array(
'controller' => 'myController',
'action' => 'editUserData',
0 => $userInfo['user']['id'],));?>',
data: { email: 'cabraham#delhi.k12'},//"my edited data for example"
success: function (data) {
alert(data);
}
});
My controller method looks like this:
public function editUserData($id) {
if($this->request->is('post') || $this->request->is('put')) {
$this->AcsaUser->save($this->request->data('email'));//edit and save the new data
echo 'ok';
}
}
Any ideas??
Two things that may be throwing it.
(1) Cake's built-in security - so exempt the method from it:
In AppController.php
public function beforeFilter() {
$this->Security->unlockedActions = array('editUserData')
}
(2) Decide how you want your editUserData method to render the view, if you're echo'ing out an 'ok' it will still pull in the default layout and look for an editUserData.ctp in the view (and cause an error if it doesn't find the file), so
To not render anything, ie a .ctp view file and the default layout.. in the editUserData($id), add
$this->autoRender = false;
To only render the view file and not the layout:
$this->autoLayout = false;
......Then lastly I wound just add this parameter in the ajax call :
dataType : 'html' // (or JSON?)

How to make ajax call in yii2?

In yii version 1.14 we used
CHtml::ajaxlink
for ajax call what about in yii2?
You can make an ajax link like
Html::a('Your Link name','controller/action', [
'title' => Yii::t('yii', 'Close'),
'onclick'=>"$('#close').dialog('open');//for jui dialog in my page
$.ajax({
type :'POST',
cache : false,
url : 'controller/action',
success : function(response) {
$('#close').html(response);
}
});return false;",
]);
From: http://www.yiiframework.com/wiki/665/overcoming-removal-of-client-helpers-e-g-ajaxlink-and-clientscript-in-yii-2-0/
You can easily create and combine all such client helpers for your
need into separate JS files. Use the new AssetBundle and AssetManager
functionality with the View object in Yii2, to manage these assets and
how they are loaded.
Alternatively, inline assets (JS/CSS) can be registered at runtime
from within the View. For example you can clearly simulate the
ajaxLink feature using a inline javascript. Its however recommended if
you can merge where possible, client code (JS/CSS) into separate
JS/CSS files and loaded through the AssetBundle. Note there is no more
need of a CClientScript anymore:
$script = <<< JS
$('#el').on('click', function(e) {
$.ajax({
url: '/path/to/action',
data: {id: '<id>', 'other': '<other>'},
success: function(data) {
// process data
}
});
});
JS;
$this->registerJs($script, $position);
// where $position can be View::POS_READY (the default),
// or View::POS_HEAD, View::POS_BEGIN, View::POS_END
$.get( "' . Url::toRoute('controller/action') . '", { item: $("#idoffield").val()} ) /* to send the parameter to controller*/
.done(function( data )
{
$( "#lists" ).html( data );
})
and give lists id for div
<div id="lists"></div>
for more visit https://youtu.be/it5oNLDNU44
<?=yii\helpers\Url::toRoute("site/signup")?>

403 Forbidden Access to CodeIgniter controller from ajax request

Im having trouble with sending an ajax request to codeigniter controller. It is throwing back a 404 Forbidden Access error. I have found some sort of similar question to this but im not sure if its particular to CodeIgniter framework, and also the solution give in that thread did not solve my problem. below is my ajax request. Im wondering this is probably because of the .htaccess of the root folder of CI Application folder, but i dont want to change its default configuration yet.
Is sending ajax request to CI controller the correct way of implementing this? if not, any suggestion please. Thanks!
var ajax_load = '{loading gif img html}';
var ajax_processor = 'http://localhost/patientcare-v1/application/controller/ajax_processor/save_physical_info';
$("#save").click(function(){
$("#dialog-form").html(ajax_load);
$.post(
ajax_processor,
$("#physical-info").serialize(),
function(responseText){
$("#dialog-form").html(responseText);
},
"json"
);
});
CodeIgniter use csrf_protection, you can use it with Ajax and JQuery simply.
This (ultimate ?) solution work on multiple Ajax request (no 403 ;-) and preserve the security).
Change the configuration
Open the file /application/config/config.php
and change the line $config['csrf_token_name'] by :
$config['csrf_token_name'] = 'token';
You can use another name, but change it everywhere in future steps.
Add CSRF in your Javascript
Add script in a view; for me is in footer.php to display the code in all views.
<script type="text/javascript">
var CFG = {
url: '<?php echo $this->config->item('base_url');?>',
token: '<?php echo $this->security->get_csrf_hash();?>'
};
</script>
This script create an object named CFG. This object can be used in your Javascript code. CFG.url contain the url of your website and CFG.token ... the token.
Automatically renew the CSRF
Add this code in your part $(document).ready(function($){---}) as
$(document).ready(function($){
$.ajaxSetup({data: {token: CFG.token}});
$(document).ajaxSuccess(function(e,x) {
var result = $.parseJSON(x.responseText);
$('input:hidden[name="token"]').val(result.token);
$.ajaxSetup({data: {token: result.token}});
});
});
This script initialize the CSRF token and update it everytime when a request Ajax is sended.
Send the CSRF in PHP
I've created a new controller, named Ajax. In CodeIgniter, the link to use it is http://www.domain.ltd/ajax/foo
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Ajax extends CI_Controller {
public function foo() {
$this->send(array('foo' => 'bar'));
}
private function send($array) {
if (!is_array($array)) return false;
$send = array('token' => $this->security->get_csrf_hash()) + $array;
if (!headers_sent()) {
header('Cache-Control: no-cache, must-revalidate');
header('Expires: ' . date('r'));
header('Content-type: application/json');
}
exit(json_encode($send, JSON_FORCE_OBJECT));
}
}
The send function add the CSRF automatically and transform an array in object.
The final result
Now, you can use Ajax with JQuery very simply !
$.post(CFG.url + 'ajax/foo/', function(data) {
console.log(data)
}, 'json');
Result :
{"token":"8f65cf8e54ae8b71f4dc1f996ed4dc59","foo":"bar"}
When the request get data, the CSRF is automatically updated to the next Ajax request.
Et voilà !
Remove the <code> and application/controller from your ajax_processor like,
var ajax_processor = 'http://localhost/patientcare-v1/index.php/ajax_porcessor/save_physical_info';
If you are hiding index.php from url by using htaccess or routing then try this url,
var ajax_processor = 'http://localhost/patientcare-v1/ajax_porcessor/save_physical_info';
I was facing same problem but now I have fixed this problem.
First of all, I have created csrf_token in header.php for every pages like below code
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
<script type="text/javascript">
var cct = "<?php echo $csrf ['hash']; ?>";
</script>
After that, when we are sending particular value through ajax then we will have to sent csrf token like below code
$.ajax({
url:"<?php echo APPPATHS.'staff_leave/leaveapproval/getAppliedLeaveDetails'; ?>",
data:{id:id,status:status,'<?php echo $this->security->get_csrf_token_name(); ?>': cct},
method:"post",
dataType:"json",
success:function(response)
{
alert('success');
}
});
I hope this code will help you because this is working for me.
// Select URIs can be whitelisted from csrf protection (for example API
// endpoints expecting externally POSTed content).
// You can add these URIs by editing the
// ‘csrf_exclude_uris’ config parameter:
// config.php
// Below setting will fix 403 forbidden issue permanently
$config['csrf_exclude_uris'] = array(
'admin/users/view/fetch_user', // use ajax URL here
);
$('#zero-config').DataTable({
"processing" : true,
"serverSide" : true,
"order" : [],
"searching" : true,
"ordering": false,
"ajax" : {
url:"<?php echo site_url(); ?>admin/users/view/fetch_user",
type:"POST",
data: {
},
},
});

Drupal module jQuery PHP script location issue

I am developing a module which has a jQuery script with some AJAX code. The ajax code calls a php script located in the same location as the jQuery script.
My problem is, AJAX appends the domain name in front of the PHP script name and of course, my script does not exist at that location and so the process breaks.
The AJAX code is as follows:
$(document).ready(
function(){
$.ajax({
url: "/testscript.core.php",
asych: false,
success: function($data){
$('textarea#edit-simplechat-messages').text( $data );
}
});
}
);
And the following is the link that shows up in firebug:
http://testsite.co.uk/testscript.core.php
Again, the jQuery script and the php script are in the same directory.
I thought the forward slash before my php script name would eliminate the domain name but it did not work.
Use
Drupal.settings.basePath
url: Drupal.settings.basePath+'your file path',
This link might be useful
http://www.akchauhan.com/how-know-base-path-of-drupal-in-javascript/
EDIT :
Or you can use this approach if you are creating your own custom module then follow these steps
1] First create your module, Here my module name is "mymodule", So i created a file name mymodule.module
<?php
function mymodule_init() {
drupal_add_js(drupal_get_path('module', 'mymodule') . '/mymodule.js');
// this call my js file when module is initialized.
}
function mymodule_menu(){
$items = array();
$items['mypath'] = array(
'title' => t('To get series of the selected brand'),
'page callback' => 'mymodule_page',
'page arguments' => array(1),
// get test_parameter from url, which is your first argument
//http://domain.com/mypath/test_parameter
// here mypath is arg(0), and test_parameter is arg(1)
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mymodule_page($termID){
return drupal_json(array('message'=> $itemID));
}
2] Secondly create js file with the same name so name it mymodule.js under the same module file.
// $Id$
Drupal.behaviors.mymodule = function (context) {
var $basepath = Drupal.settings.basePath;
$('selector').change(function(e){
$.ajax({
type: 'POST',
url: $basepath+'mypath/test_parameter',
// test_parameter :value you are sending to you module.
dataType:'json',
cache:false,
beforeSend:function(){
},
success:function(data){
alert(data.message);
},
complete:function(){
},
error:function(xhr, status, error){
}
});
});
}
Notice in js file i have used mypath. your js file will call this path which is defined in the hook_menu().
the way it is now it looks like your problem is the slash before the file name.. that means "domain web root"

Categories