Ajax call and then include a blade section - laravel

I have a {{!! Form::model!!}} where I am passing a variable $values from the Controller and displaying it inside of the Form select those values. In mine main blade i have 3 additional blades I am including through
#if($jobs->open)
#include('jobs.review.open')
#endif
I am trying to load the data $jobs from controller only when someone clicks , I figured to do some by create an ajax call with onclick event, so i have the data $jobs back. An only now trying to include jobs.review.open blade.
Any help will be appreciated

One common strategy is to put the rendering in the AJAX call. The server returns a ready-to-go chunk of HTML in its reply, and the JavaScript code simply inserts it into the DOM at the appropriate place with innerHTML. The server uses a blade to prepare the HTML that it then returns.
The initial page HTML that is displayed doesn't include the content, but does include dummy placeholder <div>s which mark the places where the HTML will be inserted.

Related

Laravel - Get HTML of current page or of a view according to a path

I have a view mypage.blade.php and a route.
The url is like : https://example.com/mypage/param1/param2. The route use param1 and param2 and generate the page.
Question 1
In that page, I try to get its HTML code. Is there a way to do it?. I tried render() but I don't get what I want.
Question 2
In the view, can I get the HTML code of an other view by specifying a path ?
You had the right idea. Not sure why it wouldn't work for you.
In the controller, set the view into a variable:
$view = view('myBaseView', compact('people', 'places', 'things'));
Now, if you dump the rendered view variable, you have the page's HTML:
dd($view->render());
To get the html of another view by specifying the path and using the internal controller, you would need to set up some kind of a wrapper or catch so that the view variable is not returned as a view, but rendered out to html as above. Your method would need to trap whatever the original controller was sending before it pushed out the view.
Of course, old school php can get the other page's rendered html too possibly if your server is set to allow this:
$html = file_get_contents('http://mypage.com/');
Something else you might find handy is the Laravel sections method. If you just want to render part of the page you can do so by calling whatever section you want from a partial view:
$sections = $view->renderSections(); // returns an associative array of 'content', 'pageHeading' etc
dd($sections['modalContent']); // this will only dump whats in the content section
I don't know what you want to do with this html, but if you wish to display it on a page, once you send it (you'd possibly want to return the view along with a compact of the variable $view... as a normal variable if so), remember to use this format:
{!! $view !!}
HTH

Check to see if a page is called via Ajax in Laravel

This is an extension from a post I made a few days ago: Change a page without refreshing - Laravel / Ajax
Basically, I'm trying to replicate the URL Structure of Soundcloud where you can click on a link, it'll load the content without refreshing the page however if you land directly on that page, it won't replicate design and effecitvely break.
I've been thinking of ways on how I can check in Laravel if the page is requested via Ajax or has been landed on without an Ajax call.
What's happening at the moment is that when I call the page, the view has a master template that's extended thus creating duplicate master templates on the one view.
I was thinking if I done something like
#if(!Request::ajax())
#extends('masterlayout')
#endif
It would work but tried and no luck.
Any help as always is greatly appreciated!
Thanks
Looks like #extends directive is always executed even in falsy if
You can add an empty layout and perform check like this:
#extends(Request::ajax()? 'layouts.empty' : 'layouts.master')
and you need add only this in layout empty.blade.php:
#yield('content')
or you can add ajax check in the master layout
#if(!Request::ajax())
// all layout code
#else
#yield('content')
#endif
You can check that in your controller action.
public function index(Request $request)
{
if($request->ajax()){
return "This is an AJAX call!";
}
return "Not an AJAX call...";
}
Thanks for all the answers, I eventually got this fixed by using #if(!Request::ajax()) on section that didn't need to be shown when the page was loaded via ajax.
Thank you again! :D

Reload javascript after thymeleaf fragment render

I have javascript files defined in the <head> of both my layout decorator template and my individual pages which are decorated. When I update a thymeleaf fragment in one of my pages the javascript defined in the head of the parent page no longer works. Is there a standard way to 'refresh' these js files?
Thanks.
Additional clarification :
I have a form submitted by an ajax call which updates a table in the page. I have a Jquery onClick function targeting a button in the updated table. The javascript doesn't seem able to bind to the returned elements in the updated part of the page. I select by element class and can see that the selection works prior to the partial fragment render.
For me it is unclear what you mean by
javascript defined in the head of the parent page no longer works.
The page is created on the server. Normally it contains urls of the javascript files
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
In this case 'refreshing' the javascript files can happen only in the client.
Check the html of the page in the client.
Are the tags as expected ?
Are there tags for all expected javascript files ?
With the browser tools (for example Google Chrom developer tools ) check that all script files are actually loaded.
If this doesnt help, it could be that the order of the script tags has changed between the first and second load. This could cause a different behaviour of the javascript executed in the browser.
EDIT :
With the initial load you bind javascript callbacks to dom elements.
You do this directly or through Jquery or other libraries.
When a new dom element is loaded, it has no callbacks bound to it, even if it has the same id as a replaced dom element.
So after the load you have to bind your callbacks again.
If you bound them 'by hand', just bind it again.
If you are using a JQuery plugin, that made the bindings, look into the code or documentation, many of them have a function for that or you can call initialization again.
Once you added new content to the DOM you need to bind again the new content.
Let's say I have a button with some class, the event in binded to the class:
<button class="someclass">Button 1</button>
<script>
var something = function() {
// do something
};
$(".someclass").on("click", something);
</script>
If I add more buttons from the same class to the DOM, they will have not have the click event binded. So once you load the new content via ajax, also remove all binding and add again (you need to remove or you will have buttons with 2 events).
$(".someclass").off("click");
$(".someclass").on("click" , something);

