handling database error with ajax request codeigniter - ajax

I am intentionally making error i.e. using one of the coulmn's name wrong to learn how to handle the error with ajax call with codeigniter.
Last Comment in controller function at the end is my question/problem
My AJX Code is following. I am using ajaxform plugin. It shows me all response from controller perfectly but problem is only I am unable to get response from model in controller while using ajax call that is little weird
$('#myForm').ajaxForm
({
success: function(responseText)
{
if(responseText != "1")
$('#feedback').html(responseText);
}
});
Following is snapshot of exact error which i can see in console but unable to get in controller and hence in view. It describes complete error i.e unknown column in given query, but i captured only upper portion.
My model function is below
public function updateItem($id, $data, $tbl)
{
$this->db->where('id', $id);
$r = $this->db->update($tbl, $data);
if($r)
return $r;
else
{
$r = $this->db->_error_message();
return $r;
}
}
My controller function code
public function upadteme()
{
$r = $this->ajax_model->updateItem($uid, $data, 'users');
echo $r." -- "; // Unable to get this echo working
//when using ajaxcall (calling controller through ajax) otherwise fine
}

It looks like the class will not populate _error_message if db_debug is on which it appears to be by default.
In config/database.php, set
$db['default']['db_debug'] = FALSE;
and try again.

Related

laravel - how can I call a function stored in a controller after saving to a database?

I'm following a tutorial on Laravel, adding to a DB via a form. At the end of a function that saves to a DB, it returns back to the page where the form is, but I want to be taken to another page where the information is displayed. In the tutorial I created a controller with a function that returns a view containing all the database info - that element works fine however I can't seem to find a way of calling this function directly after saving to the database. I can also return any other view which just displays static view ( just html with no data handling ). Is what I'm trying to achieve possible?
public function store(){
$li = new \App\LTest1();
$li->creator = request('creator');
$li->title = request('title');
$li->views = request('views');
$li->save();
return back(); // this works
// return view('info'); // this works
//return ('Listings#showList'); this doesnt work = how do i call a function in a controller???
}
// routing
Route::get('info', function () {
return view('info'); // i can get to this static page from my store() function
});
Route::get('thedataviewpage', 'Listings#showList'); // you can route to this but not from the store() function
Redirect is the thing you need here
public function store() {
$li = new \App\LTest1();
$li->creator = request('creator');
$li->title = request('title');
$li->views = request('views');
$li->save();
return redirect('info'); // Redirect to the info route
}
Take this example. Be sure to add the proper route name and a proper message.
return redirect()->route('put here the route name')->with('success', 'Created.');'
to return to a controller action just use
return redirect()->action('Listings#showList');
or you can use route to call that controller action
return redirect('/thedataviewpage');

Codeigniter can't use this->uri->segment(3) as value in function

