Dynamic drop down box change depend on database in CakePHP - php

I am new to CakePHP, the problem is I need to create the dynamic values to drop down box the values which are come from mysql.the following is code which i used in controller:
$wires = $this->wire->find('all',array('conditions'=>array('wire_id'=>$wire_id)));
foreach($wires as $key=>$gs) {
$options[$gs['wires']['type_of_wire']] = $gs['wires']['type_of_wire'];
$options1[$gs['wires']['length']] = $gs['wires']['length'];
$options2[$gs['wires']['color']] = $gs['wires']['color'];
}
In ctp
echo $this->Form->input('wire', array('type' => 'select', 'class'=>'dropdn', 'options'=> $options, 'selected'=> $options, 'div'=>false, 'label'=>false,'id'=>'metal'));
echo $this->Form->input('wire', array('type' => 'select', 'class'=>'dropdns', 'options'=> $options1, 'selected'=> $options, 'div'=>false, 'label'=>false,'id'=>'metal'));
echo $this->Form->input('wire', array('type' => 'select', 'class'=>'dropdned', 'options'=> $options1, 'selected'=> $options, 'div'=>false, 'label'=>false,'id'=>'metal'));
Here I create three drop down boxes, but the problem is if I changed the drop down box value type of wire means its dynamically change its correct length and color for rest of the drop down box.
I also tried it ob onchange but I can't.

Use AJAX calling for dynamic drop down list. something like this in your layout/ where you have jquery defined..
$('#metal').change(function() {
var wire= $(this).val();
$.ajax({
type: "POST",
url: "HERE GIVE URL TO YOUR ACTION WHERE YOU FETCH DATA FROM TABLE",
data: { wire: wire , submit: "submit" },
success: function(result){
$("#metal").html(result);
}
});
});
})
Then in your controller, action for ajax call--
public function get_wires()
{
$this->autoRender=false;
$value=$_POST['wire'];
$wire_length = $this->wire->find('list',array('fields' => array('wire_length'),'conditions' => array('wire'=>$value)));
foreach($wire_length as $q)
{
$data[]="<option>".$q."</option>";
}
print_r($data);
}
Then post this value you get into your form in view.ctp page.

Related

Dependent (Chained) Dropdown in CakePHP 3.8.0 using AJAX

I'm new to CakePHP and ajax. I'm trying to figure out how to utilize AJAX to make dependent (chained) dropdown in CakePHP 3.8.0.
I'm making a few tables for example to learn how to build the chained dropdown menu. I have three tables models, chapters, userinputs. In the Userinputs table, I would to chapter to load based on model. Right now all models and all chapters are shown. This is how they're all connected.
how all three tables are connected
I've been looking at some examples online and tried to apply them into my code but nothing seems to be working. This is my add.ctp of my Userinputs table.
<div class="userinputs form large-9 medium-8 columns content">
<?= $this->Form->create($userinput, ['type' => 'file', 'class' => 'ajax_page']) ?>
<fieldset>
<legend><?= __('Add Userinput') ?><div class="ajax_loading_image"></legend>
<?php
echo $this->Form->control('model_id', ['options' => $models, 'empty' => true, 'id'=>'models']);
echo $this->Form->control('chapter_id', ['options' => $chapters, 'empty' => true, 'id'=>'chapters']);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
I also added this script at the end of add.ctp of Userinputs table
<script>
$("#models").on('change',function() {
var id = $(this).val();
$("#chapters").find('option').remove();
if (id) {
var dataString = 'id='+ id;
$.ajax({
dataType:'json',
type: "POST",
url: '<?php echo Router::url(array("controller" => "Userinputs", "action" => "getChapters")); ?>' ,
data: dataString,
cache: false,
success: function(html) {
//$("#loding1").hide();
$.each(html, function(key, value) {
//alert(key);
//alert(value);
//$('<option>').val('').text('select');
$('<option>').val(key).text(value).appendTo($("#chapters"));
});
}
});
}
});
</script>
In the controller of my Userinputs, I added a public function
public function getChapters()
{
$id = $this->request->data('id');
$chapters = $this->Chapters->find('all', [ 'conditions' => [ 'model_id' => $id ] ]);
echo json_encode($chapters);
}
Please take a look at my codes and please assist me on how to get this working properly. Any help is much appreciated.

Kartik select2 widget not working in Ajax request in Yii2?

