"$ is not defined" jQuery bottom with PHP include - php

They are good practices put jQuery the bottom of the page, before the </ body>, but when you have an include PHP in the middle of the page and in this include I have that jQuery code like this:
[code of index.php]
[include]
<script>
$(function() {
<?php
echo "$('#".$_SESSION['user']['flags']."').attr('selected', true);";
?>
});
</script>
[/include]
[code of index.php including jQuery.js here before </body>]
Firebug tells me that $ is not defined. I used "defer" but it does not work either. I searched Stackoverflow but do not know how to fix it.
Here my code:
index.php
<!doctype html>
<html class="no-js" lang="es">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="robots" content="noodp, noydir">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body id="body">
<?php
include './step1.php';
?>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
step1.php
<script>
$(function() {
<?php
echo "$('#".$_SESSION['user']['flags']."').attr('selected', true);";
?>
});
</script>

If you replace the "$(function(){" section with window.onload you can ensure that all script files have been loaded before attempting to fire your function.
However, be aware that this fires much later that jQuery's document.ready. jQuery's method fires when the dom is loaded whereas window.onload waits until the whole document and it's scripts have been loaded.
More info and example here:
https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload

You included the jQuery.js after the inclusion of that script. Move your jQuery.js include above include statement that contains your js code.

Answer to the problem:
You have included the step1.php before including jQuery.js. This is why it won't work. Include jQuery.js before including step1.php.
Answer regarding jQuery in end of HTML body:
Yes, it's a good practice but that seems to me as a micro-optimization. As it would speed up the loadtime. But you can only do that if you include your written jQuery code after including the actual jQuery.js library. Since you're not able to do that in the current contruction, you need to change the order to make it work.
Otherwise general debugging techniques apply:
Check your browser. Right click. Inspect element. Open tab network. Make sure the jQuery.js file is really included so you'll have a HTTP status 200 code on this request.
Make sure jQuery is really inside jQuery.js and the file is not empty or having other contents.
Make sure jQuery not included twice.
Also checkout:
https://api.jquery.com/jquery.noconflict/
http://www.sitepoint.com/types-document-ready/
or try:
jQuery(document).ready(function(){ /* [code here] */ });

Related

Proper use of Bootstrap 3 Tooltip on a PHP based system

I have been trying to get this tooltip code to initialize on a page and I cannot get the jQuery to connect properly.
We have PHP running on Ubuntu and we are using Silverstripe. I cannot get the following script to work, no matter where or what file I add it to. I have even tried calling it in from a separate file and it also did not initialize.
How would I add this code to a PHP or SS file? (Silverstripe CMS file)
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
<button type=\"button\" class=\"btn btn-default help-tool\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Below you will find state-by-state breakdowns in Federal, State, and where available Local categories.
Explore the data by clicking the map or by clicking the magnifying lens in the table view.\"><i class=\"fa fa-info-circle fa-fw\"></i></button>
This is generally an issue involving the order in which your scripts are called.
As I'm sure you know, you need to call JQuery before Bootstrap, which it seems like you are doing. Your tooltip code, which is in a different file, is most likely being called before your JQuery and Bootstrap have a chance to load. You can test this by copying your JQuery and Bootstrap script calls into your separate file right before the tooltip script call.
If your script calls are at the bottom of your body tag, and part of the page is being dynamically loaded, you can try calling JQuery and Bootstrap in your head tag instead after your CSS:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" src="bootstrap.css" />
<link rel="stylesheet" type="text/css" src="main.css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="bootstrap.js"></script>
</head>
<body>
<!--
Your separate file code that
includes tooltip
-->
<!-- Before
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="bootstrap.js"></script>
-->
</body>
</html>
There are two causes that come to mind here. First, it's possible that the $ is getting interpreted by SS's template parser as a variable expression. I would expect you would be getting an error if that is the case. Second, as Sumit Kukreja indicated it's likely that jQuery and Bootstrap are being injected at the bottom of your template and this code is getting executed before those are loaded.
Option 1: To verify if this is happening you could add the following code to Page_Controller::init() or mysite/_config.php:
Requirements::set_write_js_to_body(false);
Which will cause all required javascript to be added in the <head> tag. Not a good idea for production but could help diagnose your problem.
Option 2: You can include that javascript from your controller using Requirements::customScript.
Option 3: Wrap your js snippet in a non-jquery domready listener like so:
document.addEventListener("DOMContentLoaded", function(event) {
$('[data-toggle="tooltip"]').tooltip()
});

