Yii2 - How can I add a search in Dropdownlist Widget - yii2

Good day!
How can I add a search on a dropdownlist?
I want a dropdown search like the Select2 widget.
Dropdownlist:
<?= $form->field($modelRis, "[{$i}]lib_item_item_id")->dropDownList(
ArrayHelper::map(LibItem::find()->orderBy('item_description')->all(), 'item_id', 'item_description'),
[
'prompt'=>'Select Item',
'onchange'=>'
var tmp = $(this).attr("id");
var thisId = tmp.split("-");
var tmp2 = "";
var tmp3 = "";
var sample_id = $(this).val();
$.post( "'.Yii::$app->urlManager->createUrl(['online-requisition/listsofunit?item_id=']).'"+$(this).val(),
function( data ) {
$( "#risrequesteditem-"+thisId[1]+"-lib_unit_id").html( data );
$( "#loop-"+thisId[1]+"-lib_item_item_id").val( sample_id );
tmp2 = data;
tmp3 = tmp2.split("=====");
$( "#loop-"+thisId[1]+"-available_stock").val( tmp3[1] );
});
',
'pluginOptions' => [
'allowClear' => true
],
])->label('Item',['class'=>'label-class']); ?>
I can't use the select2 widget because the 'onchange' or this line of code is not supported:
'onchange'=>'
var tmp = $(this).attr("id");
var thisId = tmp.split("-");
var tmp2 = "";
var tmp3 = "";
var sample_id = $(this).val();
$.post( "'.Yii::$app->urlManager->createUrl(['online-requisition/listsofunit?item_id=']).'"+$(this).val(),
function( data ) {
$( "#risrequesteditem-"+thisId[1]+"-lib_unit_id").html( data );
$( "#loop-"+thisId[1]+"-lib_item_item_id").val( sample_id );
tmp2 = data;
tmp3 = tmp2.split("=====");
$( "#loop-"+thisId[1]+"-available_stock").val( tmp3[1] );
});
',
Thanks...
Updates:
If i'm going to used the select2 widget in order to have a search function during the selection of items there will be a problem.
In the :
first selection its working:
And the onchange function has been working also. And automatically fill all the data in form field (Item no, Unit and StockAvailable) after the selection of item.
1st Selection
second selection is not working:
But I can select an item. Only the jquery function onchange is the problem...
2nd Selection
Thanks...

As suggested by Ajith above, you should use the Yii2 Select2 Widget from http://demos.krajee.com/widget-details/select2
If you go through the details you will find that the above widget does allow you to add event handlers by using the pluginEvents parameter settings of the widget.
pluginEvents = [
"change" => "function() { log('change'); }",
"select2:opening" => "function() { log('select2:opening'); }",
"select2:open" => "function() { log('open'); }",
"select2:closing" => "function() { log('close'); }",
"select2:close" => "function() { log('close'); }",
"select2:selecting" => "function() { log('selecting'); }",
"select2:select" => "function() { log('select'); }",
"select2:unselecting" => "function() { log('unselecting'); }",
"select2:unselect" => "function() { log('unselect'); }"
];
Although it's not possible to provide proper code without knowing the context etc of your code snippet, however it can be re-written using Yii2 Select2 widget as below (the code below is untested, but should give you an idea of the structure):
use kartik\widgets\Select2;
$data = ArrayHelper::map(LibItem::find()->orderBy('item_description')->all(), 'item_id', 'item_description');
// Usage with ActiveForm and model
echo $form->field($modelRis, "[{$i}]lib_item_item_id")->widget(Select2::classname(), [
'data' => $data,
'options' => ['placeholder' => 'Select Item'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents' => [
'select2:select' => 'function(e) {
var tmp = e.target.id;
var thisId = tmp.split("-");
var tmp2 = "";
var tmp3 = "";
var sample_id = e.target.value;
$.post( "'.Yii::$app->urlManager->createUrl(['online-requisition/listsofunit?item_id=']).'"+$(this).val(),
function( data ) {
$( "#risrequesteditem-"+thisId[1]+"-lib_unit_id").html( data );
$( "#loop-"+thisId[1]+"-lib_item_item_id").val( sample_id );
tmp2 = data;
tmp3 = tmp2.split("=====");
$( "#loop-"+thisId[1]+"-available_stock").val( tmp3[1] );
});
}
'
],
]);
Please note I have used select2:select as the event handler.
I had to provide this as a separate answer because I don't have enough reputation to add a comment.

You can use yii2 select2 widget for this purpose. There is good documentation with demos available at
http://demos.krajee.com/widget-details/select2
An example usage with active form is given below
// Usage with ActiveForm and model
echo $form->field($model, 'state_1')->widget(Select2::classname(), [
'data' => $data,// the select option data items.The array keys are option values, and the array values are the corresponding option labels
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents' => [
'change' => 'function(){// write your on change code here}'
]
]);