I am using kartik select2 widget in my yii2 basic app. now i have to display province names in select2 widget on ajax call. It is working fine if i put it directly in form. however not working with ajax call.
Here are my form fields:
<?= $form->field($model, 'role')->dropDownList(
ArrayHelper::map(SubAdminRoles::find()->all(), 'id', 'role_name'),
[
'prompt' => 'Select Role',
'onchange' => '
if($(this).val() != 3) {
$( "#user_area" ).html("showLoading");
$.post( "fetch-area-list?id='.'"+$(this).val(),
function(data) {
$( "#user_area" ).html(data);
})
}'
]
) ?>
<div id="user_area">
</div>
And here is my action code
public function actionFetchAreaList($id) {
// $this->layout = 'none';
$data = [];
if($id == 1) {
$provinceList = \app\modules\adminpanel\models\ProvinceMaster::findAll(['status' => 1, 'is_deleted' => 0]);
foreach($provinceList as $obj) {
$data[$obj['id']] = $obj['province_name'];
}
//print_r($data);
//exit;
} else if($id == 2) {
$subDistrictList = \app\modules\adminpanel\models\SubDistrictMaster::findAll(['status' => 1, 'is_deleted' => 0]);
foreach($subDistrictList as $obj) {
$data[$obj['id']] = $obj['sub_district_name'];
}
}
echo '<label class="control-label">Select Province</label>';
echo Select2::widget([
'name' => 'state_2',
'value' => '1',
'data' => $data,
'options' => ['multiple' => true, 'placeholder' => 'Select Province']
]);
exit;
}
now when i try to get it through ajax i comes with display:none property so i am not able to show my select2 box.
I Also tried changing display:none to display:block in select2 class. In that case i got the select box, but is simple html multiple select box not select2 widget.
How to get it from controller using ajax call?
Thanks in advance.
It is bad practice to render html inside action.
In your case widget requires related JS for initialization. But it will not include in your response.
Move all your html to view area-list and render using following code:
public function actionFetchAreaList($id) {
$this->layout = false;
// ... preparing data
return $this->renderAjax('area-list', [
// ... some view data
]);
}
Method renderAjax renders a named view and injects all registered JS/CSS scripts and files. It is usually used in response to AJAX Web requests.
I also have similar project like this.
I have 2 combobox (using select2). When select a district from the first combobox. It will call an ajax request to get province list and fill into the second combobox.
Here is my solution:
Using Select2 widget as normally in form
Using javascript to call ajax request and change data of the second combobox.
My controller response data in json format.
$('#district-selector').on('change', function() {
var districtId = $(this).val();
var url = $(this).attr('tb_href');
$('#province-selector').html('');
$.get(
url,
{
city_id: districtId
},
function(response) {
if (response.error == 0 && response.data.length) {
$('#province-selector').append(new Option('', ''));
$.each(response.data, function() {
console.log(this.id + '--' + this.title);
var newOption = new Option(this.title, this.id);
$('#province-selector').append(newOption);
});
}
$('#province-selector').trigger('change');
}
);
});
Demo: demo link

Yii2 CKeditor not initialized when requested via ajax

I am trying to add a from with a CKeditor widget imbedded via an AJAX request. The request itself works fine and returns the general partial view as I want it. Except for the Ckeditor widget, a normal textbox is return instead.
When the item is added to the group and the page is reloaded, the same partialView is being rendered (in a foreach with all group-items) and this time the CKeditor is nicely in place.
Posted my controller, initialization of the CKeditor and Scipt with AJAX request below. (The CKeditor is inlcuded in the _ContentItemHtml view)
I have taken a look at this, but I cannot call any CKeditor functions from JS since it is loaded as a widget.
Controller Action
public function actionCreateHtml($contentitemgroupid)
{
$model = new ContentItemHtml();
if (isset(Yii::$app->request->post()['ContentItemHtml'])) {
$item = Yii::$app->request->post()['ContentItemHtml'];
$model->contentitemgroupid = $contentitemgroupid;
$model->title = $item['title'];
$model->body = $item['body'];
$model->save();
// return $this->redirect(['edit', 'id' => $model->contentitemgroupid]);
}
else
return $this->renderPartial('_ContentItemHtml', ['model' => $model]);
}
Active form in view:
echo $form->field($model, 'body')->widget(CKEditor::className(), [
'preset' => 'custom',
'clientOptions' => [
'height' => 200,
'toolbarGroups' => [
['name' => 'basicstyles', 'groups' => ['basicstyles', 'cleanup']],
['name' => 'paragraph', 'groups' => ['templates', 'list']],
['name' => 'mode']]
]])->label(false);
Script.js
$('#addNewContentItem').on('click', function (e) {
e.preventDefault();
var url = 'create-' + $('#itemSelector').val().toLowerCase() + '?contentitemgroupid=' + $('#itemSelector').attr('contentitemgroupid');
$.ajax({
type: 'POST',
url: url,
cache: false,
success: function(res) {
$('.contentItemsManager').append('<div class="ContentItemContainer row">' + res + '</div>');
AddSaveEventListener();
AddSaveMediafileEventListener();
AddRemoveEventListener();
}
});
});
Use renderAjax instead of renderPartial. From the docs:
[renderAjax] Renders a view in response to an AJAX request.
This method is similar to renderPartial() except that it will inject into the rendering result with JS/CSS scripts and files which are registered with the view. For this reason, you should use this method instead of renderPartial() to render a view to respond to an AJAX request.

