Status change by clicking image button in yii2 - ajax

I am working on yii2 gridview and I want to change the status by clicking image.
Here is my gridview code:`
['header'=>'Deleted',
'format' => 'image',
'value'=>function($data) { return $data->deleteimageurl; },],
['header'=>'Reports Status',
'format' => 'image',
'value'=>function($data) { return $data->statusimageurl; },],`
And in model I have created these functions in model to view the images using the image path:
public function getdeleteImageurl()
{
return \Yii::$app->request->BaseUrl.'/images/'.$this->is_deleted.'.png';
}
public function getstatusImageurl()
{
return \Yii::$app->request->BaseUrl.'/images/'.$this->reports_status.'.png';
}
Now How can I change the status? How can I add an ID in image column ? I can use ajax if I add an ID there.Or if there is any other solutions please let me know.

You should use format raw and value like as:
'value'=>function($data) {
return HTML:img($data->statusimageurl, ['data-id'=>$data->id]);
},
After you can use ajax with data-id

Related

Hidden input value does not update model property value yii2

Im using activeform. In my User model, i initialized a model property Public formType;, set its rule to safe and i am trying to use this property with hiddeninput to create condition in the user controller. But i am getting that the activeform doesn't update the value of the property. Ive read this but i am still unclear whats the workaround of updating the property while still using activeform.
Form
<?= $form->field($model, 'formType')->hiddenInput(['value' => 'userRowUpdate'])->label(false) ?>
User Controller
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$model->scannedFile = \yii\web\UploadedFile::getInstance($model, 'scannedFile');
$type = Yii::$app->request->post('formType');
if ($model->processAndSave()) {
FlashHandler::success("User profile updated success!");
if ($type == "userDetailView") {
return $this->redirect(['view', 'id' => $model->id]);
} else if ($type == "userRowUpdate") {
return $this->redirect(Yii::$app->request->referrer);
}
} else {
FlashHandler::err("User profile updated FAIL!");
}
}
return $this->render('update', [
'model' => $model,
]);
}
Replace the hiddeninput from using activeform to
<?=Html::hiddenInput('name', $value);?>
Reasons:-
code in question is probably not the right approach since its creating a attribute/model property just for the condition in action controller
html input wouldnt affect the model but the data is still readable and be used in the actioncontroller as a condition
You can use
Html::activeHiddenInput($model, 'formType')
to avoid hiding the label and it's shorter.
if the value is not being updated, check your rules in the model. That attribute at least must have a safe rule to be able to be assigned on the $model->load(Yii::$pp->request->post()) call

Sharing create and update form in Laravel

I'm learning Laravel and have created a single form that is shared by the create and edit controller.
The create controller just returns the view.
public function create()
{
return view('hotels.create');
}
However i've had to put my edit controller and return it in an array
return view('hotels.edit', [
'hotel' => Hotel::with('hotelFacilities')->where('id', $id)->get()
]);
Now in my view I have to pass
$hotel[0]->hotelFacilities->fitness_centre
instead of
$hotel->hotelFacilities->fitness_centre
So now my create view is looking for $hotel where it is now $hotel[0] in the shared view. How can I change this so it's looking at the same reference to the $hotel variable?
If you are using the same view for create and edit, you have to pass the same object for views. change code as below.
return view('hotels.create', [
'hotel' => new Hotel
]);
return view('hotels.edit', [
'hotel' => Hotel::with('hotelFacilities')->where('id', $id)->first()
]);

Laravel livewire not seeing render update after attach

I have a livewire component rendering two lists on a page. I have a button on the left list to add that item to the right list (many to many) relation using attach. This is working, but the right list isn't getting re-rendered. When I then click a filter I have on the left list, the right list re-renders showing the newly attached item. It seems like either render() isn't being called when I do the attach method, or it is taking another call to render to pick up the new relation? I also tried calling $this->render from the attach method, but that didn't help.
public function render()
{
$items = item::with('status')
->where(function($query){
$query->when(!empty($this->selectedStati), function ($query) {
$query->whereHas('status', function ($query) {
$query->whereIn('id', $this->selectedStati);
})->orWhereDoesntHave('status');
});
})
->get();
$testItems = $this->test->items;
//dd($testItems);
return view('livewire.items-source', [
'selectedStati' => $this->selectedStati,
'statuses' => $this->status,
'items' => $items,
'testItems' => $testItems
]);
}
public function filterStatus($id){
if (($key = array_search($id, $this->selectedStati)) !== false) {
unset($this->selectedStati[$key]);
} else {
$this->selectedStati[]=$id;
}
session(['status'=>$this->selectedStati]);
}
public function addToTest($id){
//attach the given item to the test
$this->test->items()->attach($id);
dd($this->test->items);
}
public function removeFromTest($id){
//detach the given item from the test
$this->test->items()->detach($id);
}
after attach the item to test collection refresh model to rehydrate it with fresh data like
public function addToTest($id){
//attach the given item to the test
$this->test->items()->attach($id);
$this->test->refresh();
}

Conditional Validation in Yii2

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.

Magento category edit page and ajax

I am adding some extra html to some input attributes in the category edit area by creating a new attribute input renderer type in my modules mysql install script:
$installer->addAttribute(
'catalog_category',
'mymodule_category_popularity',
array(
'label' => 'My Label',
'group' => 'My Group',
'type' => 'int',
'class' => 'validate-number',
'required' => false,
'default' => 50,
'input_renderer' => 'mymodule/adminhtml_catalog_category_widget_slider',
)
);
And the renderer:
class Mynamespace_Mymodule_Block_Adminhtml_Catalog_Category_Widget_Slider extends Varien_Data_Form_Element_Text
{
public function getAfterElementHtml()
{
$html = parent::getAfterElementHtml();
return $html." <div id=\"slider\"></div>";
}
}
And the javascript:
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j( "#slider" ).slider();
});
This works fine, the plugins get loaded correctly and so does jQuery (as I have loaded it using my layout xml for the module). I see a slider. However, after the page has completely finished (the Magento ajax has re-loaded the category edit tabs) my slider dissapears. This, I assume, is because the javascript code is not getting ran again.
I have tried adding my javascript to the core edit.phtml (as there is other Magento JS there) however I just get an error: $j('#slider).slider() is not a function. This is because the content is getting loaded via ajax.
So, how do I make sure that I can use $j('#slider).slider() in the category edit area? Confusing I know.
I accomplished this by creating a javascript function:
function loadedInput() {
$('#slider').slider();
}
And calling that function in the attribute renderer:
class Mynamespace_Mymodule_Block_Adminhtml_Catalog_Category_Widget_Slider extends Varien_Data_Form_Element_Text
{
public function getAfterElementHtml()
{
$html = parent::getAfterElementHtml();
return $html." <div id=\"slider\"></div><script>loadedInput();</script>";
}
}

Resources