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.
Related
I have a big problem with Cakephp 3.4
This is my controller:
//$id=$_POST["idString"]; ---- how can i do this in cakephp?
$id = $this->request->data('idString');
$posts = $this->Posts->find('all', array(
'conditions' => array(
'Animal_id' => $id
)
));
$this->set(compact('posts'));
And this is my script
$(document).ready(function() {
$(".dropdown-item").click(function(){
idString = $(this).attr("value");
alert(idString);
$.ajax({
type: "POST",
url: "<?php echo \Cake\Routing\Router::url(array('controller' => 'MyControllerName', 'action' => 'index')); ?>",
data: "idString="+idString,
success: function(result){
$("#show").html(result);
}
});
});
});
And this is my index :
<?php foreach($posts as $post):?>
<li><?= $post->title, $post->text; ?></li>
<?php endforeach ?>
<div id="show">
<--show id-->
</div>
And error that I have is
Deprecated (16384): Controller::$layout is deprecated. Use $this->viewBuilder()->setLayout() instead. [CORE\src\Controller\Controller.php, line 383]
And it returns me one div 2 time.
Cakephp 3.4 have in src/Template/Layout/ajax.ctp look there if don't have $this->fetch('content'); if yes then delete it or comment.
I 've a search filter in a view A, users can choose some values for the research. I want to display the results of the research, without reloading the page, at the bottom of the view in a table.
In a view A, I'va the search filter. In the same view, I'm doing this ajax call :
var tab = new Array();
function updateResult(){
$.ajax({
type:"POST",
url:"<?php echo Router::url(array('controller'=>'AController','action'=>'index'));?>",
data : {dataFVariables: $("select[name='filtreVariable\\[\\]']").map(function(){return $(this).val();}).get()},
dataType: 'json',
async:false,
success: function(tab){
..........
// Creating a table with the data in 'tab'
..........
},
error: function (tab) {
alert('error');
}
});
}
In the action 'index' of my controller, I retrieve a lot of data from the database. With this data, I create a table but the pagination doesn't work on this table..
Indeed, in my controller, I do :
.............
$this->paginate($query);
// the data send to the ajax call
echo json_encode($query);
The results are in the first page of my table but there is nothing in the others pages.
Thank you in advance !!
First Add in your controller :
$condition=array();
$this->paginate = array('conditions' => $condition, 'limit'=>'2');
$users = $this->paginate('YourModelName');
$this->set(compact('users'));
Then add this code in your corresponding ctp file :
<tr><td><?php echo $this->Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?></td>
<td><?php echo $this->Paginator->numbers(array( 'class' => 'numbers' ));?></td>
<td><?php echo $this->Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?></td>
<td colspan="4"></td></tr>
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.
I'm having troubles getting content displayed on page load using ajax. The ajax is calling the right action in the respective controller. The first part of the action code where i update the database is working fine. But the part where i'm calling renderPartial is not working.
**EDIT***
Ok here is the controller action ::
public function actionUpdateProductData() {
Yii::import('application.components.DataScraper.*');
require_once('GetProductData.php');
$productRealTime = RealTime::model()->findAll();
if (count($productRealTime) === 0) {
$symbolData = new GetProductData();
$symbolData->getAmazonProductData();
} else {
echo CJSON::encode( array(
'status' => 'OK',
'div' => $this->renderPartial('_productDataGrid', array(
'model' => $productRealTime),
true, true ),
));
}
}
The if part is working fine. But the else portion is not working.
Here is the view index.php::
<?php
/*
* Include the ajax Stock update script
*
*/
$baseUrl = Yii::app()->baseUrl;
$cs = Yii::app()->getClientScript();
$cs->registerScriptFile($baseUrl . '/js/ajaxProductDataUpdate.js');
?>
<div>
<hr>
<ul class="breadcrumb">
<li>
Home <span class="divider">/</span>
</li>
<li>
Product Info
</li>
</ul>
<hr>
</div>
<div class="span-10">
<div id="section2">
</div>
</div>
Here is the partial view file _productDataGrid.php
<?php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'real-time-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'id',
'name',
'category',
'price'
'rating'
array(
'class' => 'bootstrap.widgets.TbButtonColumn',
),
),
));
?>
And here is the jQuery file which is making the ajax request
var productParameters = {
ajaxUpdate: function() {
$.ajax({
url: "/ProductAnalysis/index.php/realTime/updateProductData",
type: "GET",
dataType:"json",
error: function(xhr, tStatus, e) {
if (!xhr) {
alert(" We have an error ");
alert(tStatus + " " + e.message);
} else {
alert("else: " + e.message); // the great unknown
}
},
success: function(data) {
$.fn.yiiGridView.update('real-time-grid', {
data: $(this).serialize()
});
}
});
}
};
$(document).ready(function() {
productParameters.ajaxUpdate();
});
Upon loading the page /realTime/index.php i'm getting an error which says
else:
undefined
Obviously the ajax call is failing, but i don't know how will i fix it. Also in Firebug, the echo date() function in the controller is working, but the Gridview is not working.
Please provide some help on how to solve this. Let me know where i'm doing wrong. I can't seem to make any headway around this.
Thanks in advance,
Maxx
Your actionUpdateStockData() is echoing the date before the actual JSON content is encoded. As a result you're not transmitting correct JSON, and XHR will fail.
Remove the echo date ... line and you should be fine. And as you're just at it - you should add some response for the case where count(RealTime::model()->findAll()) === 0.
Well it seems that the gridview widget won't work with findall(). So i changed the dataprovider to simple model and it works now.
Here is the working code ::
public function actionUpdateStockData() {
Yii::import('application.components.DataScraper.*');
require_once('GetStockData.php');
$productRealTime = new RealTime();
if (count($productRealTime->model()->findAll()) === 0) {
$symbolData = new GetproductData();
$symbolData->getAmazonProductData();
} else {
echo CJSON::encode( array(
'status' => 'success',
'div' => $this->renderPartial('_productDataGrid', array(
'model' => $productRealTime),
true, true ),
));
}
}
I am new in code Igniter so I don't know how to do it. So what my problem is I have a form which I am submitting from ajax. So what I want to do is as the form submit successfully then a notification or a css div class will appear above the form and then disappear it.I don't know how can I perform this as after accepting the parameter from view page to controller I don't know how to send the parameter controller to view or how can I perform all this .Here is my controller:
class categoryController extends CI_Controller {
function index(){
$data['main_content'] = 'categoryView';
$this->load->view('dashboardTemplate/template',$data);
}
function addCategory(){
//getting parameters from view
$data = array(
'cat_name' => $this->input->post('cat_name')
);
$is_ajax = $this->input->post('ajax'); //or use this line
$this->load->model('categoryModel');
$query = $this->categoryModel->addCategories($data);
if ($query && $is_ajax){
$page['main_content'] = 'categoryView';
$page['v'] = '1'; // i dont know how this variable is not accessing in view page by echo $v
$this->load->view('dashboardTemplate/template',$page);
}
else
{
//
}
}}
Here is my view:
<?php
$attributes = array('id' => 'form-horizontal',
'class' => 'form-horizontal'
);
echo form_open('categoryController/addCategory', $attributes);
$cat_name = array(
'name' => 'cat_name',
'id' => 'cat_name',
'class' => 'cat_name');
$button = array(
'name' => 'button',
'id' => 'btn',
'class' => 'btn btn-primary',
'value' => 'submit',
'type' => 'submit',
'content' => 'Submit'
);
?>
<h3>Add Category</h3>
//here i want to do this .. that if form is submitted succesfully then this class will load only and the whole page remain the same
<div> class="alert-heading">sucess or not success!<div>
</div>
<div class="control-group">
<label for="basicround" class="control-label">Category Name:</label>
<div class="controls">
<?php echo form_input($cat_name); ?>
<div class="form-actions">
<?php echo form_button($button); ?></div>
<script type="text/javascript">
$('#btn').click(function() {
var cat_name = $('#cat_name').val();
if (!cat_name || cat_name == 'Name') {
alert('Please enter Category Name');
return false;
}
var form_data = {
cat_name: $('#cat_name').val(),
ajax: '1'
};
$.ajax({
url: "<?php echo site_url('categoryController/addCategory'); ?>",
type: 'POST',
data: form_data,
success: function(msg) {
$('#message').html(msg);
}
});
return false;
});
</script>
Since it is an Ajax submit, So you need to pass JSON array from controller to view
echo json_encode($page);
Controller
$page['main_content'] = 'categoryView';
$page['v'] = '1'; // i dont know how this variable is not accessing in view page by echo $v
echo json_encode($page);
For the above step, you need to define
data-type:JSON
in your ajax function.
Ajax Function
$.ajax({
url: "<?php echo site_url('categoryController/addCategory'); ?>",
type: 'POST',
data: form_data,
data-type: "json",
success: function(msg) {
// Here you can access the values from controller like msg.v
$('#message').html(msg);
}
});
Based on the response, you can show the success message using
$(".alert-heading").show();