TarekRaafat / autoComplete.js

Simple autocomplete pure vanilla Javascript library.
https://tarekraafat.github.io/autoComplete.js
Apache License 2.0
3.93k stars 236 forks source link

How can i have linkable results in dropdown ? #131

Closed greatdesign closed 4 years ago

greatdesign commented 4 years ago

I have a json with structure like that:

[ { "link": "\/games\/assassins-creed-odyssey", "title": "Assassin's Creed Odyssey" } ]

Autocomplete works fine, but how can i have the result so if i click on it go to the specific url ???

TarekRaafat commented 4 years ago

Hello @codebox-studio,

You will need to add the URL to each record "assuming that it's unique" as shown below.

[ { "link": "\/games\/assassins-creed-odyssey", "title": "Assassin's Creed Odyssey", "url":"http://www.gamepage.com" } ]

Then use one of the below two ways for navigating to URLs.

// The autoComplete.js Engine instance creator
const autoCompletejs = new autoComplete({
  onSelection: (feedback) => {
    // 1- First Method
    window.location.href = feedback.selection.url;
    // OR
    // 2- Second Method
    window.location.assign(feedback.selection.url);
  },
});

Try it out and let me know if that's the result you're after or not.

Have a nice day, cheers! :)

woshichuanqilz commented 2 years ago

I want the result list item can be a clickable link, will lead to another page. Nothing happens when I change the code like this

It wont work for me. Here is the data.

[
  {
    "url":"http://www.baidu.com",
    "pinyin": "sh-u"
  }
]

Here is the related code:

const autoCompleteJS = new autoComplete({
 onSelection: (feedback) => {
    // 1- First Method
    window.location.href = feedback.selection.url;
    // OR
    // 2- Second Method
    window.location.assign(feedback.selection.url);
  },
  data: {
    src: async () => {
      try {
        // Loading placeholder text
        document
          .getElementById("autoComplete")
          .setAttribute("placeholder", "Loading...");
        // Fetch External Data Source
        const source = await fetch(
          // "https://tarekraafat.github.io/autoComplete.js/demo/db/generic.json"
          "./static/data/pinyin.json"
        );
        const data = await source.json();
        // Post Loading placeholder text
        document
          .getElementById("autoComplete")
          .setAttribute("placeholder", autoCompleteJS.placeHolder);
        // Returns Fetched data
        return data;
      } catch (error) {
        return error;
      }
    },
    keys: ["pinyin"],
    cache: true,
    filter: (list) => {
      // Filter duplicates
      // incase of multiple data keys usage
      const filteredResults = Array.from(
        new Set(list.map((value) => value.match))
      ).map((food) => {
        return list.find((value) => value.match === food);
      });

      return filteredResults;
    }
  },
  placeHolder: "双拼查询",
  resultsList: {
    element: (list, data) => {
      const info = document.createElement("p");
      if (data.results.length > 0) {
        info.innerHTML = `Displaying <strong>${data.results.length}</strong> out of <strong>${data.matches.length}</strong> results`;
      } else {
        info.innerHTML = `Found <strong>${data.matches.length}</strong> matching results for <strong>"${data.query}"</strong>`;
      }
      list.prepend(info);
    },
    noResults: true,
    maxResults: 15,
    tabSelect: true
  },
  resultItem: {
    element: (item, data) => {
      // Modify Results Item Style
      item.style = "display: flex; justify-content: space-between;";
      // Modify Results Item Content
      item.innerHTML = `
      <span style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
        ${data.match}
      </span>
      <span style="display: flex; align-items: center; font-size: 13px; font-weight: 100; text-transform: uppercase; color: rgba(0,0,0,.2);">
        ${data.key}
      </span>`;
    },
    highlight: true
  },
  events: {
    input: {
      focus: () => {
        if (autoCompleteJS.input.value.length) autoCompleteJS.start();
      }
    }
  }
});
woshichuanqilz commented 2 years ago

I want the result list item can be a clickable link, will lead to another page. Nothing happens when I change the code like this