How to load model data to Select2 dropdown which uses Ajax filtering in Yii

I use the following select2 Yii widget in my view to populate a drop-down list. Since the data necessary for the preparation of the select list consists of more than 2K records I use select2 with minimumInputLength parameter and an ajax query to generate partial result of the list based on user input. If I create a new record I have no problem at all. It populates everything fine and I can save data to my database. However I don't know how to load saved data back to this drop-down during my update action. I read somewhere that initselection intended for this purpose but I couldn't figure out how to use it.
Can someone help me out on this?
My view:
$this->widget('ext.select2.ESelect2', array(
'selector' => '#EtelOsszerendeles_osszetevo_id',
'options' => array(
'allowClear'=>true,
'placeholder'=>'Kérem válasszon összetevőt!',
'minimumInputLength' => 3,
'ajax' => array(
'url' => Yii::app()->createUrl('etelOsszerendeles/filterOsszetevo'),
'dataType' => 'json',
'quietMillis'=> 100,
'data' => 'js: function(text,page) {
return {
q: text,
page_limit: 10,
page: page,
};
}',
'results'=>'js:function(data,page) { var more = (page * 10) < data.total; return {results: data, more:more }; }',
),
),
));?>
My controller's action filter:
public function actionFilterOsszetevo()
{
$list = EtelOsszetevo::model()->findAll('nev like :osszetevo_neve',array(':osszetevo_neve'=>"%".$_GET['q']."%"));
$result = array();
foreach ($list as $item){
$result[] = array(
'id'=>$item->id,
'text'=>$item->nev,
);
}
echo CJSON::encode($result);
}
I use initSelection to load existing record for update in this way (I replaced some of your view code with ... to focus in main changes). Tested with Yii 1.1.14. Essentially, I use two different ajax calls:
View:
<?php
$this->widget('ext.select2.ESelect2', array(
'selector' => '#EtelOsszerendeles_osszetevo_id',
'options' => array(
...
...
'ajax' => array(
'url' => Yii::app()->createUrl('client/searchByQuery'),
...
...
'data' => 'js: function(text,page) {
return {
q: text,
...
};
}',
...
),
'initSelection'=>'js:function(element,callback) {
var id=$(element).val(); // read #selector value
if ( id !== "" ) {
$.ajax("'.Yii::app()->createUrl('client/searchById').'", {
data: { id: id },
dataType: "json"
}).done(function(data,textStatus, jqXHR) { callback(data[0]); });
}
}',
),
));
?>
Now in your controller you should receive parameters for ajax processing: query (q), as string, when inserting; id (id) as int when updating. Parameter names must be same as ajax data parameters (in this sample insert q; in update id) when read in $_GET. Code is not refactored/optimized:
Controller:
public function actionSearchByQuery(){
$data = Client::model()->searchByQuery( (string)$_GET['q'] );
$result = array();
foreach($data as $item):
$result[] = array(
'id' => $item->id,
'text' => $item->name,
);
endforeach;
header('Content-type: application/json');
echo CJSON::encode( $result );
Yii::app()->end();
}
public function actionSearchById(){
$data = Client::model()->findByPk( (int) $_GET['id'] );
$result = array();
foreach($data as $item):
$result[] = array(
'id' => $item->id,
'text' => $item->name,
);
endforeach;
header('Content-type: application/json');
echo CJSON::encode( $result );
Yii::app()->end();
}
Model - custom query and a little of order / security / clean :)
public function searchByQuery( $query='' ) {
$criteria = new CDbCriteria;
$criteria->select = 'id, ssn, full_name';
$criteria->condition = "ssn LIKE :ssn OR full_name LIKE :full_name";
$criteria->params = array (
':ssn' => '%'. $query .'%',
':full_name' => '%'. $query .'%',
);
$criteria->limit = 10;
return $this->findAll( $criteria );
}
EDIT:
It works out of box when update is preloaded with traditional HTTP Post (synchronous, for example with Yii generated forms). For async/Ajax updates, for example with JQuery:
Event / Trigger:
$('#button').on("click", function(e) {
...
... your update logic, ajax request, read values, etc
...
$('#select2_element').select2('val', id_to_load );
});
With this, initSelection will run again in async way with new id_to_load value, reloading record by id.
In your case and for your needs, initSelection could be complete different to avoid load record from db or you can use formatResult and formatSelection custom functions (are described in Load Remote Data sample source code). Reading documentation, I understand that initSelection's callback need JSON data with id and text elements to load properly or you could try to combine both concepts (this initSelection with your custom JS event/trigger call) (not tested):
'initSelection'=>'js:function(element,callback) {
// here your code to load and build your values,
// this is very basic sample
var id='myId';
var text='myValue';
data = {
"id": id,
"text": text
}
callback(data);
}',
Or directly on Trigger call:
$('#button').on("click", function(e) {
...
... ...
$("#select2_element").select2("data", {id: "myId", text: "MyVal"});
});
Hope that helps.
I tried doing that way, but couldn't do it
the solution I came up to get my record filled and selected was:
In case of the attribute having some data(in update mode or default value), I wrote some javascript that after document ready event, would fill the select with my data (just selected it ind pushed html in it), and made it selected, and then I rest( or update) the select to show my work.

