I "fixed" my code, which, of course, broke it. I played with it for a long time before returning to the way it was before I fixed it. I don't understand why it works ONLY this way, so I'm trying to learn.
When I place the call to my javascript functions code (_functions.js) before my <html> and <head> tags, the functions pick up the CSS fine. When I place the code IN my head, it doesn't pick up the CSS at all. My CSS works as expected in the rest of my document.
Styles load for my JS functions when my code in header.php looks like this:
<?php
echo <<<HTML
<script src='{$_(URL_CTB)}/includes/_functions.js?v-1.10'></script> // <!-- THIS loads CSS info -->
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js'></script>
<link rel='stylesheet' type='text/css' href='{$_(URL_CTB)}/includes/jquery-ui-1.13.2.custom/jquery-ui.min.css'>
<script type="text/javascript" src="{$_(URL_CTB)}/includes/clockpicker/dist/jquery-clockpicker.js"></script>
<link rel='stylesheet' type='text/css' href='{$_(URL_CTB)}/includes/clockpicker/dist/jquery-clockpicker.css'>
<link rel='stylesheet' type='text/css' href='{$_(URL_CTB)}/styles/ctb.css?v1.10'> <!- THIS CSS -->
<link rel='icon' href='{$_(URL_CTB)}/favicon.ico?v=0.20' />
HTML . PHP_EOL;
And my buttons look like this:
...but when I do this:
<?php
echo <<<HTML
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js'></script>
<link rel='stylesheet' type='text/css' href='{$_(URL_CTB)}/includes/jquery-ui-1.13.2.custom/jquery-ui.min.css'>
<script type="text/javascript" src="{$_(URL_CTB)}/includes/clockpicker/dist/jquery-clockpicker.js"></script>
<link rel='stylesheet' type='text/css' href='{$_(URL_CTB)}/includes/clockpicker/dist/jquery-clockpicker.css'>
<script src='{$_(URL_CTB)}/includes/_functions.js?v-1.10'></script> <!-----HERE CSS WON'T work-->
<link rel='stylesheet' type='text/css' href='{$_(URL_CTB)}/styles/ctb.css?v1.10'> <!-- THIS CSS -->
<link rel='icon' href='{$_(URL_CTB)}/favicon.ico?v=0.20' />
HTML . PHP_EOL;
...my buttons look like this:
_functions.js looks like this:
function fnListButtons(elementId, jsonButts) {
let aButts = JSON.parse(jsonButts);
for (let aBtnVals of aButts) {
let btn = document.createElement('button');
btn.type = 'button';
btn.value = aBtnVals[0];
btn.innerHTML = aBtnVals[1];
btn.classList.add('CTBButton', 'CTBSubmitBtn');
btn.style.margin = '4px';
switch (aBtnVals[2]) {
case 'orange':
btn.style.fontWeight = 'bold';
btn.classList.add('CTBOrangeBtn');
break;
case 'green':
btn.style.fontWeight = 'bold';
btn.classList.add('CTBGreenBtn');
break;
default:
btn.style.fontWeight = 'normal';
}
document.getElementById(elementId).appendChild(btn);
btn.onclick = function () {
fnClickButton(this.value);
}
}
}
function fnClickButton(sURL) {
location.href = sURL;
}
function delay(msecs) {
return new Promise(resolve => setTimeout(resolve, msecs));
}
It's called from a PHP function called fnButtons saved in a file called _functions.php, listed, in part, here:
<?php
date_default_timezone_set('US/Eastern');
define('SECS', 1);
define('MINS', SECS*60);
define('HOURS', MINS*60);
define('DAYS', HOURS*24);
define('WEEKS', DAYS*7);
define('YEARS', DAYS*365);
// ... other constants
if(isset($_SERVER['HTTP_REFERER'])) {
define('REF_URL', $_SERVER['HTTP_REFERER']);
} else {
define('REF_URL', '');
}
/*
...many other php functions here
*/
function fnC($v){return($v);};
$_ = 'fnC';
function fnButtons($aButtons) { // <----my button building code
$jsonButts = json_encode($aButtons);
echo <<<HTML
<div id='menu_butts' style='text-align:center;'>
<script>
fnListButtons('menu_butts', '$jsonButts');
</script>
</div>
HTML . PHP_EOL;
}
My main code starts like this:
?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/_functions.php'; // <---my main PHP functions
require_once DOC_CTB . '/includes/_day_params.php';
require_once DOC_CTB . '/includes/_rrules_mine.php';
use RRule\RRule;
require_once DOC_CTB . '/includes/header.php'; // <--- my header file
echo <<<HTML
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--...-->
<title>List Tasks</title>
</head>
<body>
HTML . PHP_EOL;
// GET PASSED URL PARAMETERS
$aTask_Types = (isset($_GET['type'])) ? (array) $_GET['type'] : [];
$iWhere = (isset($_GET['where'])) ? (int) $_GET['where'] : -1;
fnPageTitle('List Tasks');
$aButtons = [];
$aButtons[] = [URL_CTB . '/edit_task.php?new=true', 'Add New Task', 'green'];
if (THIS_URL !== $URL_no_type) {
$aButtons[] = [URL_CTB . '/list_tasks.php', 'List All Tasks', ''];
}
if (!in_array("today", $aTask_Types)) {
$aButtons[] = [URL_CTB . '/list_tasks.php?type=today', 'List Today Only', ''];
}
$aButtons[] = [URL_CTB . '/list_notes.php', 'List Notes', ''];
$aButtons[] = [URL_CTB . '/edit_note.php', 'Add New Note', 'green'];
fnButtons($aButtons);
My css code looks, in part, like this:
:root {
--CTBGREEN:#229999;
--CTBGREENM:#6cbbbb;
--CTBGREENL:#E2F2F2;
--CTBBLUE:#2EA3F2;
--CTBBLUEL:#9FD5F9;
--CTBRED:#750000;
--CTBORANGE:#E97A00;
--CTBORANGEL:#FEB658;
}
.ctbButton {
box-shadow:inset 0px 1px 0px 0px #bbdaf7;
background:linear-gradient(to bottom, var(--CTBBLUEL) 5%, var(--CTBBLUE));
background-color: var(--CTBBLUEL);
border-top-left-radius:6px;
border-top-right-radius:6px;
border-bottom-right-radius:6px;
border-bottom-left-radius:6px;
text-indent:0;
border:1px solid #84bbf3;
display:inline-block;
color:white !important;
font-family:Arial;
font-size:15px;
font-weight:bold !important;
font-style:normal;
height:27px;
line-height:27px;
width:fit-content;
padding-left:8px;
padding-right:8px;
padding-bottom:0px;
padding-top:0px;
text-decoration:none;
text-align:center;
text-shadow:1px 1px 0 #507ca8, -1px 1px 0 #507ca8, 1px -1px 0 #507ca8, -1px -1px 0 #507ca8;
}.ctbButton:hover {
background:linear-gradient(to bottom, var(--CTBBLUE) 5%, var(--CTBBLUEL));
background-color: var(--CTBBLUE);
}.ctbButton:active {
position:relative;
top:1px;
}
.ctbGreenBtn {
box-shadow:inset 0px 1px 0px 0px #b5dddd;
background:linear-gradient(to bottom, var(--CTBGREENM) 5%, var(--CTBGREEN));
background-color: var(--CTBGREENM);
border:1px solid #84c6c6;
text-shadow:1px 1px 0px #194a4a;
}.ctbGreenBtn:hover {
background:linear-gradient(to bottom, var(--CTBGREEN) 5%, var(--CTBGREENM));
background-color: var(--CTBGREEN);
}
.ctbOrangeBtn {
box-shadow:inset 0px 1px 0px 0px #fce2c1;
background:linear-gradient(to bottom, var(--CTBORANGEL) 5%, var(--CTBORANGE));
background-color: var(--CTBORANGEL);
border:1px solid #eeb44f;
text-shadow:1px 1px 0 #71582d, -1px 1px 0 #71582d, 1px -1px 0 #71582d, -1px -1px 0 #71582d;
}
.ctbOrangeBtn:hover {
background:linear-gradient(to bottom, var(--CTBORANGE) 5%, var(--CTBORANGEL));
background-color: var(--CTBORANGE);
}
I'm happy enough to leave the _functions.js where it is, but almost everything I've read suggests putting this kind of thing just before </body> (which I did try--it still doesn't load the styles). Putting it before even the head makes no sense to me at all. Why is it behaving this way?
The problem is typos in your code - they are all prefixed with "CTB" while in the css it is "ctb" - the css selectors should read like this
function fnListButtons(elementId, jsonButts) {
let aButts = JSON.parse(jsonButts);
for (let aBtnVals of aButts) {
let btn = document.createElement('button');
btn.type = 'button';
btn.value = aBtnVals[0];
btn.innerHTML = aBtnVals[1];
btn.classList.add('ctbButton', 'ctbSubmitBtn');
btn.style.margin = '4px';
switch (aBtnVals[2]) {
case 'orange':
btn.style.fontWeight = 'bold';
btn.classList.add('ctbOrangeBtn');
break;
case 'green':
btn.style.fontWeight = 'bold';
btn.classList.add('ctbGreenBtn');
break;
default:
btn.style.fontWeight = 'normal';
}
document.getElementById(elementId).appendChild(btn);
btn.onclick = function () {
fnClickButton(this.value);
}
}
}