Previously I've created a question where I was wondering how to set selected value for dependent dropdown. That was easy, man adviced me just set second parameter.
echo CHtml::dropDownList('OpenLessons[Building]', $buildingClassID, $buildingList,array(
'ajax' => array(
'type'=>'POST',
'url'=>CController::createUrl('ajax/floorList'),
'update'=>'#OpenLessons_Floor',
)));
echo CHtml::dropDownList('OpenLessons[Floor]',$model->Class_ID, array(),array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('ajax/roomList'),
'update'=>'#OpenLessons_Class_ID',
)));
echo CHtml::dropDownList('OpenLessons[Class_ID]',$model->Class_ID, array());
where $buildingClassId is value of select. So that works fine for first select. But how can I set the same for dependent ones? When I look at it's code it looks like this:
<select name="OpenLessons[Floor]" id="OpenLessons_Floor">
</select>
I expected it to have some options, because I set default value for first one. So even if I put as second parameter of seconddropdown some value it wouln't be selected.
Any advices/suggestions?
UPDATE I'd mention that I don't see at XHR console call of floorlist. How can I make it?
UPDATE
$(document).ready(function()
{
$('#OpenLessons_Building').trigger('change');
$('#OpenLessons_Building option').trigger('click');
}).on('change','#OpenLessons_Building',function()
{
console.log('changed');
}).on('click','#OpenLessons_Building option',function()
{
console.log('clicked');
});
Tried like this. Both actions - change and click has happened because I can see output in console, but the dependent arrays are still empty.
You should use $("#OpenLessions_Building").on("change", function() { your code here });
The trigger function was actually does is execute the action (change or click in your case) of the dropdown as soon as the page loads.
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 using Jquery-option-tree plugin on a standalone website not based on Wordpress as in example 7 on the demo page, except that I am not passing a .txt file but a PHP page is generating the array of < options > to be passed to the plugin.
http://kotowicz.net/jquery-option-tree/demo/demo.html
This perfectly works: so let's say that the user wants to select a category for a new product, the plugin suits the purpose generating a nice: " Food -> fruit -> apples " upon user clicks. (see demo page ex. 7)
What instead if a product already exists with its categories assigned? I want to show it to the user when he edit that product, preloading the tree.
I have the ids path coming from database, so it would just be a matter of having the plugin to run without the user interact, using the value I pass. I saw this question: jQuery simulate click event on select option
and tried to simulate user' click with this (and other) methods with no luck.
$('#select')
.val(value)
.trigger('click');
Here the call to the function:
$(function() {
var options = {
empty_value: '',
set_value_on: 'each',
indexed: true, // the data in tree is indexed by values (ids), not by labels
on_each_change: '/js/jquery-option-tree/get-subtree.php', // this file will be called with 'id' parameter, JSON data must be returned
choose: function(level) {
return 'Choose level ' + level;
},
loading_image: '/js/jquery-option-tree/ajax-load.gif',
show_multiple: 10, // if true - will set the size to show all options
choose: ''
};
$.getJSON('/js/jquery-option-tree/get-subtree.php', function(tree) { // initialize the tree by loading the file first
$('input[name=parent_category_id]').optionTree(tree, options);
});
});
Here you can see the plugin:
https://code.google.com/p/jquery-option-tree/
I don't know that plugin, but looking at the examples there seems to be one that fits your need; Example 6 - AJAX lazy loading & setting value on each level change.
This would, in theory, just require some config options:
preselect: {'demo6': ['220','226']}, // array of default values - if on any level option value will be in this list, it will be selected
preselect_only_once: true, // prevent auto selecting whole branch when user maniputales one of branch levels
get_parent_value_if_empty: true,
attr: "id" // we'll use input id instead of name
If this doesn't fit you need though, you could initiate it from an event, like change, keyup, etc.
$(document).on('change', '#select', function() {
$('#nextSelect').val($(this).val());
})
$(document).on('change', '#nextSelect', function() {
$('#finalInput').val($(this).val());
})
Yes, you are right Mackan ! I saw that "preselect" option but I was initially unable to use it transferring the path from database to javascript, I ended up with my "newbie" solution to match the syntax:
preselect: {'parent_category_id': [0,'2','22']},
PHP
$category_path comes from DB query and is like "0,2,76,140,"
$path = explode(',', $category_path);
$preselect="";
foreach ($path as $value) {
$int = (int)$value;
if ($int != 0) $preselect.= "'". $int ."',";
else $preselect.= $int.","; // have to do this as ZERO in my case has to be without apostrophes ''
}
$preselect = "{'parent_category_id':[".$preselect."]}"
JS
var presel= <?php echo($preselect); ?>;
var options = {
preselect: (presel),
}
Any suggestion for a better code ?
Thanks a lot !!
I have seen this wiki where they populate a dropdownlist of cities, depending of the value of another dropdownlists that contains countries, using an ajax call with the update option. I need to implement something similar, but my dropdownlist depends on two dropdownlists:
<div class="row">
<?php echo CHtml::label('Countries', 'country_id'); ?>
<?php echo CHtml::dropdownlist('country_id', '',$countries); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'globaladmin'); ?>
<?php echo $form->dropDownList($model,'globaladmin',User::itemAlias('AdminStatus')); ?>
<?php echo $form->error($model,'globaladmin'); ?>
</div>
The user must select a country, and then only if in the second list "No" is selected, a new dropdown lists must be populated with the cities info (just like in the wiki example).
As I said it is similar to the example, but the new dropdown depends on 2 values (the id of the contry selected on the first list and if "No" is selected in the second one). How could I solve it?
EDIT: Explaining a little more
In the example, the country dropdown which contains the ajax call is like:
echo CHtml::dropDownList('country_id','', array(1=>'USA',2=>'France',3=>'Japan'),
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('currentController/dynamiccities'), //url to call.
'update'=>'#city_id', //selector to update
)));
I can't define such a ajax call in my country list, because I must wait the value of the second dropbox. Only if "No" is selected in this list, the ajax will be executed (and the city dropdownlist populated and showed). If "Yes" is selected then the city dropdownlist must be hidden.
Just add an ID to your globaladmin drop down and then do like below:
$("#THE ID YOU HAVE SET").on('change',function(){
// You can use $(this).val()
// and send it via an ajax request into your own url
var valueOfMyGlobalAdminDropDown=$(this).val();
if(valueOfMyGlobalAdminDropDown=="yes"){
//DO SOMETHING
}else{
//DO SOMETHING ELSE
}
});
it is also strongly recommended to use jquery live(in jquery version -1.7) or jquery ON(in jquery version +1.7) to keep your page alive in ajax requests.
When i select value from drop down list,
and I submit form, i want my drop down list to have selected value,
not to be on default value again.
I try like this, but not working:
<?php echo $form->dropDownList($model, 'code', $countriesIssuedList, array('name'=>'countriesIssued'), $select = array($_POST['countriesIssued']));?>
Also i would like to add a first value to be default, not from db, i want to do it in the code like this, array('empty'=>'--Select country--')
but not working.
Thanks
If you must change the name of your dropdownList you must manually set the value of code to $_POST['countriesIssued'] in your controller/view. As for the default, prompt is used to set this.
<?php if(!$model->code) $model->code=$_POST['countriesIssued'];?>
<?php echo $form->dropDownList($model, 'code', $countriesIssuedList, array(
'name'=>'countriesIssued','prompt'=>'--Select country--'
));?>
The second parameter (currently 'code') must be a key in this array: $countriesIssuedList
See for example here.
"Also i would like to add a first value to be default" ... perhaps you can use array_merge()?
I have a dropdown form that with option values 1, 2, and 3. When this form is submitted ($this->Form->create('MyModel', array('action' => 'view'))), I'd like one of these options to be an argument variable that gets passed into the action view and go to controller/view/option_value so that I can load some appropriate data using option_value.
I can't seem to have this option_value passed as the action argument. It's a POST data, so I do have this option_value available to me in the controller, but I thought it would be good to have the value in the URL also because this view.ctp allows the user to update some things and I want the user to be redirected to the referrer easily.
Any ideas? I think this is a client-side issue.. but I'm not yet familiar with Javascripts.
Edit:
Still looking into how to do this.. but for now, I am just redirecting the form-submitted page, which does not include the option_value in the URL, to the same page with the option_value as the parameter. It works for what I need, but if anyone would like to add an answer, I'd appreciate it!
Using jQuery:
<?php
echo $this->Form->create('MyModel', array('id' => 'myForm', 'action' => 'view'));
echo $this->Form->input('MyField', array('id' => 'myField'));
echo $this->Html->scriptStart();
?>
$('#myForm').on('submit', null, null, function(evt) {
var form = $('myForm'),
field = $('#myField');
form.action += "/" + field.value;
form.submit();
evt.stopPropagation();
});
<?php
echo $this->Html->scriptEnd();
echo $this->Form->end(__('Submit', true));
?>
Try that, you might have to tweak some stuff to your needs. Cheers.
-Andrew