I want to post data to a controller in CakePHP, but posting with JQuery always results in an error and I can't figure out why.
In my view I have the following method, that posts the data to the controller page
function RenameNode(name, id)
{
$.ajax({
type: "POST",
url: '<?php echo Router::url(array('controller' => 'categories', 'action' => 'rename')); ?>',
data: {
id: id,
name: name
},
success: function(){
}
});
}
My controller method looks like this:
public function rename($id = null, $name = null) {
if ($this->request->is('get')) {
throw new MethodNotAllowedException();
}
if(!$id)
{
$id = #$this->request->query('id');
}
if(!$name)
{
$name = #$this->request->query('name');
}
if (!$id) {
throw new NotFoundException(__('No id'));
}
$category = $this->Category->findById($id);
if (!$category) {
throw new NotFoundException(__('Invalid category'));
}
$this->autoRender = false;
$this->layout = 'ajax';
if ($this->request->is('post') || $this->request->is('put')) {
$this->Category->id = $id;
$this->request->data['Category']['name'] = $name;
if ($this->Category->save($this->request->data)) {
$this->Session->setFlash(__('The category has been updated.'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('Unable to update the category.'));
}
}
}
When I do a post with the jquery method, I keep getting the following error message in my log:
2013-05-20 11:34:25 Error: [NotFoundException] No id
Request URL: /cakephp/categories/rename
Stack Trace:
#0 [internal function]: CategoriesController->rename()
When I comment the request checks for get and post, the controller itself works perfectly when I call it with /categories/rename?id=1&name=test. For some reason the ajax way doesn't work, but I can't figure out why. Any ideas?
Update
I fixed it by changing the following code, now it works perfectly
if(!$id)
{
$id = #$this->request->query('id');
}
if(!$name)
{
$name = #$this->request->query('name');
}
to
if(!$id)
{
$id = #$this->request->data('id');
}
if(!$name)
{
$name = #$this->request->data('name');
}
You are not including the id and/or name in the URL you're posting to;
echo Router::url(array('controller' => 'categories', 'action' => 'rename'));
Will output;
/categories/rename
But you're expecting
/categories/rename/1/test
Or
/categories/rename?id=1&name=test
Change the URL in your AJAX code to something like;
echo Router::url(array(
'controller' => 'categories',
'action' => 'rename',
0 => $this->request->params['pass'][0],
1 => $this->request->params['pass'][1]
));
Which should output the right url, containing the original id and name of the current request (e.g. /categories/rename/123/oldname)
use somthing like that
data = 'name='+name+'&id='id'';
$.ajax({
type:'post',
url: '/categories/rename',
data: data
});
and in controller function
$name=$_POST[name];
$id=$_POST[id];
$('a.ajax-delete-pdf').on('click', function (event) {
event.preventDefault();
var id = $(this).data('id');
$.ajax(
{
url: webroot + 'productos/ajax_eliminar_pdf/' + id ,
async : false,
success: function(respuesta)
{
if(respuesta == 'Borrado')
{
$(this).parent().toggle();
}
}
});
});
Related
I am creating a rating system in which when user rate any company then rate stored into rate along with the v_id table. (v_id is company id),
This is my url in which i want to rate...
www.ABC.com/controller/function/company_id
Here company_id is getting from database. I want to store the company rating into rate table. when user click on the star.
Controller
function visa_company_profile($v_id) {
$data['total_ratings'] = $this->Visa_mdl->total_ratings($v_id);
$data['total_average'] = $this->Visa_mdl->total_average($v_id);
$result = $this->Visa_mdl->get_company_profile($v_id);
$data['items_company_profile'] = $result;
$this->load->view('include/header');
$this->load->view('hotels/company_profile',$data);
$this->load->view('include/footer');
}
Views
This is ajax part in which i am sending the star values to the controller
$(document).ready(function(){
var click_val = 0;
$("#1_star").hover(function(){
$("#1_star").attr("src","<?php echo base_url('assets/rating/star.png'); ?>");
$("#2_star").attr("src","<?php echo base_url('assets/rating/blank_star.png'); ?>");
$('#3_star').attr('src',"<?php echo base_url('assets/rating/blank_star.png'); ?>");
$('#4_star').attr('src',"<?php echo base_url('assets/rating/blank_star.png'); ?>");
$('#5_star').attr('src',"<?php echo base_url('assets/rating/blank_star.png'); ?>");
});
$("#1_star").click(function(){
click_val = 1;
$.ajax({
url: '<?php echo base_url('Account/loggedin');?>',
success: function(logged_in) {
if (logged_in === "1") {
ajaxCall();
}else {
$("#l_modal").modal('show');
}
}
});
});
function ajaxCall() {
$.ajax({
method : 'POST',
data: {'click_val':click_val},
url: '<?php echo base_url('Hotels/ratings/');?>',
success: function() {
location.reload();
}
});
}
Star Controller To store Rate into data
Here i am trying to get the company id from url and store into column(v_id) rate table.
function ratings() {
date_default_timezone_set('Asia/Kolkata');
$last = $this->uri->total_segments();
$record_num = $this->uri->segment($last);
$value = array (
'rate' => $this->input->post('click_val'),
'date' => date('Y-m-d H:i:s'),
'v_id' => $record_num
);
$this->Visa_mdl->ratings($value);
}
Model
function ratings($value) {
$this->db->insert('user_ratings',$value);
}
You can do it simply modifying you ajax function input value
function ajaxCall() {
$.ajax({
method : 'POST',
data: {'click_val':click_val,'company_id':<?php echo $this->uri->segment(3)},
url: '<?php echo base_url('Hotels/ratings/');?>',
success: function() {
location.reload();
}
});
}
Again you can catch the company ID in your controller Function Hotels/ratings.
function visa_company_profile($v_id) {
$data['v_id'] = $v_id;
$data['total_ratings'] = $this->Visa_mdl->total_ratings($v_id);
$data['total_average'] = $this->Visa_mdl->total_average($v_id);
$result = $this->Visa_mdl->get_company_profile($v_id);
$data['items_company_profile'] = $result;
$this->load->view('include/header');
$this->load->view('hotels/company_profile',$data);
$this->load->view('include/footer');
}
If you pass click value in url then ajax script should be like this:
function ajaxCall() {
var company_id = '<?php echo $v_id; ?>';
$.ajax({
method : 'POST',
data: {'click_val':click_val, 'company_id':company_id},
url: '<?php echo base_url('Hotels/ratings/');?>'+click_val+'/'+company_id,
success: function() {
location.reload();
}
});
}
Because you are not passing click value in url so controller should be like that:
function ratings() {
date_default_timezone_set('Asia/Kolkata');
$record_num = $this->input->post('company_id', true);
$value = array (
'rate' => $this->input->post('click_val', true),
'date' => date('Y-m-d H:i:s'),
'v_id' => $record_num
);
$this->Visa_mdl->ratings($value);
}
And controller:
function ratings($record_num = 0, $company_id = 0) {
date_default_timezone_set('Asia/Kolkata');
$value = array (
'rate' => $record_num,
'date' => date('Y-m-d H:i:s'),
'v_id' => $company_id
);
$this->Visa_mdl->ratings($value);
}
The code below only deletes the data when I add the extra statement in the controller. why is that?
I've only been using codeigniter for a few months now and I keep getting stuck with weird bugs like this.
this is the models file:
My_model.php
function delete_data($where=array())
{
return $this->db->delete('table1', $where);
}
and the code in controller:
tasks.php
function do_delete_data()
{
$this->load->model('My_model');
$result = array('status' => '', 'message' => '');
try
{
$this->db->trans_begin();
$id = $this->input->post('post_id', TRUE);
if ( ! $this->My_model->delete_data(array('id' => $id)))
{
throw new Exception('Database process failed.');
}
$result['message'] = $this->db->last_query(); // extra statement
$this->db->trans_commit();
$result['status'] = 1;
}
catch(Exception $e)
{
$this->db->trans_rollback();
$result['message'] = $e->getMessage();
}
if ($this->input->is_ajax_request())
{
echo json_encode($result);
}
}
it works fine until recently I tried to call this function via ajax like this:
display.php
$.ajax({
url: '/tasks/do_delete_data',
type: 'post',
data: {
'post_id' : $('#post_id').val(), // e.g. 12
},
dataType: 'json',
success: function(response) {
alert('File deleted successfully.');
console.log(response);
},
error: function(e) {
alert('an error occurred.');
}
});
You are using id in ajax param but using post_id as in your controller, which is undefined index.
You need to correct your index name as:
$id = $this->input->post('id', TRUE); // use id
It's better to check what are you getting in controller by using print_r($_POST) this will you to understand, what kind of array are you getting from ajax data.
There is my form:
$form = ActiveForm::begin([
'id' => 'user-create-form',
'enableAjaxValidation' => true,
'enableClientValidation' => false,
'validationUrl' => Url::toRoute(Yii::$app->controller->id . '/validation'),
'validateOnType' => true,
]);
JS-script is registered on this form and performed Russian to English transliteration according to some rules on .keyup() event. Transliteration result is added to samname field.
There is validation rule in UserCreateForm model:
public function rules()
{
return [
[['samname'], 'validateUserExist'],
];
}
public function validateUserExist()
{
$check = Yii::$app->CustomComponents->checkUserExist($this->samname);
if ($check) {
$errorMessage = 'User exists: ' . $check;
$this->addError('samname', $errorMessage);
}
}
Function checkUserExist() checks existing of created name and returns an error in matching case.
There is action on controller:
public function actionValidation()
{
$model = new UserCreateForm();
if (\Yii::$app->request->isAjax && $model->load(\Yii::$app->request->post())) {
\Yii::$app->response->format = Response::FORMAT_JSON;
echo json_encode(ActiveForm::validate($model));
\Yii::$app->end();
}
}
It works great, validation is performed, matching case returns an error...
But!
It's required that JS-script is run again and added next letter to the name on error (JS-script provides this functionality). How to run JS-script again after validator was return an error?
#yafater Thanks for help! I find solution.
$('form').on('afterValidateAttribute', function (event, attribute, message) {
if (attribute.name === 'samname')
{
$.ajax({
url: "url-to-action",
type: "POST",
dataType: "json",
data: $(this).serialize(),
success: function(response) {
if ( typeof(response["form-samname"]) != "undefined" && response["form-samname"] !== null ) {
// code here
}
},
});
return false;
}
});
i have written this script in View. In onblur event i have check whether the mail id is already exits r not.for that i have to pass mailId id to the controller action and i want to get the return result.
$.ajax({
type: "POST",
url: "<?php Yii::app()->createAbsoluteUrl("Approval/checkMailid"); ?>",
data: mailId,
success: function() {
return data;
},
error: function() {
alert('Error occured');
}
});
public function actionCheckMailid($mailId)
{
$model = YourModel::model()->findAll('id = :mid', array(':mid'=>$mailId));
echo json_encdoe($model);
}
Just need to throw a 404 page and ajax error handle can catch it.
public function actionCheckMailid($mailId){
$exist = Yii::app()->db->createCommand('select count(*) from your_email_table where id_email = :id_email')
->queryScalar(array(
'id_email' => $mailId
));
if($exist > 0){
echo json_encode(array(
'success'=>true
));
}else{
throw new CHttpException('Email can not be found');
}
}
I am working on a Cakephp 2.x but I don't think the problem has anything to do with the Cakephp. I want to delete a file without a page refresh.
HTML / PHP :
<div class = "success" style="display:none;">Deleted successfully </div>
<div class = "error" style="display:none;">Error </div>
JavaScript :
function openConfirm(filename, idImage) {
$.modal.confirm('Are you sure you want to delete the file?', function () {
deleteFile(filename, idImage);
}, function () {
});
};
function deleteFile(filename, idImage) {
var filename = filename;
$.ajax({
type: "POST",
data: {
idImage: idImage
},
url: "http://localhost/bugshot/deleteFile/" + filename,
success: function (data) {
if (data == 1) {
$(".success").fadeIn(500).delay(2000).fadeOut(500);
} else {
$(".error").fadeIn(500).delay(2000).fadeOut(500);
}
},
error: function () {
alert("error");
}
});
}
my images which is in foreach loop
this code is displaying the image
foreach($file as $files):?>
<?php $downloadUrl = array('controller' => 'bugshot', 'action' => 'downloadImages', $files['Image']['filename'], '?' => array('download' => true));
$imageUrl = array('controller' => 'bugshot', 'action' => 'downloadImages', $files['Image']['filename']);
?>
<?php echo $this->Html->link(
$this->Html->image($imageUrl),
$downloadUrl,
array('class' => 'frame', 'escape' => false)
);?>
Delete link
The code works great except that after the image or record is deleted the record/image is still displayed on the page until it is refreshed. How do I fix this?
You need to remove it with javascript.
$.ajax({
...
success: function (data) {
if (data == 1) {
$(".success").fadeIn(500).delay(2000).fadeOut(500);
$('img[src="/pathToImg/' + filename + '"]').remove(); // Remove by src
// $('#' + idImage).remove(); // Remove by ID.
} else {
$(".error").fadeIn(500).delay(2000).fadeOut(500);
}
}
...
});
Note : var filename = filename; means nothing because you are assigning filename argument to a new variable with the same name. You can just remove it.