Cass Cass - 7 months ago 61
Ajax Question

Auto-complete search box, selecting multiple values from results

I'm creating my own recipe box using php/mysql and one part I'm stuck on is actually creating the recipes, specifically selecting the ingredients.

What I wanted to do instead is have a auto-complete search box where I can type out names of the ingredients, have the results drop down right below, and click the ones I'm looking for. After clicking the ingredient, it'll be listed below the search box with an input to put quantity and an "x" to delete if needed. This of course would grow depending on how many ingredients the recipe requires. At the end, I would just take the data and do an insert into my database.

I've seen a lot of AJAX tutorials on getting the auto-complete search box functionality, but nothing tying it to the value selection. The best example of what I'm going for can be found at http://supercook.com. They have it so you can search for recipes.

Any suggestions or online resources?

Thanks!

Answer Source

you asked a great question. Below I've written a short example to get you started. Just save it as ingredients.php and it should work. Of course, you'll need to add your database connection and query to give it real data. I've used the jQuery library because it makes the Javascript part a lot easier.

<?php

// connect to database here

if (isset($_POST['q'])) {
    if (trim($_POST['q']) === '') die('[]');
    // $q = mysql_real_escape_string($_POST['q']);
    // run a query like: "SELECT id, name FROM ingredients WHERE name LIKE '{$q}%'"
    // and put the result in the $result array.
    // This is sample data:
    $result = array(
        array('id' => 71, 'name' => 'apple'),
        array('id' => 3, 'name' => 'anchovies'),
        array('id' => 230, 'name' => 'artichoke'),
        );

    if (function_exists('json_encode')) die(json_encode($result));
    else {
        $escaped = array();
        foreach ($result as $r) $escaped[] = str_replace(array('\\', '"'), array('\\\\', '\"'), $r);
        die('["'.join('","', $escaped).'"]');
    }
}

$data = array();
if (isset($_POST['ingredients'])) {
    foreach ($_POST['ingredients'] as $i => $ingredient) {
        $data[] = array(
            'ingredient' => $ingredient,
            'quantity' => $_POST['quantities'][$i],
            );
    }
    // save data to the database here (or inside the foreach loop above)
}

?>
<html><head></head><body>
<style>
    #wrap { position: relative }
    #pop {
        position: absolute;
        border: 1px solid black;
        background-color: white;
        display: none;
    }
</style>

<?php if (count($data)): ?>
<h3>Saved:</h3>
<pre><?php print_r($data) ?></pre>
<?php endif; ?>

<div id="wrap">
    <input id="adder" />
    <div id="pop"></div>
</div>
<form method="post">
    Ingredients:<br />
    <div id="recipe"></div>
    <input type="submit" value="Save" />
</form>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
    var last_query = '';
    jQuery(function() {
        jQuery('#adder').val('').keyup(function() {
            var query = jQuery(this).val();
            if (query != last_query) jQuery.post('ingredients.php', {q: query}, function(data) {
                var p = jQuery('#pop').html('').show();
                for (var i=0; i<data.length; i++) {
                    p.append(jQuery('<p>'+data[i].name+'</p>').bind('click', { ingredient: data[i] }, function(e) {
                        add_ingredient(e.data.ingredient);
                        jQuery('#pop').hide();
                        jQuery('#adder').val('');
                    }));
                }
            }, 'json');
            else jQuery('#pop').show();
            last_query = query;
        });
    });
    function add_ingredient(data) {
        console.log(data);
        var ingredient = jQuery('<div> <input name="quantities[]" size="2" /> '+data.name
            + '<input type="hidden" name="ingredients[]" value="'+data.id+'" /></div>');
        var remover = jQuery('<span>X</span>').click(function() {
            jQuery(this).parent().remove();
        });
        jQuery('#recipe').append(ingredient.prepend(remover));
    }
</script>
</body></html>
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download