Why this code is ok
$this->sch_teacher_id = $this->ion_auth->user_by_username("vika")->row()->id;
But this doesn't work?
$this->sch_teacher_id = $this->ion_auth->user_by_username($this->uri->segment(3))->row()->id;
My url is domain:8888/admin_schedule/teacher/vika
route.php contains
$route['admin_schedule/teacher/(:any)'] = "admin_schedule/index/$1";
I use code lines in function __construct(), and the result of it use in another controller function, because 3 functions use this result. If I move this code in one of this functions and use $this->uri->segment(3) then I get not 'vika's lessons, but my own lessons, so
public function user_by_username($username = FALSE)
{
$this->trigger_events('user');
//if no id was passed use the current users id
$username || $username = $this->session->userdata('username');
$this->limit(1);
$this->where($this->tables['users'].'.username', $username);
$this->users();
return $this;
}
works good. But $this->uri->segment(3) if use it as parameter in user_by_username function, doesn't work!
page generated next way:
controller admin_schedule have function index which render view index.php.
And in that view I use javascript, that call another function from admin_schedule controller = get_schedule_db_recurring_events_on_daysweek such way:
...
{
url: '/admin_schedule/get_schedule_db_recurring_events_on_daysweek/',//"<?echo $data_path?>",
backgroundColor: 'red',
}
and in controller
function get_schedule_db_recurring_events_on_daysweek()
{
$start = date('Y-m-d H:i', $this->input->get('start'));
$end = date('Y-m-d H:i', $this->input->get('end'));
$sch_teacher_id = $this->uri->segment(3); // <--- this doesn't work, but $sch_teacher_id = 111 works perfectly
$result=$this->Schedule_model->get_schedule_recurring_events_on_daysweek($start, $end, $sch_teacher_id);
$count=count($result);
if($count>0){
echo json_encode($result);
}
}
Please, help understand this problem.
I can't remember the reason - it's just CI quirk you have learn to accept - you can't use $this->uri->segment(3) etc as an argument directly, you will need to assign it and then pass that as #almix suggested for his sanity test.
At-least I have also always had trouble using it directly as an argument - tho I will be happy for anyone to correct me!
I solved my problem!
Think that something goes wrong because of ajax calls. So when I code in controller
function __construct()
{
parent::__construct();
...
$this->sch_teacher_row = $this->ion_auth->user_by_username($this->uri->segment(3))->row();
$this->data['sch_teacher_id'] = $this->sch_teacher_row->id;
$this->data['subtitle'] = $this->sch_teacher_row->username;
}
Next I have the right value ('vika'), or to be more precise vika's id ('911') in view file but not in other function of my controller. But I can pass this value now (sch_teacher_id) from the view to this controller with jQuery $.ajax option data:
eventSources: [
...
{
url: '/admin_schedule/get_schedule_db_recurring_events_on_daysweek/',//"<?echo $data_path?>",
type: 'GET',
data: {sch_teacher_id: sch_teacher_id},
backgroundColor: 'red',
}
],
And next (on the other side of the mountain) catch this GET parameter and kick it to the model function:
function get_schedule_db_recurring_events_on_daysweek()
{
...
$sch_teacher_id_from_view = $this->input->get('sch_teacher_id');
$result=$this->Schedule_model->get_schedule_recurring_events_on_daysweek($start, $end, $sch_teacher_id_from_view);
...
}
And it is all the breakdance.

How to use form_validation library rules for AJAX requests

One of my forms uses AJAX to send data. Since my page never reloads because of AJAX, is there a way I can still make use of form_validation to validate and output which fields are wrong? The url my form sends to using jquery is contact/ajax_send.
The entire AJAX works fine except I haven't inserted any validation yet.
Since you are using ajax to send the data, what you can do is, simply add the form_validation code calls before inserting into the database.
If there are any validation errors, you can either return the error messages as json response to the front end to display the error messages.
The form validation library assigns all errors that occurred to a private array called _error_array, but does not expose it or provide documentation on it (notice the first underscore?). Just return a json encoded object of the errors in the controller:
echo json_encode($this->form_validation->_error_array);
If you wish, you can extend CodeIgniter's form validation library, perhaps returning FALSE instead of an empty array... or whatever you see fit:
/* libraries/MY_Form_validation.php */
<?php
class MY_Form_validation extends CI_Form_validation
{
function __construct($config = array())
{
parent::__construct($config);
}
function error_array()
{
if (count($this->_error_array) === 0) return FALSE;
else return $this->_error_array;
}
}
Now, drop the initial underscore in the controller:
echo json_encode($this->form_validation->error_array);
Then decode and display errors on the client.
I found a method, thanks in part to Jordan's answer. This returns an array containing the names of the fields which have errors.
// library/MY_Form_validation.php
class MY_Form_validation extends CI_Form_validation {
public function get_field_data(){
return count($this->_field_data) ? $this->_field_data : FALSE;
}
}
// Controller file
$field_data = $this->form_validation->get_field_data();
foreach($field_data as $key=>$val){
if($key == '__proto__') break;
foreach($val as $k=>$v){
if($k == 'error' && !empty($v)) $errors[] = $key;
}
}
$return = array('success'=>FALSE, 'errors'=>$errors);
The above code checks the error key whether it's empty or not. Empty values mean that it passed the CI validation while none empty values would contain the string you see when you use validation_errors(). Since I'm after those fields which have errors, I only needed to see which values are not empty disregardig those which are.

Redirect to show_404 in Codeigniter from a partial view

