Reopening page on Codeigniter - codeigniter

I am trying to reopen same page on Codeigniter. See code below:
<?php
class Leads extends CI_Controller
{
public $tempName;
public $tempFrom;
public $tempTo;
public function index() {
$this->load->model('Lead');
$leads = $this->Lead->getAllLeads();
$pageNum = count($leads);
$this->load->view('main', array('leads' => $leads, 'pageNum' => $pageNum));
}
public function getLeads(){
$this->load->model('Lead');
$name = $this->input->post('name');
$from = $this->input->post('from');
$to = $this->input->post('to');
$leads = $this->Lead->getLeads($name, $from, $to);
$pageNum = count($leads);
$this->load->view('main', array('leads' => $leads, 'pageNum' => $pageNum));
}
}
?>
As you can see, first I open 'main' from 'index()'. In main, I call 'getLeads()', but my page is not getting updated. Is it because I can't refresh data while on the same page? If yes, how can I work around it?
Thanks a lot!

You cannot call a controller from a view. It sounds like you probably should be using AJAX in your "main" view to get additional data from getLeads().

Option A:
redirect with js to the same function you have, but change the method to get (send params in the URL and get them on the server with $this->input->get()).
Option B:
Since you are posting to getLeads I assume you are using ajax. And since you are using ajax, you should return an url or data to render on your website. Maybe you could use $this->session->set_flashdata('leads',$leads) and $this->session->set_flashdata('pageNum',$pageNum) , send an url to another controller function, extract leads and pageNum $this->session->flashdata('leads') & $this->session->flashdata('pageNum') and then render the view?
Responding with load view will not automatically set the html to what you get.

Related

Testing redirect links to external sites