Jquery load() works for html but not for php page

I'm trying to load a php page in a div with Jquery. The following code works perfectly with a html page (Test.html) but not with a php page (Test.php with exactly the same code as Test.html): when I clik on the button nothing occurs. My php page loads correctly outside the Jquery code. I even tried to use a url instead of a relative link without any success.
$(function() {
$('#Button').click(function() {
$('#Div').load('Test.php');
});
});
Thanks in advance for your answers.
Here is the code of Test.php :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
Test Test
</body>
</html>

Inline Javascript with Fat-Free Layouts

I'm working with PHP Fat Free and I am attempting to create a layout/sublayout system which will eventually mimic MVC to some extent. I have a main layout which has placeholders (essentially the backend sets different sublayout or partial file paths and then the view takes care of calling the rendering of that file name. This all works great.
The issue I'm running into is when I need inline javascript in my sublayout to run after scripts in the main layout (after the jquery include line, for instance). In a previous framework I was using, I was able to do us output buffering ob_start and ob_get_clean to grab the script in the sublayout and then pass that to the layout to display below the script line. I hope that makes sense, but if not, here's the current code I'm working with in F3.
The route:
$f3->route('GET /test',
function($f3) {
// set the sublayout name
$f3->set('sublayout', 'testpage.php');
// render the whole shebang
echo View::instance()->render('testlayout.php');
}
);
The layout:
<!DOCTYPE html>
<html>
<head>
<title>Test Layout</title>
</head>
<body>
<h1>Test Layout</h1>
<?php echo View::instance()->render($sublayout) ?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" />
<!-- inline script should go here -->
</body>
</html>
The sublayout:
<h2>My Test Page</h2>
<div id='message'></div>
<script>
// This code needs to be placed AFTER the jquery include in the main layout
$(function(){
$('#message').html('This is my message');
});
</script>
I tried extending the view to include a "beginRegion" and endRegion function that basically handled the ob_start and ob_get_clean portion so that my inline script could be picked up, but once I'm in the sublayout I wasn't able to figure out how to pass that buffered code back to the layout so it could be echo'd after the jquery include.
Before you tell me that I should not be using inline script, I know this and most things I do are in external script files which I have a solution for including, but there are times when I need it inline and that's where I'm stuck.
Is there a way to handle what I'm trying to do with output buffering, or better yet is there a better way to solve this than the output buffering approach?
Update:
Best practices generally dictate that you should include the script at the bottom of the page right before the closing body tag. If I put the script above the sublayout, it breaks both our FE best practices and has the disadvantage of blocking the rest of the page while the script downloads. That's why I'd like to keep it structured the way I have noted instead of placing the jquery include ABOVE the sublayout.
I don't understand what's the problem.
Your layout is:
<!DOCTYPE html>
<html>
<head>
<title>Test Layout</title>
</head>
<body>
<h1>Test Layout</h1>
<?php echo View::instance()->render($sublayout) ?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" />
<!-- inline script should go here -->
</body>
</html>
You want to include sublayout after jquery usage. So why not to write it like this? :
<!DOCTYPE html>
<html>
<head>
<title>Test Layout</title>
</head>
<body>
<h1>Test Layout</h1>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" />
<!-- inline script should go here -->
<?php echo View::instance()->render($sublayout) ?>
</body>
</html>
Also You can write custom function. Lets say You've folder with partials or something else more structured and want to use it:
$f3->set('partial',
function($file) {
$file .= (strpos($file, '.php')>0)? '' : '.php';
if(!is_file($file)) return '';
return View::instance()->render($file);
}
);
and then use it like:
<!DOCTYPE html>
<html>
<head>
<title>Test Layout</title>
</head>
<body>
<h1>Test Layout</h1>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" />
<!-- inline script should go here -->
{{ #partial('partials/testpage') }}
</body>
</html>
I knew why You want to do so. But what's the problem to decouple scripts in scripts.php file and HTML,php part to another file and render them as needed? (:
From a google groups discussion I had, someone offered up a JS solution that might work:
inside your layout:
<head>
<script>
var callbacks=[];
</script>
</head>
<body>
<script src="...jquery.min.js"/>
<script>
$.each(callbacks,function(i,func){func.call(null,jQuery);}) //<< triggers all queued callbacks
</script>
</body>
inside your sublayout:
<h2>My Test Page</h2>
<div id="message"></div>
<script>
callbacks.push(function($){
//do something with jQuery
});
</script>
Here's the link:
https://groups.google.com/forum/#!topic/f3-framework/iGcDuDueN8c

Alternative to CSS in body tag?

In my login system in my site I wanted the user's selected CSS to be loaded after validation was complete. The only problem is that my PHP is located in the body element and I ECHOed the user's CSS link there. I know this is "bad", but what else can I do?
if (isset($_SESSION['loggedin'])){
ECHO $_SESSION['style'];
}
else
{
ECHO 'green';
}
ECHO ".css' />";
The PHP script echos some text in the body after the user is logged in, this is why I cannot put the PHP script in the header.
I'm under the assumption that you're not at all familiar with the basics of PHP, so I'll break it down as simply as I can. If your document is able to execute PHP (which it sounds like it can because you have things happening in the body), all you need to do is wrap the PHP code with <?php and ?> for it to parse as PHP.
You shouldn't put stylesheets inside your body. Indeed, that is something that no one will recommend. What you can do, however, is execute PHP in the head of your document.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.css">
<?php
echo "<link rel='stylesheet' href='{$_SESSION['user_css']}'>";
?>
<script src="script.js"></script>
</head>
<body>
<?php
echo 'body text';
?>
</body>
</html>
It doesn't matter where you decide to inject PHP code into your document, it will render as you wish. I'd suggest an MVC solution, but if this is just a small, one-off file, feel free to inject PHP wherever you want it, as often as you need it.
http://php.net/manual/en/language.basic-syntax.phptags.php
You can load the user css after the document is loaded using jQuery.
<script>
$(document).ready(function() {
$(head).append('<style>
<?php echo($user_css); ?>
</style>');
});
</script>
Though just adding a section to output the CSS in the head would be easier to maintain in the future and doesn't need the page to load. A dramatic enough change on a slow(ish) connection and the user will see the flicker as the CSS loads their style.
you could use some jQuery to append the style in the <head>:
$(head).append('<style><?php echo user_css ?></style>');

Using LiveValidation in HTML/PHP project

I've found following javascript library for client-side validation:
http://livevalidation.com/
The examples on the website are very clear, but I just can't get them to work...
Even when creating a very basic html-only website like this:
<html>
<head>
<link rel="scrip" type="text/javascript" href="scripts/LiveValidation-1.3.js" title="LiveValidation"/>
</head>
Enter the field then click somewhere else:
<input type="text" id="f1"/>
<script type="text/javascript">
var f1 = new LiveValidation('f1');
f1.add(Validate.Presence);
</script>
</html>
This code comes directly from the examples provided on the website, however it doesn't do anything, the reference to the .js file is correct... What am I overlooking here? Thanks.
You need to use a script tag to reference the javascript file not the link tag.
<html>
<head>
<script type="text/javascript" src="scripts/LiveValidation-1.3.js"></script>
</head>

Categories