I have a CJUIDialog where i load the content of another form using renderPartial. In that form there is an ajax button where it loads another form. That form contains another ajax button where i need to load the previous form inside the dialog itself. I have tried doing it like this. But it doesnt work.
In my controller i have two methods that prints out the two forms like this.
public function actionNewRecipients(){
$customer = new Customer;
$address = new Address;
$content = $this->renderPartial('_form_new',array('customer'=>$customer,'address'=>$address,'guest'=>true),true);
echo $content;
}
public function actionAddRecipients()
{ $content = $this->renderPartial('_form_inner',array(),true);
echo $content;}
And then in one form i have the ajax button like,
echo CHtml::ajaxSubmitButton(Yii::t('New','New Recipient'),CHtml::normalizeUrl(array('customer/newRecipients')),array('success'=>'js: function(data) {
alert("new");
$("#dialog_gift").html(data);
$("#dialog_gift").dialog("option","title","Select Recipient");
}'));
and in the other form i have the ajax button like,
echo CHtml::ajaxSubmitButton(Yii::t('New','New Recipient'),CHtml::normalizeUrl(array('customer/addRecipients')),array('success'=>'js: function(data) {
alert("select");
$("#dialog_gift").html(data);
$("#dialog_gift").dialog("option","title","Select Recipient");
//$("customer-form_inner").attr("action","'.CHtml::normalizeUrl(array('customer/newRecipients')).'")
}'));
And the CJUIDialog looks like,
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
'id'=>'dialog_gift',
// additional javascript options for the dialog plugin
'options'=>array(
'title'=>$title,
'autoOpen'=>false,
'modal'=>true,
'scrolling'=>'no',
'resizable'=>false,
'scrollable'=>false,
'closeOnEscape' => true,
),
));
echo '<div class="span-24">';
echo $content;
echo '</div>';
$this->endWidget('zii.widgets.jui.CJuiDialog');
Ill be initially loading one forms content.
The first transition happens properly. But after i replace the html content the second transition to load the other view does not happen.
Please let me know if anyone can help.
Thanks
Try setting the 4th parameter of the renderPartial(string $view, array $data=NULL, boolean $return=false, boolean $processOutput=false)-function. By setting $processOutput to true, all necessary scripts (including those to enable ajax-button-functionality) will be included and executed.
Related
I am developing a plugin in which I get data from API, and then the user has an option to add this data to the cart and purchase the product. Everything works perfectly, except once we reload the page, the user cart value gets lost. How can I solve this?
I think one solution is, If we add the cart object to the session, it will be easy to use that session value to get the cart object. For this, I added the below function
my_file.js
function savecartObj(cartObj) {
$.post(
'cartObj.php',
{
cartobj : cartObj
},
function success(data) {
console.log(data);
}
);
}
and in my cartObj.php
<?php
/** Set up WordPress environment, just in case */
$path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__);
require_once($path.'wp-load.php');
session_id() || session_start();
nocache_headers();
$_SESSION['ajjx'] = $_POST;
$value = '';
if (array_key_exists('ajjx', $_SESSION)) {
if (array_key_exists('cartobj', $_SESSION['ajjx']) {
$value = $_SESSION['ajjx']['cartobj'];
}
}
Header('Content-Type: application/json;charset=utf8');
die(json_encode(array(
'result' => $_SESSION['ajjx']['cart_obj'],
)));
Now I can see that $_SESSION['ajjx']['cart_obj'] is set and in console.log(data); I can see the session value. How can i use this value from $_SESSION['ajjx']['cartobj'] as cartobj in my_file.js
What I need is will create one file named get_session.php and in
that file, I will call the value of $_SESSION['ajjx']['cart_obj'] .
And then once my plugin is loaded I will call the value in
get_session.php & need to take the obj from the file and then add that value to add to cart function in the my_file.js. In that way, page reload doesn't
affect my cart.
Update
For getting the value I write the following function in my my_file.js
function get_cartObj(){
$.post(
'get_cartObj.php',
function success(data) {
console.log(data);
}
);
}
and in get_cartObj.php
<?php
/** Set up WordPress environment, just in case */
$path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__);
require_once($path.'wp-load.php');
session_id() || session_start();
nocache_headers();
Header('Content-Type: application/json;charset=utf8');
json_encode(array(
'result' => $_SESSION['ajjx']['cart_obj'], // This in case you want to return something to the caller
));
but here get_cartObj() is not working as expected. No data coming in console.log(data);
The same way you saved it. Actually you can add a parameter to (save)CartObj:
function cartObj(operation, cartObj) {
$.post(
'cartObj.php',
{
op : operation,
cartobj : cartObj
},
function success(data) {
console.log(data);
}
);
}
and in the PHP code (7.4+ required because of the ?? operator)
if ($_POST['operation'] === 'set') {
$_SESSION['ajjx']['cartObj'] = $_POST['cartObj'] ?? [ ];
}
$value = $_SESSION['ajjx']['cartObj'] ?? [ ];
Header('Content-Type: application/json;charset=utf8');
die(json_encode(['result' => $value]));
Now calling the function with 'set' will save the Javascript cart into session, using 'get' will recover the cart.
update
You can also do it like this:
assuming that your page might receive a cart or it might not,
and you will always run the same AJAX code regardless,
then the PHP code must avoid removing the cart if the cartObj parameter is empty (you will need a different call to remove the cart when you need to do this; or you may do it from PHP).
session_id()||session_start();
if ('set' === $_POST['operation'] && !empty($_POST['cartObj'])) {
$_SESSION['ajjx']['cartObj'] = $_POST['cartObj'];
}
Header('Content-Type: application/json;charset=utf8');
die(json_encode(['result'=>$_SESSION['ajjx']['cartObj']??[]]));
This way, if you reload the page but the POSTed cart is now empty (because it's a reload), the AJAX script will not update the session, and it will return the previous session value.
Before im going to answer the question i have some dubt to clear, it looks like you are in a wordpress environment but you are not using his AJAX standard procedures. Check it out here https://codex.wordpress.org/AJAX_in_Plugins
About the issue since JS is client side and PHP is server side you need something to have the values available in JS. I can think of two option:
Print into the page with some PHP a little script tag which is made like this:
<script>
var myObjectVar = '<?php echo json_encode($_SESSION['ajjx']['cart_obj']); ?>';
</script>
You make a new AJAX call as soon as the page load to read that same value from PHP again and then use it to make what you need to do
I am trying to make a delete button which I'll be able to delete some user from my database but main thing how to call PHP function with clicking on some div etc..
<div class="cross" onclick='<?php deleteUser("Nickname")?>'>X</div>
<?php
function deleteUser($username) {
//... code
}
?>
Html can't directly call php, it can do a separate call to load the same page, with the action.
<?php
function deleteUser($username){}
if($_GET['action'] == "delete")
{
deleteUser($_GET['username']);
}
?>
<a class="cross" href='?action=delete&username=NickName'>X</a>
The reason for this is because PHP runs on the server, BEFORE anything is sent to the browser. So it requires another page load to run the function by clicking something. It is possible to use javascript and AJAX calls to send a call to a php script without reloading the main page. Just look into Jquery's post or ajax features.
You cannot call a PHP function that resides on the server by just clicking on a div that exists on the client browser.
You need to trigger a Javascript event (using e.g. jQuery), that will call a function on the server (e.g. through AJAX), that after checking the parameters are correct and the user has the right of calling it will do what you seek.
There are ready-made frameworks that would allow you to do that.
Otherwise (after including jQuery in your HTML page) you can do something like,
<div class="cross" id="deleteUserButton" data-user="nickname">X</div>
<script type="text/javascript">
$('#deleteUserButton').on('click', function() {
let nick = $(this).attr('data-user');
$.post('/services/delete.php',
{
cmd: 'delete',
user: nick
}).then( reply => {
if (reply.status === 'OK') {
alert("User deleted");
}
});
<?php
$cmd = $_POST['cmd'];
switch($cmd) {
case 'delete':
$user = $_POST['user'];
if (deleteUser($user)) {
$reply = [ 'status' => 'OK' ];
} else {
$reply = [ 'status' => 'failure', 'message' => 'Doh!' ];
}
break;
...
header('Content-Type: application/json;charset=UTF-8');
print json_encode($reply);
exit();
I want to update a div contents automatically with refresh whole page. So i did Ajax renderPartial in YII. Now I implement using AJAX button onclick
My code as follows
<?php
echo CHtml::ajaxButton ("Update data",
CController::createUrl("blog/UpdateAjax?url=$url"),
array('update' => '#inrscrn'));
?>
Now I want to render with in a time limit please help
Your question is not very clear. I suppose you want to setup an automatical & periodical refresh of the content within a div instead of clicking on the button.
This is the JavaScript you need on your page:
<script type="text/javascript">
timeout = 60 * 1000; // in Milliseconds -> multiply with 1000 to use seconds
function refresh() {
<?php
echo CHtml::ajax(array(
'url'=> CController::createUrl("blog/UpdateAjax?url=".$url),
'type'=>'post',
'update'=> '#inrscrn',
))
?>
}
window.setInterval("refresh()", timeout);
</script>
But it is not a good approach to send an URL to your controler, rather make a direct request to to make a special AJAX return of a controler which needs to return the correspondent data.
<?php
public function actionTest(){
if (isset($_REQUEST['AJAX']) || Yii::app()->getRequest()->getIsAjaxRequest()) {
$this->renderPartial(
'test',
array('model' => $model),
false,
true
);
} else {
$this->render(
'test',
array('model' => $model),
);
}
}
?>
Does anyone have experience with ajax in drupal 7?
I'm a little stuck.
So, with my module, I output a link and map the path to a callback function with hook_menu()
In the callback function I used ajax_command_replace() and ajax_deliver() to update content.
Well, so far, so good. It all works. But turns out, for complicated reasons, that using links won't work.
So instead I decided to try the jQuery ajax way. So I attach a click event to a div so when it gets clicked something like this runs in a JavaScript file that I load:
jQuery.ajax({
type: 'POST',
url: 'http://path/etc',
});
Then, in my module, I use hook menu to map the path to a callback function that looks like this:
function the_callback($var) {
// a lot of code that gets the right nid to load. This all works...
// and eventually I end up here:
$node = node_load($nid, NULL, false);
if ($node) {
$node_view = node_view($node);
$output = theme("node",$node_view);
$commands = array();
$commands = ajax_command_replace('#content','<div id = "content">' . $output . '</div>';
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
This is the exact same code that was sucessfully replacing content when I had the links. But for some reason this doesn't work when I try to invoke the ajax call with jQuery. The callback function gets called, the correct stuff gets loaded in $output, but the page isn't updating.
Does anyone know what is going on here?
Are you missing a closing parenthesis?
$c = ajax_command_replace('#content','<div id = "content">' .$output. '</div>';
Should be:
$c = ajax_command_replace('#content','<div id = "content">' .$output. '</div>');
probably there is some javascript code inside the $output returned by theme('node', $node_view) , which you need to strip(remove).
here's some code from my ajax function returning the node rendered content:
$n = node_load($nid, NULL, FALSE);
$output = drupal_render(node_view($n));
$output = preg_replace('~<script\s+type="text/javascript">.+</script>~is', '', $output);
I'm in a page called 'add.cpt' that has a list of images. The user has the option to remove the images but I can't make it work. In the event of click I try to call an ajax trying to pass the name of the image and id of the item (.../item/imageName) but it does delete the image and alerts what seems to be the content of delete_photo_file.ctp. It looks like the ajax is using the URL but it is not sending the data to delete the file wanted.
ItemsController:
App::uses('File', 'Utility');
class ItemsController extends AppController{
[...]
public function deletePhotoFile(){
//$this->autoRender = false; //did not tested but maybe I need to use this
$imgName = //don't know how to get it from ajax call
$itemId = //don't know how to get it from ajax call
$file = new File($dir.'/'.$itemId.'/'.$imgName);
$file->delete();
}
}
Ajax Call (from my ctp file):
$('#delete').click(function (){
[...]
var itemId=$('#itemId').val(); //comes from hidden input
var imgName = $('#imgName').val(); //comes from hidden input
$.ajax({
type: 'POST',
url:'http://localhost/html/Project/v5/CakeStrap/items/deletePhotoFile/',
data:{"itemId":itemId, imgName: imgName},
success: function(data){
alert(data); //alerts some HTML... seems to be delete_photo_file.ctp content
}
});
});
Can anyone help me? Thanks!
In your ItemsController, make sure you actually load the File utility class, by adding:
App::uses('File', 'Utility');
Just below the opening <?php tag before your class definition. In your action you can just use $this->request->data to get the data keys. Also, return the action of the delete() function, so you can trigger your AJAX success/error call accordingly.
public function deletePhotoFile() {
$imgName = $this->request->data['imgName'];
$itemId = $this->request->data['itemId'];
/**
* Where is the $dir below actually set? Make sure to pass it properly!
* Furthermore, it's always cleaner to use DS constant
* (short for DIRECTORY_SEPARATOR), so the code will work on any OS
*/
$file = new File($dir . DS . $itemId . DS . $imgName);
return $file->delete();
}
Finally, mind your quotes in the AJAX call:
data:{"itemId":itemId, imgName: imgName},
Should become:
data:{"itemId":itemId, "imgName": imgName},
As otherwise, you just call the imgName JS var twice.
In the php $imgName = $this->request->data('imgName'); $itemId = $this->request->data('imgId'); In the js you might want to put quotes around the variable name since it's the same as the name of the value being passed data: {'itemId': itemId, 'imgName': imgName},
To get the data out simply debug($this->request->data) in your deletePhotoFile() method and check the response in your browsers console, it should be a nicely formatted array with the data you POST`d over in your ajax request, you should be able to work out the rest from there.
You'll also want to look into using the RequestHandler component so you can assure the request is an ajax request.