i simply want to have a gridview that has checkbox column in front of each row and my admins can delete row by check all or check one or check how many box they disire and then by click on delete button all checked row remove from their view
in the back its important to update their delete column to 1 a row not delete
here is my code for delete one id
controller(ignore persian words)
public function actionDelete($id=[])
{
$model = \Yii::$app->db->createCommand()
->update('tbl_post',['Delete'=>1],['id'=>$id])->execute();
if($model==true){
\Yii::$app->session->setFlash('با موفقیت نیست شد');
}else{
\Yii::$app->session->setFlash('با موفقیت نیست نشد');
}
return $this->redirect('index');
}
here is view(ignore persian words)
//in baraye ine ke form taiid shod payam bede
foreach (Yii::$app->session->getAllFlashes() as $key => $message) {
echo '<div class="alert alert-' . $message . '">' . $key . '</div>';
}
//-------------------------table it self
echo \yii\grid\GridView::widget([
'dataProvider' => $adp,
'caption' => 'لیست تمامی محتوا ها',
'captionOptions' => ['id' => 'atro-caption'],
'headerRowOptions' => ['class' => 'atro-th'],
'columns' => [
['class' => \yii\grid\SerialColumn::className(),],
['class' => \yii\grid\CheckboxColumn::className(),
'checkboxOptions' => function ($a) {
return ['value' => $a->id];
}],
'Title',
'FK_PostType',
'FK_Author',
]
]);
Before I suggest you anything about your problem you should know the basic rules of programming that never use reserved keywords for function naming variable or database field names, you have used the Delete as a column name you should change it immediately to something like is_deleted. i will be using this name in my example reference.
About your problem, you have 2 ways to do it.
Add a button and bind javascript click event to it which will serialize all the selected checkboxes and then use an ajax post request to submit the selected ids and mark them delete.
Wrap your Gridview inside a form tag and then use a submit button to submit that for to the delete action.
I will demonstrate the first option to you
add the button on top of your GridView
<?=Html::button('Delete', ['class' => 'btn btn-danger', 'id' => 'delete'])?>
Then assign an ID to the pjax container
<?php Pjax::begin(['id' => 'my-grid']);?>
Paste this javascript on top of your view but update the url of the ajax call to your actual controller/delete action
$this->registerJs('
$(document).on("click","#delete",function(e){
let selected=$(".grid-view>table>tbody :input");
let data=selected.serialize();
if(selected.length){
let confirmDelete = confirm("Are you sure you want to delete?");
if(confirmDelete){
$.ajax({
url:"/test/delete",
data:data,
dataType:"json",
method:"post",
success:function(data){
if(data.success){
$.pjax({container:"#my-grid"});
}else{
alert(data.msg);
}
},
error:function(erorr,responseText,code){}
});
}
}else{
alert("select someitems to delete");
}
});
', \yii\web\view::POS_READY);
And change your delete action to the following, try using transaction block so that if something happens in the middle of the operation it will revert all the changes back, change the model name and namespace to the appropriate model, I assumed your model name is Post.
public function actionDelete()
{
if (Yii::$app->request->isPost) {
$selection = Yii::$app->request->post('selection');
$response['success'] = false;
$transaction = Yii::$app->db->beginTransaction();
try {
\frontend\models\Post::updateAll(['is_deleted' => 1], ['IN', 'id', $selection]);
$response['success'] = true;
$transaction->commit();
} catch (\Exception $ex) {
$transaction->rollBack();
$response['msg'] = $ex->getMessage();
}
echo \yii\helpers\Json::encode($response);
}
}
Related
I'm trying to have a query result in the show view and then to normally edit/delete the rows as in the list view (pagination as well).
As far I did this:
protected function configureShowFields(ShowMapper $show): void
{
$userId = $this->getSubject()->getId();
$show
->add('lastName')
->add('firstName')
->add('phoneNumber')
->add('email')
->add('fullAddress')
->end();
$show
->with('Cars', [
'class' => 'col-md-8',
'box_class' => 'box box-solid',
])
->add('cars', null, [
'query_builder' => function (EntityRepository $er) use ($userId) {
return $er->createQueryBuilder('u')
->where('u.user = :user')
->setParameter('param', $userId);
},
'template' => 'Admin/list_items.html.twig'
])
->end();
}
but in the template I've only added a table and displayed the car items but I must be able to click on the item and go to their detail page. Any ideas what to use to achieve that?
I have a radio button with two values (required field) based on that value one field is shown (there are two fields which are intially hidden, its shown based on value of radio button) which should be required. So I used conditional validation for the initially hidden fields.
This is my model code:
public function rules()
{
return [
[['receipt_no', 'date_of_payment', 'payment_method_id',
'total_amount'], 'required'],
['nonmember_name', 'required', 'whenClient' => function($model)
{
return $model->is_member == 2;
}, 'enableClientValidation' => false],
['member_id', 'required', 'whenClient' => function($model)
{
return $model->is_member == 1;
}, 'enableClientValidation' => false],
[['receipt_no', 'date_of_payment', 'payment_method_id',
'total_amount','is_member'], 'required','on' => 'receipt'],
];
}
I use a scenario receipt, is_member is the radio button field. If I select a value of 1 for is_member then field member_id is visible and it should be a required one. If is_member has a value 2 then nonmember_name is displayed and it should become a required field. With my code in model I managed to achieve it. But now other actions (saving a new row of data into model) using this model is having error
Array ( [nonmember_name] => Array ( [0] => Name cannot be blank. ) )
So my question is how can I make conditional validation specific to a scenario (I think that my error is due to required rule defined in conditional validation )
EDIT:
This is my radio button
<?= $form->field($model, 'is_member')->radioList(array('1'=>'Member',2=>'Non Member'))->label('Member or Not'); ?>
In rules
public function rules()
{
return [
[
'nonmember_name',
'required',
'when' => function ($model) {
return $model->is_member == 2;
},
'whenClient' => "function (attribute, value) {
return $('#id').val() == '2';
}"
]
];
}
I prefer to use functions inside the model's rules, which makes it a lot easier to work with in the future.
One thing to mention that a lot of answers don't mention, is that you MUST manually re-trigger the Yii2 client side validation!
$("#w0").yiiActiveForm("validateAttribute", "createuserform-trainer_id");
In my example below, there are 2 types of accounts: trainer and trainee. In my admin panel, the admin can create a new user. If they choose "trainer" there is nothing more to do. If they choose a "trainee", that "trainee" must be assigned a "trainer" to go under.
So in code terms:
If user role == trainee, trainer_id is required and show it's form input.
Else hide the trainer_id input and trainer_id will not be required.
Model rules:
public function rules()
{
return [
[
'trainer_id', 'required', 'when' => function ($model) {
return $model->role == 2;
}, 'whenClient' => "isUserTypeTraineeChosen"
],
];
}
View after your form:
<?php $this->registerJs('
function isUserTypeTraineeChosen (attribute, value) {
if ($("#createuserform-role").val() == 2) {
$(".field-createuserform-trainer_id").show();
} else {
$("#createuserform-trainer_id").val(null);
$(".field-createuserform-trainer_id").hide();
}
return ($("#createuserform-role").val() == 2) ? true : false;
};
jQuery( "#createuserform-role" ).change(function() {
$("#w0").yiiActiveForm("validateAttribute", "createuserform-trainer_id");
});
jQuery( "#createuserform-role" ).keyup(function() {
$("#w0").yiiActiveForm("validateAttribute", "createuserform-trainer_id");
});
'); ?>
Note: This is a dropdown list, so change and keyup both are necessary to accurately detect it's change statuses. If your not using a dropdown, then both may not be necessary.
I also have targeted the trainer_id input to be hidden by default using CSS, as the default user type is a trainer.
I had a form which when submitted, either returned an error if there was one, or it subbmited the data to the DB table if validation passed, and it worked fine.
Now I wanna do the same thing with ajax, but the validation seems to always return false, no matter if I type in something or not.
My controller:
function add_new_category_ajax()
{
// make sure it's the admin, else redirect
if ( ! $this->session->userdata('is_admin') ) {
redirect('admin/login');
exit();
}
// load form validation library
$this->load->library('form_validation');
// validate fields
$this->form_validation->set_rules('category_title', 'Category Title', 'trim|required');
// if validation failed
if ($this->form_validation->run($this) == FALSE)
{
// dummy var
$data['dummy'] = '';
// generate error message
$data['error'] = '<p class="errormsg">You must enter a category title.</p>';
// load the view
$this->load->view('new_category_view', $data);
}
else
// validation passed, add new category
{
// get category_title
$ct = $this->input->post('category_title');
// check if category title exists
$cte = $this->mdl_categories->category_title_exists($ct);
if ( $cte )
{
$data['msg'] = '<p class="errormsg">That category title already exists, please choose another.</p>';
}
else // it does not, proceed with insert
{
// prepare data
$data = array(
'title' => $ct
);
// add new page
$this->db->insert('categories', $data);
// show success message and add another page link
$flag = $this->db->affected_rows();
if ($flag == 1)
{
$data['msg'] = '<p class="successmsg">The category has been added!</p>';
$data['aac'] = '<br><p><a href='.base_url().'admin/add-new-category/>Add another category +</a></p>';
}
}
$data['msg'] = '<p class="successmsg">The category has been added!</p>';
// load the view
$this->load->view('new_category_view', $data);
} // end else
}
My ajax:
$('body').on('click', 'a.submitnewcat', function(e) {
e.preventDefault();
// alert('code');return;
$('#ajaximg img').addClass('act');
setTimeout(function() {
$("#ajax").load('<?php echo site_url('admin/add-new-category-ajax'); ?>');
$('#ajaximg img').removeClass('act');
}, 200)
});
Linking to admin/add-new-category-ajax is not a mistake, routes are set up that way.
Why does it always return a failed validation?
As I said in the comment, you need an extra parameter to make load uses POST method instead of GET method :
$("#ajax").load('<?php echo site_url('admin/add-new-category-ajax'); ?>', { "category_title " : "myTitle" });
The run method doesn't take a parameter if I'm not wrong :
if ($this->form_validation->run() == FALSE)
I am unable to load select box value when I want to update the value. The same code perfectly working when I am going to save value.
My controller code is:
public function listwardByCircle($category = "") {
$this->layout = 'ajax';
$this->beforeRender();
$this->autoRender = false;
$ward=$this->Ward->find('list',array(
"fields" => 'id, wardname',
"conditions" => array('Ward.circle_id' => $category)
));
//$this->set('ward',$ward);
print_r($ward);
foreach($ward as $key => $val) {
echo "<option value=$key>$val</option>";
}
}
And this is my js code :
$("#AreaCircleId").change(function() {
alert("testing....");
$.post('../Admins/listwardByCircle/' + $(this).val(), function(data) {
alert( data);
$("#AreaWardId").empty().append(data);
}, 'html');
});
In js file
Url in Controller Like
`\../../Admins\/listwardByCircle`
You may need to update your URL post location in the ajax from:
$.post('../Admins/listwardByCircle/'
to
$.post('/admins/listwardByCircle/'
This is if the controller name is admins.
I have a dropdown list which is being populated from database. It is working fine but in the form_dropdown in the view file, I want to add class="required" for validating the dropdown using Jquery. I have tried to make it work but as it turned out it won't work. Would you please kindly help me where exactly to put the class="required" - and make the jquery validation work?
Thanks in Advance
I have this in my controller
// To get the batch name
$this->load->model('dropdown_batchlist');
$data['dropdown_batchlist']= $this->dropdown_batchlist->dropdown_batchlist();
this in my model-
function dropdown_batchlist() {
$this->db->select('batchname, batchid');
$records=$this->db->get('batch');
$data=array();
// add it here as the first item in the array,
// assuming you don't have a $row->batchid of 0 in your results.
$data[0] = 'SELECT';
foreach ($records->result() as $row)
{
$data[$row->batchid] = $row->batchname;
}
return ($data);
}
And this in my view file
<?php echo form_dropdown('batchid', $dropdown_batchlist,'', 'class="required"' ); ?>
The Problem is Solved
I have figured out the problem. The view file was okay, all I had to do is replace $data[0] = 'SELECT'; with
$data[' '] = 'SELECT';
Thanks
Try setting the attributes using an associative array:
$attributes = array(
'name' => 'batchid',
'class' => 'required',
'options' => $dropdown_batchlist
);
echo form_dropdown($attributes);