Kai
Kai

Reputation: 93

JavaScript Search bar to display results after user input

I have a webpage that displays a list of my local files, and I have a search bar that goes through the list of files and highlights the first match.

However, how can I display the files only when a user searches for a filename. So instead of all the files showing, I'd only like the files that match the search criteria to be returned.

PHP, JavaScript, jQuery is totally an option here if anyone can help in that area.

testexec.php:

<?php
$path = '/var/www/html/'; //get list of files
$files = scandir($path);

//display the links

foreach($files as $file) {
     if($file != '.' && $file != '..') {
        echo '<div><a href="readfile.php?file='.urlencode($file).'"> '.$file.'</a></div>';
     }
}

?>

readfile.php:

<?php
 // PHP script to allow the file to be downloaded
$filename = $_GET['file'];

if (file_exists($filename)) {
  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; 
filename="'.basename($filename).'"');
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');
  header('Content-Length: ' . filesize($file));
  readfile($filename);
  exit;
 }
 ?>
    //JavaScript for searchbar

     function FindNext() {
     var str = document.getElementById ("livesearch").value;
            if (str == "") {
                alert ("Please enter some text to search!");
                return;
            }
     var supported = false;
            var found = false;
            if (window.find) {        // Firefox, Google Chrome, Safari
                supported = true;
                    // if some content is selected, the start position of the search 
                    // will be the end position of the selection
                found = window.find (str);
            } else {
                if (document.selection && document.selection.createRange) { // Internet Explorer, Opera before version 10.5
                    var textRange = document.selection.createRange ();
                    if (textRange.findText) {   // Internet Explorer
                        supported = true;
                            // if some content is selected, the start position of the search 
                            // will be the position after the start position of the selection
                        if (textRange.text.length > 0) {
                            textRange.collapse (true);
                            textRange.move ("character", 1);
                        }

                        found = textRange.findText (str);
                        if (found) {
                            textRange.select ();
                        }
                    }
                }
            }

            if (supported) {
                if (!found) {
                    alert ("The following text was not found:\n" + str);
                }
            }
            else {
                alert ("Your browser does not support this example!");
            }
        }
    

Upvotes: 2

Views: 7247

Answers (3)

plonknimbuzz
plonknimbuzz

Reputation: 2664

this really easy. you just need to use event keyup and some code fix

index.php

<input type="text" id="searchbar" placeholder="search file"> <span id="loading" style="display:none;">loading</span>
<div id="result"></div>
<script src="../../vendor/jquery/jquery-3.2.1.min.js"></script>
<script>
    $(function(){
        $('#searchbar').keyup(function(){//event after user release keyboard
            var val = $(this).val();
            if(val.length >= 2){//min 2 words to start find
                $.ajax({
                    url: 'search.php',
                    type: 'POST',
                    dataType: 'json', //we use json
                    data: {keyword: val},
                    beforeSend: function(){
                        $('#loading').show();
                    },
                    success: function(d){
                        if(d.ok==1){
                            $('#result').html(d.list);
                        }else{
                            alert(d.msg);
                        }
                        $('#loading').hide();
                    },
                    error: function(d){
                        alert('error');
                        $('#loading').hide();
                    }
                });
            }
        })
    });
</script>

search.php

<?php
$path = 'C:/xampp/htdocs/';
$keyword = isset($_POST['keyword']) ? $_POST['keyword'] : '';
$scan = scandir($path);
$result = array('ok'=>0); //prepare output cz we will use json instead text/html
if($scan !== false){
    $result['ok']=1;
    $list = array();
    foreach($scan as $file){
        if(is_file($path.$file)){ //only file
            if(preg_match('/'.$keyword.'/', $file)) //is file containts keyword?
            $list[] = '<div><a href="readfile.php?file='.$file.'">'.$file.'</a></div>';
        }
    }
    $result['list'] = count($list) == 0 ? 'no file match': $list;
}else
    $result['msg'] = "failed open dir";

echo json_encode($result);

readfile.php

<?php
 // PHP script to allow the file to be downloaded
$filename = $_GET['file'];
$path = 'C:/xampp/htdocs/';
$fullPath = $path.$filename; //you need this
if (file_exists($fullPath)) {
  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; filename="'.basename($filename).'"');
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');
  header('Content-Length: ' . filesize($fullPath));
  readfile($fullPath);
  exit;
 }
 ?>

Upvotes: 0

Lee
Lee

Reputation: 418

This is the simplest idea.

Frontend

index.html

$('input').keydown(function(e) {
  var str = $(this).val();
  alert(str);
  $.get("/search.php?query=" + str, function(data) {
    $('.result').html(data);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>File search and download</h3>
<input name="filename" placeholder="file name" class="kw"/>
<div class="result">
</div>

Backend

search.php

<?php
// You need code search file
// after search $files
$str = '';
foreach($files as file) {
    $str .= '<a href="readfile.php?file=...">'.$file.'</a> <br>'
}
return $str;
?>

readfile.php

    <?php
     // PHP script to allow the file to be downloaded
    $filename = $_GET['file'];

    if (file_exists($filename)) {
      header('Content-Description: File Transfer');
      header('Content-Type: application/octet-stream');
      header('Content-Disposition: attachment; 
    filename="'.basename($filename).'"');
      header('Expires: 0');
      header('Cache-Control: must-revalidate');
      header('Pragma: public');
      header('Content-Length: ' . filesize($file));
      readfile($filename);
      exit;
     }
     ?>

Upvotes: 1

Rafael Paulino
Rafael Paulino

Reputation: 581

There are many ways to do that.

I would suggest that:

  1. Make your PHP answer a JSON with the files that match a given criteria. So you will ask to the PHP, passing in POST data ou QUERY string the "text" that is being search. It will give you only the files that matches.

  2. In you html file (could be another PHP as well), you will call ajax (you can use jQuery) to the page above everytime user changes the search text. It's good thing to "throttle" (see lodash/underscore library) (wait some time waiting for more key presses).

  3. After receiving the JSON with the files that matches, build dynamically you table (or another way you want).

search.php:

<?php
header('Content-Type: application/json');

$path = '/var/www/html/'; //get list of files
$files = scandir($path);
$search = $_GET['search'];

$links = array();

foreach ($files as $file) {
    if($file != '.' && $file != '..' && strpos(strtolower($file), strtolower($search)) !== false) {
        array_push($links, array(
            "name" => $file,
            "url" => "readfile.php?file=" . urlencode($file)
        ));
    }
}

echo json_encode($data);
?>

index.php / index.html

<html>
<head>
    <script src="http://code.jquery.com/jquery-2.2.4.min.js">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js">
</head>
<body>

    <input id="searchbox" type="text" placeholder="search for files" />

    <div id="results">
    </div>

    <script>
        $(function () {
          var searchbox = $("#searchbox");
          var results = $("#results");
          var doSearch = _.throttle(function () {
              var searchtext = searchbox.val();
              $.ajax({
                  type: 'get',
                  url: 'search.php',
                  dataType: "json",
                  data: {
                      search: searchtext
                  }
              }).done(function (response) {
                  results.html(response.reduce(function (html, item) {
                      return html + '<div><a href="' + item.url + '">' + item.name + '</a></div>';
                  }, ''));
              });
          }, 200);
          searchbox.on('keydown', doSearch);
        });
    </script>
</body>
</html>

Upvotes: 0

Related Questions