I have a dependent dropdown which I fill through ajax. I want to call a function after ajax is done. How can I do this?
echo Chtml::dropDownList('optAudioSura', $strAudioSuraTemp, $suraOptions,
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('QuText/audioFiles'), //url to call.
'update'=>'#optAudio',
'data'=>'js:jQuery(this).serialize()',
)
));
Thanks.
Add a success function to the ajax, e.g.:
echo Chtml::dropDownList('optAudioSura', $strAudioSuraTemp, $suraOptions,
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('QuText/audioFiles'), //url to call.
'update'=>'#optAudio',
'data'=>'js:jQuery(this).serialize()',
'success'=>'function(data) {
// function code here
}',
)
));
Related
In my Yii web application, any type of Ajax call like Ajax validation, Ajax for dependent dropdown etc.... Is not working.
My codes are,
In my form page:
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'workdetails-form',
'enableClientValidation' => true,
'clientOptions' => array(
'validateOnChange' => true,
'validateOnSubmit' => true,
),
// Please note: When you enable ajax validation, make sure the corresponding
// controller action is handling ajax validation correctly.
// There is a call to performAjaxValidation() commented in generated controller code.
// See class documentation of CActiveForm for details on this.
'enableAjaxValidation' => true,
'htmlOptions' => array('enctype' => 'multipart/form-data'),
));
?>
in controller:
public function actionCreate() {
$model = new Workdetails;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if (isset($_POST['Workdetails'])) {
$model->attributes = $_POST['Workdetails'];
if ($model->validate()) {
if ($model->save()) {
$this->redirect(array('create'));
}
}
}
$this->render('create', array(
'model' => $model,
));
}
For dependant dropdown:
<div class="form-group col-sm-6">
<?php echo $form->label($model, 'designationid', array('class' => 'req')); ?>
<?php
$designation = CHtml::listData(Designation::model()->findAll(), 'designationid', 'designation_name');
echo $form->dropDownList($model, 'designationid', $designation, array(
'class' => 'form-control',
'prompt' => 'Please Select',
'ajax' => array(
'type' => 'POST',
'url' => $this->createUrl('workdetails/Fetchemployee'), // here for a specific item, there should be different URL
'update' => '#' . CHtml::activeId($model, 'employeeid'), // here for a specific item, there should be different update
'data'=>array('designationid'=>'js:this.value'),
)));
?>
<?php echo $form->error($model, 'designationid', array('class' => 'school_val_error')); ?>
</div>
How to solve this...
Please help me..
Arya I had the same problem with Yii1 and i gave up using yii-ajax validation cause i could not find a way to fix it. First make sure you have initialize/ register Yii-js file these are
yiiactiveform and yii.js
If you don't have these files on your project, it means you have not registered them. To register the core JS file proceed with this config in your main.
'clientScript' => array(
'scriptMap' => array(
'jquery.js' => true,
'jquery.min.js' => true,
),
),
or if that doesn't work use this on your main view in the header section.
Yii::app()->clientScript->registerCoreScript('jquery');
You can also add it to your base controller which is at components/Controller.php
public function init() {
parent::init();
Yii::app()->clientScript->registerCoreScript('jquery');
}
On your view have this when creating your forms. It will help in placing the error messages. to your elements
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'patient-registration-form',
'enableClientValidation' => True,
'enableAjaxValidation' => FALSE,
'clientOptions' => array(
'validateOnSubmit' => true,
'afterValidate' => 'js:function(form, data, hasError) {
if(hasError) {
for(var i in data) $("#"+i).parent().addClass("has-error");
return false;
}
else {
form.children().removeClass("has-error");
return true;
}
}',
'afterValidateAttribute' => 'js:function(form, attribute, data, hasError) {
if(hasError) $("#"+attribute.id).parent().addClass("has-error");
else $("#"+attribute.id).parent().removeClass("has-error");
$("#"+attribute.id).parent().addClass("has-success");
}'
),
'htmlOptions' => array(
'class' => 'form-horizontal form-bordered form-row-stripped',
),
));
?>
alternatively use Yii2 it has fixed alot of stufff and if you are loading the current page with ajax you need to render the the whole page including the js file again. since when you use renderPartial it doesn't initalize the js files hence no js scripts will work, including validation.
I'm trying to enable ajax validation in a form, I've added the right parameters to the form, but it's not working, here's my code:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'user-form',
'enableAjaxValidation'=>true,
'htmlOptions' => array(
'enctype' => 'multipart/form-data',
'enableClientValidation'=>true
),
)); ?>
Please advice.
In the top of your action, add the following lines:
if(isset($_POST['ajax']) && $_POST['ajax']==='user-form'){
echo CActiveForm::validate($model);
Yii::app()->end();
}
I have situation like on this screen:
I have column where user check rows. After that user can call some actions like example delete data.
To show menu with multi actions for users i use button dropdown in yii-booster TbButtonGroup. I tried all possible buttonType and all doesnt work.
All what i need is send information about what rows are selected, do some action inside controller and after that reload grid. I dont have any idea how...
To generate button dropdown i use code:
Yii::app()->controller->widget('bootstrap.widgets.TbButtonGroup', array(
'size'=>'mini',
'type'=>'link',
'buttons'=>array(
array('icon'=>'edit', 'items'=>$this->filter),
),
));
To generate grid i use code:
$this->widget('bootstrap.widgets.TbJsonGridView', array(
'dataProvider' => $model->search(),
'filter' => $model,
'type' => 'striped condensed',
'summaryText' => false,
'cacheTTL' => 10, // cache will be stored 10 seconds (see cacheTTLType)
'cacheTTLType' => 's', // type can be of seconds, minutes or hours
'selectableRows'=>2,
'columns' => array(
array(
'class'=>'ext._TbJsonCheckBoxColumn._TbJsonCheckBoxColumn',
'id'=>'selectedTickets',
'filter'=>array(
array('label'=>'close', 'url'=>'javascript:'.CHtml::ajax(array('type'=>'POST', 'url'=>array('','multi_action'=>'close'), 'success'=>'function(data, status){ console.log(data); console.log(status); }', 'error'=>"function(data, status){ console.log(data); console.log(status); }")) ),
array('label'=>'Another action', 'url'=>'#'),
array('label'=>'Something else', 'url'=>'#'),
'---',
array('label'=>'Separate link', 'url'=>'#'),
),
),
'id',
'email_from',
'subject',
'status',
array(
'name'=>'last_update',
'value'=>'$data->last_update_from_now',
//'filter'=>false,
),
array(
'header' => Yii::t('ses', 'Edit'),
'class' => 'bootstrap.widgets.TbJsonButtonColumn',
'template' => '{view} {update} {delete}',
),
),
));
To generate form i use code:
$this->widget('bootstrap.widgets.TbButton',array(
'label' => 'Add new ticket',
'type' => 'primary',
'size' => 'medium',
'url' => $this->createUrl('create'),
));
<?php
$form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'id'=>'tickets',
'type'=>'horizontal',
'enableAjaxValidation'=>true,
));
echo $this->renderPartial('_grid', array('model'=>$model));
echo CHtml::ajaxSubmitButton('Activate',array('menu/ajaxupdate','act'=>'doActive'), array('success'=>'reloadGrid'));
$this->endWidget();
After many spent hours i wrote something like that and it solved my problem:
Yii::app()->clientScript->registerScript('multi_button', "
$('[data-multi=action]').delegate('li a', 'click', function(event){
event.preventDefault();
var th = $(this),
action = th.attr('href').substr(1);
if( action=='delete' && !confirm('Are you sure you want to delete selected items?') ) return true;
".
CHtml::ajax(array(
'type'=>'POST',
'data'=>'js:th.closest("form").serialize()',
'url'=>'js:location.href+(/\?/.test(location.href) ? "&" : "?")+"multi_action="+action',
'success'=>'function(data, status){ th.closest("div.grid-view").yiiJsonGridView("update"); }',
'error'=>'function(data, status){ alert(status); }',
'cache'=>false
))."
});
");
When users click on a button (with id graph), I'd like to fill the default Drupal content div (<div class="content">) with a graphael instance.
The JavaScript:
jQuery(document).ready(function($) {
$('#toggle #graph').click(function() {
$.ajax({
url: "http://www.mysite.com/?q=publications/callback",
type: 'POST',
data: {
'format' : 'graph'
},
success: function(response) {
$('div#content div.content').html(response);
}
});
});
});
The PHP:
$items['publications/callback'] = array(
'type' => MENU_CALLBACK,
'title' => 'All Publications Callback',
'page callback' => '_process_publications',
'page arguments' => array(t('journal')),
'access callback' => TRUE,
);
which leads to the page callback: (I'm concerned with the if code block)
function _process_publications($venue) {
if( isset($_POST['format']) && $_POST['format'] == "graph" ){
_make_bar_chart($venue);
}
elseif( isset($_POST['format']) && $_POST['format'] == "list" ) {
_make_list($venue);
}
else{
return("<p>blah</p>");
}
}
and finally the function called within the callback function:
function _make_bar_chart($venue) {
// get active database connection
$mysql = Database::getConnection();
// if connection is successful, proceed
if($mysql){
// do stuff
$graphael = array(
'method' => 'bar',
'values' => $ycoordinates,
'params' => array(
'colors' => $colors,
'font' => '10px Arial, sans-serif',
'opts' => array(
'gutter' => '20%',
'type' => 'square',
),
'label' => array(
'values' => $xcoordinates,
'isBottom' => true,
),
),
'extend' => array(
'label' => array(
'values' => $ycoordinates,
'params' => array('attrText' => array(
'fill' => '#aaa',
'font' => '10px Arial, sans-serif',
)),
),
),
);
return theme('graphael', $graphael);
}
// else, connection was unsuccessful
else{
print("<p>bad connection</p>");
}
}
THE PROBLEM: returning a theme doesn't really send anything back to the AJAX request (unlike print statements). I tried to print the theme, but that produces a white screen of death. How would I generate the graph without printing something?
Much thanks to nevets on the Drupal forums for the helpful hint: http://drupal.org/node/1664798#comment-6177944
If you want to use AJAX with Drupal, you are best off actually using Drupal-specific AJAX-related functions. In my theme's page.tpl.php file, I added the following to make the links which would call AJAX:
<?php
// drupal_add_library is invoked automatically when a form element has the
// '#ajax' property, but since we are not rendering a form here, we have to
// do it ourselves.
drupal_add_library('system', 'drupal.ajax');
// The use-ajax class is special, so that the link will call without causing
// a page reload. Note the /nojs portion of the path - if javascript is
// enabled, this part will be stripped from the path before it is called.
$link1 = l(t('Graph'), 'ajax_link_callback/graph/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link2 = l(t('List'), 'ajax_link_callback/list/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link3 = l(t('Create Alert'), 'ajax_link_callback/alert/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$output = "<span>$link1</span><span>$link2</span><span>$link3</span><div id='myDiv'></div>";
print $output;
?>
When one of the links above is clicked, the callback function is called (e.g. ajax_link_callback/graph):
// A menu callback is required when using ajax outside of the Form API.
$items['ajax_link_callback/graph'] = array(
'page callback' => 'ajax_link_response_graph',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
.. and the callback to which it refers:
function ajax_link_response_graph($type = 'ajax') {
if ($type == 'ajax') {
$output = _make_bar_chart('journal');
$commands = array();
// See ajax_example_advanced.inc for more details on the available commands
// and how to use them.
$commands[] = ajax_command_html('div#content div.content', $output);
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
else {
$output = t("This is some content delivered via a page load.");
return $output;
}
}
This replaces any HTML within <div class="content"> with the graphael chart returned from _make_bar_chart above.
I had created several modules extending the UI elements of the FormAPI. This works fine when I render forms in a normal way (not AJAX). But if the rendered form is delivered though the AJAX request, JS script simply inserts the code via the $.html function. So I can't access elements of the document by their ID from the script evaluated by the $.html.
Is there any solution to pass JavaScript code through the Form/Ajax API?
I think jQuery("#new-id") (not $(..)) should take the newest dom elements.
You can use either the 'ajax' property of form api
$form['myitem'] = array(
'#type'=>'textfield',
'#ajax' => array(
'callback' => 'my_callback',
'wrapper' => 'new-id',
'method' => 'html',
'effect' => 'fade',
),
);
$form['myitem2'] = array(
'#type'=>'markup',
'#value'=>"<div id='new-id'> I'm #new-id </div>"
);
function my_callback(&$form, &$form_state){
$commands = array();
$commands[] = ajax_command_invoke('#new-id', 'html', array('<div id="new-id2">#new.id2 here!</div>'));
$commands[] = ajax_command_invoke('#new-id2', 'addClass', array('error'));
return array('#type' => 'ajax', '#commands' => $commands);
}
D7 ajax_commands:
http://api.drupal.org/api/drupal/includes--ajax.inc/group/ajax_commands/7
hope this help