Cannot call method 'update' of undefined Cgridcview

$.fn.yiiGridView.update('sopodetail-grid'+itemcd);
this function it's not running.
It says Cannot call method 'update' of undefined in console.
I have problem when inserting data via ajax gridview not refreshing.
I render multiple grid view with foreach looping, and make each of them unique id with concatenating item_cd.
function validateDetailForm()
{
var jForm = $('#sopodetail-form');
var data = jForm.serialize();
var itemcd = $('#cmbitemcd').val();
$.ajax({
type: 'POST',
url : jForm.attr('action'),
data: data,
dataType:'html',
success:function(data)
{
$(".info").animate({opacity: 1.0}, 3000).fadeOut("slow");
$.fn.yiiGridView.update('sopodetail-grid'+itemcd);
},
error: function(data) { // if error occured
alert('Error occured.please try again');
$('#detail-content').html(data);
},
});
}
this how i can render multiple gridview i concating the id...
foreach($modelSoDet as $modelSoDetObj):
$this->widget('zii.widgets.CDetailView', array(
'data'=>$modelSoDetObj,
'attributes'=>array(
'item_cd',
'item.item_name',
'item.item_desc',
'qty',
'qty_purchased'
)
));
$modelSoPoDetail = new Sopodetail();
$modelSoPoDetail->unsetAttributes();
$modelSoPoDetail->so_cd = $modelSoDetObj->so_cd;
$modelSoPoDetail->item_cd = $modelSoDetObj->item_cd;
$gridid = 'sopodetail-grid'.$modelSoPoDetail->item_cd;
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$modelSoPoDetail->search(),
'summaryText' => '',
'id'=>$gridid,
'columns'=>array(
'type',
'po_cd',
'qty'
)
));
endforeach;
You should simply try with the right syntax :
$('sopodetail-grid'+itemcd).yiiGridView('update');
$.param.querystring is called from the yiiGridView.update and is located in the jquery.ba-bbq.js.
check your HTML source if you have the jquery.ba-bbq.js included...
If the jquery.ba-bbq.js is included then you may be recreating the jQuery object after jquery.ba-bbq.js. E.g. jQuery is loaded more than once....
Source: http://www.yiiframework.com/forum/index.php/topic/9387-cgridview-update/

Categories