Comment créer un input qui suggère des résultats ?

Le problème exposé dans ce sujet a été résolu.

Yo les zesteux !

Aujourd'hui, j'essaie de résoudre un nouveau problème pour moi (surtout que je galère trop avec Ajax) J'aimerais faire un peu comme ça : http://www.w3schools.com/asp/asp_ajax_asp.asp

C'est à dire qu'avec ASP.NET, C#, Sql server et en MVC 5; je voudrais avoir un input html, et avec le trigger "onKeyUp" qu'à chaque fois que l'utilisateur tape un caractère, le contrôlleur éxécute sur la base une requête LIKE %caractère% pour proposer des résultats.

Côté sql et tout c'est bon, je galère pour ce qui est de l'Ajax et du C#.

Quelqu'un a une idée ?

En fait par rapport à la source donnée par la w3schools, si tu utilise MVC, il faudra que tu changes cette ligne xmlhttp.open("GET", "gethint.asp?q=" + str, true) pour que l'url corresponde à une url qui mappe vers une action. Et c'est cette action qui génèrera une liste d'éléments à autocompléter.

Bon, ma page ressemble à ça :

1
2
3
4
    <div id="check-name" class="form-row">
        <input id="name" type="text" name="name" placeholder="Titre de l'événement" onkeyup="showHint(this.value)">
        <span id="txtHint"></span>
    </div>

mon script à ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function showHint(str) {
    if (str.length == 0) {
        document.getElementById("txtHint").innerHTML = "";
        return;
    } else {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
            }
        };
        var titre = str;
        xmlhttp.open("POST", "CheckReturn", true);
        xmlhttp.send(titre);
    }
}

et enfin, mon contrôlleur à ça :

1
2
3
4
5
6
7
8
9
        [HttpPost]
        public ActionResult CheckReturn(string titre)
        {
            var contexte = new intranetEntities();
            var ajax = contexte.evenementiel.SqlQuery("SELECT * FROM evenementiel WHERE titrebri_evenementiel LIKE '%"+titre+"%' ORDER BY datecreation_evenementiel DESC;");
            ViewBag.ajax = ajax;

            return PartialView();
        }

et je sais pas pourquoi ça marche pas :( avec firebug, je vois que ma page envoie une requête POST avec les bonnes données; mais le contrôlleur me retorune toutes les entrées de la base (titre est nul) je sais pas pourquoi.

+0 -0

Salut,

je vois ceci : xmlhttp.open("POST", "CheckReturn", true); avec une action CheckReturn qui prend un paramètre "titre". Pour l'instant il y a donc un problème : tu n'envoies jamais le titre.

En outre : var ajax = contexte.evenementiel.SqlQuery("SELECT * FROM evenementiel WHERE titrebri_evenementiel LIKE '%"+titre+"%' ORDER BY datecreation_evenementiel DESC;"); est une faille de sécurité assez importante.

Si tu utilises un ORM, n'utilise pas des requêtes en brut.

Enfin, tant que jen e connais pas l'état de ton template, je ne peux pas te dire grand chose.

attend, c'est bien "xmlhttp.send(titre);" qui envoie les données ?

pour ce qui est de l'injection, le compte utiliser les requêtes avec paramètres; je veux juste réussir à faire passer les données pour l'instant.

Qu'est ce qu'il te manque comme information ?

ok, ça c'est ma vue partielle :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@model Evenementiel_1.Models.Query

<table class="bordered centered striped">
    <thead>
        <tr>
            <th data-field="name">Intitulé</th>
            <th data-field="lieu">Lieu</th>
            <th data-field="date">Date</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in ViewBag.ajax)
        {
            <tr class="parent">
                <th>@item.titrebri_evenementiel</th>
                <th>@item.lieubri_evenementiel</th>
                <th>@item.datebri_evenementiel</th>
            </tr>
        }
    </tbody>
</table>

et pour ce qui est de la configuration de route :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
namespace Evenementiel_1
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

Ok : il est fort probable qu'il te manque la mention du contrôleur dans l'url que tu utilises dans ton appel ajax.

