I have a php application that makes use of a Listener class, which basically just sets up an ajax request with jquery (example below). But for some reason, echoing the javascript just seems inelegant. Is it better practice to build a singleton class for the javascript to be passed to (which could introduce coupling) or to just echo the script like I'm doing now?
Here's a code snippet of what I'm doing.
<?php
$script = "
<script>
$(document).ready(function(){
$('".$trigger."').".$action."(function() {
".$js_variables."
var ajax_load = '';
var loadUrl = '".$this->controller_path."';
var action = $(this).attr('id');
$('".$this->parent."')
.hide(2)
.html(ajax_load)
.load(loadUrl, {action: action, ".$post_mapper."})
.fadeIn(800);
});
});
</script>
";
echo $script;
?>
Edit: Using a singleton class would also allow me to use $(document).ready()
or the shortcut version $(function(){})
only once instead of every single time I add a listener. But I'm not sure if this is worth the extra time and effort... Any ideas?
mm it's all preference... I generally would do it like this so my text editor would be able to determine what's javascript and what's PHP so it wouldn't make my eyes bleed trying to look at non-code-colored text.
Generally: Yes
It's a common practice to echo JavaScript from php, but I highly discourage it.
In most cases you can avoid mixing languages by following a front-end MVC structure:
HTML belongs in
.html
* files. It's the model.CSS belongs in
.css
files. It's the view.JS belongs in
.js
files. It's the controller.I find it very rare that I actually need to generate JavaScript from a server-side language. Most of the time what I actually need is to pass information that JavaScript can use.
Instead of trying to output:
for every link, try using native HTML attributes to do most of the heavy lifting:
and in your script you could have:
The delegate function only has to be bound once, and can be done from a static JS file, without needing to try and inject JS into PHP code.
If you need more information passed through, use
data-*
attributes in conjunction with.data(...)
.* or
.php
or any other server side language used for templating.There are niche reasons to echo client-side code from the server. An example would be generating JSON for a JSONP API, where you need to dynamically generate the callback.
If you don't have a really good reason for generating JS with a server-side language, don't.
As always it depends. If you are writing a small application this mixture won't hurt you. When an application grows to a certain size, I personally find it easier to maintain, when I don't mix languages in one file.
History has taught us on the frontend not to mix HTML, JavaScript and CSS in one file. It's much better to keep them separated, otherwise it is very hard to find the right spot to look at when you try to track a bug. Mixing JavaScript and a server side language is not much better. There are still some things that come to my mind that I find ok. E.g. configuration or localization files, that need to have dynamic values.
In your example I would rather prefer to keep it separated. All you are doing can be perfectly done with (data) attributes on HTML elements and some DOM lookup. It also seems that you need to gather some information for your view that is better stored in HTML. E.g.:
$action
This could be derived rather simple from a form:HTML
JS
The logic why this exact form is submitted, can be in JavaScript and/or PHP. It does not matter how they communicate.
It's perfectly acceptable, but somewhat risky - you're generating parts of the JS on-the-fly, which means you have to generate VALID JS code, or the whole code block will be killed by a syntax error.
e.g. if you're using PHP to insert the value of a PHP variable in the JS code block, something like:
and $last_name happens to be
O'Brien
, you've now introduced a syntax error, because the generated code will be:Anytime you're inserting raw PHP-based data into a Javascript variable, you basically MUST use json_encode(), which guarantees that the generated JS data is syntactically valid JS code:
Note that I didn't put any
'
into this version - json_encode takes care of that for you.