Laravel usage "#layout" in Ajax Requests

Hi there stackoverflow!
In my laravel views I am using a default layout by calling
#layout('layouts.default')
to the same controller I am sending Ajax Requests yet I can't put 'if' to #layout if its a ajax call. Because if ajax request has made to controller it also produce header, footer and content(header and footer are in default layout). So to avoid this I made one copy without #layout of my view.
However its so boring to edit two files for making changes. Can't I add a code to my view something like that?:
#if(!$ajaxrequest)
#layout('layouts.master')
#endif
I want this because my codes in controllers are too messy
A slight variation is to put the logic for the layouts in your main layout template. e.g.
layouts/app.blade.php:
#if (Request::ajax())
#include('layouts.ajax-app')
#else
#include('layouts.default-app')
#endif
Your views just extend the main layout as usual e.g.
#extends('layouts.app')
#section('content')
Content goes here...
#endsection
And then create a default layout file (default-app.blade.php) and an ajax layout file (ajax-app.blade.php). The advantage of doing it this way is that any of your blade templates can be loaded via Ajax, without having to clutter up controller methods with lots of duplicated logic.
You can't have the #layout call after the if statement like that (see the notice in red under "Blade Templating" in the docs. You'll have to set the public $layout and call $this->layout->nest instead of View::make (see "The Basics" on the page linked to above).
You can use something like this in your view template:
#extends( 'layouts.' . (isset($layout) ? $layout : 'default'))
Also apply check in your controller(or Supercontroller) for AJAX request, if it is set $layout variable to needed layout. Otherwise "default" layout will be taken.

Codeigniter AJAX and POST

What is the best way to address an AJAX script that sends data to POST in codeigniter? Right now I am loading a view with the AJAX through $this->load->view('AJAX', $data); however there is no UI or user actions in the view. It's simply running through the script and returning POST data a little after the script loads. I receive the POST data in my model where I input the values into the DB and output some other values based on the data.
I need to open a real view, set metatags and re-direct the user to another website afterwards.
How do I address this?
The problem I'm facing is that I cannot open up another view because the AJAX view is the one that's in focus but I need this AJAX view to be temporary that basically does it's thing and sends to POST.
Is there any convention that I can lookup/research to what I'm describing? Let me know what kind of clarification is needed if any.
Some people like to write "ajax" controllers and post to them exclusively, but you don't need to do that. You can handle the request in the same controller that handles the non-ajax request. Personally, I exclusively return json, but you can return chunks of HTML if that works better for you.
Your exact problem is vague (actual code would help clarify), but I think you are on the wrong track. Don't use a view for processing anything ever. Use your Controller layer, this is for handling input and requests.
Example of controller method responding to either ajax or non-ajax request:
function edit_user()
{
$data['status'] = $this->user_model->save();
if ($this->input->is_ajax_request())
{
// return json string with our update status
// Something like: {"status":true}
echo json_encode($data);
exit;
}
// Load the non ajax view with the same data
$this->load->view('users/edit', $data)
}
$this->input->is_ajax_request() is a function of the Input class that reads $_SERVER['HTTP_X_REQUESTED_WITH'] and checks if it's value is XMLHttpRequest. This should only be true if it's an "ajax" request.
You can make life easier by wrapping this in a class or function. No matter what you decide to do, don't use the view layer for processing data.
I think my problem is, how do I address javascript without a view? how do I call the script and/or where do I put the JS code in the controller? I felt it was the wrong direction to address the code in a view but I didn't see how else to do it.
Whenever possible, you should put javascript code in a .js file and use a <script> tag to load it, in an HTML document. The only other exception is putting it in a "view" file (a file that's only purpose is to construct your final HTML output). In other words, follow the same rules of HTML as to where to put javascript, and follow the usual conventions of MVC of where HTML belongs (in the view). Javascript code does not belong in your controller. Javascript is not processing your data, it is sending the data to the server.
I need to open a real view, set metatags and re-direct the user to another website afterwards.
If you want to load a view, then redirect (after a certain amount of time I assume), you can do it with javascript or a <meta> tag (but don't use a meta tag, use js).

Resources