Faire un champ texte de formulaire pour retourner plusieurs valeurs

Voici une petite astuce qui m’a bien servi l’autre jour : Comment faire un champ de formulaire de type texte, et mettre plusieurs données dedans (genre liste de contacts, tags, etc..)

Tout d’abord, côté HTML (dans l’exemple j’utilise Twig comme moteur de templates), on va créer une liste dans laquelle on va mettre un champ input :

<label for="contacts">Contacts :</label>
<div class="value" style="margin:0px">
    <ul id="contacts_list" class="holder">
        <li class="input-text"><input type="text" value="" id="contacts_search" /></li>
        {% for c in f.contacts %}
            <li class="bit-box" value="{{ c.id }}" id="{{ c.id }}">
                <input type="hidden" name="contacts[]" value="{{ c.id }}" />{{ c.nom }} {{ c.prenom }}
                <img id="close-{{ c.id }}" class="closebutton" src="images/close.gif"></img>
            </li>
        {% endfor %}
    </ul>
</div>

Ensuite, un peut de javascript / jquery UI pour avoir de l’autocompletion lorsque l’on tape dans le champ input :

<script type="text/javascript" src="js/jquery-ui-1.10.4.custom.min.js"></script>
<script>
$(document).ready(function() {
    $('#contacts_search').autocomplete({
        source: function(req, add) {
            $.getJSON("ws/search_contacts.php", { search: req.term }, function(data) {
                //create array for response objects
                var contacts = [];
                //process response
                $.each(data, function(i, val){
                    contacts.push({ label: val.nom+' '+val.prenom, id: val.id, value: val.id });
                });
                add(contacts);
            });
        },
        minLength: 2,
        delay: 500,
        focus : function(event, ui) {
            this.value = ui.item.label;
            event.preventDefault();
        },
        select: function(event, ui) {
            $('#contacts_list').append('<li id="contact-'+ui.item.id+'" class="bit-box" value="'+ui.item.id+'"><input type="hidden" name="contacts[]" value="'+ui.item.id+'" />'+ui.item.label+'<img src="images/close.gif" id="close-'+ui.item.id+'" class="closebutton" /></li>');
            this.value= "";
            event.preventDefault();
        }
    });
});
</script>

Encore du jquery pour enlver des elements de la liste quand on clique sur la petite croix

<script>
$(document).ready(function() {
    $(document).on('click', ".closebutton", function() {
        var liId = $(this).parent("li").attr("id");
        $('#'+liId).remove();
    });
});
</script>

Le petit pour de code php appelé en ajax :

<?php

$conf = parse_ini_file('../config.ini');
try {
    $dbh = new PDO($conf['db_type'].':host='.$conf['db_host'].';dbname='.$conf['db_name'].";port=".$conf['db_port'], $conf['db_user'], $conf['db_pass']);
} catch(PDOException $e) {
    echo json_encode(array('error' => $e->getMessage()) );
    exit;
}
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$contacts = array();
foreach ($dbh->query("SELECT * FROM contacts ORDER BY nom") as $row) {
    $contacts[] = $row;
}

$search = array();
if (isset($_GET['search'])) {
     foreach ($contacts as $c) {
        $pattern = "/".trim($_GET['search'])."/i";
        if (preg_match($pattern, $c['nom']) or preg_match($pattern, $c['prenom'])) {
            $search[$c['id']] = $c;
        }
    }
}

echo json_encode($search);

?>

Et enfin, côté serveur, y’a plus qu’a récupérer les infos dans un tableau « contacts », et les insérer dans la table de relation objet / contacts :

$sth = $dbh->prepare("INSERT INTO contacts_object (id_object, id_contact) values (?, ?)");
if (isset($_POST['contacts'])) {
    $contacts = $_POST['contacts'];
    $id_object = $_POST['id'];
    try {
        foreach ($contacts as $c) {
            $sth->execute(array($id_object, $c));
        }
    } catch (PDOException $e) {
        $error .= "Erreur Replace : ".$e->getMessage();
    }
}

Ah, j’allais oublier ! Un peut de CSS pour que la liste apparaisse bien comme il faut :

ul.holder {
    margin: 5px;
    border: 1px solid rgb(153, 153, 153);
    overflow: hidden;
    height: auto !important;
    list-style:none;
    padding: 0px 1px 0px;
}

ul.holder li.bit-box {
    border-radius: 6px;
    border: 1px solid rgb(202, 216, 243);
    background: none repeat scroll 0% 0% rgb(222, 231, 248);
    padding-right: 15px;
    position: relative;
    padding: 1px 5px 1px;
}

ul.holder input {
    width: 250px;
    margin: 0px;
    border: medium none;
    outline: 0px none;
    padding: 3px 0px 2px;
}

.ui-helper-hidden-accessible { display:none; }
.ui-corner-all {
    list-style:none;
    background: white;
}
.ui-corner-all a {
    text-decoration: none;
    color:black;
}

.closebutton {
    position: absolute;
    right: 4px;
    top: 5px;
    display: block;
    width: 7px;
    height: 7px;
    font-size: 1px;
    cursor: pointer;
}

Et voila !

Streeme : Le serveur de musique en streaming open source

streeme_logo

Voila, comme j’ai migré mon serveur chez OVH, j’me suis réinstallé un ptit serveur de musique en streaming, pour pouvoir écouter ma musique au boulot 🙂

ca s’appelle Streeme, c’est open source et ça utilise PHP / Apache / MySQL.

Voici un petit screenshot de ce que ça donne :

streeme_screenshot

Bref, c’est bien pratique pour écouter sa propre musique depuis n’importe où.

En plus y’a même une interface mobile simplifiée compatible avec la majorité des navigateurs de smartphone 🙂

Gate One

 

J’avais vu une news sur le fameux blog de Korben qui parlait d’un client ssh en web.

Du coup, j’me suis motivé pour l’installer sur mon ptit serveur et voir ce que ça donne.

C’est vachement cool, ça permet d’avoir accès à un terminal depuis n’importe ou, (pour peut que le méchant proxy du taf n’ai pas une #%$& de white list SSL).

C’est open Source, et c’est codé en python.

Toutes les infos sont sur le site officiel !

Hawken sur Steam

hawken

Trop bien ! Un FPS avec des mechas futuristes arrive enfin dans Steam !

J’avais déjà participé a la beta, et j’avais bien kiffé, même si a l’époque le jeu en était encore qu’à ses début.

En tout cas c’est un Free to play bien sympa, et je pense que je vais m’y remettre pour le coup 🙂