My home page had some inline javascript that was mixed up with some blade syntax e.g.
<script type="text/javascript">
#if(Auth::user())
if(path.indexOf('/user/' + {{Auth::user()->id}} ) != -1) {
$( "#tabs" ).tabs();
};
#endif
</script>
It worked until I wanted to move the javascript to an external file.js. I got error whenever blade syntax was added. Is there a way I can fuse blade syntax in my javascript files.js? I tried renaming to file.blade.js with no luck...
Although the accepted solution will work, this is a most definitely an antipattern.
If I saw this not being the one who wrote it, I would be extremely confused to what's going on.
My suggestion is in your PHP file, have a block, which gets all of the values that you'll need in your external files, then call the external files.
So in your PHP file you would have something like:
<script>
var userID = "{{ Auth::user()->id }}";
var isUser = "{{ Auth::user() }}"
</script>
{{ HTML::script('path/to/js/file.js') }}
And in your javascript file:
if(isUser)
{
if(path.indexOf('/user/' + userID ) != -1) {
$( "#tabs" ).tabs();
};
}
you can try this save your javascript file in app/views folder and rename it to xxx.blade.php , yes .blade.php because Blade Engine will parse it only if its .blade.php and use #include('your javascript filename') to include the javascript file parsed by Blade, it will work.
I was doing the same than #BrandonRomano, but I found a better approach. Sending directly the value from PHP to JS vars using:
PHP-Vars-To-Js-Transformer
PHP:
JavaScript::put([
'foo' => 'bar',
'user' => User::first(),
'age' => 29
]);
JS:
console.log(foo); // bar
console.log(user); // User Obj
console.log(age); // 29
You can set a namespace like:
console.log(server.foo)
You are outputing string from PHP, so you have to enclose that string in '
<script type="text/javascript">
#if(Auth::user())
if(path.indexOf('/user/' + '{{Auth::user()->id}}' ) != -1) {
$( "#tabs" ).tabs();
};
#endif
</script>
Related
laravel Controller
if($validator->failed())
{
return redirect()->back()->with(['errors'=>$validator->errors(),'input'=>$request]);
}
JavaScript file
<script type="text/javascript" >
var registrationErrors = #json($errors);
var input= #json($input);
</script>
In this case registrationErrors it's working fine but input return error like
Action Facade\Ignition\Http\Controllers\ExecuteSolutionController not defined.
If pass only one argument in with() function that should be work fine.
Laravel Controller
if($validator->failed())
{
$data=["errors"=>$validator->errors(),
"input" => $input
];
return redirect()->back()->with('data',$data);
}
Java Script
<script type="text/javascript" >
var data = #json($data);
</script>
My issue is solved, this way is perfectly working
I'm trying to use jquery in an ejs template to make an input auto complete using an array sent by the server to the template.I get the following error :
ReferenceError: /var/www/html/DM/views/formulaire.ejs:8
6| <title>Formulaire </title>
7| </head>
>> 8| <%
9| $( "#depart" ).autocomplete({
10| source: autoComp
11| });
$ is not defined
I made some researches and found out that you can't use client side javascript (jquery) with server side javascript (ejs), but i didn't find any solution.
Here is the code :
<!DOCTYPE html>
<html lang="fr">
<head>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<meta charset="UTF-8">
<title>Formulaire </title>
</head>
<body>
<script>
$( "#depart" ).autocomplete({
source: autoComp
});
</script>
<form action="/result" method="post">
Départ:<input type="text" name="depart" id="depart"><br>
Arrivée: <input type="text" name="arrivee"><br>
<input type="submit" value="Chercher un itinéraire">
</form>
<%
if(erreur){
%> <p>Erreur lors de la saisie des stations</p>
<%
}
%>
</body>
</html>
Thank you for your help
EDIT : No error anymore but auto completion doesn't work.
You need to put client side code in a <script> tag
Change
<%
$( "#depart" ).autocomplete({
source: autoComp
});
%>
To
<script>
$( "#depart" ).autocomplete({
source: autoComp
});
</script>
And put it inside the head or body
I assume you were creating the array in the action and passing it to the view. You then have to go one step further and pass it from the server-side view engine, to the actual browser engine.
<script>
let autoComp = JSON.parse( `<%= JSON.stringify( autoComp ) %>` );
What this does:
tells the EJS engine to render the array as a JSON string
(note the backticks, you need some kind of quotation mark because it's a string)
The browser-side JS engine then runs that string through JSON.parse
Obviously this ability only works one-way; to get a variable from the browser to the EJS you need to commit an action (POST/GET).
You may also need some substitutions to make the string play nice, such as:
function fixForJSON(val) {
return val.replace(/'/g, ''').replace(/\\/g, '\\\\');
}
function fixForDisplay(val) {
return val.replace(/'/g, "'").replace(/\\\\/g, '\\');
}
If you really want to do this:
<%
$(selector).doStuff();
You need to pass the JQuery object itself, into the template variables.
E.g. in your node code:
const jsdom = require('jsdom');
const jquery = require('jquery');
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
const $ = jquery(dom.window);
global.jq = $;
Then in your specific route action (still node code)
var locals = { // the var you are sending to the EJS template
jq: global.jq,
And finally in your EJS you can:
const $ = jq;
var testDiv = $('<div>').html('hello jquery in the template').appendTo('body');
console.log($('body').html());
How do I pass a variable to a javascript file?
Here is the call to my js file that I have on my page:
<script src="../js/myfilename.js"></script>
Here is the value that I want to pass into the javascript file:
language_value_xxx = "uk";
Here is the trimmed down javascript file (myfilename.js):
(function (language_value_xxx) {
....
language: language_value_xxx,
....
1.
<script> language_value_xxx = "uk"; </script>
<script src="../js/myfilename.js"></script>
2.
<script data-lang='uk' src="../js/myfilename.js"></script>
// filename.js
var lang = []
.slice
.call(document.querySelectorAll('script'))
.pop()
.dataset
.lang
;
Anyway, this methods are not a good practice at all )
In my application, I make an ajax call that renders this template with js:
<div id="ajax_reply">
<div id="hidden_data" style="display:none;"></div>
<script type="text/javascript">
var data = [];
data.push(['Col1', 'Col2', 'Col3', 'Col4']);
{% for entry in mydata %}
var dCell = [];
dCell.push({{ entry.Col1 }});
dCell.push({{ entry.Col2 }});
dCell.push({{ entry.Col3 }});
dCell.push({{ entry.Col4 }});
data.push(dCell);
{% endfor %}
document.getElementById('hidden_data').innerHTML = JSON.stringify(data);
</script>
</div>
This doesn't work, if I run the resulting js manually in console, it does get inserted into the div, but otherwise, the javascript is never executed. I've searched on SO but couldn't find questions on this exact topic. hidden_data is in scope, any suggestions?
EDIT:
Code seen in console after wrapping in onload (I had to make a few edits but running this manually in console works)
<div id="ajax_reply">
<div id="hidden_data" style="display:none;"></div>
<script type="text/javascript">
window.onload = function() {
var data = [];
data.push(['Col1', 'Col2', 'Col3', 'Col4']);
var dCell = [];
dCell.push('1233');
dCell.push('123312');
dCell.push('1233');
dCell.push('1482.61');
data.push(relation);
var dCell = [];
dCell.push('1231');
dCell.push('2112.0');
dCell.push('1231');
dCell.push('123123.00');
data.push(relation);
document.getElementById('hidden_data').innerHTML = JSON.stringify(relationsData);
};
</script>
</div>
If entry.Col1 contains string 'my text', resulting template will give you lines like this:
dCell.push(my text);
and, i suppose, you need
dCell.push('my text');
Make sure that this is executing after the DOM is loaded.
Try wrapping your script like:
window.onload=function(){
//script here
}
You can see on jsfiddle that this should be working.
Update:
It seems to be a problem with how Django is inserting data since it works with hardcoded sample data. Try the escapejs template filter to handle any potential javascript escaping problems. I've had to debug similar problems before with newlines and '&' symbols in particular.
dCell.push("{{ entry.Col1|escapejs }}");
Unfortunately I have to use VPN to visit google, including recapcha. Some chrome extensions can redirect those to recaptcha.net, otherwise I won't see captcha at all.....works in most cases, but sometimes not. Now I got this site, the source code shows replacement did not happen.
It's like:
<div class="gglcptch gglcptch_v3"><input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response"> <script src="https://www.google.com/recaptcha/api.js?render=6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w', {action: 'BWS_reCaptcha'}).then(function(token) {
document.querySelectorAll( "#g-recaptcha-response" ).forEach( elem => ( elem.value = token ) );
});
});
</script></div>
So I essembled this code:
$(document).ready(function(){
$('.gglcptch gglcptch_v3').html(function(index,html){
return html.replace(/www\.google\.com\/recaptcha\//g,'recaptcha.net/recaptcha/');
});
});
Chrome dev did not show error, but still replacement not happening.
So my guess is the sequence? when document.ready, script already done running?
What should I do?
1. Your selector is wrong. Should be like the below one:
$('.gglcptch.gglcptch_v3').html(
// ... your function
)
$(document).ready(function(){
$('.gglcptch.gglcptch_v3').html(function(index,html){
return html.replace(/www\.google\.com\/recaptcha\//g,'recaptcha.net/recaptcha/');
});
console.log($('.gglcptch.gglcptch_v3 script').attr('src'))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="gglcptch gglcptch_v3"><input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response"> <script src="https://www.google.com/recaptcha/api.js?render=6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w', {action: 'BWS_reCaptcha'}).then(function(token) {
document.querySelectorAll( "#g-recaptcha-response" ).forEach( elem => ( elem.value = token ) );
});
});
</script></div>
2. But this won't replace google recaptcha to any other external source.
when document.ready, script already done running?
The answer is: Yes.
3. You should load external script(from recaptcha.net or so).
See e.g. this link: JavaScript - function to load external JS files is needed