I am using the HMVC pattern in CodeIgniter. I have a controller that loads 2 modules via modules::run() function and a parameter is passed to each module.
If either module cannot match the passed paramter I want to call show_404(). It works, but it loads the full HTML of the error page within my existing template so the HTML breaks and looks terrible. I think I want it to redirect to the error page so it doesn't run the 2nd module. Is there some way to do that and not change the URL?
Is it possible to just redirect to show_404() from the module without changing the URL?
Here is an over simplified example of what's going on:
www.example.com/users/profile/usernamehere
The url calls this function in the users controller:
function profile($username)
{
echo modules::run('user/details', $username);
echo modules::run('user/friends', $username);
}
Which run these modules, which find out if user exists or not:
function details($username)
{
$details = lookup_user($username);
if($details == 'User Not Found')
show_404(); // This seems to display within the template when what I want is for it to redirect
else
$this->load->view('details', $details);
}
function friends($username)
{
$details = lookup_user($username);
if($friends == 'User Not Found')
show_404(); // Redundant, I know, just added for this example
else
$this->load->view('friends', $friends);
}
I imagine there is just a better way to go at it, but I am not seeing it. Any ideas?
You could throw an exception if there was an error in a submodule and catch this in your controller where you would do show_404() then.
Controller:
function profile($username)
{
try{
$out = modules::run('user/details', $username);
$out .= modules::run('user/friends', $username);
echo $out;
}
catch(Exception $e){
show_404();
}
}
Submodule:
function details($username)
{
$details = lookup_user($username);
if($details == 'User Not Found')
throw new Exception();
else
// Added third parameter as true to be able to return the data, instead of outputting it directly.
return $this->load->view('details', $details,true);
}
function friends($username)
{
$details = lookup_user($username);
if($friends == 'User Not Found')
throw new Exception();
else
return $this->load->view('friends', $friends,true);
}
You can use this function to redirect 404 not found page.
if ( ! file_exists('application/search/'.$page.'.php')) {
show_404(); // redirect to 404 page
}
its very simple , i solved the problem
please controler name's first letter must be capital e.g
A controller with
pages should be Pages
and also save cotroler file with same name Pages.php not pages.php
also same for model class
enjoy

CodeIgniter - showing original URL of index function?

I'm not sure if I'm approaching this fundamentally wrong or if I'm just missing something.
I have a controller and within it an index function that is, obviously, the default loaded when that controller is called:
function index($showMessage = false) {
$currentEmployee = $this->getCurrentEmployee();
$data['currentEmp'] = $currentEmployee;
$data['callList'] = $currentEmployee->getDirectReports();
$data['showMessage'] = $showMessage;
$this->load->view('main', $data);
}
I have another function within that controller that does a bulk update. After the updates are complete, I want the original page to show again with the message showing, so I tried this:
/**
* Will save all employee information and return to the call sheet page
*/
function bulkSave() {
//update each employee
for ($x = 0; $x < sizeof($_POST['id']); $x++) {
$success = Employee::updateEmployeeManualData($_POST['id'][$x], $_POST['ext'][$x], $_POST['pager'][$x], $_POST['cell'][$x], $_POST['other'][$x], $_POST['notes'][$x]);
}
$this->index($success);
}
What is happening is that the original page is accessed using:
localhost/myApp/myController
after the bulk update it is showing as:
localhost/myApp/myController/bulkSave
when I really want it to show the url as the index page again, meaning that the user never really sees the /bulkSave portion of the URL. This would also mean that if the user were to refresh the page it would call the index() function in the controller and not the bulkSave() function.
Thanks in advance.
Is this possible?
You are calling your index() funciton directly, within bulkUpdate() hence the uri does not change back to index because you are not making a new server request, you are just navigating within your controller class.
I usually use the same Controller function for tasks like this, directing traffic based on whether or not $_POST data has been passed or not like this...
function index() {
if($_POST) {
//process posted data
for ($x = 0; $x < sizeof($_POST['id']); $x++) {
$data['showMessage'] = Employee::updateEmployeeManualData($_POST['id'][$x], $_POST['ext'][$x], $_POST['pager'][$x], $_POST['cell'][$x], $_POST['other'][$x], $_POST['notes'][$x]);
}
}
else {
//show page normally
$data['showMessage'] = FALSE;
}
//continue to load page
$currentEmployee = $this->getCurrentEmployee();
$data['currentEmp'] = $currentEmployee;
$data['callList'] = $currentEmployee->getDirectReports();
$this->load->view('main', $data);
}
Then if it is a form that you are submitting, just point the form at itself in your view like this...
<?= form_open($this->uri->uri_string()) ?>
This points the form back at index, and because you are posting form data via $_POST it will process the data.
I usually do a redirect to the previous page as it prevent users to refresh (and submit twice) their data.
You can use the redirect() helper function of CI.
http://codeigniter.com/user_guide/helpers/url_helper.html (at the bottom)

Resources