Date published: 2025-06-20
Source: Amy and ChatGPT (ID1356)
Author: Howard, Amy (ID633)
Primary doc? 0
Published in:
Race described:
Full text? 0
Online link:
Content id: 27981
Filename received:
Filename assigned: 2026-01-12_howard_chatgpt.pdf
2026-01-12 - 0000-00-00

Jump to author on Authors pageedit

Skip to content

You said:
authors.php
File
authors_run.php
File
I have attached the front-end and back-end code for my "Authors" page. The Authors list is growing too long. How can I add an option to type the first letter(s) of an author's last name to jump to it?
ChatGPT said:

Thought for 1m 5s
Do it client-side: add a small “jump” search box above the list, tag each author link with a data-last attribute, and use JavaScript to scroll to the first match as you type.

1) Update authors_run.php to add id + data-last
Replace your “display results” loop with this:

while ($row = mysqli_fetch_assoc($result_list)) {
    $author_id   = (int)$row['author_id'];
    $author_name = trim($row['author_name']);

    // Try to infer last name:
    // - If name is stored as "Last, First", last is before comma
    // - Otherwise use the last word as last name
    if (strpos($author_name, ',') !== false) {
        $last = trim(strtok($author_name, ','));
    } else {
        $parts = preg_split('/\s+/', $author_name);
        $last = trim(end($parts));
    }

    $safe_name = htmlspecialchars($author_name, ENT_QUOTES, 'UTF-8');
    $safe_last = htmlspecialchars($last, ENT_QUOTES, 'UTF-8');

    echo "<a
            id='author-$author_id'
            class='author-link'
            data-last='$safe_last'
            href='author.php?author_id=$author_id'
          >$safe_name</a><br>";
}
2) Update authors.php to add the input + wrapper div + JS
Where you currently include '../run_code/authors_run.php';, wrap it in a container and add a text box above it:

<label for="authorJump"><strong>Jump to author (type last name):</strong></label><br>
<input
  type="text"
  id="authorJump"
  placeholder="e.g., Smi"
  autocomplete="off"
  style="max-width:320px; width:100%; padding:8px; margin:6px 0 14px;"
>

<div id="authorList">
  <?php include '../run_code/authors_run.php'; ?>
</div>

<script>
(() => {
  const input = document.getElementById('authorJump');
  const list  = document.getElementById('authorList');

  function norm(s) {
    return (s || '').toString().trim().toLowerCase();
  }

  function clearHighlights() {
    list.querySelectorAll('.author-hit').forEach(a => a.classList.remove('author-hit'));
  }

  function jump() {
    const q = norm(input.value);
    clearHighlights();
    if (!q) return;

    const links = list.querySelectorAll('a.author-link');
    let hit = null;

    for (const a of links) {
      const last = norm(a.dataset.last);
      const full = norm(a.textContent);

      // Prefer matching last name; fall back to full display text
      if (last.startsWith(q) || full.startsWith(q)) { hit = a; break; }
    }

    if (hit) {
      hit.classList.add('author-hit');
      hit.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
  }

  input.addEventListener('input', jump);

  // Optional: Enter opens the highlighted author
  input.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
      const hit = list.querySelector('a.author-link.author-hit');
      if (hit) window.location.href = hit.href;
    }
  });
})();
</script>

<style>
  /* cheap but effective */
  .author-hit { background: #fff3a0; padding: 2px 4px; border-radius: 4px; }
</style>
Why this works (and won’t hurt performance)
No extra database queries.

The page loads once, then the user can “type-to-jump” instantly.

scrollIntoView() gives the “jump” behavior you asked for (not a filter), and the highlight makes it obvious where you landed.

If your author_name format is not “Last, First” or “First Last” (for example “Grant, James (ed.)”), tell me the format and I’ll tweak the last-name extraction so it’s bulletproof.

You said:
authors_run.php
File
authors.php
File
I believe I did what you said. The Authors list no longer appears, and nothing happens when I enter something in the jump input box.
ChatGPT said:

Thought for 1m 42s
Right now, your uploaded files do not include the “jump input + JS” at all, and your authors_run.php is still outputting plain links with no class="author-link" and no data-last. So even if you type in a box, the script has nothing to hook into.

That explains both symptoms:

Nothing happens when you type → because the JS isn’t on the page (or it can’t find #authorList / .author-link).

Authors list not appearing → usually a PHP fatal error (often from a bad include path). Your authors_run.php does include 'database.php'; which is fragile when the file is included from another directory.

Here’s the “it will work” version.

Fix 1: Make the database include unbreakable (authors_run.php)
Use __DIR__ so PHP includes from the file’s own folder, not whatever the current script happens to be:

<?php
// Connect to database (adjust path if your database.php is elsewhere)
require_once __DIR__ . '/database.php';

$sql_list = "SELECT * FROM authors ORDER BY author_name;";
$result_list = mysqli_query($connection, $sql_list);

$sql_count = "SELECT COUNT(*) AS count FROM authors;";
$result_count = mysqli_query($connection, $sql_count);

if (!$result_list || !$result_count) {
    echo "<p><strong>DB query failed:</strong> " . htmlspecialchars(mysqli_error($connection)) . "</p>";
    return;
}

$row = mysqli_fetch_assoc($result_count);
echo "<h3>" . (int)$row['count'] . " Authors</h3><br>";

while ($row = mysqli_fetch_assoc($result_list)) {
    $author_id   = (int)$row['author_id'];
    $author_name = trim($row['author_name']);

    // Infer last name: "Last, First" OR "First Last"
    if (strpos($author_name, ',') !== false) {
        $last = trim(strtok($author_name, ','));
    } else {
        $parts = preg_split('/\s+/', $author_name);
        $last = trim(end($parts));
    }

    $safe_name = htmlspecialchars($author_name, ENT_QUOTES, 'UTF-8');
    $safe_last = htmlspecialchars($last, ENT_QUOTES, 'UTF-8');

    echo "<a
            id='author-$author_id'
            class='author-link'
            data-last='$safe_last'
            href='author.php?author_id=$author_id'
          >$safe_name</a><br>";
}
⚠️ If your database.php is not in the same folder as authors_run.php, change that line to something like:

require_once __DIR__ . '/../database.php'; (one level up)

Fix 2: Actually add the jump input + JS (authors.php)
Put this right before you include authors_run.php:

<label for="authorJump"><strong>Jump to author (type last name):</strong></label><br>
<input
  type="text"
  id="authorJump"
  placeholder="e.g., Smi"
  autocomplete="off"
  style="max-width:320px; width:100%; padding:8px; margin:6px 0 14px;"
>

<div id="authorList">
  <?php include '../run_code/authors_run.php'; ?>
</div>

<script>
(() => {
  const input = document.getElementById('authorJump');
  const list  = document.getElementById('authorList');
  if (!input || !list) return;

  const norm = s => (s || '').toString().trim().toLowerCase();

  function clearHighlights() {
    list.querySelectorAll('.author-hit').forEach(a => a.classList.remove('author-hit'));
  }

  function jump() {
    const q = norm(input.value);
    clearHighlights();
    if (!q) return;

    const links = list.querySelectorAll('a.author-link');
    let hit = null;

    for (const a of links) {
      const last = norm(a.dataset.last);
      if (last.startsWith(q)) { hit = a; break; }
    }

    if (hit) {
      hit.classList.add('author-hit');
      hit.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
  }

  input.addEventListener('input', jump);
})();
</script>

<style>
.author-hit { background: #fff3a0; padding: 2px 4px; border-radius: 4px; }
</style>
Fast way to confirm what’s wrong (no guessing)
Open the Authors page and view page source.
Search for authorJump. If it’s not there, you didn’t actually paste the input+script into the page that’s running.

If the author list is blank: turn on PHP errors temporarily at the very top of authors.php:

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
?>
If your include path is broken, you’ll immediately see the error.

If you paste your actual live file contents (or upload the edited versions again), I can point to the exact line that’s breaking. But the two fixes above cover the most common “list disappeared + JS does nothing” failure modes: fatal include error and missing hooks/classes/IDs.

You said:
I uploaded my updated files to you. Authors.php does include the “jump input + JS” that you gave me.
ChatGPT said:

Thought for 40s
I pulled the two files you uploaded in this chat and… they’re not the versions you think they are.

What I’m actually seeing in your uploads
authors.php: does not contain authorJump, the <script>, or the #authorList wrapper. Also it literally contains a line with ... in the middle of the HTML, which suggests you pasted a truncated snippet into the file at some point.

authors_run.php: is unchanged from your old version: no class="author-link", no data-last, and it still does include 'database.php'; (which commonly breaks when the file is included from another directory).

So your symptoms make perfect sense:

The JS can’t run because it’s not actually in the loaded page (or it has nothing to target).

The author list can disappear if authors_run.php dies on include 'database.php'.

Let’s fix it in a way that can’t silently fail.

1) Replace authors_run.php with this (copy/paste the whole thing)
This fixes the fragile DB include and outputs the data-last + class hooks your JS needs.

<?php
// Always include db relative to THIS file's folder:
require_once __DIR__ . '/database.php';

$sql_list  = "SELECT * FROM authors ORDER BY author_name;";
$sql_count = "SELECT COUNT(*) AS count FROM authors;";

$result_list  = mysqli_query($connection, $sql_list);
$result_count = mysqli_query($connection, $sql_count);

if (!$result_list || !$result_count) {
    echo "<p><strong>DB query failed:</strong> " . htmlspecialchars(mysqli_error($connection)) . "</p>";
    return;
}

$row = mysqli_fetch_assoc($result_count);
echo "<h3>" . (int)$row['count'] . " Authors</h3><br>";

while ($row = mysqli_fetch_assoc($result_list)) {
    $author_id   = (int)$row['author_id'];
    $author_name = trim($row['author_name']);

    // Infer last name: "Last, First" OR "First Last"
    if (strpos($author_name, ',') !== false) {
        $last = trim(strtok($author_name, ','));
    } else {
        $parts = preg_split('/\s+/', $author_name);
        $last = trim(end($parts));
    }

    $safe_name = htmlspecialchars($author_name, ENT_QUOTES, 'UTF-8');
    $safe_last = htmlspecialchars($last, ENT_QUOTES, 'UTF-8');

    echo "<a
            id='author-$author_id'
            class='author-link'
            data-last='$safe_last'
            href='author.php?author_id=$author_id'
          >$safe_name</a><br>";
}
If your database.php is not in the same folder as authors_run.php, change that one line to something like:
require_once __DIR__ . '/../database.php';

2) In authors.php, insert the jump UI + wrapper immediately before the include
Find this:

<?php    
    include '../run_code/authors_run.php';  
?>
Replace it with this:

<label for="authorJump"><strong>Jump to author (type last name):</strong></label><br>
<input
  type="text"
  id="authorJump"
  placeholder="e.g., Smi"
  autocomplete="off"
  style="max-width:320px; width:100%; padding:8px; margin:6px 0 14px;"
>

<div id="authorList">
  <?php include '../run_code/authors_run.php'; ?>
</div>

<script>
(() => {
  const input = document.getElementById('authorJump');
  const list  = document.getElementById('authorList');

  // If either is missing, nothing can work:
  if (!input || !list) return;

  const norm = s => (s || '').toString().trim().toLowerCase();

  function clearHighlights() {
    list.querySelectorAll('.author-hit').forEach(a => a.classList.remove('author-hit'));
  }

  function jump() {
    const q = norm(input.value);
    clearHighlights();
    if (!q) return;

    const links = list.querySelectorAll('a.author-link');
    for (const a of links) {
      const last = norm(a.dataset.last);
      if (last.startsWith(q)) {
        a.classList.add('author-hit');
        a.scrollIntoView({ behavior: 'smooth', block: 'center' });
        break;
      }
    }
  }

  input.addEventListener('input', jump);
})();
</script>

<style>
  .author-hit { background: #fff3a0; padding: 2px 4px; border-radius: 4px; }
</style>
3) Remove the literal ... from your authors.php
Your uploaded authors.php contains a ... line inside the HTML. That’s not a comment; it’s real text and it’s a red flag that the file you edited isn’t the one you’re running, or you pasted a truncated example into production.

Delete it.

4) Quick sanity checks (takes 30 seconds)
Load the Authors page → Right-click → View Page Source → search for authorJump

If it’s not there, you’re editing one file but serving another.

Open DevTools Console:

If you see errors like “Cannot find database.php” or a PHP error output, your include path was the problem (fixed by __DIR__).

If you want, tell me where database.php physically lives relative to authors_run.php (same folder? one level up?), and I’ll give you the exact correct require_once path so you don’t have to guess.

Is this conversation helpful so far?






No file chosenNo file chosen
ChatGPT can make mistakes. Check important info.

Cross references

No cross references.