CakePHP 2.1 Ajax validation errors - php

I'm trying to get validation errors with Ajax and jQuery working in CakePHP 2.1 for a contact form. On blur of the name field a js function is called:
$(document).ready(function(){
$('#name').blur(function(){
$.post(
'/Cake_ajax/Contacts/validate_form',
{ field: $(this).attr('id'), value: $(this).val() },
handleNameValidation
);
});
function handleNameValidation(error){
if(error.length > 0){
if($('#name-notEmpty').length == 0){
$('#name').after($('<div id="name-notEmpty" class="error-message">' + error + '</div>'));
}
}else{
$('#name-notEmpty').remove();
}
}
});
The javascript calls the validate_form function in my controller:
public function validate_form(){
if($this->RequestHandler->isAjax()){
$this->request->data['Contact'][$this->request->params['form']['field']] = $this->request->params['form']['value'];
$this->Contact->set($this->request->data);
if($this->Contact->validates()){
$this->autorender = FALSE; // don't render a view
}else{
$error = $this->validateErrors($this->Contact);
$this->set('error', $error[$this->request->params['form']['field']]);
}
}
}
In my view I'm getting a couple of errors when the error is called:
Undefined index: form [APP\Controller\ContactsController.php
Undefined index: form [APP\Controller\ContactsController.php
I'm at my wits end, and I'm fairly new to CakePHP. Any help would be greatly appreciated.

In your controller you should have something like below. Cake 2.0 replaces many features in RequestHandlerComponent and Controller. It also replaces $this->params array in all places and the old $this->data to $this->request->data, something like that. You can visit the migration guide.
public function validate_form(){
if($this->RequestHandler->isAjax()){
$this->request->data['Contact'][$this->request['form']['field']] = $this->request['form']['value'];
$this->Contact->set($this->request->data);
if($this->Contact->validates()){
$this->autorender = FALSE; // don't render a view
}else{
$error = $this->validateErrors($this->Contact);
// didn't validate logic
$this->set('error',$this->Contact->validationErrors[$this->request['data']['field']][0]);
}
}
}

Try $this->request->params['field'] instead of $this->request->params['form']['field'].
Or right after you check to isAjax(), try doing a var_dump on $this->request->params. From the error you are getting, the form index does not exist in $this->request->params.

If you want to simulate a POST like done when using a standard form and the Cake FormHelper, you could also simply name the posted parameters the same way the FormHelper names the input fields.
$j.post(
'/Cake_ajax/Contacts/validate_form',
{ "data[Contact][" + $(this).attr('id') + "]": $(this).val() },
handleNameValidation
);
This would automatically populate $this->request->data['Contact']['name'] and you could just comment this line:
//$this->request->data['Contact'][$this->request->params['form']['field']] = $this->request->params['form']['value'];

Related

sending form data to server by ajax

I am new with ajax and want to make a to-do-list.
for add-form submit method() ,I have an if-else .the else works and give me alert in its situation but if doesnt work I think it's about my post method.
by the way it's my jquery code :
$('#add_task').submit(function(event) {
/* stop form from submitting normally */
event.preventDefault();
var title = $('#task_title').val();
if(title){
//ajax post the form
$.post("/add", {title: title}).done(function(data) {
$('#add_task').hide("slow");
$("#task_list").append(data);
});
}
else{
alert("Please give a title to task");
}
});
and when I click on my add btn the console output shows me a 404 not found error and refer to this line of my jquery main file that I download from http://code.jquery.com/jquery-latest.min.js: it is :
f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&& (e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();
it's my controller :
public function postAdd() {
if(Request::ajax()){
$todo = new Todo();
$todo->title = Input::get("title");
$todo->save();
$last_todo = $todo->id;
$todos = Todo::whereId($last_todo)->get();
return View::make("ajaxData")
->with("todos", $todos);
}
}
and my route:
Route::controller('/', 'TodoController');
thanks for time
Change "submit button" to simple button and change as below.
$('#add_task').click(function() {
var titleField = $('#task_title');
if(titleField.length > 0){
$.post("/add", {title: titleField.val()}).done(function(data) {
$('#add_task').hide();
$("#task_list").append(data);
});
} else {
alert("Please give a title to task");
}
return false;
});
I think you have an problem with routing in Laravel. This routing should work:
Route::post('add/',array('uses' => 'TodoController#add'));
404 HTTP Status errors in AJAX are only related to the URL you are sending your data. Change /add with something your backend can handle, like a simple PHP file, because /add means you need some htaccess/nginx rewrites to be done.
Anyway, it's a simple tutorial, and I'll downvote you for copying code claiming to be yours from: packtpub
You should do a simple ajax request like this:
$.ajax({ url : 'ajax.php', data: {title:title}, type: 'POST', success:
function(response) {
// exec success code
}
});
Never do internet tutorials if you have no idea about programming because you'll never get them to work. It's just a simple php file that you need to code, and change it's url from that tutorial in your Route:: controller, though, that tutorial is way too complex for a to-do list.
I fixed it just by changing:
$.post("/add", {title: title})
to:
$.post("http://localhost/Blueprints/to-doListWithAjax/public/index.php/add", {title: title})
it didnt found localhost://add so I gave it complete addrerss
.
THANKS ALL FOR REPLIES

posting array using ajax to the controller in cakePHP

I am relatively new to cake and I am struggling with a custom filter that im making in order to display products based on which checkboxes have been ticked. The checkboxes get populated based on which attributes the user creates in the backend, i then collect all the values of the selected boxes into an array with javascript and post it to the controller, but for some reason I cannot access the controller variable named '$find_tags' in my view, it throughs undefined variable.
Here is my javascript and ajax which collects and posts correctly (when i firebug it 'data' in my controller has array values which im posting) so thats fine
$("#clickme").click(function(event){
event.preventDefault();
var searchIDs = $("#checkboxes input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var contentType = "application/x-www-form-urlencoded";
var data = 'data[ID]='+searchIDs;
$.post("",data,function(data){
console.log(data);
});
});
Here is my controller code which im assuming is where the fault lies
if ($this->request->is('post') ) {
$data = $this->request->data['ID'];
$find_tags = array();
$selected_tags = $data;
foreach($selected_tags as $tag)
{
array_push($find_tags,$this->Product->findByTag($tag));
$this->set('find_tags', _($find_tags));
}
}
And here is my view code where i get Undefined variable: find_tags
foreach($find_tags as $all_tag)
{
echo $all_tag['Product']['name'];
echo '</br>';
}
Any help or suggestions would really be appreciated been struggling with this for a while now
If searchIDs is array of ids you just need to make the json of array and then send to your controller
$("#clickme").click(function(event){
event.preventDefault();
var searchIDs = $("#checkboxes input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var contentType = "application/x-www-form-urlencoded";
var data = 'ids='+JSON.stringify(searchIDs);
$.post("controller url",data,function(data){
console.log(data);
});
});
On php side you are getting wrong variable
if ($this->request->is('post') ) {
$data = $this->request->data['ids'];
$find_tags = array();
$selected_tags = $data;
foreach($selected_tags as $tag)
{
array_push($find_tags,$this->Product->findByTag($tag));
}
$this->set('find_tags', _($find_tags));
}

php - codeigniter ajax form validation

Hi I’m quite new to jquery -ajax and I’d like some help please to join it with CI.
I have followed this tutorial on Submitting a Form with AJAX and I’d like to add this functionality to my CodeIgniter site. What I’d like to do is when the user submits the form, if there are any validation errors to show the individually on each input field (as in native ci process), or if this is not possible via validation_errors() function. If no errors occured to display a success message above the form.
Here's my code so far:
my view
// If validation succeeds then show a message like this, else show errors individually or in validation_errors() in a list
<div class="alert alert-success">Success!</div>
<?php echo validation_errors(); //show all errors that ajax returns here if not individualy ?>
<?php echo form_open('admin/product/add, array('class' => 'ajax-form')); ?>
<p>
<label for="product_name">Product *</label>
<input type="text" name="product_name" value="<?php echo set_value('product_name', $prod->product_name); ?>" />
<?php echo form_error('product_name'); ?>
</p>
<p>
<label for="brand">Brand</label>
<input type="text" name="brand" value="<?php echo set_value('brand', $prod->brand); ?>" />
<?php echo form_error('brand'); ?>
</p>
...
my controller
public function add($id){
// set validation rules in CI native
$rules = $this->product_model->rules;
$this->form_validation->set_rules($rules);
if ($this->form_validation->run() === true) {
// get post data and store them in db
$data = $this->input_posts(array('product_name', 'brand', 'category_id', 'description'));
$this->product_model->save($data, $id);
// no errors - data stored - inform the user with display success-div
} else {
// validation failed - inform the user by showing the errors
}
//load the view
$this->load->view('admin/products/add', $data);
}
and here’s the js script
$(document).ready(function () {
$('form.ajax-form').on('submit', function() {
var obj = $(this), // (*) references the current object/form each time
url = obj.attr('action'),
method = obj.attr('method'),
data = {};
obj.find('[name]').each(function(index, value) {
// console.log(value);
var obj = $(this),
name = obj.attr('name'),
value = obj.val();
data[name] = value;
});
$.ajax({
// see the (*)
url: url,
type: method,
data: data,
success: function(response) {
console.log(response); // how to output success or the errors instead??
}
});
return false; //disable refresh
});
});
How should I pass my validation results (either success or the post errors) throught the ajax request and display them on my view??
From some little research I did I've found that you can use a single controller, that holds both the native proccess and the ajax request (instead of using 2 controllers), but my main difficulty is, I don't understand how the results of the validation will pass through the js script and display them on my view?? Please note that I don't want to display anything on an alert box, instead show the results on a div or the errors individualy(if possible).
EDIT I did some changes to my application, here's the code so far:
the controller
public function manage($id = NULL){
$this->load->library('form_validation');
$data['categ'] = $this->category_model->with_parents();
//fetch a single product or create(initialize inputs empty) a new one
if (isset($id) === true) {
$data['prod'] = $this->product_model->get($id);
$data['attr'] = $this->attribute_model->get_by('product_id', $id, null, true);
} else {
$data['prod'] = $this->product_model->make_new();
$data['attr'] = $this->attribute_model_model->make_new();
}
if (isset($_POST['general_settings'])) {
if ($this->form_validation->run('product_rules') === true) {
// get post inputs and store them in database
$data = $this->product_model->input_posts(array('product_name', 'brand', 'category_id', 'general_description'));
$this->product_model->save($data, $id);
$status = true;
} else {
// validation failed
$status = validation_errors();
}
if ( $this->input->is_ajax_request() ) {
echo json_encode($status);
exit;
}
redirect('admin/product');
}
//if (isset($_POST['attributes_settings'])) { the same thing here }
// load the view
$this->load->view('admin/products/manage', $data);
}
and the js
success: function(response) {
//console.log(response);
if (data.status === true) {
$('#ajaxResults').addClass('alert alert-success').html(response);
} else {
$('#ajaxResults').addClass('alert alert-error').html(response);
};
}
But I'm having some issues
Although I get the error messages from validation_errors() as an alert-error when there are no errors I get the true in an alert-error too, insted of alert-success.
2.how should I return the success message too? eg. a message saying "Saves were done!".
Althought in a non-ajax-request the data are stored in the database, in case fo ajax the don't store. Any ideas What may be wrong???
HTML:
<div id="ajaxResults"></div>
Javascript ajax:
success: function(response) {
$('#ajaxResults').text(response);
}
this script you've wrote is only if the validation succeeds, right?
Wrong. The code in "success" gets executed any time you get a response back from the server (assuming the HTTP header is 200). Does your javascript knows if the server has any error for you? No.
You need your JavaScript to recognize if the validation failed or succeeded. You have many ways to do that. One of these could be sending the message to display followed by a 0 or 1.
So your PHP will looks like:
return "0 " . $errorMessage;
and
return "1 " . $successMessage;
and your javascript should then recognize, with if statement and substring, if the message starts with 0 or with 1.
Use this way i hope this will work for you
<script type='text/javascript'>
var base_url = '<?=base_url()?>';
function ajax_call()
{
var ids = $("#all_users").val();
$.ajax({
type:"POST",
url: base_url+"expense/home/get_expense",
data: "userid=" + ids,
success: function(result){
$("#your_div_id").html(result);
}
});
}
</script>

POST data from knockout.js to CakePHP controller

I'm posting data from a knockout.js page to a controller in cakephp and it says the data was successfully posted, however, my controller doesn't seem to be responding and I don't get an alert back...not even a null response. I even checked the network tab in chrome and it shows the correct data being POSTED
Here's the data being posted from my knockout viewmodel file
var JSON_order = JSON.stringify({"orderInfo":[{"itemNumber":"1","quantity":"1","price":1.00,"productName":"test"}]});
$.post("/orders/submit_order", JSON_order,
function(data){
alert(data.check); //alert doesn't appear
}, "json");
Here's my controller
function submit_order(){
$this->layout = false;
$this->autoRender = false;
if ($this->request->is('post')) {
$order = $this->request->data;
$order = json_decode($order, true);
$finalize_order = new submit;
$finalize_order->display_submitted_order_success($order);
}
}
Here's the code for display_submitted_order_success (I also tried this on a php file outside of CakePHP but it didn't work either)
function display_submitted_order_success($order = null){
$this->layout = false;
$this->autoRender = false;
//I'm just trying to display the order as-is so that I know it's even being posted to begin with
echo json_encode(array("check" => "success","order_num" => $order)); //the values passed the price check, display the result
}
You have to assign the value of JSON_order to a var:
var JSON_order = JSON.stringify({"orderInfo":[{"itemNumber":"1","quantity":"1","price":1.00,"productName":"test"}]});
$.post("/orders/submit_order", {order:JSON_order},
function(data){
alert(data.check); //alert doesn't appear
}, "json");
So that your controller would receive it like this:
$data['order'] = '{"orderInfo":[{"itemNumber":"1","quantity":"1","price":1,"productName":"test"}]}'

Post method not working in Codeigniter

I am using HMVC codeigniter. I am trying to use jquery ajax first time. When i use POST then it gives undefined error while it response me the data while using GET.
$.ajax({
type: "POST",
url: filelink+"cart/add_cart_item",
data: {"product_id":id,"quantity":qty,"ajax":"1"},
dataType: "json",
success: function(msg){
alert( "Data Saved: " + msg );
},
error: function(jqXHR, textStatus, errorThrown){
alert(textStatus + " " + errorThrown);
}
});
What I have tried so far after googling and SO-ing-
my file url location is accessible directly. I checked it. giving response.
Firebug is giving 500 internal server error for the same file.
Using Get is responding me back well
added json in the datatype
controller function
class Cart extends CI_Controller { // Our Cart class extends the Controller class
function __construct()
{
parent::__construct();
$this->template->set('controller', $this);
}
function _remap()
{
$uri2 = $this->uri->segment(2);
if (is_numeric($uri2) OR $uri2 == FALSE) {
$this->index();
} else if ($uri2 == 'add_cart_item') {
$this->add_cart_item();
} else if ($uri2 == 'show_cart') {
$this->show_cart();
}
}
function add_cart_item(){
echo "asdfsadfdsf";
exit;
}
}
can anybody please help me out?
There are possible reasons for your problem
You might be using model which is not loaded.
There might be some code problem in the model.
You may not be returning anything from your model and echo it.
Also if you need the data back use echo json_encode($data)
Sometimes this problem arises when you have loaded the site as https://example.com but the url in your ajax call is http://example.com .
Managed to find the solution. The problem was due to CI_TOKEN which is sent with the FORM. That was absent and due to which POST method was giving 500 Internal server Error. I added following in my view file.
<?php echo form_open_multipart(); ?>
<?php echo form_close(); ?>
and sent ci_token with the ajax post request.
var ci_token = formObj.find('input[name=ci_token]').val();
var qty = 1;
var dataString = 'product_id='+ id + '&quantity=' + qty + '&ajax=' + 1
+'&ci_token=' + ci_token;
This solved the problem. I am not sure but this is called CSRF related some problem
Thanks
you have used _remap function and after getting $uri2 there is an if check which is checking the quantity variable you have passed in your ajax request and it may have integer value as obvious may contain some integer.
there for
$this->uri->segment();
returns you:
product_id=id
quantity=qty
ajax=1
and you take value 2 that is quantity by calling
$uri2 = $this->uri->segment(2);
it will return quantity to you and you have not defined an index() function in your code which gives 500 error
function _remap()
{
$uri2 = $this->uri->segment(2);
if (is_numeric($uri2) OR $uri2 == FALSE) {
$this->index();
} else if ($uri2 == 'add_cart_item') {
$this->add_cart_item();
} else if ($uri2 == 'show_cart') {
$this->show_cart();
}
}

Categories