JavaScript code in view issue in Laravel - laravel

I put JavaScript code in a view file name product/js.blade.php, and include it in another view like
{{ HTML::script('product.js') }}
I did it because I want to do something in JavaScript with Laravel function, for example
var $path = '{{ URL::action("CartController#postAjax") }}';
Actually everything is work, but browser throw a warning message, I want to ask how to fix it if possible.
Resource interpreted as Script but transferred with MIME type text/html

Firstly, putting your Javascript code in a Blade view is risky. Javascript might contain strings by accident that are also Blade syntax and you definitely don't want that to be interpreted.
Secondly, this is also the reason for the browser warning message you get:
Laravel thinks your Javascript is a normal webpage, because you've put it into a Blade view, and therefore it's sent with this header...
Content-Type: text/html
If you name your file product.js and instead of putting it in your view folder you drop it into your javascript asset folder, it will have the correct header:
Content-Type: application/javascript
.. and the warning message will be gone.
EDIT:
If you want to pass values to Javascript from Laravel, use this approach:
Insert this into your view:
<script type="text/javascript">
var myPath = '{{ URL::action("CartController#postAjax") }}';
</script>
And then use the variable in your external script.

Just make sure that CartController#postAjax returns the content type of javascript and you should be good to go. Something like this:
#CartController.php
protected function postAjax() {
....
$contents = a whole bunch of javascript code;
$response = Response::make($contents, '200');
$response->header('Content-Type', 'application/javascript');
....
}

