Yii2: Change Gridviews' DataProvider on button click - javascript

I have 3 seperate dataProviders for my Gridview, one with Saved data, one with Unsaved data and one with both.
Now this is what I'm trying to accomplish:
If you click on saved, the dataProvider changes to the one with saved data.
I'm trying it like this:
<?php
if($i == 1){
$dataProvider = $dataProviderSaved;
} elseif($i == 2) {
$dataProvider = $dataProviderNotsaved;
} else {
$dataProvider = $dataProviderBoth;
};
\yii\widgets\Pjax::begin(['id' => 'gridview', 'timeout' => false,
'enablePushState' => false, 'clientOptions' => ['method' => 'POST']]) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
//regular gridview..
\yii\widgets\Pjax::end(); ?>
Javascript:
var i = $i;
$("#saved").click(function(){
i=1;
$.pjax.defaults.timeout = false;//IMPORTANT
$.pjax.reload({container:"#gridview"});
});
', \yii\web\View::POS_READY);
So, I've just read that changing PHP variables inside JS is 'impossible'.
How would I accomplish this?
Is there a better way?
Do I need 3
DataProviders? (This means 3 find()'s inside of the controller)

If I understood properly you don't need 3 dataProviders. You should use GridView's FilterSelector option to treat that external element as part of GridView's filter.
For example
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'filterSelector' => "input[name='ModelSearch[_selection]'],",
...
Then, in your Filter Model you filter depending on that value
switch($this->_selection) {
case 'Saved':
$query->andFilterWhere([...]);
break;
case 'Unsaved':
$query->andFilterWhere([...]);
break;
case 'Both':
$query->andFilterWhere([...]);
break;
Don't forget to add the _selection attribute to your Model class and to rules() as 'safe' in the Search Model class.

You can try in two ways:
The first the simpler you assign to each button (saved, unsaved, both) the call of three separate cation of your controller
that invoke each a respective view connected to a single gridview each of these latter with the appropriate dataprovider
The second consists of controller you have the three dataprovider different as this example
return $this->render('viewYourView', [
'/modelContribuente' =>$modelContribuente,
'dataProviderOne' => $providerOne,
'dataProviderTwo' => $providerTwo,
'dataProviderThree' => $providerThree,
]);(
In a single View you can create your three gridview everyone who uses the dataprovider appropriate and then visalizzare or hide gridviewn with JQuery functions controlled by buttons

Related

alpine component fails to execute on livewire update

I have an alpine.js component with livewire data save. https://github.com/TerrePorter/CustomCountrySelectBox.git
I am trying to load two and eventually three of these in sequence on the page. First, the country then when that is selected, I update the state/region, and finally when that is updated I update the city.
The problem is when I update the state/region the alpine.js code does not execute when livewire refreshed that part of the page.
I also tried to make it work all on one page, a select box that updates the next select box, but it would always fail to load the second array.
Here is the relevant part of the template
<div class="p-6">
<lable>Please select your location: </lable>
#if ($country == '')
#component('components.country-select-box', ['countryJson' => $countryJson])#endcomponent
#endif
#if ($stateJson != '')
#component('components.state-select-box', ['stateJson' => $stateJson])#endcomponent
#endif
</div>
Here is part of the livewire code where I update the state's JSON file.
public function updatedCountry() {
$this->stateJson = $this->getStateJson();
}
public function getStateJson() {
$r = Countries::where('short_name', '=', $this->country)->with('states')->first();
$ret = [];
foreach ($r->states as $index => $item) {
$ret[] = ['title' => $item->state_name, 'value' => $item->id];
}
return json_encode($ret);
}
And finally as mentioned before this is the select box dropdown I am using, https://github.com/TerrePorter/CustomCountrySelectBox.git

Update status column on basis of multiple id in one table

i have subjects table with status column and parent_id column so from view page if i click on active button change the status to active/inactive..
So now if i click on subject active button it should change status of that child subjects too..
here is my code:
public function updateStatus(subject $subject)
{
$subject_id = $subject->id;
$subjects = Subject::where(['parent_id' => $subject_id])->get();
$subjects->status = !$subjects->status;
$subjects->save();
return redirect()->route('subject.index');
}
I am storing the main id in parent_id column.So if i change status of main id it should change status of related parent_id column status also. if it is 1 it should change to 0. if it is 0 it should change to 1.
Can anyone help me to solve this..TIA
If I understood correctly, first, you need to add parent data to your query:
$subjects = Subject::where('parent_id', $subject_id)->orWhere('id', $subject_id)->get();
Since this is a collection, you should create a loop to update each item. BTW, Laravel may have a built-in function for this, but I don't know.
foreach($subjects as $subject) {
$subject->update([
'status' => !$subject->status
]);
}
All you have to do is execute two queries, one for update status 0 where status is 1 :
Subject::where('parent_id', $subject_id)->where('status', 1)->update(['status' => 0]);
and other for change status 0 to 1 for the id you received
Subject::where('parent_id', $subject_id)->where('status', 0)->update(['status' => 1]);
So finally your code will be look like :
public function updateStatus(subject $subject)
{
$subject_id = $subject->id;
$subject = Subject::where('parent_id', $subject_id)->where('status', 1)->update(['status' => 0]);
$subject = Subject::where('parent_id', $subject_id)->where('status', 0)->update(['status' => 1]);
return redirect()->route('subject.index');
}

radio button list with text option cakephp

I am new to CakePHP. I need to make a form with radio buttons and the last one is "other" where the user can type in an answer in a text box.
Is there any way FormHelper can do this that's built in?
One way I was going to do was create a radio list and a text field. When "other" is selected Javascript will show the text field. For this I don't understand how to use any other variables besides the fields in the database. How does one create a variable from a model that can be accessed from a view and the value returned for processing?
For the model I have:
class User extends AppModel {
/**
* Display field
*
* #var string
*/
public $displayField = 'title';
var $sourceOther = ' ';
var $passwordRepeat = ' ';
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = sha1(
$this->data[$this->alias]['password']);
}
// $this->data[$this->alias]['created']= CakeTime::gmt();
// $this->data[$this->alias]['updated']= CakeTime::gmt();
$this->data[$this->alias]['username']= $this->data[$this->alias]['email'];
return true;
In the view I have
echo $this->Form->input('mobilePhone',array(
'label'=>'Mobile or fixed phone with no spaces'));
echo $this->Form->input('alternatePhone');
echo $this->Form->input('leadSource', array(
'options'=>array('Google'=>'Google','OnlineAd'=>'Online Ad',
'Printed Media'=>'Printed Media','LetterDrop'=>'Letter Drop',
'Other'=>'Other (specify text)'),
'empty'=>'(choose one)'));
echo $this->Form->input($this->sourceOther);
...but it doesn't like sourceOther, the variable in the model. How do I get data from the view (the text box) into the user model so beforeSave can do something with it?
Thanks.
Thanks.
Sorted it out after reading "Cake PHP Application Development". It works for Cake 2.x and 1.2 (as used in the book).
In your view put:
echo $this->Form->input('sourceOther');
Then in the model you can access your variable with:
$this->data['User']['sourceOther'];
For example, use it to save "other" text field in beforesave:
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = sha1(
$this->data[$this->alias]['password']);
}
$this->data[$this->alias]['username'] = $this->data[$this->alias]['email'];
$this->data[$this->alias]['activation'] = md5(uniqid(rand(), true));
if ($this->data[$this->alias]['leadSource'] == 'Other') {
$this->data[$this->alias]['leadSource'] =
$this->data['User']['sourceOther'];
}
return true;
}

give two function in one button in Yii framework

I have a question about Yii framework, i have problem with submit button, i want to given two fungsi save and update in one submit button, can anyone tell me how to set that function on form ?
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
i change 'Save' with 'Update' it's still have error Primary key added, how i can create two function update and save in one push button ?
public function actionCreate()
{
$model=new TblUasUts;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['TblUasUts']))
{
$model->attributes=$_POST['TblUasUts'];
if($model->save())
$this->redirect(array('view','id'=>$model->nim_mhs));
}
if(isset($_POST['TblUasUts'])
{
$model->attributes=$_POST['TblUasUts'];
if($model->update())
$this->redirect(array('view','id'=>$model->nim_mhs));
}
$this->render('update',array(
'model'=>$model,
));
}
In your form, you can use something like :
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Update'); ?>
</div>
As far as processing different actions on the backend code, there are a few options, for example, you could :-
Direct your form to different URLs
Set a (hidden) field (for example ID) and parse for that.
Use the default action from the activeForm, which directs back to the invoking action, for example actionCreate(), or actionUpdate()
In light of your updates, please extend your controller as per my initial suggestion to have another action actionUpdate()
The main difference between the actionCreate(), or actionUpdate() actions is that the Create action create a new (empty) TblUasUts object, while the Update action populates the TblUasUts object from the database.
public function actionCreate()
{
$model=new TblUasUts;
...
... Do things with $model ...
...
$model->save();
}
public function actionUpdate
{
// The id of the existing entry is passed in the url. for example
// ...http:// .... /update/id/10
//
$model = TblUasUts::model()->findByPK($_GET['id']);
...
... Do things with $model ...
...
$model->save();
}

