Hope you are all good. I have a problem that is I use an extension i.e. select2 which shows all Products' name in the dropdown list and it works fine to me. In my database, every product has individual price. So, I want to show the sum of all selected products' price in the next of dropdown. So, I used ajax to send the product id to the controller to find the product price. Unfortunately, I can't sum all of product price because when I add new product then previous Id of product gets change then price also gets change. But I want to hold the price of products in a variable when product is selected.
the form code:
<div class="row">
<?php echo $form->labelEx($model,'item_list'); ?>
<?php
$data = CHtml::listData(Products::model()->findAll(),'id', 'name');
echo Select2::activeMultiSelect(
$model, 'item_list', $data, array(
'required' => 'required',
'style' => 'width: 270px;',
'placeholder' => 'Add Product',
'select2Options' => array(),
'ajax' => array('type'=>'POST',
'url'=>$this->createUrl('totalOrderPrice'), //url to call.
'update'=>'#price', //selector to update
'data'=>array('item_list'=>'js:this.value'),
),
)
);
?>
<?php echo $form->error($model,'item_list'); ?>
</div>
the controller code:
...
...
public $prices;
...
...
public function actionTotalOrderPrice(){
$data = Products::model()->findByPk(array('id'=>$_POST['item_list']));
$this->prices += $data->prices;
echo CHtml::tag('input', array( 'type'=>'text' , 'name'=>'Order[price]' , 'value' => $this->prices));
}
I spent a lot of time to solve this problem but anyhow couldn't. Please help someone.
Thanks in advance,
Shimul
Since I don't have products schema , I have used another model i.e User to give you can example of how it could be done.
<div class="row">
<?php
$model=User::model();
$attribute='products';
$data = CHtml::listData(Yii::app()->db->createCommand("select id, concat(RAND()*1000,':',username) as name FROM `User` ")->queryAll(),'id','name');
echo Select2::activeMultiSelect($model,$attribute, $data,
array(
'required' => 'required',
'style' => 'min-width:200px',
'placeholder' => 'Choose User',
'select2Options'=>array(
'formatResult'=>'js:format',
'formatSelection'=>'js:format',
),
'onChange'=>'js:{
var total=0;
$($(this).select2("data")).each(function(){
total+=this.text.split(":")[0]*1;
});
$("#total > label").text(total);
}',
)
);
$js_format_fun = <<<JS
function format(opt){
var price_lbl=opt.text.split(':');
return price_lbl[1];
}
JS;
Yii::app()->clientScript->registerScript('select2_format_option', $js_format_fun, CClientScript::POS_READY);
?>
</div>
<br/>
<div id="total"><strong>Total Price: </strong><label></label></div>
You will see sth like this:
The idea is to avoid ajax and add prices to names e.g product name will be of format: price:name. You split the price ,name and calculate the total as I give above.
Maybe you have to look outside YII, you can use javascript for this, out there, you can find JS libraries and frameworks who can help you to save variables and calculate the sum, for example CanJS has can.compute which has an observable nature so it fires events everytime the sum changes and you can implement function who does the calculation or KnockoutJS too has computed values this two libs are my favorite (I use canjs) they are lightweight and effecient and you can use them just where you need, hope this can help you
Store it in user session
Yii::app()->session['products_prices'] += $data->prices
But you will face a problem when you remove items from your list
I don't know this widget but there is certainly a .seralize() function witch will serialize all selected items id into a json string array.
You then can then use this array in a "in" Condition to sum your total.
Related
I have a form generated using YII2 ActiveForm. there are some field I need to be on the if I select certain options , or need to have them removed if I select some other option.
For e.g. I Have a dropdown AccountType, with two options "individual" and "company".
If the user selects "individual" some fields on the form needs to go away say company name, and some other fields need to appear such as First name, last name. Initially when the display the form , only the Account Type field is there.
below is the code I have at the moment
<?php
$form = ActiveForm::begin(['id' => 'account-setup-form']); ?>
echo $form->field($modelAccMain, 'account_type')
->widget(Select2::classname(), [
'data' => $accountTypeArray,
'options' => ['placeholder' => 'Select account type'],
]);
echo $form->field($modelUsers, 'firstname')->textInput()
->hint('')->label('First Name');
echo $form->field($modelUsers, 'lastname')->textInput()
->hint('')->label('Last Name');
<?php ActiveForm::end(); ?>
Any help is greatly appreciated.
You can use scenarios for that, first define them in your model and than you can use a if statement in your view
if ($model->isAttributeActive('attribute_name')) {
But like #nterms wrote, if you want the user to be able to switch on the client side, javascript would be better.
Defining scenarios also helps with the validation (only active attributes will be validated).
p.s. Don't forget to set the scenario in your controller
$model = new MyModel(['scenario'=>'my_scenario']);
The way i would handle it is with jquery hide and show using the change event of the dropdown,
In your javascript
Assuming that the data in the select 2 widget is in the form of array
eg:
[1=>"first-item",2=>"second-item",...]
$(document).ready(function(){
var id= //check the id of the select2
on the inspect element id using chrome;
$("#id").on("change", function(){
if(id.value==1){
//show a div
}else{
//hide a div
}
//for multiple values better use switch
like this
switch(id){
case 1:{
$("#divid").show();
......
}
}
})
})
I hope you get the idea,
For the select 2 id you can set it via
echo $form->field($modelAccMain, 'account_type')
->widget(Select2::classname(), [
'data' => $accountTypeArray,
'options' => ['placeholder' => 'Select account type',"id"=>"mypreffereid"],
]);
I am trying to pass the values of form inputs to a controller for validation. The values are populated in the view using an array. The problem is that I don't know how to get the necessary 'name' values from the array for the individual inputs in order to pass them through validation.
In the first view the form inputs are described this way:
<?php echo form_checkbox('study_items[]', 'Medical History', FALSE);
echo form_label('Medical History', 'Medical History');?>
<br>
<?php echo form_checkbox('study_items[]', 'Physical Exam', FALSE);
echo form_label('Physical Exam', 'Physical Exam');?>
<br>
<?php echo form_checkbox('study_items[]', 'Clinical Assessment', FALSE);
echo form_label('Clinical Assessment', 'Clinical Assessment');?>
The user only has to check the item(s) that apply to their specific need. This is submitted to the validation controller which, after successful validation, ONLY sends those items that were selected back to a view in an array like so:
$data['si_items'] = $this->input->post('study_items');
In the next view, the code for a sample input looks like this:
<?php foreach ($si_items as $si_item) {
echo $si_item. ' '. "$";
$data001 = array(
'name' => $si_item,
'id' => $si_item,
'value' => '',
'maxlength' => '10',
'size' => '50',
'style' => 'width:100px',
);
echo form_input($data001);
echo '<br>';
}
?>
and allows the user to enter a dollar amount for the items they selected to fit their need on the previous page.
As sample output of this portion of the code looks like this:
"Medical History $_______________"
"Physical Exam $_______________"
"Clinical Assessment $_______________"
where the blank is a textbox for entering the price of each item. So far, this all works perfectly to display each form input box and labels checked by the user in the previous view.
However, I'm at a loss as to how to get the 'name' for each individual input in order to validate it. The validation controller does not recognize '$si_items' as a name value. This has me stumped and there HAS to be a way to do this.
In my validation controller I want to check that each entry has a decimal value (i.e. 234.56) as the user's input.
Any ideas? Is there a more efficient way to do this?
we are missing swaths of code, but from what you have shown;\
$data['si_items'] = $this->input->post('study_items');
is the assignment of your study items (which is an array), meaning that the call in your foreach should not be
foreach ($si_items as $si_item) {
but rather
foreach ($data['si_items'] as $si_item) {
that or change your initial assignment to the following;
$si_items = $this->input->post('study_items');
I used the below code to create two radio buttons(approved messages and rejected messages) in Yii framework
<?php echo CHtml::activeRadioButtonList($model, 'Approved', array('Approved Messages', 'Rejected Messages'), array('labelOptions'=>array('style'=>'display:inline'),'separator'=>'')) ?>
Now I have to filter and display all the rows in CGridView of the table where column 'approved' has value=1 when I click on "approved messages" radio button and all the rows in CGridView of the table where column 'Approved' has value=0 when I click on "rejected messages" radio button. How can I do this
I used a drop down for this, the values are Yes and No. Just translate the approved column into text using the following code:
array(
'name' => 'approved',
'value' => '($data->approved ? "Yes" : "No")',
'filter' = >CHtml::dropDownList('Approved', '',
array(
' '=>'All',
'1'=>'On',
'0'=>'Off',
)
),
)
This link is where I got this info: http://www.yiiframework.com/forum/index.php/topic/30694-cgridview-filter-dropdown-from-array/
I googled using cgridview filter example
Alright, lets put in the radio buttons instead of all the dropdowns haha.
I assume you have your view set up something like this:
// view/index.php (or similar)
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$model->search(),
'filter'=>Message::model(),
'columns'=>
[
'id',
'username',
'email:email',
'approved'=>[
'name'=>'approved',
'filter'=>$this->approvedFilter(),
// I like moving stuff like this out of the way.
// But maybe it's smarter to put it in your model instead?
]
]
));
Next for the controller.
// MessageController.php (or similar)
public function actionIndex()
{
$model = Message::model();
// All we need to do is to assign the incoming value to the model we are using...
if ( isset( $_GET['Message']['Approved'] )){
$model->approved = $_GET['Message']['Approved'];
}
$this->render('index', ['model'=>$model]);
}
// Oh yeah the filter. I just copied your code.
public function approvedFilter(){
return CHtml::activeRadioButtonList(
Message::model(), 'approved', array(0,1),
array(
'labelOptions'=>array('style'=>'display:inline'),
'separator'=>''
)
);
}
This code has been tested, but I made some last minute changes, so sorry if it blows up!
And I still think a simple 'approved:boolean' is much cleaner. ;)
I have table types and i want to build selectbox with all values from this table
In my controller i wrote this code
$allRegistrationTypes = RegistrationType::model()->findAll();
$this->render('index', array('allRegistrationTypes' => $allRegistrationTypes))
How build selectbox in view file ?
Well then its pretty simple all you need to do is first create List Data like
CHtml::ListData(allRegistrationTypes,'value you want to pass when item is selected','value you have to display');
for ex
typeList = CHtml::ListData(allRegistrationTypes,'id','type');
now remember both id and type are fields in table
now all you have to do is if you are using form then
<?php echo $form->dropDownList($model, 'type_id', $typeList, array('empty'=>'Select a tyoe')); ?>
and if you need multiple you can pass multiple => multiple in the array as htmlOptions
You would use CHtml::dropDownList, or activeDropDownList if there is a "parent" model and you want to leverage its validation rules.
If you want to make the <select> element multiple-selection-capable, pass in 'multiple' => 'multiple' and 'size' => X as part of the $htmlOptions parameter.
Simplest Method to get "Select Box" in YII Framework:
<div class="row">
<?php
echo $form->labelEx($model,'county');
$data = CHtml::listData(County::model()->findAll(), 'id', 'county');
$htmlOptions = array('size' => '1', 'prompt'=>'-- select county --', );
echo $form->listBox($model,'county', $data, $htmlOptions);
echo $form->error($model,'county');
?>
</div>
Good Luck..
I have two combos; provinces and cities.
I would like to change cities value when the province combo value changes. Here is my code
<div class="cities form">
<?php
$v = $ajax->remoteFunction(array('url' => '/cities/','update' => 'divcity'));
print $form-> input('Province.province_id', array('type' => 'select', 'options'=> $provinces, 'onChange' => $v));
?>
<div id="divcity">
<?php
echo $form->input('Cities.cities_name');
?>
</div>
Every time I change province combo, it call cities/index.ctp. anybody want to help?
really thank for your help
wawan
The 'url' => '/cities/' is calling the default index action of the cities controller.
This automatically renders the cities/index.ctp view.
Have you included the RequestHandler component in the cities controller?
This can be used to detect Ajax requests and then render a different view.
You need to first include the RequestHandler Component at the top of the CitiesController, then write a function to list cities, optionally requiring a Province's id.
I think you'll end up having something like this:
<?php
// In the view
$v = $ajax->remoteFunction(array('url' => '/cities/list','update' => 'divcity'));
print $form-> input('Province.province_id', array('type' => 'select', 'options'=> $provinces, 'onChange' => $v));
// In CitiesController
function list($province_id = null) {
// use $this->City->find('list', array('fields'=>array('City.id', 'City.name')))
// to generate a list of cities, based on the providence id if required
if($this->RequestHandler->isAjax()) {
$this->layout = 'ajax';
$this->render();
}
} ?>