I'm not sure if this is what you're asking for, but here is a way to map ajax requests to laravel controller methods pretty easily, without having to mix up your scripts, which is usually not the best way to do things.
I use these kinds of calls to load views via ajax into a dashboard app.The code looks something like this.
AJAX REQUEST (using jquery, but anything you use to send ajax will work)
$.ajax({
//send post ajax request to laravel
type:'post',
//no need for a full URL. Also note that /ajax/ can be /anything/.
url: '/ajax/get-contact-form',
//let's send some data over too.
data: ajaxdata,
//our laravel view is going to come in as html
dataType:'html'
}).done(function(data){
//clear out any html where the form is going to appear, then append the new view.
$('.dashboard-right').empty().append(data);
});
LARAVEL ROUTES.PHP
Route::post('/ajax/get-contact-form', 'YourController#method_you_want');
CONTROLLER
public function method_you_want(){
if (Request::ajax())
{
$data = Input::get('ajaxdata');
return View::make('forms.contact')->with('data', $data);
}
I hope this helps you... This controller method just calls a view, but you can use the same method to access any controller function you might need.
This method returns no errors, and is generally much less risky than putting JS in your views, which are really meant more for page layouts and not any heavy scripting / calculation.

public function getWebServices() {
$content = View::make("_javascript.webService", $data);
return (new Response($content, 200))->header('Content-Type', "text/javascript");
}
return the above in a method of your controller
and write your javascript code in your webService view inside _javascript folder.
Instead of loading get datas via ajax, I create js blade with that specific data and base64_encode it, then in my js code, I decode and use it.

Related

Laravel: controller not teletransporting me (redirect-ing me) to the page

from Ajax the controller does get the keyword I want, as it confirms it (because I echo it), and my idea was that on getting that keyword, it should redirect to the page I want. Yet, it does not, and also, while it does change the locale, I have to reload the page, otherwise, it won't show any translation and locale changes on the page. In Firebug when I hover over the POST, I get the correct URL to where I would want to go: sort of http://myweb.com/es but the controller does not change the http URL box of my browser on my web to go there.
I am simplifying the Controller code here, but actually I will want it to go to different URLs depending on the keyword it gets, something that I would do with a switch statement or IF else if etc.
So the controller is as simple as this:
public function changelanguage()
{
$lang = \Input::get('locale');
echo "I got $lang";
Session::put('locale', $lang);
return redirect('/es');
}
If instead of using ajax I use a Form, then I dont need to reload, the Action of the form makes the controller change the locale and translate the page without reloading. But I need to use ajax and in any case, the controller does get correctly the keyword ('en', 'es', 'de' etc ) for languages, so it should take it from there and redirect me to the URL page, but it just doesnt move.
if you are curious about the Ajax, here it is, but it does send the keyword as I said.
$(document).ready(function(){
$('.choose-language').on('click', function(e){
e.preventDefault();
var selectedlanguage = $(this).data('value');
$.ajax({ // so I want to send it to the controller
type:"POST", // via post
url: 'language',
data:{'locale': selectedlanguage},
}); // HERE FINISHES THE $.POST STUFF
}); //HERE FINISHES THE CLICK FUNCTION
}); // HERE FINISHES THE CODE
ROUTES
Route::post('language', array(
'as' =>'language',
'uses' => 'LanguageController#changelanguage'
));
If you’re trying to perform the redirect in the AJAX-requested script, then it won’t work. You can’t redirect from a script request via AJAX otherwise people would be doing all kinds of nefarious redirects.
Instead, set up a “success” handler on your AJAX request that refreshes your page if the request was successful. It can be as simple as:
var url = '/language';
var data = {
locale: $(this).data('value');
};
var request = $.post(url, data)
.success(function (response) {
// Script was successful; reload page
location.reload();
});
I’m not sure how you’re allowing users to select locales, but since you need a reload any way I think AJAX is pointless here. Just have a traditional form that submits the new locale to an action, set the locale in a session/cookie/whatever, and then redirect back to the referring page.

Serialize Laravel Query Builder

I would like to be able to construct a query using laravel, and serialize it into a url string.
This would allow me to create routes which would unserialize a query builder, run the query, and make a view which displays the database results.
For example, to implement a button which refreshes a list of posts made by kryo:
http://example.com/ajax/posts.php?name=kryo&order_by=created_at&order_type=desc
Posts.php would simply be a route which unserializes, validates, and runs the query in the url params, and provides the results to a view.
Perhaps this is not useful in general, but I would personally find it handy specifically for ajax requests. If anyone knows how to implement this as a laravel plugin of some nature, that would be fantastic.
I'll try to give you a basic idea:
In Laravel you have to create a route to make a request to a function/method, so at first you need to create a route which will be listening for the ajax request, for example:
Route::get('/ajax/posts', array('uses' => 'PostController#index', 'as' => 'showPosts'));
Now, create a link in the view which points to this route, to create a link you may try this:
$url = to_route('showPosts');
If you use something like this:
<a class='ajaxPost' href="{{ $url }}?name=kryo&order_by=created_at&order_type=desc">Get Posts</a>
It'll create a ink to that route. So, make sure you are able to pass that $url to your JavaScript or manually you can write the url using /ajax/posts?name=.... Once you done creating the link then you need to create your JavaScript handler for this link (maybe using click event) then handle the click event from your handler, make ajax request, if it's jQuery then it could be something like this:
$('.ajaxPost').on('clcik', function(e){
e.preventDefault();
var url = $(this).attar('href');
$.getJSON(url, function(response){
$.each(response, function(key, value){
// loop... you may use $(this) or value
});
});
});
In your PostController controller class, create the index method:
class PostController extends BaseController {
public function index()
{
$name = Input::get('name');
$order_by = Input::get('order_by');
$created_at = Input::get('created_at');
$order_type = Input::get('order_type');
$posts = Post::whereName($name)->orderBy($order_by, $order_type)->get();
if(Request::ajax()) {
return Response::json($posts);
}
else {
// return a view for non ajax
}
}
}
If you want to send a rendered view from the server side to your JavaScript handler as HTML then change the getJson to get and instead of return Response::json($posts); use
return View::make('viewname')->with('posts', $posts);
In this case make sure that, your view doesn't extends the master layout. This may not be what you need but it gives you the idea how you can implement it.

How to use AJAX in Joomla component to load the State field based on the country selected?

Inside a component's view, I have something like this:
<?php echo TestcompHelperFind::loadStates(...); ?>
<?php echo TestcompHelperFind::loadCounties(...); ?>
The above static functions load <select> dropdowns with the state names and countries respectively.
The class TestcompHelperFind is located in the file /administrator/components/com_testcomp/helpers/find.php.
How do I load States dropdown list based on the country selected using AJAX? I'm not sure what url I should provide in the ajax function.
On the client, you will need a function that watches the country select for changes, and when it happens calls the appropriate url with a callback that will populate the counties select.
On the server, you need to output the select content.
Since you have the html output already working, let's use this approach. As an alternative you could have your server method return a json object and use the javascript to parse it and populate the select. But let's stick to html communication, i.e. the server returns the html contents of the select.
1. On the server
1.a. Output the counties select
We only need to return the result of the TestcompHelperFind::loadCounties(...); to the ajax call. This is achieved easily writing a new method in the component's controller, i.e. the controller.php in the root of the component folder or one of the sub-controllers if appropriate. It's up to you to place it in a meaningful spot.
Inside the controller simply add a new public task such as
class SomethingController extends JController
{
public function getCountiesHTML() {
$input = JFactory::getApplication()->input;
$country = $input->getCMD('filter_country');
// load helper if necessary, then:
echo TestcompHelperFind::loadCounties($country);
exit; // this will stop Joomla processing, and not output template modules etc.
}
Please note the exit; at the end, this will make Joomla output only the component's output (our echo) and not the whole template/modules etc.
1.b Add an ID to the country and county selects so that it will be possible to manipulate them on the client; I'll assume filter_country and filter_county ;
2. On the client
you will want to invoke the url
index.php?option=com_something&action=getCountiesHTML&filter_country=UK
when the country select is changed. It will also need to cancel any pending requests to avoid overlapping messages. To keep things simple, let's assume you use a library to handle Ajax, I'll write an example for jQuery:
<script>
var xhr;
jQuery(function($) {
$('#filter_country').change(function(){
var filterCountry = $('#filter_country').val();
if (xhr && xhr.abort) {xhr.abort();xhr=false;}
xhr = jQuery.ajax(
url: 'index.php',
data: 'option=com_something&task=getCountiesHTML&filter_country='+filterCountry,
success: function(data){
jQuery('#filter_county').replaceWith(data);
}
);
});
});
</script>
For cancelling the previous request, please see a dedicated answer such as this one.

Sammy intercepts a POST that is not one of the added routes

I have an application that uses Sammy for some simple client-side routing.
One of the pages has a "Download Pdf" button, which needs to do a POST to get and download a pdf document (not very resty, I know, but it has to be a POST due to the large amount of data I'm submitting). It does this using the old trick of dynamically creating, populating, and submitting a <form> element.
Everything works fine, except for I can see in the console an error from sammy that my route was not found. Note that this is not a route, or even a verb that Sammy should be handling.
Here is my reduced test case
Sammy(function initializeClientRouting(app) {
app.get('#/', show('#default'));
app.get('#/test', show('#test'));
function show(selector) { return function() {
$('section').slideUp();
$(selector).slideDown();
}; }
}).run('#/');
$('button').click(function() {
var form = $("<form method=post action: 'http://www.google.com'>").hide();
$('<textarea name=q>').text("search text").appendTo(form);
form.appendTo('body').submit().remove();
});
Does anyone know how to prevent this error? Is this a bug in Sammy?
It's a combination of sammy & JQuery behaviour (bug?). When generated dynamically the way you put it, the form tag is being rendered as
<form www.google.com'="" 'http:="" action:="" method="post">
This will try to POST to the current page which probably is something like
http://blah/# or http://blah/#/test
For some reason, Sammy will be triggered because of the hashtag, not finding a POST configured and log an error.
Fiddling with your example, what worked for me was:
var form = $("<form>");
form.attr('method', 'post');
form.attr('action', 'http://www.google.com');
$('<textarea name=q>').text("search text").appendTo(form);
form.appendTo('body').submit().remove();
This seemed to generate the proper HTML and remove the Sammy error.

codeigniter get URL after ajax

I am trying to get the URL i see on my browser after i do an ajax request but the problem is that it changes the URL with the Ajax URL.
ex.
i am on domain.com/user/username
and the ajax URL that i call is in domain.com/posts/submit
when i echo $_SERVER['REQUEST_URI'] on the posts controller in submit function it will display the second URL and not the first... how can i assure and get the first inside the ajax function that its 100% valid and not changed by the user to prevent any bad action?
Thanks
There is HTTP_REFERER but I don't know if that works for javascript requests. Another problem of this: It won't work for all browsers.
You could try the following:
1.) As the user visits domain.com/user/username the current URL is saved with a token - let's say 5299sQA332 - into the database and the token is provided through PHP to Javascript
2.) The ajax request will send this token along with the other variables needed to the controller through POST
3.) In your ajax controller you search the database for the given token 5299sQA332 and there you have your first URL and you can be damn sure, that it hasn't been manupulated
:)
If I understand you correctly, you want to make sure the ajax call is coming from the page it is supposed to be on? In that case just pass a token with the call.
In the controller function set a token variable in session;
public function username() {
$this->session->set_userdata('ajax_token', time());
}
Then in the view with the js;
$.ajax({
url: '/user/username',
type: 'post',
data: 'whatever=bob&token='+<?php echo $this->session->userdata('ajax_token'),
success: function( data ) {
},
error: function( data ) {
}
});
Then in you form validation, do a custome callback to check they are the same.
Have you looked at CodeIgniter's Input Class ?
$this->input->get('something', TRUE);
i used javascript for it and it seems to work... hope not to have any problems in the future with it...
ps: i dont get why my other answer was deleted.. thats the answer anyway.

Resources