Zend forms working with ajax/javascript onchange event

I am writing a code to use onchange in my application this is my code so far
.Phtml
<script type="text/javascript">
function submit()
{
$id = intval($_GET['id']);
$satellite = intval($_GET['satellite_id']);
if ($id == 0)
{
echo "Please select a Region";
}
else
{
$query = "select * from satellites where region_id = '".$id."'";
$query = mysql_query($query);
echo "<select name='satellite_id'><option value=''>-- select one --</option>";
while ($row = mysql_fetch_assoc($query))
{
echo "<option value='".$row['satellite_id']."'".($row['satellite_id']==$satellite?" selected":"").">".$row['satellite_name']."</option>";
}
echo "</select>";
//DisplayFormRow ("Satellite", FormDropDownBox ("satellite_id", $SatelliteARY, $Result['satellite_id']));
}
}
</script
//zend code Form
$region_name = new Zend_Form_Element_Select('region_name');
$region_name->setAttribs(array('style' => 'width: 150px;'));
$region_name ->setLabel('Region')
->onchange('this.form.submit();') //tried this code ->onchange('javascript:submit();')
->addMultiOption('--Select One--', '--Select One--');
$mdlRegions = new Model_Regions();
$regions = $mdlRegions->getRegions();
foreach ($regions as $region)
{
$region_name->addMultiOption($region->region_id, $region->region_name, $region->region_short_name);
}
//model
<?php
class Model_Regions extends Zend_Db_Table_Abstract
{
protected $_name = 'regions';
//protected $_name = 'smmedetails';
public function getregion($region_id)
{
$region_id = (int)$region_id;
$row = $this->fetchRow('region_id = ' . $region_id);
if (!$row) {
throw new Exception("Could not find row $region_id");
}
return $row->toArray();
}
public function smmedetails2region($region_name)
{
$data = array(
'region_name'=> $region_name
);
return $this->insert($data);
}
public function getRegions()
{
$select = $this->select();
return $this->fetchAll($select);
}
}
//controller
public function registerAction()
{
$this->view->headScript()->appendFile('/js/ui/jquery.ui.autocomplete.js');
$form = new Form_SmmeDetails();
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$companyname = $form->getValue('companyname');
$companytradingname = $form->getValue('companytradingname');
$region_name = $form->getValue('region_name');
$satellite_name = $form->getValue('satellite_name');
$city = $form->getValue('city');
$companyaddress = $form->getValue('companyaddress');
$addresscode = $form->getValue('addresscode');
$companypostaladdress = $form->getValue('companypostaladdress');
$postalcode = $form->getValue('postalcode');
$companyphonenumber = $form->getValue('companyphonenumber');
$companyfaxnumber = $form->getValue('companyfaxnumber');
$companycellnumber = $form->getValue('companycellnumber');
$businessemailaddress = $form->getValue('businessemailaddress');
$businesswebsite = $form->getValue('businesswebsite');
$smmedetails = new Application_Model_DbTable_SmmeDetails();
$smmeid = $smmedetails ->smmedetailsSmmeDetails($companyname, $companytradingname, $region_name, $satellite_name, $city, $companyaddress, $addresscode, $companypostaladdress, $postalcode, $companyphonenumber, $companyfaxnumber,
$companycellnumber, $businessemailaddress, $businesswebsite);
// $region = new Application_Model_DbTable_Region();
//$region ->smmedetails2region($formData, $smmedetails->smmeid);
$this->_redirect('/admin/smme/register2/smmeid/'.$smmeid);
} else {
$form->populate($formData);
}
}
}
The code is suppose to view a hidden input select, called satellite when you select a feild option from regions, the satellite should view certain options based on the region selected. In short the region selected should correspond with what the user selected. eg Province is Gauteng, so cites would be, Johannseburg,Pretoria etc. Take note the region and satellite options are called from the database table according to they names and id. The code above keeps giving me and error Message: Method onchange does not exist. Was told not to use onchange method should I be using ajax and can I use javascript and sqlquery in the view or should I call it as an action? If so how? Here is a slight picture example.
Please be of help
Thanks in advance
I'd make a few suggestions to what you have there.
Firstly, for simplicity, I'd not use the onChange function, because I don't see it in the API, plus JavaScript or jQuery written in that way can become difficult to maintain and write properly. It is a lot simpler to instead include an external JavaScript file. By doing this, you can also test and debug the JavaScript separately, as well as reuse it.
Have a look at the excellent document for onChange, and getJson. I've used these and others and they're quite straight-forward. For testing, I recommend QUnit for starters. It makes testing a breeze.
Secondly, if you're using the Zend libraries for Model_Regions and $region_name, then I'd suggest using them instead of the direct mysql calls as well. This will allow you to build a good library which you can continue to expand as needed, plus it makes composing SQL quicker and safer.
For the controller, I'd suggest a RestController with a Restful Route. Here's an excellent tutorial.
I hope this helps you out with the problem. If you need anything more, let me know.
Thanks for emailing me about this.
The way I go about this is as follows:
Firstly I set up the form, and then an action in a controller.
Lets say getmajorgroupAction()
which in that action I would then disable layout, and just get the relevent results based on the id.
Then in the view file, loop through the
so the output from that call would be
<option value="1">1</option>
<option value="2">2</option>
etc
Personally I use jquery now, whereas the post you referenced when you emailed me, I was using another method.
trying to use something like this
jQuery(document).ready(function() {
jQuery("#division").change(function () {var division = jQuery("#division").val();
jQuery("#major_group").load("/module/getmajorgroup/", {division_id: division} );});
});
Hope that makes sense.
Thanks that was useful but i found a way to do it using this formula below, but everytime I click on the first select the while still in the session the second select appears all the time, eg if a person choose the wrong selection and re tried it brings up another field instead of fixing the field. I think its in a countinous loop . heres my script
<script type="text/javascript">
$(document).ready(function() {
$("#region_name").on('change', function () {
ajaxAddField();
}
);
}
);
// Retrieve new element's html from controller
function ajaxAddField()
{
$.ajax(
{
type: "POST",
url: '<?php echo $this->baseURL()?>/admin/ajax/get-cities/city/' + encodeURIComponent($('#region_name').val()),
success: function(newElement) {
// Insert new element before the Add button
//$(this).prev().remove().end().before('#city-label');
$("#city-label").before(newElement);
}
}
);
}
</script>

Categories