Related

How to add new values to multiple Select2 from Kartik instead of replace old ones?

I use Select2 widget in multiply mode in YII2 framework. "kartik-v/yii2-widget-select2": "#dev" - this one I have downloaded via composer.
kartik-v/yii2-widget-select2 dev-master dd09e46
I added initial values with ajax on widget init ('initSelection'). And added another ajax method to suggest new values on user's typing. When user select one from list, it replaced initial values what were added on init. New values replace initial values, but don't another new.
I want new values to add to initial instead of replace it.
<?= $form->field($model, 'security[]')->widget(Select2::class, [
'attribute' => 'security',
'hideSearch' => true,
'data'=>$security_data,
'options' => [
'placeholder' => 'Security',
'multiple' => true,
],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => Url::toRoute([ '/admin/security/select-items' ]),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }'),
'results' => new JsExpression('function(data,page) { return {results:data.results}; }'),
],
'initSelection' => new JsExpression('function(element, callback) { var id = '.Yii::$app->request->getQueryParams()['id'].';if(id !== "") {$.ajax("' . \yii\helpers\Url::toRoute([ '/admin/security/init-items' ]) . '", {data: {id: id},dataType: "json"}).done(function(data) {callback(data.results);});}}'),
],
]); ?>
And here is my api methods:
public function actionSelectItems($q = null){
Yii::$app->response->format = Response::FORMAT_JSON;
$out = ['results' => []];
if(!empty($q)){
$items = Security::find()->where(['like', 'title', $q])->all();
foreach ($items as $item){
$out['results'][] = ['id'=>$item->id, 'text'=>$item->title];
}
}
return $out;
}
public function actionInitItems($id = null){
Yii::$app->response->format = Response::FORMAT_JSON;
$adv = Adv::findOne($id);
$security = #json_decode($adv->security, true);
$out = ['results' => []];
foreach ($security as $item){
$text = Security::findOne($item)->title;
$out['results'][] = ['id'=>$item, 'text'=>$text];
}
return $out;
}
Is there some sort of settings or I missed something when handle http result?

Dropdown in list data

This is my code:
[
'attribute' => 'status',
'value' => function ($model) {
return Html::dropDownList('status', ['10' => 'Active', '20' => 'Deactive']);
},
],
I just want dropdown in status column. If record is active or deactive it will be selected.
You need to use 'format' => 'raw' for the column options and your definition for the dropDownList() is wrong you need to have the selection string as the second parameter and the dropdown options as the third parameter. Change your code to below:
[
'attribute' => 'status',
'format' => 'raw',
'value' => function ($model) {
return Html::dropDownList('status', $model->status, ['10' => 'Active', '20' => 'Deactive']);
},
],
EDIT
You didnt had in the initial requirements that you waned to update the status too when the drop down is changed. You can bind ajax call to the drop-down.
Add the following javascript on top of your view where you are initializing the GridView.
NOTE: Change the url:'controller/update-status?id'+id in the ajax call to the relative controller where you want to update the status for the row, but dont remove the id
$js = <<<JS
$(document).on('ready pjax:success',function(){
$(".switch-status").on('change',function(){
var data={};
data[$(this).attr("name")]=$(this).val();
var id=$(this).closest("tr").data('key');
$.ajax({
method:'post',
url:'/controller/update-status?id='+id,
data:data,
success:function(data){
if(!data.success){
alert(data.message);
}else{
alert("Status updated.");
}
},
error:function(jqXHR, textStatus, errorThrown ){
alert(errorThrown);
}
});
});
});
JS;
$this->registerJs($js, yii\web\View::POS_END);
Then inside your GridView column for status change the dropdown to the following
return Html::dropDownList(Html::getInputName($model, 'active'), $model->active, [10 => 'Active', 20 => 'Deactive'], ['class' => 'switch-status']);
And the go to your controller and add the action code for updating the status
Note: Change the Model in the first line $model = Model::findOne($id); name with the respective model you are using.
public function actionUpdateStatus($id) {
$model = Affiliate::findOne($id);
$app = Yii::$app;
$request = $app->request;
if($request->IsAjax && $request->isPost) {
Yii::$app->response->format = Response::FORMAT_JSON;
if($model->load($request->post()) && $model->save()) {
return ['success' => true];
} else {
return [
'success' => false,
'message' => implode('<br />', ArrayHelper::getColumn($model->errors, '0'))
];
}
}
}
Use content property to render HTML elements. For example:
[
'attribute' => 'status',
'content' => function ($model) {
return Html::dropDownList('status', $model->status, ['10' => 'Active', '20' => 'Deactive']);
},
],

How to display info of selected items?