I have a link on a page /my/example/page which links to a laravel route my.route.
Route
Route::group(['middleware' => ['auth']], function () {
Route::group(['middleware' => ['Some\Custom\Auth\Middleware:1']], function () {
Route::match(['GET', 'POST'], '/my/route/to/external/controller', 'exampleController#externalLink')->name('my.route');
}
}
Link on /my/example/page
Link
This route /my/route/to/external/controller points to this controller method externalLink in the exampleController controller, which returns the url for the href to use
public function externalLink()
{
return $this->redirect->away('www.externalsite.com');
}
My test is
$this->visit(/my/example/page)
->click('Link')
->assertRedirectedToRoute('my.route');
I constantly get the error
Symfony\Component\HttpKernel\Exception\NotFoundHttpException
when I use the click() testing method.
I can catch this using #expectedException but his doesn't help as I am expecting to see a different page.
I have also tried (not together);
->assertResponseStatus(200);
->seePageIs('www.externalsite.com');
->assertRedirect();
->followRedirects();
From browser inspection, when the url is clicked I get
http://www.example.com/my/route/to/external 302
http://www.externalsite.com 200
How can I functionally test the button being clicked and redirecting to an external site?
I am struggling with a similar problem right now, and I have just about given up on testing the endpoint directly. Opting for a solution like this...
Test that the link contains proper information in the view:
$this->visit('/my/example/page')
->seeElement('a', ['href' => route('my.route')]);
Moving the logic in the controller to something you can test directly. The Laravel\Socialite package has some interesting tests that might be helpful if you do this...
class ExternalLinkRedirect {
public function __construct($request){
$this->request = $request;
}
public function redirect()
{
return redirect()->away('exteranlsite.com');
}
}
Then test it directly
$route = route('my.route');
$request = \Illuminate\Http\Request::create($route);
$redirector = new ExternalLinkRedirect($request);
$response = $redirector->redirect();
$this->assertEquals('www.externalsite.com', $response->getTargetUrl());
A simple way is to use the get method instead of visit.
An example:
$this->get('/facebook')
->assertRedirectedTo('https://www.facebook.com/Les-Teachers-du-NET-516952535045054');

Laravel Trying to get property of non-object but not sure why

I want to grab some data from a database and display on a layout page, I've basically started building a small CMS to get into Laravel and all has gone fine so far but now i'm at a wall, and can't find a solution.
I have a layout blade file like so: http://paste.laravel.com/1fB1 nothing majot but you will see i have used $page->meta_title etc in there and in my controller i have:
public function home()
{
$pages = Pages::all();
return View::make('frontend/home')->with('pages',$pages);
}
Which I have a pages model doing nothing else really like so:
class Pages extends Eloquent {
protected $table = 'pages';
}
So why is it trying to get property of non-object and I don't really want to use a foreach because this is going to be the frontend of my 'test' website so a foreach wouldn't suite.
You'll need to access these items as a multi-dimensional array if you don't want to loop through them.
$pages[0]['field_name_here']
or
$pages[1]['field_name_here']
Its a bit of a tough one to answer without knowing how you want your CMS to work.
For example, you could have a route as {pagename} in your routes.php file, then have a page controller where you would get the requested route from the variable passed in. This would then load the page you wanted using the variable
public function page( $pagename ) {
$page = Page::where('page_title', '=', $pagename)->first();
View::make('frontend/page', array( 'page' => $page ));
}
Using a route like that, and the controller, in your view you could use {{ $page->content }} to get the content of the requested page from the database and display it.
Hope this helps.
Edit: Example Route:
Route::get('{pagename}', 'PageController#page');

Laravel 4: Responding to AJAX requests from controller

I'm trying to generate ajax specific responses from my controllers by using the Request::ajax() method, which is working just fine. The only problem is that the way I have it set up right now isn't really a nice looking solution.
My controller:
class HomeController extends BaseController {
protected $layout = 'layouts/main';
public function __construct()
{
$this->beforeFilter('auth');
}
public function getIndex()
{
$view = View::make('content.home.index');
if(Request::ajax()) return $view; //For ajax calls we only want to return the content to be placed inside our container, without the layout
$this->layout->menu = 'content.menu';
$this->layout->content = $view;
}
}
So right now, for every method I define within my controllers I need to add the code snippet that checks for an AJAX request and returns a single view if the statement returns true.
This leads to my question that is probably more PHP related than it is to the framework;
Is there a way of executing my AJAX check on every method call, without actually placing it inside the method? Or is there some other solution to keep my code DRY?
Thanks in advance!
PS: This is my first post on stackoverflow, so feel free to correct me if I made any mistakes
Create a new barebone layout named 'layouts/ajax' (or any name you like).
<?php echo $content ?>
In your Base controller, override this setupLayout() function.
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$layout = Request::ajax() ? 'layouts/ajax' : $this->layout;
$this->layout = View::make($layout);
}
}
Change your getIndex() function to this.
public function getIndex()
{
$view = View::make('content.home.index');
$this->layout->menu = 'content.menu';
$this->layout->content = $view;
}
Now non-ajax requests will be rendered using layout set in the controller, where as ajax requests will receive whatever set to $this->layout->content.
Note : Controller will neglect the layout setup in setupLayout(), if the called method returns truthy value. So this method will not work for functions like below.
public function getIndex()
{
return View::make('content.home.index');
}
You could just change the layout property, in the constructor, if it's an ajax request:
public function __construct()
{
$this->beforeFilter('auth');
if(Request::ajax()) {
$this->layout = '';
}
}
If it doesn't work try setting it to NULL instead.
Why would you return a VIEW via ajax? Are you using it to create a SPA? If so there are better ways. I'm generally against returning HTML via AJAX.
The route I'd go in your position is probably opposite of how you're doing it. Render the view no matter what, if the request is ajax, pass the extra data back and have JS render the data on the page. That's essentially how most Javascript MVC frameworks function.
Sorry if I am totally missing the point here, just going on an assumption of your end goal with the info you provided.

post the form and again load the view ,best suggested way

Till now i am using the form post method like this::
controller ::
public function loading_view()
{
.
.
.
.
$this->load->view('abc');
}
view abc:
">
when this form posted it will redirected to
public function method_of_controller()
{
.
//perform query
.
// here i am havin 2 way to call
//1.
$this ->load->view('abc');
//and 2.
load->loading_view();
}
//bu url remain same after the post method like ....index.php/loading_view
and but on reloading the page again the query runs fr 2nd method of loading view
so which way you will suggest me to use best
1- If you are not passing data to your view and your view is just contains html and javascript
than first method is beter.
2- if you are passing data to our abc view page than second is beter.
3- beter way is to make another view for this part for portability
because in some point you will reach you make changes so it is beter to each should be
separate.
yes you can post data to save view, without changing url redirection, in following way
controller
class PostTest extends CI_Controller{
public function loading_view()
{
$this->form_validation->rules('name','Name','required');
if(!$this->form_validation->run()){
$this->load->view('abc');
}
else{
$name = $this->input->post('name');
}
}
}
now here is most interesting part is view in form action you need to use uri_string() method like this
view
<? echo form_open(uri_string())
.form_input('name').br()
.form_error('name')
.form_submit('submit','Post data');
?>

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