Is there someone who can help me with the following?
I use a modal/form to edit a model onscreen, and update the model via Pjax. Saving is no problem, but now the gridview must be updated with Pjax as well.
For my modal I use the following code
<?php
$form = ActiveForm::begin(
['enableClientValidation' => true, 'options' => ['id' => $model->formName()]]);
?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><?= $actionTitle ?> <?= StringHelper::basename(get_class($model)); ?></h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<?php echo Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
<?php ActiveForm::end();
$this->registerJs(<<<JS
$(document).on('hidden.bs.modal', function (e) {
$(e.target).removeData('bs.modal');
});
JS
);
?>
<?php $script = <<< JS
$('form#{$model->formName()}').on('beforeSubmit', function(e){
var \$form = $(this);
$.post(
\$form.attr("action"), //Serialize Yii2 Form
\$form.serialize()
).done(function(result){
if(result == true){
$(\$form).trigger("reset");
$(document).find('#modalphysicalcomponent').modal('hide');
$.pjax.defaults.timeout = false;
$.pjax.reload({container:'#Grid'});
}else{
$("#message").html(result.message);
}
}).fail(function(){
console.log("server error");
});
return false;
});
JS;
$this->registerJs($script);
?>
It should update only the following gridview, but instead reloads the entire page which results in an error as certain POST variables are not resend.
<?php Pjax::begin(['id' => 'Grid']); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'component.tag',
'component.name',
'component.parent.tag',
[
'label' => 'Configure',
'format'=>'raw',
'value' => function ($model, $key, $index, $column){
return Html::a('Configure '.get_class($model), ['update-modal', 'id' => $model->component->id], ['data-toggle'=>'modal', 'data-target'=>'#modalphysicalcomponent' ,'class' => 'btn btn-xs btn-primary', ]);
}
],
],
]); ?>
<?php Pjax::end(); ?>
I use the same modal on a different page, and it seems to work fine there, but I can't spot any differences between the two view pages.
Anyone who can help?
You need to pass the grid id as text, and not object when reloading the gridview. The object is passed as the second parameter which are the options.
This is your mistake
$.pjax.reload({container:'#Grid'});`
it should be like below
$.pjax.reload('#Grid');
See the docs for the Pjax here
Related
I have a table: Users with 3 different attributes:
ID
firstname
lastname
In the index.ctp page for Users, for each data entry, I have the Edit action available to use.
<div>
<table class="usersTables" id="userTable">
<thead>
<tr>
<th scope="col"><?= $this->Paginator->sort('firstname') ?></th>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?= h($user->firstname) ?></td>
<td class="actions">
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $user->id], ['class' => 'view', 'data-id' => $user->id]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<script type="text/javascript">
$(function () {
$('.edit').click(function () {
ev.preventDefault();
var userId = $(this).attr('data-id');
$('#editModal').modal('show');
alert(userId);
});
});
</script>
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="editModalLabel">Edit</h4>
<div>
<div class="col-sm-6">
<?= $this->Form->input('firstname', ['class' => 'form-control', 'label' => 'First Name', 'placeholder' => 'First name', 'id' => 'firstname']); ?>
</div>
<div class="col-sm-6">
<?= $this->Form->input('lastname', ['class' => 'form-control', 'label' => 'Last Name', 'placeholder' => 'Last name', 'id' => 'lastname']); ?>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="savebutton" type="button" class="btn btn-primary" data-dismiss="modal">Save changes</button>
</div>
</div>
</div>
</div>
Clicking the Edit button in the table first gives me an alert pop up that tells me which $user->id I selected, then opens up the Edit modal. However, my form inputs are still empty even though the related attributes for that specific datat entry are fileld in the database. I'm not sure how to connect the data-id variable that was then defined as a JavaScript variable to the form input which I believe requires a PHP variable again ($user->firstname).
If I use 'value' => $user->firstname in the firstname form input, I get the data from the very last data entry every time (eg. if I have 3 data entries in my Users table, I will always get the 3rd entry's firstname).
Glad you researched about AJAX. First you need to create a function in your controller that will return a user's details.
// Just an example in the UsersController
public function userDetails($id = null) {
$userDetails = $this->Users->find('all'['where(['id' => $id])])->first();
$this->set(array(
'output' => $userDetails,
'_serialize' => 'output',
'_jsonp'=>true
));
}
Then setup an ajax request from your view.
// in your index.ctp's script
<script type="text/javascript">
$(function () {
$('.edit').click(function () {
ev.preventDefault();
var userId = $(this).attr('data-id');
$('#editModal').modal('show');
$.ajax({
url:"localhost/your_project/Users/userDetails/"+userId+".json",
type:'POST',
success:function(res) {
console.log(res); // check the response in your console
if(res) {
$('#firstname').val(res.firstname);
$('#lastname').val(res.lastname);
}
}
});
});
});
You can send the userId as a post data for the function's parameter.
I have following code in my view:
<?= $form->labelEx($model, 'p_2_1', array('class' => 'col-xs-12 col-sm-2 control-label')) ?>
<div class="col-xs-12 col-sm-3">
<?= $form->dropDownList($model, 'p_2_1',array_combine($model->getData('money'),$model->getData('money')), array('class' => 'form-control')) ?>
<?= $form->error($model, 'p_2_1') ?>
</div>
<?= $form->labelEx($model, 'p_3_1', array('class' => 'col-xs-12 col-sm-2 control-label')) ?>
<div class="col-xs-12 col-sm-3">
<?= $form->dropDownList($model, 'p_3_1',array_combine($model->getData('money'),$model->getData('money')), array('class' => 'form-control')) ?>
<?= $form->error($model, 'p_3_1') ?>
</div>
And in my model, I have following code:
public function getData($property) {
$data = array(
'money' => array(
Yii::t('plaintinfo', 'RUB'),
Yii::t('plaintinfo', 'USD'),
Yii::t('plaintinfo', 'EURO'),
),
);
return $data[$property];
}
I need to develop JavaScript code when user p_2_1 value changes, p_3_1 value also changes and becomes the same as p_2_1 value. (for example, if user chooses USD from the drop down list p_2_1, the value of p_3_1 will be USD automatically (the same as p_2_1(USD) ). How can I do it?
You can solve it with following Javascript code. You could also change your ids to more understandable.
<script>
$("#p_2_1").change(function(){
var selected = $("#p_2_1 option:selected").val();
var elementToChange = document.getElementById('p_2_1');
elementToChange.value = selected;
});
</script>
I have a page that contains CGridView in my app. Users can search data by filling the form and clicking submit button. The search function works, and CGridView successfully updated. The problem is it can't be done through ajax, Yii keep doing it through parameters in URL.
I want to update CGridView through ajax so the URL still nice to look. Here's my code.
View File
<?php
Yii::app()->clientScript->registerScript('search', "
$('.btn-link').click(function(){
$('.section').toggle();
return false;
});
$('.section form').submit(function(){
$('#customer2-grid').yiiGridView('update', {
data: $(this).serialize()
});
return false;
});
");
?>
<?php echo CHtml::link('Advanced Search','#',array('class'=>'btn-link')); ?>
<div class="section" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div><!-- search-form -->
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'customer2-grid',
'dataProvider'=>$model->search(),
'htmlOptions'=>array('style'=>'font-weight:bold'),
'filter'=>$model,
'columns'=>array(
'NAME',
'BIRTHDATE',
'ADDRESS',
'EMAIL',
array(
'header'=>'Action',
'class'=>'CButtonColumn',
'template' => '{add} {updates}',
'buttons' => array(
'add' => array(
'label' => '',
//'imageUrl' => Yii::app()->request->baseUrl.'/images/icon/add.png',
'url' => 'Yii::app()->createUrl("/goods/create/",array("id"=>$data->ID))',
'options'=>array('class'=>'btn btn-info', 'style'=> 'margin-bottom:2px '),
),
'updates' => array(
'label' => 'Update Profil',
// 'imageUrl' => Yii::app()->request->baseUrl.'/images/icon/update.png',
'url' => 'Yii::app()->createUrl("/customer/update/",array("id"=>$data->ID))',
'options'=>array('class'=>'btn btn-info'),
),
),
),
),
));
?>
Here's my _search.php code
<div class="form-horizontal">
<?php $form=$this->beginWidget('CActiveForm', array(
'action'=>Yii::app()->createUrl($this->route),
'method'=>'get',
)); ?>
<div class="form-group">
<?php echo $form->labelEx($model,'NAME',array('class'=>'col-sm-2 control-label')); ?>
<div class="col-sm-6">
<?php echo $form->textField($model,'NAME',array('size'=>60,'maxlength'=>128,'class'=>'form-control')); ?>
</div>
</div>
<div class="form-group">
<?php echo $form->labelEx($model,'BIRTHDATE',array('class'=>'col-sm-2 control-label')); ?>
<div class="col-sm-6">
<?php echo $form->textField($model,'BIRTHDATE',array('class'=>'form-control')); ?>
</div>
</div>
<div class="form-group">
<?php echo $form->labelEx($model,'ADDRESS',array('class'=>'col-sm-2 control-label')); ?>
<div class="col-sm-6">
<?php echo $form->textField($model,'ADDRESS',array('size'=>60,'maxlength'=>512,'class'=>'form-control')); ?>
</div>
</div>
<div class="form-group">
<?php echo $form->labelEx($model,'EMAIL',array('class'=>'col-sm-2 control-label')); ?>
<div class="col-sm-6">
<?php echo $form->textField($model,'EMAIL',array('size'=>60,'maxlength'=>64,'class'=>'form-control')); ?>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<?php echo CHtml::submitButton('Search', array('class'=>'btn btn-primary')); ?>
</div>
</div>
<?php $this->endWidget(); ?>
</div><!-- search-form -->
Here's my controller code
public function actionAdmin()
{
$this->layout = '//layouts/column1';
$model=new Customer('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Customer']))
$model->attributes=$_GET['Customer'];
$this->render('admin',array(
'model'=>$model,
));
}
The toggle function in the jQuery works just fine but the update function doesn't work. The sorting function in CGridView works as well. What do I miss here?
Is there any restriction in CSS for jQuery/CGridView? I presume there's something wrong with the CSS Selector
EDIT :
I've found the problem which unexpectedly lies in layout/main.php
I've included three javascript files and one of them causing the error.
<!-- JAVASCRIPTS -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- JQUERY -->
<script src="<?php echo Yii::app()->request->baseUrl; ?>/css/default/js/jquery/jquery-2.0.3.min.js"></script>
<!-- JQUERY UI-->
<script src="<?php echo Yii::app()->request->baseUrl; ?>/css/default/js/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js"></script>
<!-- BOOTSTRAP -->
<script src="<?php echo Yii::app()->request->baseUrl; ?>/css/default/bootstrap-dist/js/bootstrap.min.js"></script>
After I discarded the first script, everything's fine. However, I don't have idea why. Maybe somebody can explain why. Any explanation will be appreciated. Sorry if this question going out of topic
ok I try to describe common solution
this code exampling with default gii crud generator
let you have model Customer.php generetad with standard gii module
class Customer extends CActiveRecord
{
// ...
public function search() {
return new CActiveDataProvider(
// provider properties
'criteria' => new CDbCriteria(), // searches and filters
'sort' => new CSort(), // ordering
'pagination' => new CPagination(), // pagging
);
}
// also there are exists rules for search scneario
public function rules() {
return array(
// ... some other rules
// rule for scenario search
array('NAME, BIRTHDATE,ADDRESS, EMAIL', 'safe', 'on'=>'search'),
);
}
// ...
}
next we should describe primitive controller
class CustomerController extends CController
{
public function actionIndex()
{
// create model with scenario search
$model = new Customer('search');
// check for incoming filter requests and apply filter
if(isset($_GET['Customer']) {
$model->attributes = $_GET['Customer'];
}
$this->render('index', array('model'=>$model);
}
}
now we have to create simplest view with basic CGridView settings
<?php $this->widget('zii.widgets.grid.CGridView', array(
'provider' => $model->search(),
// this property automatically add search field above each columns
'filter' => $model,
));
try this code. and you no need to invent already existing solution by specifying custom search form, of course if you want to have extended search tools, you have to some hard codding
I am new to Yii. I need to have a bulk action like bulk delete in CGrid view. I tried by doing in javascript and performing the action using AJAX call. But I dont get what I needed. Please help me solve this.
My view:
<?php $details=$details;
?>
<h3><?php echo $name; ?></h3>
<div id="content" style="margin: 0">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'nimsoft-host-form',
//'enableAjaxValidation'=>true,
'enableClientValidation' => true,
'clientOptions' => array(
'validateOnSubmit' => true,
'validateOnChange' => true, // allow client validation for every field
),
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>
<?php $this->endWidget();?>
<h3><?php echo htmlspecialchars($title); ?></h3>
<h3><?php echo $title; ?></h3>
<div style="padding: 10px;">
<a href="<?php echo $this->createUrl('/Nimsoft/create?id='.$details->host_customer_id);?>" title="Create New Host" class="btn btn-primary circle_ok" style="text-decoration: none;" >Add New Host to Customer</a>
<a href="<?php echo $this->createUrl('/Nimsoft/Search_all?id='.$details->host_customer_id);?>" title="View All Hosts" class="btn btn-primary circle_ok" style="text-decoration: none;" >View All Hosts</a>
<a href="<?php echo $this->createUrl('/Nimsoft/Search_all',array('id'=>$details->host_customer_id,'isXLSDownload'=>1));?>" title="Export" class="btn btn-primary circle_ok" style="text-decoration: none;" >Export</a>
<a href="<?php echo $this->createUrl('/Nimsoft/Search_all',array('id'=>$details->host_customer_id,'isXLSDownload'=>2));?>" title="Export For All Customers" class="btn btn-primary circle_ok" style="text-decoration: none;" >Export For All Customers</a>
<div style="float:right">
<?php
echo CHtml::link('Upload Customer CSV', array('/Nimsoft/uploadCustomers?id='.$details->host_customer_id), array(
'onclick'=>'return hs.htmlExpand(this, { objectType: "iframe", wrapperClassName: "full-size", align: "center" } )',
'class'=>'btn btn-primary',
'id'=>'upload_link',
));
?>
</div>
<?php //echo CHtml::Button('Export CSV', array('class' => 'btn btn-primary circle_ok exportCSV-button'));
echo '<form method="post" name="exportCSV-form" id="exportCSV-form" action="' . yii::app()->createUrl('/export/exportCSV') . '">';
echo '<input type="hidden" name="filename" value="HostName">';
$this->renderPartial('_export_list', array(
'model' => $model,
));
echo '</form>';
?>
<div class="innerLR">
<div class="row-fluid">
<?php
Yii::app()->clientScript->registerScript('search_inc', "
$('.exportCSV-button').click(function() {
$.fn.yiiListView.update('exportListView', {
data: $('#search-pm-form').serialize() + '&export=true',
complete: function() {
$('#exportCSV-form').submit();
}
});
});
");?>
<?php
echo CHtml::button("Add Date Entries",array("id"=>"butt"));
?>
<?php
$obj=$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'id'=>'yiisession-grid',//'host_grid',
'dataProvider'=>$dataProvider,
'type' => 'striped bordered',
'columns'=>array(
array(
'id' => 'selectedIds',
'class' => 'CCheckBoxColumn',
'selectableRows'=>2,
),
array( // display 'create_time' using an expression
'name'=>'host_name',
'value'=>'$data->host_name',
),
array(
'name'=>'host_serviceid',
'value'=>'$data->host_serviceid',
),
array(
'name'=>'status',
'value'=>'$data->status',
),
array(
'class'=>'CButtonColumn',
'template'=>'{edit_date}{update}{delete}',
'htmlOptions'=>array('width'=>'95px'),
'buttons' => array(
'edit_date' => array( //the name {reply} must be same
'label' => 'Add Date', // text label of the button
'url' => 'Yii::app()->createAbsoluteUrl("NimsoftHostsDetails/View", array("id"=>$data->host_id))',
'imageUrl' => Yii::app()->baseUrl.'/images/icons/pencil.png', // image URL of the button. If not set or false, a text link is used, The image must be 16X16 pixels
),
),)
),
))
;
?>
</div>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
<div class="separator bottom"></div>
</div>
</div>
<div class="clearfix"></div>
<div id="footer" class="hidden-print">
<?php $this->renderPartial('application.views.layouts._footer_inc'); ?>
</div>
</div>
<script>
hs.preserveContent = false;
hs.dimmingOpacity = 0.75;
hs.zIndexCounter = 10000;
hs.showCredits = false;
// this will disable close when we click on other area than close button
hs.onDimmerClick = function() {
return false;
}
$('.exportCSV-button').click(function() {
$.fn.yiiListView.update('exportListView', {
data: $('#search-faq-form').serialize() + '&export=true',
complete: function() {
$('#exportCSV-form').submit();
}
});
});
</script>
<script type="text/javascript">
var gridId = "yiisession-grid";
$(function(){
$(document).on('click','#yiisession-grid a.bulk-action',function() {
return false;
});
});
function batchActions(values){
var url = $(this).attr('Nimsoft/select_all');
var ids = new Array();
if(values.size()>0){
values.each(function(idx){
ids.push($(this).val());
});
$.ajax({
type: "POST",
url: url,
data: {"ids":ids},
dataType:'json',
success: function(resp){
//alert( "Data Saved: " + resp);
if(resp.status == "success"){
$.fn.yiiGridView.update(gridId);
}else{
alert(resp.msg);
}
}
});
}
}
</script>
<?php
Yii::app()->clientScript->registerScript('edit_date','
$("#butt").click(function(){
var checked=$("#host_grid").yiiGridView("getChecked","host_grid_c1");
var count=checked.length;
if(count>0 && confirm("Do you want to delete these "+count+" item(s)"))
{
$.ajax({
data:{checked:checked},
url:"'.CHtml::normalizeUrl(array('item/remove')).'",
success:function(data){$("#host_grid").yiiGridView("update",{});},
});
}
});
');
?>
My Bulk action code is not working. Please correct me where I went wrong. Thanks in advance.
Answer for yii2:
Checkbox column in a gridview:
GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
'id'=>'grid',
'country',
],
]);
Button that fires a javascript and sends a url like this: index.php?r=mycontroller/bulk&action=1&ids=2,6,7,8
this is the button:
<a href="#" onclick="bulkAction('p');">
this is the Javascript:
<script>
function bulkAction(a) {
var keys = $('#grid').yiiGridView('getSelectedRows');
window.location.href='<?php echo Url::to(['mycontroller/bulk']); ?>&action='+a+'&ids='+keys.join();
}
</script>
I have a dropdown in my menu but when I click on the search form field inside the dropdown the dropdown instantly closes.
This is my code:
<button id="sharebutton" type="button" class="btn btn-sm btn-info" data-toggle="dropdown" data-hover="dropdown"
data-close-others="true"><i class="fa fa-search"></i> Search
</button>
<ul class="dropdown-menu extended notification">
<li>
<div class="form-group">
<?php echo $this->Form->create('Search', array('controller' => 'searches', 'action' => 'prodsearch')); ?>
<div class="input-group">
<?php echo $this->Form->input('newsearchterm', array('required' => true, 'class' => 'form-control', 'label' => false, 'placeholder' => 'Search Products...', 'name' => 'newsearchterm')); ?>
<span class="input-group-btn">
<?php
echo $this->Form->button(
'<i class="fa fa-search"></i>',
array(
'type' => 'submit',
'class' => 'btn blue',
),
array('escape' => 'false')
);
?>
</span>
</div>
</div>
<?php echo $this->Form->end(); ?>
</li>
</ul>
(I am using CakePHP which is why the form code is a bit funny)
Add stopPropagation() to the your search form field.
jQuery('.your-form-selector').click(function (e) {
e.stopPropagation();
});
Everything else will work as expected.
JQuery reference
I was just looking for the same thing and found it at here
Remove the "li" tags and try. Like this:
<div class="form-group">
<?php echo $this->Form->create('Search', array('controller' => 'searches', 'action' => 'prodsearch')); ?>
<div class="input-group">
<?php echo $this->Form->input('newsearchterm', array('required' => true, 'class' => 'form-control', 'label' => false, 'placeholder' => 'Search Products...', 'name' => 'newsearchterm')); ?>
<span class="input-group-btn">
<?php
echo $this->Form->button(
'<i class="fa fa-search"></i>',
array(
'type' => 'submit',
'class' => 'btn blue',
),
array('escape' => 'false')
);
?>
</span>
</div>
</div>
<?php echo $this->Form->end(); ?>
</ul>
This worked for me once in adding forms in Bootstrap nav dropdowns.