It wont work for me. Here is the data.

[
  {
    "url":"http://www.baidu.com",
    "pinyin": "sh-u"
  }
]

Here is the related code:

const autoCompleteJS = new autoComplete({
 onSelection: (feedback) => {
    // 1- First Method
    window.location.href = feedback.selection.url;
    // OR
    // 2- Second Method
    window.location.assign(feedback.selection.url);
  },
  data: {
    src: async () => {
      try {
        // Loading placeholder text
        document
          .getElementById("autoComplete")
          .setAttribute("placeholder", "Loading...");
        // Fetch External Data Source
        const source = await fetch(
          // "https://tarekraafat.github.io/autoComplete.js/demo/db/generic.json"
          "./static/data/pinyin.json"
        );
        const data = await source.json();
        // Post Loading placeholder text
        document
          .getElementById("autoComplete")
          .setAttribute("placeholder", autoCompleteJS.placeHolder);
        // Returns Fetched data
        return data;
      } catch (error) {
        return error;
      }
    },
    keys: ["pinyin"],
    cache: true,
    filter: (list) => {
      // Filter duplicates
      // incase of multiple data keys usage
      const filteredResults = Array.from(
        new Set(list.map((value) => value.match))
      ).map((food) => {
        return list.find((value) => value.match === food);
      });

      return filteredResults;
    }
  },
  placeHolder: "双拼查询",
  resultsList: {
    element: (list, data) => {
      const info = document.createElement("p");
      if (data.results.length > 0) {
        info.innerHTML = `Displaying <strong>${data.results.length}</strong> out of <strong>${data.matches.length}</strong> results`;
      } else {
        info.innerHTML = `Found <strong>${data.matches.length}</strong> matching results for <strong>"${data.query}"</strong>`;
      }
      list.prepend(info);
    },
    noResults: true,
    maxResults: 15,
    tabSelect: true
  },
  resultItem: {
    element: (item, data) => {
      // Modify Results Item Style
      item.style = "display: flex; justify-content: space-between;";
      // Modify Results Item Content
      item.innerHTML = `
      <span style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
        ${data.match}
      </span>
      <span style="display: flex; align-items: center; font-size: 13px; font-weight: 100; text-transform: uppercase; color: rgba(0,0,0,.2);">
        ${data.key}
      </span>`;
    },
    highlight: true
  },
  events: {
    input: {
      focus: () => {
        if (autoCompleteJS.input.value.length) autoCompleteJS.start();
      }
    }
  }
});

Solved by check this link https://tarekraafat.github.io/autoComplete.js/#/usage?id=demo

Here is the related code


<!DOCTYPE html>
<html lang="en">

<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/css/autoComplete.min.css">
</head>

<body>
    <div class="autoComplete_wrapper">
        <input id="autoComplete" type="search" dir="ltr" spellcheck=false autocorrect="off" autocomplete="off" autocapitalize="off">
    </div>

    <script src="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/autoComplete.min.js"></script>
    <script>
        const autoCompleteJS = new autoComplete({
            placeHolder: "Search for Food...",
            data: {
                src: [
                        {
                            "name": "Sauce - Thousand Island", 
                            "url": "https://www.baidu.com"
                        },
                    {
                        "name": "Wild Boar - Tenderloin", 
                        "url": "baidu"
                    }
                ],
                cache: true,
                keys: ["name"],
            },
            resultItem: {
                highlight: true
            },
    events: {
        input: {
            selection(event) {
                const feedback = event.detail;
                console.log(feedback.selection.value.url);
                window.open(feedback.selection.value.url, "_blank");
                const input = autoCompleteJS.input;
                // Trim selected Value
                const selection = feedback.selection.value["name"].trim();
                // Split query into array and trim each value
                const query = input.value.split(",").map(item => item.trim());
                // Remove last query
                query.pop();
                // Add selected value
                query.push(selection);
                // Replace Input value with the new query
                input.value = query.join(", ") + ", ";
            }
        }
},
        });
    </script>
</body>

</html>