I am new in Yii framework, so I don't have much idea in it.
My question is, I want to get details of the company which is selected in a search box.
Code in my frontend/companies.php
<?= Html::SubmitButton( 'Get info', [ 'class' => 'btn btn-success' , 'id' =>'getinfo']) ?>
Here's my select2 widget code:-
$typeahead = Select2::widget([
'id' => 'front_companies_select',
'name' => 'state_10',
'data' => $companyNameList,
'options' => [
'placeholder' => 'Select ...',
'sigle' => true
],
]);
My js code:-
$("#getinfo").click(function(){
var obj = $("#front_companies_select option:selected").val();
console.log(obj);
});
If you want to get only company name you can try this.
$("#getinfo").click(function(){
var company_id = $("#front_companies_select option:selected").val();
console.log(company_id);
var companyName = $("#front_companies_select option:selected").text();
console.log(companyName); //here you can get company name
});
Or If you want to get whole company details then you have to call ajax like this.
$("#getinfo").click(function(){
var company_id = $("#front_companies_select option:selected").val();
$.ajax({
type: "POST",
url:"YOUR_URL/YOUR_FUNCTION_TO_GET_COMPANY_DETAILS",
data: {company_id:company_id},
dataType:'json',
async: false,
success: function (data)
{
console.log(data); //here you can get all the company details in object
}
});
});

how to pass a variable from javascript to yii2 function

I have a dropdown list of company names. When I select companies from it and click on 'get info' button I should get rows with selected company id.
View
$typeahead = Select2::widget([
'id' => 'front_companies_select',
'name' => 'state_10',
'data' => $companyNameList,
'options' => [
'placeholder' => 'Select ...',
'multiple' => true
],
]);
<?= Html::SubmitButton( 'Get info', [ 'class' => 'btn btn-success' , 'id' =>'getinfo']) ?>
Javascript file
$("#getinfo").click(function(){
var id = $("#front_companies_select option:selected").val();
console.log(id); //want to pass this id in controller as ap parameter actionInfo($id)
});
Controller
public function actionVerify($id) // want to get id here
{
$model = $this->findModel($id);
$connection = Yii::$app->db;
$model = $connection->createCommand("SELECT * FROM companies where id=$id");
$users = $model->queryOne();
return $this->redirect(['companies/index']); //want to show rows in this gridview
}
Can any one fix it? I am stuck with it..
Asuming that you're in a controller without any URL params you can do something like this:
$("#getinfo").click(function(){
var id = $("#front_companies_select option:selected").val();
window.location.href = 'verify?id=' + id;
});
Otherwise you have to build the URL and passing it to window.location

fetch data from url with $.get() give me 404- url manager

i have this function in index.php view file.(see it below)
as you see after click button it get data with get method
if my url be http://example.com/admin/site-developer/index
after click button in console i get error
GET http://example.com/admin/site-developer/site-developer/get-note?developer_id=7 404 (Not Found)
but with url without index at end it work correctly
http://example.com/admin/site-developer
if change $.(get) url to
$.get("get-note",{developer_id: Id},function(data) {}
after click http://example.com/admin/site-developer
give me
GET http://example.com/admin/get-note?developer_id=7 404 (Not Found)
error but if i add index to end of url it works corrctly
this is complete function code:
$('#noteBtn').on('click',function(e) {
$.get("site-developer/get-note",{developer_id: Id},function(data) {
var data = JSON.parse(data);
var elm = "";
$.each( data, function( i, val ) {
elm = elm+'<div id="id-'+i+'"><div>'+val.note+'</div><div>'+val.created_at+'</div></div>';
});
$("#developer_note").html(elm);
})
;})
i think maybe its url manager problem??
here is my url manager config
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
'/'=>'site/index',
'login' => 'site/login',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
],
],
action getnote
public function actionGetNote($developer_id)
{
$model = DevelopersNote::findAll(['developer_id' => $developer_id]);
echo Json::encode($model);
}
Seems that you url is not build properly
Assuming you javascript code is inside a php file
try use UrlHelper
<?php
use yii\helpers\Url;
?>
$('#noteBtn').on('click',function(e) {
<?php echo 'var myUrl = "' . Url::to(['site-developer/get-note']) . '";
' ; ?>
$.get(myUrl ,{developer_id: Id},function(data) {
var data = JSON.parse(data);
var elm = "";
$.each( data, function( i, val ) {
elm = elm+'<div id="id-'+i+'"><div>'+val.note+'</div><div>'+val.created_at+'</div></div>';
});
$("#developer_note").html(elm);
})
;})
for check your problem with the code above try use this way
$('#noteBtn').on('click',function(e) {
var myUrl "http://example.com/admin/site-developer/get-note";
$.get(myUrl ,{developer_id: Id},function(data) {
var data = JSON.parse(data);
var elm = "";
$.each( data, function( i, val ) {
elm = elm+'<div id="id-'+i+'"><div>'+val.note+'</div><div>'+val.created_at+'</div></div>';
});
$("#developer_note").html(elm);
})
;})