So I am loading data into a form and the user should be able to change it and save it. The data loads fine and when the user clicks on the save button, jQuery grabs that data and should send it to my codeignighter controller, but it does not. The weird thing is that codeignighter is saying that the call was successful.
Here is my jQuery (it is in a seperate .js file):
$(document).ready(function(){
$("#checkin").submit(function(e){
e.preventDefault();
var ConditionID = [];
$('input[name^="ConditionID"]').each(function() {
ConditionID.push($(this).val());
});
var Field = [];
$('div[name^="Field"]').each(function() {
Field.push($(this).val());
});
var Status = [];
$('select[name^="Status"]').each(function() {
Status.push($(this).val());
});
var Description = [];
$('textarea[name^="Description"]').each(function() {
Description.push($(this).val());
});
$.ajax({
url: "/index.php/ConditionReports/saveCheckin",
type: "POST",
data: {'ConditionID':ConditionID,'Field':Field,'Status':Status,'Description':Description},
success:function(data)
{
alert('SUCCESS!!');
},
error:function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
}
});
});
});
My view:
<form action='' method='post' id='checkin' accept-charset='ytf-8'>
<?php
$i=0;
foreach($Conditions as $c) {
echo("
<input type='hidden' id='ConditionID' name='ConditionID[]' value='$c->ConditionID' />
<div id='Field' name='Field[]' value='$c->Field'>$c->Field</div>
<select id='Status' name='Status[]'>");
$e=($c->Status=="E"?"selected":"");
$g=($c->Status=="G"?"selected":"");
$s=($c->Status=="S"?"selected":"");
$b=($c->Status=="B"?"selected":"");
$m=($c->Status=="M"?"selected":"");
echo("
<option $e value='E'>Excellent/New</option>
<option $g value='G'>Good</option>
<option $s value='S'>Satisfactory</option>
<option $b value='B'>Poor/Needs Repair</option>
<option $m value='M'>Missing</option>
</select>
<textarea class='form-control' name='Description[]' id='Description'>$c->Description</textarea>
");
$i++;
}
?>
<button type="button" class="btn btn-info">Print</button>
<input type="submit" id="saveCheckin" value='Save' class="btn btn-success save">
<button type="button" class="btn btn-success">Check-In</button>
</form>
My controller:
class ConditionReports extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper(array('form', 'url'));
$this->load->model('ConditionReportsVM');
$header_data['js'] = array('jquery-2.2.1.min','checkin');
$this->load->view('header', $header_data);
}
public function saveCheckin()
{
$data = array(
'ConditionID' => $this->input->post('ConditionID'),
'Field' => $this->input->post('Field'),
'Status' => $this->input->post('Status'),
'Description' => $this->input->post('Description'),
);
$this->ConditionReportsVM->UpdateReport($data);
}
}
And lastly my model:
public function UpdateReport($data)
{
$this->db->where('ConditionID',$data['ConditionID']);
$this->db->update('Conditions',$data);
}
I have been stuck on this for quite a bit of time now and any help I can get is most appreciated. I have debugged jQuery and found out that the appropriate data is being called. There are no console errors. I have tried to echo something from the controller and I have also tried to redirect the page from the controller but the controller just seems like it is not being hit.
Thank you in advance.
Note: Currently the response I get after I click save is an alert with this in it: "SUCCESS!!"
SOLUTION
Thanks to Goose (in the comments) I was able to find my issue. I did not know this, but you can see the response from the server if you go to the developer tools, and go to the Network tab. As soon as I went there I noticed that codeigniter was throwing an Array to string conversion error in my model.
Here is what my model looks like now (the data is saving and everything):
public function UpdateReport($data)
{
for($i=0;$i<count($data['ConditionID']);$i++) {
$this->db->where('ConditionID',$data['ConditionID'][$i]);
$this->db->update('Conditions', array('Status' => $data['Status'][$i], 'Description' => $data['Description'][$i]));
}
}
Related
I have a problem, i need to use, ajax in a form, in my page i have to change the color of a label after i search if a data is in a data base, if the data exist i must change the color of the label to red, if not i have to changed to green, i know how to use this in pure php, but i don´t know how to do that in cakephp, if i am not wrong in pure php this is the forme to do it:
View
<form action="prueba.php" method="post">
<input type="text" id="txt_prueba" class="validador" />
<submit value="enviar"/>
</form>
View in Cake
<?php
echo $this->Form->create('Prueba', array('url' => 'prueba.php', 'type' => 'post'));
echo $this->Form->input('textoPrueba', array('label' => false,
'class' => 'validador'));
echo $this->Form->end(); ?>
Script
$(".validador").on('keyup keypress blur change', function (tecla) {
$.ajax({
method: "POST",
url: "algun.php",
data: {
name: $("#txt_prueba").val();
}
})
.done(function( msg ) {
if (msg=="Yes"){
$("#txt_prueba").css('background-color', 'red');
} else{
$("#txt_prueba").css('background-color', 'green');
}
});
});
Controller
require('conexion.php');
$consulta = $_POST['name'];
if (isset($consulta)) {
$consulta = mysqli_query($conexion, "SELECT * FROM tabla1
WHERE nombre LIKE '$consulta'");
$filas = mysqli_num_rows($consulta);
if ($filas === 0) {
echo 'Not';
}else {
echo 'Yes';
}
};
Have you read something about CakePHP? You should read some basic tutorial
Download and install CakePHP (https://book.cakephp.org/3.0/en/installation.html)
Build Your first controller with action and view (https://book.cakephp.org/3.0/en/tutorials-and-examples/cms/articles-controller.html)
Add Your JavaScript AJAX code in default.ctp layout file
Build Your first form (https://book.cakephp.org/3.0/en/tutorials-and-examples/cms/articles-controller.html#create-add-template)
Run, if You have some problems, try find solution on stackoverflow.com...
i have a problem in ajax, indeed, i try to send value with ajax to my upload function before submit.
But when i check the $_POST array in my php code, there is only the value of the form, and not from the ajax, and I don't know why.
Here is my code :
HTML:
<button id="btn_saisie" class="btn btn-app saver adddocu" ><i class="fa fa-save whiter"></i></button>
<form action="/uploader/adddocu" id="form_saisie" class="form_saisie" method="POST" enctype="multipart/form-data">
<input type="file" name="document" class="val_peage form-control form_num" id="document" data-rest="document" placeholder="Document">
<input type="text" name="description" class="val_parking form-control form_num" id="description" data-rest="description" placeholder="Description">
JS :
$( ".adddocu" ).click(function() {
if ($('#document').val() != "" && $('#description').val() != ""){
api_sendvalue_adddoc();
}
if ($('#document').val() == "")
alert('test');
else if ($('#description').val() == "")
alert('test2'); });
function api_sendvalue_adddoc(){
user = JSON.parse(sessionStorage.getItem('user'));
pays = localStorage.getItem("pays");
magasin = localStorage.getItem("magasin");
$.ajax({
type: 'POST',
url: '/uploader/adddocu',
data: {pays:pays, magasin:magasin},
success: function(data){
alert(data);
$("#form_saisie").submit();
console.log(data);
},
error: function(xhr){
alert(xhr.responseText);
console.log(xhr.responseText);
}
}); }
PHP:
public function adddocu(){
$path = './asset/upload/pdf/';
$path2 = '/asset/upload/pdf/';
$config['upload_path'] = $path;
$config['encrypt_name'] = false;
$config['file_ext_tolower'] = true;
$config['allowed_types'] = 'pdf';
// die(var_dump($_POST));
$this->load->library('upload', $config);
foreach($_FILES as $id => $name)
{
$this->upload->do_upload('document');
$upload_data = $this->upload->data();
$url = $path2 . $upload_data['file_name'];
$data = array('nom' => $upload_data['raw_name'], 'description' => $_POST['description'], 'url' => $url, 'user_id' => '17');
$this->db->insert('pdf', $data);
}
redirect("/login/docu");
}
So, when I var_dump the $_POST array, I only have the value of "description", and not of "pays" and "magasin".
Can you help me please?
Thanks for your time.
Seems like you are accessing localstorage value , you are posting it somewhere and then submiting the form.
More you are submiting the form which dont have this pays & magasin so i have a trick using which you can achieve it.
Create two hidden inputs inside your HTML form like
<input type="hidden" name="pays" id="pays">
<input type="hidden" name="magasin" id="magasin">
Now before ajax call give them values after getting it from local storage, like this.
user = JSON.parse(sessionStorage.getItem('user'));
pays = localStorage.getItem("pays");
magasin = localStorage.getItem("magasin");
$("#pays").val(pays);
$("#magasin").val(magasin);
$.ajax({ .... });
Continue your code and enjoy.
Hopefully it will work for you.
The issue is because you are not preventing the form from being submit normally, so the AJAX request is cancelled. Instead of using the click event of the button, hook to the submit event of the form and call preventDefault(). Try this:
$('#form_saisie').submit(function(e) {
e.preventDefault();
if ($('#document').val() != "" && $('#description').val() != ""){
api_sendvalue_adddoc();
}
if ($('#document').val() == "")
alert('test');
else if ($('#description').val() == "")
alert('test2');
});
EDIT:
Here is a working example of a ajax post to codeigniter:
View
<script>
$( document ).ready(function () {
// set an on click on the button
$("#button").click(function () {
$.ajax({
type: 'POST',
url: "[page]",
data: {pays: "asd", magasin: "dsa"},
success: function(data){
alert(data);
$("#text").html(data);
console.log(data);
},
error: function(xhr){
alert(xhr.responseText);
console.log(xhr.responseText);
}
});
});
});
</script>
Controller
<?php
// main ajax back end
class Time extends CI_Controller {
// just returns time
public function index()
{
var_dump($_POST);
echo time();
}
}
?>
Output
array(2) {
["pays"]=>
string(3) "asd"
["magasin"]=>
string(3) "dsa"
}
1473087963
Working example here
So you should check the request that you're making from AJAX, on dev console. There you should get the response with the var_dump($_POST).
to debug try to make your controller return only the $_POST data, comment the rest. and same thing on javascript side, test only the ajax post and data received.
I developed this shape with laravel code
When I click on + the quantity of this product increase by 1.
When I click - the quantity of this product decrease by 1.
cart.blade.php (view):
<div class="cart_quantity_button">
<a class="cart_quantity_up" href='{{url("cart?product_id=$item->id&increment=1")}}'> + </a>
<input class="cart_quantity_input" type="text" name="quantity" value="{{$item->qty}}" autocomplete="off" size="2">
<a class="cart_quantity_down" href='{{url("cart?product_id=$item->id&decrease=1")}}'> - </a>
</div>
Cart function in controller:
public function cart()
{
if (Request::isMethod('POST')) {
$product_id = Request::get('product_id');
$product = Product::find($product_id);
Cart::add(array('id' => $product_id,'name' => $product->name, 'qty' => 1, 'price' => $product->price,'options'=>array('image'=>$product->image)));
}
$id = Request::get('product_id');
//increment the quantity
if ($id && (Request::get('increment')) == 1) {
$p = Request::get('increment');
$rowId = Cart::search(array('id' => $id));
// echo "row id".$rowId."and the p=".$p;
$item = Cart::get($rowId[0]);
// echo "row id".$rowId;
$add = $item->qty + 1;
Cart::update($rowId[0], $add);
}
//decrease the quantity
if ($id && (Request::get('decrease')) == 1) {
$rowId = Cart::search(array('id' => $id));
$item = Cart::get($rowId[0]);
$sub = $item->qty - 1;
echo "item" . $sub;
Cart::update($rowId[0], $sub);
}
if ($id && (Request::get('remove')) == 1) {
$rowId = Cart::search(array('id' => $id));
Cart::remove($rowId[0]);
}
$cart = Cart::content();
return view('cart', array('cart' => $cart,'title' => 'Welcome', 'description' => '', 'page' => 'home','subscribe'=>"",'brands' => $this->brands));
}
public function cart_remove()
{
Cart::destroy();
return Redirect::away('cart');
}
public function checkout()
{
$cart = Cart::content();
return view('checkout', array('cart' => $cart,'title' => 'Welcome', 'description' => '', 'page' => 'home','subscribe'=>"",'brands' => $this->brands));
}
I want to convert this with ajax code, I do simple code for this
<script>
function getMessage($id)
{
$.ajax({
type: 'POST',
url: 'getmsg',
dataType: 'json',
data: {
valu_id: $id
},
success: function(data) {
$("#msg").html(data.msg);
}
});
}
</script>
<?php
$item_id = 3;
echo Form::button('+',['onClick'=>'getMessage($item_id)']);
?>
<div id='msg'>
<input id="msg" type="text" name="quantity" autocomplete="off" size="2">
</div>
Controller function:
public function ajax()
{
$value= $_POST['valu_id']+1;
return response()->json(array('msg'=>$value), 200);
}
I don't know how to complete this code .I have many question about this code.
like
How to get the product id from cart.blade.php view and put it in getmessage() to use it in ajax function?
How to put getmessage() in <div class="cart_quantity_button"> instead of button onclick to respect of the shape above?
How to return the quantity in the input field as the shape above?
Note: This answer doesn't simply giving you a working solution but an idea on how to handle ajax request/response.
Firstly, even tough event.preventDefault() would prevent default action which is following the URL, I'd rather store the URL to data- attribute.
<div class="cart_quantity_button">
<a class="cart_quantity_up" href="javascript:void(0)" data-route="{{url('cart?product_id=$item->id&increment=1')}}"> + </a>
<input class="cart_quantity_input" type="text" name="quantity" value="{{$item->qty}}" autocomplete="off" size="2">
<a class="cart_quantity_down" href="javascript:void(0)" data-route="{{url('cart?product_id=$item->id&decrease=1')}}"> - </a>
</div>
How to get the product id from cart.blade.php view and put it in getmessage() to use it in ajax function?
It's always better to listen to an event, which is click in this case.
$('.cart_quantity_up').on('click', function(e) {
//an ajax call here
});
Same code applies for the other one
$('.cart_quantity_down').on('click', function(e) {
//an ajax call here
});
Now, two click events has been attached to each corresponding element. Then, it's time to wrap the ajax function up.
function updateQty(url){
var $qty = $('.cart_quantity_input');
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: {
cart_qty: $qty.val()
},
success:function(data){
$qty.val(data.qty);
}
});
}
The function above is simply
takes a parameter which is URL for ajax to call to,
does a post request with uri param key 'cart_qty'
returns response which is a value of 'qty' from controller to cart_quantity_input input element
And then, put the ajax function to the first snippets (click event)
$('.cart_quantity_up').on('click', function(e) {
e.preventDefault();
//get the data-route
var url = $(this).data('route');
//call the ajax function
updateQty(url);
});
$('.cart_quantity_down').on('click', function(e) {
e.preventDefault();
//get the data-route
var url = $(this).data('route');
//call the ajax function
updateQty(url);
});
Actually to make things simpler, you can attach the event from multiple selectors at one go.
$('.cart_quantity_up, .cart_quantity_down').on('click', function(e) {
e.preventDefault();
//get the data-route for the 'up'
var url = $(this).data('route');
//call the ajax function
updateQty(url);
});
Now, you get the idea on how to create ajax post and retrieve its response to attach it to the input element afterward.
At this point, I'm going to refactor your code. And oh, all of your questions should have been answered at this stage.
Your controller looks a bit messy as you handle both post and get requests for such simple situation. I would rather do just post. Instead of having bunch of conditions, I'll put the footprint inside the data- attribute (again). In the end, I wrap them inside a form, because CSRF token gives more security on your end.
<form name="cart_form">
{{ csrf_field() }}
<input type="hidden" class="item_id" value="{{ $item->id }}">
<div class="cart_quantity_button">
<button type="button" class="cart_quantity_up" data-route="{{url('cart')}}" data-increase="1"> + </button>
<input class="cart_quantity_input" type="text" name="quantity" value="{{$item->qty}}" autocomplete="off" size="2">
<button class="cart_quantity_down" data-route="{{url('cart')}}" data-increase="0"> - </button>
</div>
</form>
You're free to design your own view as long as you're going to do a post request (as I'm doing on it). I'll explain a bit above the logic I'm going to make.
Hold the $item->id on hidden field
Going to make ajax request to url('cart') route and store it to data-route
Add data-increase to differentiate each request should increase or decrease
Now listen up on click event
$('.cart_quantity_up, .cart_quantity_down').on('click', function(e) {
e.preventDefault();
var $this = $(this),
url = $this.data('route'),
increase = $this.data('increase');
updateQty(url, increase);
});
Below updateQty function is a bit different from the first one I made. It accepts the second parameter increase as (pseudo-)boolean value. Also notice I'm posting the token as request header rather than body.
function updateQty(url, increase){
var $qty = $('.cart_quantity_input'),
itemId = $('.item_id').val();
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
headers: {
'X-CSRF-Token' : $('input[name="_token"]').val()
},
data: {
'cart_qty': $qty.val(),
'item_id': itemId,
'increase': increase
},
success:function(data){
$qty.val(data.qty);
}
});
}
Your controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Cart;
use App\Http\Requests;
class YourController extends Controller
{
public function cart(Request $request)
{
if ($request->ajax()) {
$id = $request->item_id;
$cart = Cart::search(['id' => $id]);
//Note: This code may not working as what you expect
// but it should give you the idea that laravel
// actually has increment and decrement methods
// and else.
if ($request->increase) {
$cart->increment('qty');
} else {
$cart->decrement('qty');
}
$qty = $cart->first(['qty']);
return response()->json(['qty' => $qty]);
}
//rest is your code
//...
}
}
In the above code, I'm trying to
treat ajax request separately from your code,
update qty column based on $_POST['increase']
If 1, do increment. If 0, decrements it
grab the value of qty column (though Im not sure it's going to work)
return the value keyed 'qty' as json
it will then update your input element based on $qty.val(data.qty)
Hi guys? am trying to post data to the database using laravel 5 and ajax..am also applying using csrf protection by adding
<meta name="_token" content="{!! csrf_token() !!}"/>
to my layout header and adding the following code to my footer:
<script type="text/javascript">
$.ajaxSetup({
headers: { 'X-CSRF-Token' : $('meta[name=_token]').attr('content') }
});
</script>
This is my form:
<form action="{{action('QuizController#postQuiz')}}" method="POST">
<div id="name-group" class="form-group">
<label for="name">Please type your question here</label>
<input type="text" class="form-control" name="question">
</div>
<button type="submit" class="btn btn-success">Submit <span class="fa fa-arrow-right"></span></button>
</form>
This is my JS code:
var formData = {
'question' : $('input[name=question]').val(),
};
// process the form
$.ajax({
type : 'POST',
url : 'quiz',
data : formData,
dataType : 'json',
encode : true
})
// using the done promise callback
.done(function(data) {
// log data to the console to see
console.log(data);
// ALL GOOD! just show the success message!
$('form').append('<div class="alert alert-success">' + data.message + '</div>');
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
This is my route:
Route::post('create/quiz', array(
'as' => 'post-quiz',
'uses' => 'QuizController#postQuiz'
));
When my controller is like the following:
public function postQuiz()
{
if(Request::ajax()) {
$question = Request::get('question');
$data['success'] = true;
$data['message'] = $question;
echo json_encode($data);
}
the ajax call works and it returns,
Object {success: true, message: "test question"}
but when I try posting data to the database using:
public function postQuiz()
{
if(Request::ajax()) {
$question = Request::get('question');
DB::table('questions')->insert([
'question' => $question,
]);
}
I get the following from the console
POST http://localhost/leoschool-laravel5/public/create/quiz 500 (Internal Server Error)
and
Object {readyState: 4, responseText: "{"success":true,"message":"test question"}<!DOCTYPE htm…l>↵</div>↵↵ </div>↵ </body>↵</html>", status: 500, statusText: "Internal Server Error"}
What could be the problem? Thanks..
A good place to start is with Chrome Developer tools. Load your page with the tools open and fire the event that does the AJAX request.
Under the network tab of the tools, it will show you every request made and allow you to preview the response as if you were not using AJAX. This will show you the laravel stack trace. I think the problem is that you're using facades and they're not namespaced correctly.
Change your controller function to this and see if it works:
public function postQuiz()
{
if(\Request::ajax()) {
$question = \Request::get('question');
\DB::table('questions')->insert([
'question' => $question,
]);
}
With the above instruction on how to use dev tools and with the corrected code, you should be able to fix your problem. A better way to write this code would look like this though:
// assuming you have these models setup
// this uses dependency injection
public function postQuiz(Request $request, Question $question)
{
if($request->ajax()) {
$newQuestion = $request->get('question');
//add fields here to create new question with
$question->create([ /*stuff*/ ]);
}
I want to validate a form without refreshing the page using the .post() jQuery method.
I use codeigniter for validation. Could you please tell me how to make it right? I find it pretty confusing ...
Here is the jQuery code:
$(document).ready(function(){
$(".form_errors").hide();
$("#send").on("click",function(){ //the submit button has the id="send"
$(".form_errors").hide(); //these are <p> for each input to show the error
var user=$("input.box");
var data={};
var names=$("input.box").attr("name");
for(i=0;i<user.length;i++){
name=names[i];
value=user[i].val();
data.name=value;
}
$.post('ksite/account',
data,
function(result){
$("div.answer").html(result);
for(i=0;i<user.length;i++){
error_message=<?php echo form_error("?>names[i]<?php ");?>;
$("p#error_"+names[i]+".form_errors").html(error_message).show();
}
}
return false;});
});
form_error is a CodeIgniter function. (I suppose someone who used ci is familiar with).
The form:
<p id="error_user" class="form_errors"></p>
<input type="text" class="box" name="user">
<p id="error_password" class="form_errors"></p>
<input type="password" class="box" name="password">
<input type="submit" id="send">
Is the form tag neccessary ? And if yes,do i have to mention action and method ?
Do I have to specify the type of the response?
And in ksite/account I do:
/* ...... */
if (!this->form_validation->run(''account")) {
echo "The account couldn't be made";
} else {
echo "The account was successfully created ";
}
P.S.Although you may not be familiar with codeigniter, I would appreciate if someone could tell me if the code is correct and what improvements could be made.
Here is what I did.
You have to Ajax for getting data without refreshing the page.
HTML Page
$form = $(form);
var url = $form.attr('action');
dataString = $form.serialize();
$.ajax({
type: "POST",
url: url,
data: dataString,
dataType: "json",
success: function(data) {
$(data).each(function(j,details){
var status = details.status;
var message = details.message;
$('#message_ajax_register').show();
$('#message_ajax_register').html('<div class="alert alert-success">'+message+'</div>');
});
}
});//end of $.ajax**
I am first setting up the rules in my controller method and then validating it.
Controller
public function update_fest()
{
if($this->input->post())
{
$this->form_validation->set_rules('txtgpluswebsite', 'Google Plus Page URL', 'trim|xss_clean|prep_url');
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
if($this->form_validation->run() == false){
$message = validation_errors();
$data = array('message' => $message,'status'=>0);
}
else{
$message = $this->add_fest_database();
$data = $message;
}
}
else{
$message = "Fest details are required";
$data = array('message' => $message,'status'=>0);
}
$this->output->set_content_type('application/json');
$json = $this->output->set_output(json_encode($data));
return $json;
}
If validation run is not false, then go to add_fest_database(other function). In that function,
function add_fest_database()
{
$youtubeWebsite = $this->input->post('txtyoutubewebsite');
$gplusWebsite = $this->input->post('txtgpluswebsite');
$this->load->model('model_fest');
$data = array("fest_youtube"=>$youtubeWebsite,"fest_gplus"=>$gplusWebsite);
return data;
}