As JsHelper is no more in cakephp 3.0 so what i am doing is to save my form data into database using ajax
i just have two input fields.
my files are:
add.ctp
js.js
EmployeesController.php
add.ctp
$this->Form->create('Employees');
$this->Form->input('name', array('id'=>'name'));
$this->Form->input('age', array('id'=>'age'));
$this->Form->button('Add Info', array(
'type'=>'button',
'onclick'=>'infoAdd();'
));
$this->Form->end();
js.js
function infoAdd() {
var name=$("#name").val();
var age=$("#age").val();
$.get('/employees/info?name='+name+"&age="+age, function(d) {
alert(d);
});
}
EmployeesController.php
class EmployeesController extends AppController {
public $components=array('RequestHandler');
public function add() {
$emp=$this->Employees->newEntity();
if($this->request->is('ajax')) {
$this->autoRender=false;
$this->request->data['name']=$this->request->query['name'];
$this->request->data['age']=$this->request->query['age'];
$emp=$this->Employees->patchEntity($emp,$this->request->data);
if($result=$this->Employees->save($emp)) {
echo "Success: data saved";
//echo $result->id;
}
else {
echo "Error: some error";
//print_r($emp);
}
}
}
}
Note : my model only have not empty rule for both fields
all what i am doing is working fine but i dont think i m doing it in right way or as it should be.
please help me what i m missing and what i don't need to do.
Take away the autoRender line and serialize the data you want returned:
public function add() {
$data = [];
$emp=$this->Employees->newEntity();
if($this->request->is('ajax')) {
$this->request->data['name']=$this->request->query['name'];
$this->request->data['age']=$this->request->query['age'];
$emp=$this->Employees->patchEntity($emp,$this->request->data);
if($result=$this->Employees->save($emp)) {
$data['response'] = "Success: data saved";
//echo $result->id;
}
else {
$data['response'] = "Error: some error";
//print_r($emp);
}
}
$this->set(compact('data'));
$this->set('_serialize', 'data');
}
The serialize function tells Cake that it's not expecting the function to have a view, so autoRender is not needed (http://book.cakephp.org/3.0/en/views/json-and-xml-views.html).
Related
I'm using codeigniter, for make an api rest, with the library that provide the oficial web site.
The problem is: the file routes.php doesn't redirect well. When i put localhost/API/1 into my browser apear the 404 error.
Here my controller "Apicontroller":
public function __construct() { //constructor //no tocar
parent::__construct();
$this -> load -> model("Modelocontrolador");
}
public function index_get() { //get all the info
$datos_devueltos = $this->Modelocontrolador->getPrueba(NULL, "Usuarios");
if(!is_null($datos_devueltos)){
$this->response(array("response" => $datos_devueltos), 200);
}else{
$this->response(array("response" => "No date"), 200);
}
}
public function find_get($id){ //select where
$datos_devueltos = $this->Modelocontrolador->getPrueba($id, "Usuarios");
if($id != NULL){
if(!is_null($datos_devueltos)){
$this->response(array("response" => $datos_devueltos), 200);
}else{
$this->response(array("response" => "No date"), 200);
}
}else{
$this->response(array("response" => "No dates for search"), 200);
}
}
public function index_post() { //insert in la table
if(! $this -> post("dato")){
$this->response(array("response" => "No enought info"), 200);
}else{
$datoID = $this -> Modelocontrolador -> save($this -> post("dato"),"UsuariosJJ");
if(!is_null($datoID)){
$this->response(array("response" => $datoID), 200);
}else{
$this->response(array("response" => "No found it"), 200);
}
}
}
public function index_put($id) { //"update"
if(! $this -> post("dato") || ! $id){
$this->response(array("response" => "No ha mandado informacion correcta para el update"), 200);
}else{
$datoID = $this -> Modelocontrolador -> update("Uid",$id,$this -> post("dato"),"UsuariosJJ");
if(!is_null($datoID)){
$this->response(array("response" => "Dato actualizado"), 200);
}else{
$this->response(array("response" => "Error modify"), 200);
}
}
}
public function index_delete($id) {
if(! $id){
$this->response(array("response" => "Not enought info"), 200);
}else{
$delete = $this-> Modelocontrolador -> delete("Uid",$id,"UsuariosJJ");
}
if(!is_null($delete)){
$this->response(array("response" => "Date delete"), 200);
}else{
$this->response(array("response" => "Error delete"), 200);
}
}}
And my routes file:
$route['default_controller'] = 'Apicontroller';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
/*sub-rutas*/
/*---------*/
$route["Apicontroller"]["get"] = "Apicontroller/index"; //basico
$route["Apicontroller/(:num)"]["get"] = "Apicontroller/find"; //select
$route["Apicontroller"]["post"] = "Apicontroller/index"; //insert
$route["Apicontroller/(:num)"]["put"] = "Apicontroller/index/$1"; //update
$route["Apicontroller/(:num)"]["delete"] = "Apicontroller/index/$1"; //delete
If the browser request literally uses /API then routing needs to 'see' exactly that. Also, the route rules must be explicit with the method to be called. (Hopefully the code shown reflects the mapping you had in mind.)
/*sub-rutas*/
/*---------*/
$route["API"]["get"] = "Apicontroller/index_get"; //basico
$route["API/(:num)"]["get"] = "Apicontroller/find_get/$1"; //select
$route["API"]["post"] = "Apicontroller/index_post"; //insert
$route["API/(:num)"]["put"] = "Apicontroller/index_put/$1"; //update
$route["API/(:num)"]["delete"] = "Apicontroller/index_delete/$1"; //delete
Using the above routes I created some test code. Here are those files.
The much simplified Apicontroller.
class Apicontroller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
function index_get()
{
echo "API index";
}
public function find_get($id)
{ //select where
echo "API find_get $id";
}
public function index_post()
{
echo 'API index_post';
}
public function index_put($id)
{ //"update"
echo "API put $id";
}
}
I don't believe that because your Apicontroller is extending a different Class the results would change. That may be a drastic assumption.
In order to test POST calls I used these two files.
First a Testpost.php controller
class Testpost extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->helper('form');
}
public function index()
{
$this->load->view("test");
}
}
The very simple view (test.php) loaded by the above.
<?php
echo form_open("API");
echo form_submit('mysubmit', 'Submit Post!');
echo form_close();
Directing the browser to localhost/testpost shows a page with a single submit button. Pressing the button results in a screen with the text "API index_post".
Sending the browser to localhost/API/3 produces a screen with the text "API find_get 3".
localhost/API produces "API index".
Now the interesting thing (not related to your problem, but interesting).
Given the default
$route['default_controller'] = 'Apicontroller';
and the route
$route["API"]["get"] = "Apicontroller/index_get";
I expected that directing the browser to the home page localhost would produce "API index". But it doesn't. It results in a 404. Due to that behavior it might be wise to be more explicit with default_controller
$route['default_controller'] = 'Apicontroller/index_get';
Or add an index() function to Apicontroller that calls $this->index_get().
I did not test PUT or DELETE as my server isn't setup to handle them. But as GET and POST seem to function, in a righteous world, they will work.
seems like you are using PHil's REST_Controller library with CI 2.x, correct ?
If so, I would recommend you to use what I like to call an "index gateway" because you can't do per-Method routing with CI2:
class Apicontroller extends REST_Controller
{
function index_gateway_get($id){
$this->get_get($id);
}
function index_gateway_put($id){
$this->put_put($id);
}
// This is not a "gateway" method because POST doesn't require an ID
function index_post(){
$this->post_post();
}
function get_get($id = null){
if(!isset($id)){
// Get all rows
}else{
// Get specific row
}
}
function put_put($id = null){
if(!isset($id)){
// a PUT withtout an ID is a POST
$this->post_post();
}else{
// PUT method
}
}
function post_post(){
// POST method
}
}
The routing to make this work is really easy:
$route["API/(:num)"] = "Apicontroller/index_gateway/$1";
That's all you need. Phil's REST Library will redirect to the correct index_gateway_HTTPMETHOD depending on which method is used.
Each index_gateway_HTTPMETHOD will then redirect to the correct method.
As far as I know, this trick is the only way to have CI2 use a single /API/ entry point that works for all HTTP Methods.
below code returns me blank in ajax response please help me
when i check my controller it also gives me blank.
Can you please check the code below to find out the reason of problem
here is my ajax code:
window.onload = function() {
$.ajax({
type:'json',
url:"http://localhost/myapne/admin/adminMenu/getMsg",
success:function(data){
alert(data);
// PrintSms(data);
},
error: function(error){
console.log(error);
}
});
}
here is my controller:
class AdminMenu extends CI_Controller{
function getMsg(){
$this->load->model('adminGetModel');
$data = $this->adminGetModel->getSms();
return array("status"=>"success","rows"=>$data);
}
}
here is my model:
class AdminGetModel extends CI_Model{
function getSms(){
// $a = $count*10;
// $b = $a + 10;
$this->load->database();
$query = $this->db->get('tblsms');
$rows = array(); //will hold all results
foreach($query->result_array() as $row)
{
$rows[] = $row; //add the fetched result to the result array;
}
return $rows;
}
}
Json_encode the data and use echo instead of return:
echo json_encode(array("status"=>"success","rows"=>$data));
This will return a string. If you want to turn it back into an object, you will then have to use JSON.parse() (or $.parseJSON if you're using jquery) in your ajax success handler.
I'm trying to validate some data from a form and redirect the user to the page with any errors if any. My code doesn't redirect to any route. The routing for all of my routes works correctly. I echoed the input with Input::all() and it does have the user input. The validator works as well. I'm not sure exactly what's preventing the Redirect::route from working
public function postPurchase()
{
$validator = Validator::make(Input::all(), array(
'condition' => 'required',
'memory' => 'required',
'color' => 'required',
'accessories' => 'required',
'shipping' => 'required'
));
// $input = Input::all();
// dd($input);
if ($validator->fails()) {
// echo "string";
return Redirect::route('home');
} else {
echo "this succedded";
}
//Get prices, item id, etc and send user to checkout page
// echo "Get prices, item id, etc and send user to checkout page";
}
This is the code that precede the postPurchase method:
public function getPurchase()
{
return View::make('general.purchase');
}
public function getCheckout()
{
return View::make('general.checkout');
}
public function postPurchaseCheck()
{
$input = Input::all();
$this->input = $input;
if (Input::get('buy')) {
$this->postPurchase();
}
elseif (Input::get('cart')) {
$this->postAddCart();
}
}
You call the function - but you dont 'return' the Redirect that is given back to you.
Change
if (Input::get('buy')) {
$this->postPurchase();
}
to
if (Input::get('buy')) {
return $this->postPurchase();
}
Try updating this
if (Input::get('buy')) {
return $this->postPurchase();
} elseif (Input::get('cart')) {
return $this->postAddCart();
}
and
if ($validator->fails()) {
// echo "string";
return Redirect::to('home');
} else {
echo "this succedded";
}
also don't forget to define it on route file
Change you postPurchaseCheck() method to return what is returned by $this->postPurchase() like this. Because you are calling the postPurchase() method internally but post is happening on postPurchaseCheck() method so redirect has to be returned by the method that handle POST request
public function postPurchaseCheck()
{
$input = Input::all();
$this->input = $input;
if (Input::get('buy')) {
return $this->postPurchase();
}
elseif (Input::get('cart')) {
return $this->postAddCart();
}
}
I have 2 functions in my controller that I'm sending a session using the first one to the second function. What I am talking about is:
public function search()
{
$search_term = $this->input->post('search_term');
$this->session->set_userdata('search_term', $search_term);
redirect('search_result/');
}
and the second function:
function search_result()
{
$search_term = $this->session->userdata('search_term');
$data['search_term'] = $search_term;
$this->load->view('includes/template', $data);
}
Everything is fine but, the problem is that, I want to prevent direct access to search_result() function. I mean, I want to unset search_term session when the user calls search_result() directly. What should I do?!
You can use flashdata: http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
CodeIgniter supports "flashdata", or session data that will only be available for the next server request, and are then automatically cleared. These can be very useful, and are typically used for informational or status messages
And this is the code that do what are you looking for:
public function search()
{
$search_term = $this->input->post('search_term');
$this->session->set_flashdata('search_term', $search_term);
redirect('search_result/');
}
function search_result()
{
$search_term = $this->session->flashdata('search_term') ? $this->session->flashdata('search_term') : '';
$data['search_term'] = $search_term;
$this->load->view('includes/template', $data);
}
There are many ways you can do it. Here are some
append a get parameter if it exists then search else redirect back
public function search()
{
$search_term = $this->input->post('search_term');
$this->session->set_userdata('search_term', $search_term);
redirect('search_result?status=1');
}
public function search_result()
{
$status = $this->input->get('status');
if(status == 1){
$search_term = $this->session->userdata('search_term');
$data['search_term'] = $search_term;
$this->load->view('includes/template', $data);
}else{
$this->session->unset_userdata('search_term');
redirect('search');
}
}
Protect you seach_result function and dont let user direct call it.
Using _ will do it for you.
Here is the link you can read.
public function search()
{
$search_term = $this->input->post('search_term');
$this->session->set_userdata('search_term', $search_term);
$this->_search_result($search_term);
}
function _search_result($keyword)
{
if(strlen($keyword)>0){
$data['search_term'] = $keyword;
$this->load->view('includes/template', $data);
}else{
redirect('search');
}
}
in the search function
redirect('search_result/'.$this->session->userdata('search_term'));
in the search_result function
function search_result()
{
if($this->uri->segment(3))
{
$search_term = $this->session->userdata('search_term');
$data['search_term'] = $search_term;
$this->load->view('includes/template', $data);
}
else
{
redirect('search_result/','refresh');
}
}
hope it will help you.please let me know if you face any problem.
I have two associated tables (customers hasmany commands) and this is my form:
<?php echo $this->Form->create('Customer');?>
echo $this->Form->input('Client.name', array('disabled' => true,'value' => 'francis'));
echo $this->Form->input('Command.0.the_date');
echo $this->Form->end(__('save'));?>
and this is my function:
public function add() {
if (!empty($this->request->data)) {
unset($this->Customer->Command->validate['customers_id']);
$this->Customer->saveAssociated($this->request->data);
}
}
But when i process to save data, nothing happens!
Why?
Thanks!
Please use this line on your controller
var $uses = array('Customer','Command');
public function add() {
if (!empty($this->request->data)) {
unset($this->Customer->Command->validate['customers_id']);
$this->Customer->saveall($this->request->data);
}
}