skip to Main Content

I am working on a python app where I want to make a search bar and give users the option to toggle between searching for users and posts. When they click on one or the other I want the list from the search bar to automatically update but I don’t want the value in the search bar to disappear. This is the code I was trying but I realized it didn’t update right away because the search only runs on an event listener, and the code I used to change the type of search runs on an onClick event from a different element. If anyone has any solutions, it would be greatly appreciated.

HTML:

<form method="POST" class="d-flex" >
  <input
    id="search-input"
    class="form-control me-2"
    type="search"
    placeholder="Search"
  />

  <button class="btn btn-outline-secondary ml-2" type="submit" >Search</button>
</form>
<a onClick="searchUsers()"><li>Users</a>
<a onClick="searchPosts()"><li>Posts</a>

Python:

@search.route("/search", methods=["GET", "POST"])
@login_required
def search():
    users = Users.query.all()
    usersJS = [(user.id, user.username) for user in users]
    posts = Posts.query.all()
    postJs = [(post.id, post.content) for post in posts]
    return jsonify({"users": usersJS, "posts": postJs})

JavaScript:

let searchType = 1;
function searchUsers() {
  searchType = 1;
}
function searchPosts() {
  searchType = 2;
}
fetch("/search")
  .then((response) => response.json())
  .then((data) => {
    const users = data["users"];
    const posts = data["posts"];
    const searchInput = document.getElementById("search-input");
    const usersList = document.getElementById("users-list");
    searchInput.addEventListener("input", () => {
      const searchTerm = searchInput.value.toLowerCase();
      const filteredUsers = users.filter((user) =>
        user[1].toLowerCase().includes(searchTerm)
       );
       const filteredPosts = posts.filter((post) =>
        post[1].toLowerCase().includes(searchTerm)
        );
        if (searchType == 1) {
          renderList(filteredUsers);
        } else if (searchType == 2) {
          renderList(filteredPosts);
        }
        function renderList(filteredItem) {
          usersList.innerHTML = "";
          filteredItem.forEach((searchItem) => {
            const listItem = document.createElement("li");
            listItem.textContent = searchItem[1];
            usersList.appendChild(listItem);
         });
         }
      });
    });

Thank you.

2

Answers


  1. Chosen as BEST ANSWER

    I figured out a work around. In the functions that changed the searchType in JavaScript, I added a dispatchEvent method to trigger the input in the search bar.

    function searchUsers() {
      searchType = 1;
      document.getElementById("users-link").classList.add("active");
      document.getElementById("posts-link").classList.remove("active");
      searchInput.dispatchEvent(new Event("input"));
    }
    

  2. I think the reason for this is that the search only runs on an event listener, while the code to change the search type runs on a different element’s onClick event. You can try this:

    In your HTML, add an ID to the <a> tags for users and posts:

    <a id="users-link" onClick="searchUsers()"><li>Users</a>
    <a id="posts-link" onClick="searchPosts()"><li>Posts</a>
    

    In your JavaScript, update the searchUsers and searchPosts functions to also update the style of the selected link:

    function searchUsers() {
      searchType = 1;
      document.getElementById("users-link").classList.add("active");
      document.getElementById("posts-link").classList.remove("active");
    }
    
    function searchPosts() {
      searchType = 2;
      document.getElementById("posts-link").classList.add("active");
      document.getElementById("users-link").classList.remove("active");
    }
    

    Add CSS styles for the active link:

    .active {
      font-weight: bold;
    }
    

    Therefore, when link is clicked, the corresponding search type will be updated, and the active link will be visually highlighted. This should ensure that the search results are filtered based on the selected search type.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search