I am working on Yii2. I have a gridview with checkbox and on a button click I am redirecting it to an action controller using ajax.
<?= Html::a('Disconnect', ['dco'], ['class' => 'btn btn-success', 'id'=>'dco']) ?>
<?php Pjax::begin(); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d) {
return ['value' => $d['msn']];
}],
'ref_no',
'dept_code:ntext',
'dept_name:ntext',
'allowed_units',
'msn',
'units_consumed',
[
'label' => 'Disconnected',
'attribute' => 'disconnected',
'format'=>'raw',
'contentOptions' => ['style'=>'text-align:center'],
'value' => function($model){
return $model->disconnected == 1 ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger"></span>';
},
'filter' => Html::activeDropDownList($searchModel, 'disconnected', [''=>'All','1'=>'Yes','0'=>'No'], ['class' => 'form-control']),
],
'diconnected_at',
'reconnected_at',
'active_energy_total_m',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php Pjax::end(); ?>
JS
<?php
$DCOurl = Url::toRoute(['/hecolog/dco']);
$script = <<< JS
$(document).ready(function () {
//DCO
$('#dco').on('click',function(e) {
e.preventDefault();
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!=="")
{
strValue = strValue + " , " + this.value;
}
else
strValue = this.value;
});
$.ajax({
url: '$DCOurl',
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
alert(data);
}
});
});
});
JS;
$this->registerJs($script, static::POS_END);
?>
But when I click on the disconnect button it doesn't redirect to my controller. In console it gives me Not Found (#404): Page not found.
Update 1
I have updated the ajax call like below
$.ajax({
url: $DCOurl, // removed the inverted commas ''
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
alert(data);
}
});
Controller
public function actionDco()
{
if(Yii::$app->request->isAjax && Yii::$app->request->post())
{
$data = explode(',',$_POST['data']);
var_dump($data);
die();
}
else{
$this->redirect('index');
}
}
After updating the code as suggested I am able to go into my controller but still not able to get the data
In console I am getting error Uncaught SyntaxError: Invalid regular expression flags
Update 2
Below is the code for my view
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\Pjax;
use yii\helpers\Url;
use yii\web\JqueryAsset;
/* #var $this yii\web\View */
/* #var $searchModel common\models\HescologSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'DCO / RCO';
$this->params['breadcrumbs'][] = $this->title;
?>
<section class="content-header">
<h1>DCO / RCO List</h1>
</section>
<section class="content">
<div class="box">
<div class="box-body">
<p>
<?= Html::a('Disconnect', ['dco'], ['class' => 'btn btn-success', 'id'=>'dco']) ?>
<?= Html::a('Re-Disconnect', ['rco'], ['class' => 'btn btn-info','id'=>'rco']) ?>
</p>
<?php Pjax::begin(); ?>
<div class="pre-scrollable">
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d) {
return ['value' => $d['msn']];
}],
'ref_no',
'dept_code:ntext',
'dept_name:ntext',
'allowed_units',
'msn',
'units_consumed',
[
'label' => 'Disconnected',
'attribute' => 'disconnected',
'format'=>'raw',
'contentOptions' => ['style'=>'text-align:center'],
'value' => function($model){
return $model->disconnected == 1 ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger"></span>';
},
'filter' => Html::activeDropDownList($searchModel, 'disconnected', [''=>'All','1'=>'Yes','0'=>'No'], ['class' => 'form-control']),
],
'diconnected_at',
'reconnected_at',
'active_energy_total_m',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
<?php Pjax::end(); ?>
</div>
</div>
</section>
<?php
$DCOurl = Url::toRoute(['/hescolog/dco']);
$RCOurl = Url::toRoute(['/hescolog/rco']);
$script = <<< JS
$(document).ready(function () {
//DCO
$('#dco').on('click',function(e) {
e.preventDefault();
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!=="")
{
strValue = strValue + " , " + this.value;
}
else
strValue = this.value;
});
$.ajax({
url: $DCOurl,
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
alert(data);
}
});
});
$('#rco').on('click',function(e) {
e.preventDefault();
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!=="")
{
strValue = strValue + " , " + this.value;
}
else
strValue = this.value;
});
$.ajax({
url: '$RCOurl',
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
alert(data);
}
});
});
});
JS;
$this->registerJs($script, static::POS_END);
?>
I must be doing something wrong which I am not understanding
Any help would be highly appreciated.
first of all url:'$DCOurl' is correct and url must be in single or
double quotation. so you have a not found problem:
is your project in htdocs or www followed by /inventory-web/backend/ or there are some more directories? you use relative url so the url would be for ex: localhost/inventory-web/backend/web/ ...
ajax type 'POST' should match with behaviors['verbs']['actions'] if you have set it
check controller file name, class name and namespace
First, if you're serving an Ajax request you cannot do a redirect:
public function actionDco()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$rv=[];
if(Yii::$app->request->isAjax && Yii::$app->request->post())
{
$data = explode(',',$_POST['data']);
$rv["infos"]=$data;
$rv["status"]='gotData';
}
else{
$rv["url"]=Url::to('index');
$rv["status"]='redirect';
}
return $rv;
}
About the JS error, instead of:
$.ajax({
url: $DCOurl,
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
alert(data);
}
});
Add the quotes aroun the $DCOurl and to manage the return value from the ajax call
$.ajax({
url: "$DCOurl",
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
if(data.status=='gotData'){
alert(data.infos);
}
if(data.status=='redirect'){
window.location.href=data.url;
}
}
});
Related
On me web I use ajax to submit data and pjax to reloade list view. On first time when I submit form it work good, save and reloade list view, on the second time, it save data but don't reload list view, it show response from action {"success":true,"id":68} . Can someone look on this?
action
public function actionReply()
{
$model = new ReplyForm();
$response = [];
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->save()) {
$response['success'] = true;
$response['id'] = $model->id;
}
} else {
$response['success'] = false;
}
Yii::$app->response->format = Response::FORMAT_JSON;
return $response;
}
script in view file
$(document).ready(function () {
var $form = $('form#reply-form');
$form.on('beforeSubmit', function (event) {
var data = $form.serialize();
$.ajax({
type: 'POST',
url: $form.attr('action'),
data: data,
dataType: 'json',
success: function (d) {
if(d.success === true){
//$.pjax.reload({container: '#comments', async: false});
$.pjax.reload('#comments', {timeout: false});
$form.trigger('reset');
}else {
alert('error');
}
}
});
return false;
});
});
and view form file
<div class="page-form">
<?php $form = ActiveForm::begin([
'id' => 'reply-form',
'action' => ['comment/reply'],
'options' => ['data-pjax' => true],
]); ?>
<?= $form->field($model, 'content')->textarea(['maxlength' => true, 'class' => 'form-control', 'rows' => 3]) ?>
<?= $form->field($model, 'item_id')->hiddenInput()->label(false) ?>
<?= $form->field($model, 'parent_id')->hiddenInput()->label(false) ?>
<div class="form-group">
<?= Html::submitButton('WyĆlij', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
view comments file
<?php Pjax::begin(['id' => 'comments']) ?>
<?= ListView::widget([
'dataProvider' => $commentDataProvider,
'summary' => false,
'itemView' => '_comment',
'options' => [
'tag' => 'div',
'class' => 'block-post-comments',
],
'pager' => [
'class' => LinkPager::class
]
]); ?>
<?php Pjax::end() ?>
I have two dependent select box in my form for selecting country and state.
i have a multi select checkbox dropdown for selecting country,
and i want to fetch state of selected country
but i cannot understand how to pass multiple checked id in my function from javascript.
below is my html select list box code
<?php
echo $this->Form->input('UserLogDetail.service_area_category_id', array(
'id' => 'shipping_type',
'required' => false,
'multiple' =>'multiple',
'type' => 'select',
'class' => 'form-control drop-arrow',
'label' => false,
'options' => $serviceCategory,
'empty' => '--Select--'
));
?>
<?php
echo $this->Form->input('UserLogDetail.skills', array(
'class' => 'form-control',
'required' => false,
'id' => 'skill',
'label' => false,
'options' => '$states',
'empty' => '--Select--'
));
?>
javascript function
<script type="text/javascript">
$(document).ready(function() {
$("#shipping_type").on('change', function() {
var id = $(this).val();
if (id) {
var dataString = 'id=' + id;
$.ajax({
type: "POST",
url: '<?php echo Router::url(array("controller" => "Profiles", "action" => "loadSkills"),true); ?>',
data: dataString,
dataType: 'JSON',
cache: false,
success: function(html) {
$("#skill").html("");
$.each(html, function(key, value) {
$('<option>').val('').text('select');
$('<option>').val(key).text(value).appendTo($("#skill"));
});
$('#skill').selectpicker('refresh');
}
});
}
});
});
</script>
controlller function
public function loadSkills() {
$this->loadModel('Skill');
$states = array();
if (isset($this->request['data']['id'])) {
$states = $this->Skill->find('list', array('fields' => array('Skill.id','Skill.skill_name'),'conditions' => array(
'Skill.service_area_category_id IN' => explode(",",$this->request['data']['id']))));
}
echo json_encode($states);
exit();
}
try to call ajax below way
javascript :
$("#shipping_type").change(function() {
$.ajax({
type: "POST",
url: '<?php echo Router::url(array("controller" => "Profiles", "action" => "loadSkills"),true); ?>',
//passing data to php
data: { id:$(this).val() },
dataType: 'JSON',
cache: false,
success: function(html) {
$("#skill").html("");
$.each(html, function(key, value) {
$('<option>').val('').text('select');
$('<option>').val(key).text(value).appendTo($("#skill"));
});
$('#skill').selectpicker('refresh');
}
});
});
php
public function loadSkills() {
$this->loadModel('Skill');
$states = array();
//Getting post id
if (isset($this->request['id'])) {
$states = $this->Skill->find('list', array('fields' => array('Skill.id','Skill.skill_name'),'conditions' => array(
'Skill.service_area_category_id IN' => explode(",",$this->request['data']['id']))));
}
echo json_encode($states);
exit();
}
public function loadSkills() {
$this->getServiceArea();
$this->loadModel('Skill');
$skills = array();
if (isset($this->request['data']['id'])) {
$ids = explode(",",$this->request['data']['id']);
if(count($ids)>1){
$skills = $this->Skill->find('list', array('fields' => array('Skill.id','Skill.skill_name'),'conditions' => array(
'Skill.service_area_category_id IN' => $ids)));
} else {
$skills = $this->Skill->find('list', array('fields' => array('Skill.id','Skill.skill_name'),'conditions' => array(
'Skill.service_area_category_id' => $ids)));
}
}
echo json_encode($skills);
exit();
}
i have two dependent select box in my form for selecting country and state.
when i select country India then it should populate its dependent state.upto this my code working fine...
bit i want to make this multiselect listbox.
Ex - if i select two countries from county dropdown then it populates states from two countries....not of single selected country.
below is my code...
HTML Select list box code
<?php
echo $this->Form->input('service_area_category_id', array(
'id' => 'shipping_type',
'required' => false,
'multiple' => 'multiple',
'type' => 'select',
'class' => 'form-control drop-arrow',
'label' => false,
'options' => $serviceCategory,
'empty' => '--Select--'
));
?>
<?php
echo $this->Form->input('ship_category', array(
'class' => 'form-control drop-arrow',
'required' => false,
'id' => 'state',
'label' => false,
'options' => '$states',
'empty' => '--Select--'
));
?>
Controller function
public function getServiceArea(){
$this->loadModel('ServiceAreaCategory');
$serviceCategory = $this->ServiceAreaCategory->find('list', array(
'conditions' => array(
'is_active' => 1
),
'fields' => array(
'ServiceAreaCategory.id',
'ServiceAreaCategory.name'
),
'order' => 'name ASC'
));
$this->set('serviceCategory', $serviceCategory);
}
public function loadSkills() {
$this->loadModel('Skill');
$states = array();
if (isset($this->request['data']['id'])) {
$states = $this->Skill->find('list', array(
'fields' => array(
'Skill.id',
'Skill.skill_name'
),
'conditions' => array(
'Skill.service_area_category_id' => $this->request['data']['id']
)
));
}
echo json_encode($states);
exit();
}
Ajax Script
<script type="text/javascript">
$(document).ready(function() {
$("#shipping_type").on('change', function() {
var id = $(this).val();
if (id) {
var dataString = 'id=' + id;
$.ajax({
type: "POST",
url: '<?php echo Router::url(array("controller" => "Profiles", "action" => "loadSkills")); ?>',
data: dataString,
dataType: 'JSON',
cache: false,
beforeSend: function() {
$('.spinicon').show();
},
complete: function() {
$('.spinicon').hide();
},
success: function(html) {
$("#loding1").hide();
$.each(html, function(key, value) {
$('<option>').val('').text('select');
$('<option>').val(key).text(value).appendTo($("#state"));
});
$('#state').selectpicker('refresh');
}
});
}
});
});
</script>
in your cakephp side function should be
public function loadSkills() {
$exploded_ids=explode(",",$this->request['data']['country_ids']);
$ids= "IN ('".implode(",",$exploded_ids).")";
$this->loadModel('Skill');
$states = array();
if (isset($this->request['data']['id'])) {
$states = $this->Skill->find('list', array('fields' => array('Skill.id','Skill.skill_name'),'conditions' => array(
'Skill.service_area_category_id '.$ids )));
}
echo json_encode($states);
exit();
}
And your Javascript and AJAX code Should be
<script type="text/javascript">
$(document).ready(function() {
$("#shipping_type").on('change', function() {
var ids = $(this).val();
if (id) {
$.ajax({
type: "POST",
url: '<?php echo Router::url(array("controller" => "Profiles", "action" => "loadSkills"),true); ?>',
data: {country_ids: ids}
dataType: 'JSON',
cache: false,
beforeSend: function() {
$('.spinicon').show();
},
complete: function() {
$('.spinicon').hide();
},
success: function(html) {
$("#loding1").hide();
$("#state").html("");
$.each(html, function(key, value) {
$('<option>').val('').text('select');
$('<option>').val(key).text(value).appendTo($("#state"));
});
$('#state').selectpicker('refresh');
}
});
}
});
});
</script>
i have this ajax form validation code igniter. my view is something like this
<?php
echo form_open('Provinces/create',array('id' => 'form-user'));
?>
<label for="PROVINCE" class="col-sm-2 control-label col-sm-offset-2">Province Name:</label>
<div class="col-sm-5">
<input type="text" class="form-control" id="PROVINCE" name="PROVINCE" value = "<?= set_value("PROVINCE"); ?>">
</div>
<button class="btn btn-info fa fa-save" type="submit">  Save</button>
<a href = '<?php echo base_url().'Provinces/index'; ?>' class = 'btn btn-danger fa fa-times-circle'>  Cancel</a>
<?php
echo form_close();
?>
and i have this javascript
<script>
$('#form-user').submit(function(e){
e.preventDefault();
var me = $(this);
// perform ajax
$.ajax({
url: me.attr('action'),
type: 'post',
data: me.serialize(),
dataType: 'json',
success: function(response){
if (response.success == true) {
// if success we would show message
// and also remove the error class
$('#the-message').append('<div class="alert alert-success">' +
'<span class="glyphicon glyphicon-ok"></span>' +
' Data has been saved' +
'</div>');
$('.form-group').removeClass('has-error')
.removeClass('has-success');
$('.text-danger').remove();
// reset the form
me[0].reset();
url = "<?php echo site_url('Provinces/ajax_add')?>";
// ajax adding data to database
$.ajax({
url : url,
type: "POST",
data: $('#form').serialize(),
dataType: "JSON",
success: function(data)
{
alert('success');
},
error: function (jqXHR, textStatus, errorThrown)
{
alert('Error adding / update data');
}
});
}else{
$.each(response.messages, function(key, value) {
var element = $('#' + key);
element.closest('div.form-group')
.removeClass('has-error')
.addClass(value.length > 0 ? 'has-error' : 'has-success')
.find('.text-danger')
.remove();
element.after(value)
});
}
}
});
});
</script>
i have found this code on google and just customized it. but the problem is, i am not that familiar with ajax, the part where the form validation fails, work perfectly fine, but when it is succes, even though it shows alert('success'); it doesnt add the value in the database. i need to finish this projects in a few weeks. please help.
here is where i get the validations,
public function create(){
$data = array('success' => false, 'messages' => array());
$this->form_validation->set_rules('PROVINCE','Province Name','trim|required|max_length[30]|callback_if_exist');
$this->form_validation->set_error_delimiters('<p class="text-danger"','</p>');
if($this->form_validation->run($this)){
$data['success'] = true;
}else{
foreach ($_POST as $key => $value) {
# code...
$data['messages'][$key] = form_error($key);
}
}
echo json_encode($data);
}
also here is my ajax_add
public function ajax_add()
{
$data = array(
'PROVINCE' => $this->input->post('PROVINCE'),
);
$insert = $this->Provinces_Model->save($data);
echo json_encode(array("status" => TRUE));
}
and here is my model,
public function save($data)
{
$this->db->insert($this->table, $data);
return $this->db->insert_id();
}
i have solved it. just did put
$data = array(
'PROVINCE' => $this->input->post('PROVINCE'),
);
$insert = $this->Provinces_Model->save($data);
echo json_encode(array("status" => TRUE));
into my controller, which makes my controller
public function create(){
$data = array('success' => false, 'messages' => array());
$this->form_validation->set_rules('PROVINCE','Province Name','trim|required|max_length[30]|callback_if_exist');
$this->form_validation->set_error_delimiters('<p class="text-danger"','</p>');
if($this->form_validation->run($this)){
$data['success'] = true;
$data = array(
'PROVINCE' => $this->input->post('PROVINCE'),
);
$insert = $this->Provinces_Model->save($data);
echo json_encode(array("status" => TRUE));
}else{
foreach ($_POST as $key => $value) {
# code...
$data['messages'][$key] = form_error($key);
}
}
echo json_encode($data);
}
and my javascript
$('#form-user').submit(function(e){
e.preventDefault();
var me = $(this);
// perform ajax
$.ajax({
url: me.attr('action'),
type: 'post',
data: me.serialize(),
dataType: 'json',
success: function(response){
if (response.success == true) {
// if success we would show message
// and also remove the error class
$('#the-message').append('<div class="alert alert-success">' +
'<span class="glyphicon glyphicon-ok"></span>' +
' Data has been saved' +
'</div>');
$('.form-group').removeClass('has-error')
.removeClass('has-success');
$('.text-danger').remove();
// reset the form
me[0].reset();
$('.alert-success').delay(500).show(10, function() {
$(this).delay(3000).hide(10, function() {
$(this).remove();
});
})
}else{
$.each(response.messages, function(key, value) {
var element = $('#' + key);
element.closest('div.form-group')
.removeClass('has-error')
.addClass(value.length > 0 ? 'has-error' : 'has-success')
.find('.text-danger')
.remove();
element.after(value)
});
}
}
});
});
You dont't need to use uppercase when accessing your controller
just use
url = "<?php echo site_url('provinces/ajax_add')?>";
Validation the request data before inserting
try
public function ajax_add()
{
$response = array(
'success' => false
) ;
$this->load->library('form_validation');
// add your validation
$this->form_validation->set_rules('PROVINCE', 'PROVINCE', 'required');
if ($this->form_validation->run() == FALSE)
{
$data = array(
'PROVINCE' => $this->input->post('PROVINCE')
);
$insert = $this->Provinces_Model->save($data);
if($insert){
$response['success'] = TRUE ;
$response['message'] = 'Record created successfully' ;
}
else{
$response['message'] = 'Unable to create record' ;
}
}
else
{
$response['message'] = 'Invalid data' ;
}
echo json_encode($response);
}
Then check for the 'message' index in your ajax response in the javascript code
This will give an idea of where there is problem, whether its from the
view or
controller or'
Model
I have one form with activated clientValidation, but the JS code to validate the form has not been registered by Yii.
My form code is here:
$form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'id' => 'login-form',
'enableClientValidation' => true,
'clientOptions' => array(
'validateOnSubmit' => true,
'afterValidate' => 'js:function(form, data, hasError) {
if (!hasError){
str = $("#login-form").serialize() + "&ajax=login-form";
$.ajax({
type: "POST",
url: "' . Yii::app()->createUrl('/') . '",
data: str,
dataType: "json",
beforeSend : function() {
$("#login").attr("disabled",true);
},
success: function(data, status) {
if (data.authenticated) {
window.location = data.redirectUrl;
} else {
$.each(data, function(key, value) {
var div = "#"+key+"_em_";
$(div).text(value);
$(div).show();
});
$("#login").attr("disabled",false);
}
},
});
return false;
}
}',
),
));
echo $form->textField($model, 'username');
echo $form->passwordField($model, 'password');
echo TbHtml::submitButton('Login', ['id' => 'login']);
$this->endWidget();
The registered JS code is only this:
<script type="text/javascript">
/*<![CDATA[*/
jQuery('body').popover({'selector':'a[rel=popover]'});
jQuery('body').tooltip({'selector':'a[rel=tooltip]'});
/*]]>*/
</script>
I don't see, why its not working. Please help me to find the bug.
The code is from this blog post: http://tahiryasin.wordpress.com/2013/05/23/ajax-based-yii-login-form/