Pour vérifiez cela, dans ton navigateur, va sur la page où tu as ton champ texte, ouvre l'onglet réseau (appuie sur F12 puis dans l'onglet réseau/network), puis seulement commence à tapper des choses sur ton champ texte. Regarde le status de la requête qui est envoyé.

Si c'est une erreur 500, fais en sorte d'utiliser le débugger pour trouver où est l'erreur.

bon, j'ai pas d'erreur 500. Le contrôlleur me retourne le résultat de ma requête mais avec titre nul, donc TOUS les enregistrements de la table.

Image utilisateur

Image utilisateur

mon POST envoie bien le bon truc, mais la réponse n'est pas bonne.

Je suis presque sûr que c'est mon contrôlleur qui ne reçois jamais l'info.

Ok, montre moi

  • le contenu de la réponse (juste à coté de l'onglet POST dans ta dernière image)
  • utilises de le debugger pour voir si ça entre vraiment dans ton système.

A mon humble avis, il faudra que tu changes légèrement le javascript pour mettre ceci :

xmlhttp.send({"titre":titre}); à la place de xmlhttp.send(titre); en effet ASP essaie de faire coincider les valeurs de la requête entre elles et comme tu n'envoies rien nommé "titre" il sait pas torp quoi faire.

+1 -0

bon, j'ai changé ma requête en :

"SELECT TOP 5 * FROM evenementiel WHERE titrebri_evenementiel LIKE '%"+titre+"%' ORDER BY datecreation_evenementiel DESC;" (pour qu'il y ait pas trop de temps de chargement)

et aussi changé le script; maintenant avec firebug dans mon onglet POST j'ai [object Object]. Dans l'onglet de réponse, c'est du HTML brut, ce que renvoie la base :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<table class="bordered centered striped">
    <thead>
        <tr>
            <th data-field="name">Intitulé</th>
            <th data-field="lieu">Lieu</th>
            <th data-field="date">Date</th>
        </tr>
    </thead>
    <tbody>
            <tr class="parent">
                <th>test</th>
                <th></th>
                <th>12/01/2016 00:00:00</th>
            </tr>
            <tr class="parent">
                <th>CONCERT PATRIZIA POLI</th>
                <th>AJACCIO</th>
                <th>14/01/2016 00:00:00</th>
            </tr>
            <tr class="parent">
                <th>TABLE RONDE CTC TRANSPORT ??? AVEC CGT</th>
                <th></th>
                <th>13/01/2016 00:00:00</th>
            </tr>
            <tr class="parent">
                <th>ELECTION PDT CONSEIL SCIENTIFIQUE PNRC</th>
                <th></th>
                <th>19/01/2016 00:00:00</th>
            </tr>
            <tr class="parent">
                <th>DEBUT RECENSEMENT POPULATION</th>
                <th>AJACCIO</th>
                <th>21/01/2016 00:00:00</th>
            </tr>
    </tbody>
</table>

enfin, voici pour ma variable titre :

Image utilisateur

ps : merci de m'aider, c'est cool

Salut, je suis allé chercher un peu partout, puis j'ai créé la même question sur stackoverflow (surtout, ne prenez pas ça comme une offense quelconque) et voilà ce que j'ai fait pour résoudre mon problème :

-je créé une nouvelle classe, appellée "TitreWrapper" (je l'ai mise dans "models") avec un attribut "titre"

1
        public string titre { get; set; }

-je change le paramètre de mon contrôlleur (il attend maintenant un "TitreWrapper titreWrap" au lieu d'un string) et j'ajoute "string titre = titreWrap.titre;"

-enfin, je change mon javascript :

1
2
        xmlhttp.open("POST", "CheckReturn?titre=" + titre, true);
        xmlhttp.send({titre: titre});

et voilà :D

pour ceux qui veulent voir le thread sur stack overflow (mes réponses sont dans les commentaires, sous le pseudo Orsu) : http://stackoverflow.com/questions/35179919/controller-not-receiving-data

merci beaucoup à artragis pour m'avoir aidé jusque ici !

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte