javascript - Reload div without reloading the whole page

I know it's been asked a million times but I can't find an answer that works properly for me.

When I select an option from my dropdown menu list I want to append the end of my URL which I do correctly. Then I want to display the topic selected from my dropdown list in my input field but the only thing that is showing is the letters I typed. The only time the full topic show is after I refresh the whole page but I don't want to refresh the whole page I just want to refresh the div. Like on reddit. Can anyone help me ? What I've tried below:

create_subtopic.php:

<div class="search_topics">
    
    <input type="text" name="q" placeholder="Choose Topic" id="search_topics_input"
        value="<?php echo $topic_toget; ?>" autocomplete="off">

$("#search_topics_input").load("create_subtopic.php");

backend-search.php:

echo "<div class='results_div' onclick='addUrl()'>

function addUrl() {
        var url = window.history.pushState( {}, '', '?topic_toget=<?php echo $topic_name; ?>' );
        //$( "#search_topics_input" ).load(window.location.href + " .search_topics" );
        //$(".search_topics").load(" #search_topics_input > *");
        //$("#topic_name").load("#search_topics_input");
        $("#search_topics_input").load("backend-search.php");
}

Everything commented out is what I have tried and more.

Answer

Solution:

With Link Dropdown:

The links should be buttons:
<button class="btn btn-link" type="button" onclick="updateDiv('1')">Dropdown Item 1</button>
<button class="btn btn-link" type="button" onclick="updateDiv('2')">Dropdown Item 2</button>
<button class="btn btn-link" type="button" onclick="updateDiv('3')">Dropdown Item 3</button>

With Select Input

You use the onchange attribute to call the updateDiv function:
<select id="div-changer" onchange="updateDiv()">
    <option value="1">Dropdown Item 1</option>
    <option value="2">Dropdown Item 2</option>
    <option value="3">Dropdown Item 3</option>
</select>

In the updateDiv function

First you want to get the value. In the version with the buttons you just use a function parameter:
function updateDiv(id) {

}

Thats a bit more complicated in the select version:

function updateDiv() {
    let id = document.querySelector('#div-changer').options[document.querySelector('#div-changer').selectedIndex].value;
}

Then you do a XMLHttpRequest with the id as a param. You can use it with $_POST['id'] inside php. You could also name everything 'topic' and not use 1, 2, 3 as values but politics, sports and science. The XMLHttpRequest works like this:

var r = new XMLHttpRequest();
r.open("POST", "/include/your-ajax.inc.php", true);
r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
r.onreadystatechange = function () {
    if (r.readyState != 4 || r.status != 200) return;
    
    // process response here
};
r.send('id=' + id);

Inside the onreadystatechange function you use the r.responseText. Its what the server returned. You can for example make a div with a id of content and then you set the innerHTML as the responseText. If thats what you want to do the server has to return propper HTML. If you have for example a simple website, without any querys on the server, you can make 3 documents (the sites) and return them to the client. Inside the onreadystatechange function:

if (r.readyState != 4 || r.status != 200) return;

document.querySelector('#content').innerHTML = r.responseText;

Server Side:

In this example Ill just return a string. First you check if the id param is empty. Then you echo something depending on the content:
<?php

if (!isset($_POST['id']) || strlen($_POST['id'])) {
    echo 'err';
    exit();
}

if ($_POST['id'] == '1') {
    echo '<h2>Post Number 1</h2><p>Lorem Ipsum...</p>';
    exit();
} else if ($_POST['id'] == '2') {
    echo '<h2>Post Number 2</h2><p>Lorem Ipsum...</p>';
    exit();
} else if ($_POST['id'] == '3') {
    echo '<h2>Post Number 3</h2><p>Lorem Ipsum...</p>';
    exit();
} else {
    echo 'postNotFound';
    exit();
}

Error Check in onreadystatechange

Then you can add error catching to the onreadystatechange function. You have to place this before setting the content innerHTML and after checking the readyState:
if (r.responseText == 'err' || r.responseText == 'postNotFound') {
    console.log('AJAX error');
    return;
}

I didnt test the code. If you have any errors you can ask.

Source