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();
Related
Solution
Since the php is not going to be re-executed someone told me to use a return value from the controller as a parameter of the "success" function into ajax's request.
**CONTROLLER**
if(Yii::$app->request->isAjax){
$query = new \yii\db\Query();
$rows = $query->select([])
->from('task')
->where('date(start) <= date(\'' . $this->request->getBodyParam('start_date') . '\')')
->all();
$items = "";
foreach (ArrayHelper::map($rows,'id','name') as $key => $value)
$items .= '<option value="'. $key .'">'. $value .'</option>\n';
//<option value="16">test</option> example output
echo $items;
}
VIEW
$this->registerJs("$('#task-start').on('change',function(){
$(\".btn, .btn-success\").prop(\"disabled\",true);
var date = $(this).val();
$.ajax({
url: \"".Yii::$app->request->baseUrl."/task/create\",
data: {start_date: date},
type: \"post\",
success: function(dependency_options){
//dependency_options contains what's returned with 'echo' from the controller
$('#task-dependencies').find('option:not(:first)').remove();
$('#task-dependencies').append(dependency_options);
$(\".btn, .btn-success\").prop(\"disabled\",false);
},
error: function () {
console.log('ERROR')
$(\".btn, .btn-success\").prop(\"disabled\",false);
}
});
});",View::POS_READY);
Hoping this might help someone.
My problem
I have a DropDownList with no elements and I want to update the list with elements coming from a Query whenever the user changes the datepicker without refreshing the page.
An example of something similar to this would be those forms in which you type your region and it changes the dropdownlist based on what you choose on the field before.
Maybe I'm using a wrong approach to this cause I'm still new to the MVC model and the Yii2 framework so any idea on how to change it's well appreciated.
What I've tried
With this code below as is I had issues cause after the form was created the first time I could not change it later, I've tried to change the html, as you can see from the script in the success ajax function of the View but the script was executed only the first time the view was loaded.
Controller calling the render
public function actionCreate()
{
$model = new Task();
if(Yii::$app->request->isAjax){
$query = new \yii\db\Query();
$rows = $query->select([])
->from('task')
->where('date(start) <= date(\'' . $this->request->getBodyParam('start_date') . '\')')
->all();
$items = ArrayHelper::map($rows,'id','name');
$model->setItems($items);
return $this->renderPartial('_form',[
'partial' => true,
'model' => $model
]);
}
else if ($this->request->isPost) {
..unnecessary code..
return $this->render('create', [
'model' => $model,
]);
}
The view "create" basically renders the view _form (autogenerated by Gii)
View _form
<?php
//Here it takes the items in the model
//(which will contain the new items to append after ajax call)
$objects = json_encode($model->getItems() ?? []);
var_dump($model->getItems() ?? []);
//Here whenever the datepicker is change will fire ajax request
$this->registerJs("$('#task-start').on('change',function(){
var date = $(this).val();
var items = ". json_encode($model->getItems() ?? []) .";
alert(items);
$.ajax({
url: \"".Yii::$app->request->baseUrl."/task/create\",
data: {start_date: date},
type: \"post\",
success: function(){
//$('#task-dependencies').find('option:not(:first)').remove();
$.each(items, function(key, value) {
$('#task-dependencies')
.append($('<option>', { value : key })
.text(value));
});
},
error: function () {
console.log('ERROR')
}
});
});",View::POS_READY);
?>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'start')->widget(\kartik\date\DatePicker::className(), [
...datepicker that triggers onChange...
]) ?>
//The dropdownlist that should dynamically change
<?= $form->field($model, 'dependencies')->dropDownList(
$model->getItems(),
['prompt' => 'Seleziona una o piĆ¹ dipendenze', 'multiple' => true, 'selected' => 'selected'] // options
);
?>
<?php ActiveForm::end(); ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery#3.6.0/dist/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css">
You can use Pjax in, yii2:
Controller:
public function actionCreate() {
$model = new Task();
if( Yii::$app->request->post() && Yii::$app->request->isPjax ) {
$query = new \yii\db\Query();
$rows = $query->select([])
->from('task')
->where('date(start) <= date(\'' . $this->request->getBodyParam('start_date') . '\')')
->all();
$items = ArrayHelper::map($rows,'id','name');
$model->setItems($items);
// Alert widget renders a message from session flash.
// Yii::$app->session->setFlash('info', "Ok....");
return $this->renderAjax('_form',[ // Or renderPartial
'partial' => true,
'model' => $model
]);
}
// else if ($this->request->isPost) {
// ..unnecessary code..
return $this->render('create', [
'model' => $model,
]);
}
}
view
// submitEvent: The jQuery event that will trigger form handler. Defaults to "submit".
<?php Pjax::begin(['submitEvent' => 'change']); ?>
<?php $form = ActiveForm::begin([
'options' => ['data-pjax' => ''],
]);
// if(hasFlash ....){ // If used ...
// Yii::$app->session->getFlash('info')
// }
?>
<?= $form->field($model, 'start')->widget......
<?= $form->field($model, 'dependencies')->dropDownList(
$model->getItems(),
// ......
<?php ActiveForm::end(); ?>
<?php Pjax::end(); ?>
Tip: The above codes will meet your goal. But you can use the following code to change more and respond to Pjax events.
jQuery or JavaScript...
$(document).on('pjax:send', function() {
// code ... Example: $('#loading').css({"visibility":"visible"}); //show()
});
$(document).on('pjax:complete', function() {
// code ... // hide()
});
// Or use if Pjax::$submitEvent = 'submit'
// $(document).on('change', '#id', function(event) { $(this).submit(); });
If you still have problems, check the date format method in SQL and ....
Good luck.
So basically I have a controller that handles files (images & videos) and on the "view" view I have a button that's called "view content". That button is using the controller actionContent($id) and I want it when pressed to run the AJAX call to the action & render in-page in a div the image that's located in the model with id == $id. How can I handle the AJAX request and return the image displayed in the div?
public function actionContent($id)
{
$model = $this->findModel($id);
switch (substr($model->mime, 0, strpos($model->mime, '/'))) {
case 'image' :
return $this->renderAjax('_image', [
'img' => $model->getFullPath(),
]);
break;
default:
break;
}
}
And the view:
<span class="pull-right">
<?= Html::a('View Content', ['content', 'id' => $model->id], [
'class' => 'btn btn-default',
'id' => 'content'
]); ?>
</span>
With the script I already tried:
$(document).ready(function () {
$('#content').click(function () {
$(this).preventDefault();
$.ajax({
type: "GET",
url: $(this).href,
contentType: "<?= $model->mime?>",
success: function (response) {
('.show-content').html('<img src="data:image/png;base64,' + response + '" />');
}
})
})
})
on Yii2 Advanced My form insert twice in table, if I click twice my submit button my form insert data to my table twice it's like I clicked two time on my submit button; I'm using ajax for submit my form; my form in view is
<script type="text/javascript">
$(document).ready(function (e) {
$("#upload-gallery").on('submit',(function(e) {
$form = $(this);
e.preventDefault();
$.ajax({
url: $form.attr('action'),
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false,
success: function(data)
{
document.getElementById("upload-gallery").reset();
$.pjax.reload({container: '#some_pjax_id', async: false});
},
error: function(){}
});
}));
});
</script>
<div class="post-gallery-form">
<?php $form = ActiveForm::begin(['id' => 'upload-gallery', 'options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model_PstGlr, 'PGalleryFile[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<?= $form->field($model_PstGlr, 'post_text')->textarea(['rows' => 2]) ?>
<?= $form->field($model_PstGlr, 'permission_id')->dropdownList($model_Permission->PermissionOn()) ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
and my controller is
public function actionView($chn)
{
$model_Permission = new Permission;
$model_PstGlr = new PostGallery; $acc_PstGlr = new AxPostGallery;
if ($model_PstGlr->load(Yii::$app->request->post()) )
{
$acc_PstGlr->CreateGallery($model_PstGlr, $chn);
}
return $this->render('view', [
'model' => $this->findModel($chn),
'model_Permission' => $model_Permission,
'model_PstGlr' => $model_PstGlr,
]);
}
The upload gallery function is to upload images on my contents
--
public function CreateGallery ($MPGALLERY, $CHNID)
{
$PSTID = Yii::$app->params['PSTID'];
$USRID = Yii::$app->user->id;
$MPGALLERY->post_id = $PSTID;
$MPGALLERY->user_id = $USRID;
$MPGALLERY->channel_id = $CHNID;
$ly_lgIMGFolder = 'upload/gal/'. $CHNID . '/' . $PSTID . '/' .date('YzHis');
$GLRID = Yii::$app->params['GLRID'];
$MPGALLERY->PGalleryFile = UploadedFile::getInstances($MPGALLERY, 'PGalleryFile');
if( $MPGALLERY->save() )
{
mkdir($ly_lgIMGFolder, 0777, true);
foreach ($MPGALLERY->PGalleryFile as $GImage)
{
$MGALLERY = new Gallery;
$MGALLERY->post_id = $PSTID;
$GImage->saveAs($ly_lgIMGFolder ."/". $GLRID . '.' . $GImage->extension);
$MGALLERY->gallery_lgimage = $ly_lgIMGFolder ."/". $GLRID . '.' . $GImage->extension;
$MGALLERY->save(false);
}
}
}
Appatently, there are a few changes that you may need to make in your code.
For example, create the following function in your controller, and remove the code from your view.
public function actionSave(){
//This part is removed from the actionView, so that the request only saves and does nothing else;
//You can return it back if you test and see that it works
$model_PstGlr = new PostGallery; $acc_PstGlr = new AxPostGallery;
if ($model_PstGlr->load(Yii::$app->request->post()) )
{
$acc_PstGlr->CreateGallery($model_PstGlr, $chn);
}
}
Then on the view, modify your form initialization as follows
The reason for adding the forwad slash is to prevent apache from sending the request to a new URL that ends with the '/';
<?php $form = ActiveForm::begin(['action'=> 'id' => 'upload-gallery', 'options' => ['enctype' => 'multipart/form-data']]) ?>
I hope this one now helps;
I don't want to submit a form but i want to get the value of a input field and send it to controller via ajax to be save in database.
I have this below JS code to help me get the content of the input field and send to the server side after 3 second of user input
<?php
$script = <<< JS
$(document).ready(function(){
//setup before functions
var typingTimer;
var doneTypingInterval = 3000;
var \$TitleInput = $('#product-product_title');
//on keyup, start the countdown
\$TitleInput.on('keyup input change paste',function(){
clearTimeout(typingTimer);
if (\$TitleInput.val()) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
//user is "finished typing," do something
function doneTyping () {
data = \$TitleInput.val();
$.ajax({
url: '/trobay/draft/create',
type: 'POST',
data: data,
success: function (data) {
alert(data)
},
error: function(jqXHR, errMsg) {
// handle error
alert(errMsg);
}
});
}
});
JS;
$this->registerJs($script);
?>
in my controller i have this
public function actionCreate()
{
$model = new Draft();
if ($model->load(Yii::$app->request->post())) {
$model->created_at = \time();
if($model->save()){
echo draftId;
}else{
echo '0';
}
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
I want to echo back the draftid if the title was draft was save successfully
how to make this work plase any help on this
below is my view
<?php $form = ActiveForm::begin([
'id' => $model->formName(),
'enableClientValidation' => true,
'fieldConfig' => ['template' => '{label}{input}{hint}']
]); ?>
<div class="row">
<div class="col-md-12">
<?= $form->field($model, 'product_title')->textInput([
'class' => 'title-input',
'placeholder' => 'Give us a title for your items(include size,brand,color,material. e.t.c)',
])->label(false) ?>
</div>
<div class="col-md-12 text-muted">E.g Men's blue addidas glide running shoes size 11 </div>
</div>
<?= $form->field($model, 'user_id')->textInput() ?>
<?= $form->field($model, 'product_name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'product_description')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'category_id')->textInput() ?>
i have this in my view but i would like to only save the value of the first input field after 3 second that user entered there value
Try this JS, but change $('#form') on your ID form
$(document).ready(function(){
//setup before functions
var typingTimer;
var doneTypingInterval = 3000;
var $form = $('#form');
//on keyup, start the countdown
$form.find('input[type="text"]').on('keyup input change paste',function(){
clearTimeout(typingTimer);
if ($(this).val()) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
//user is "finished typing," do something
function doneTyping () {
$.ajax({
url: '/trobay/draft/create',
type: 'POST',
data: $form.serialize(),
success: function (data) {
alert(data)
},
error: function(jqXHR, errMsg) {
// handle error
alert(errMsg);
}
});
}
});
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 ),
));
}
}