Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Je voudrais update mon formulaire sans rafreshir la page

<span class="posts-listing__locked">
                                    {{ Form::open(['style'=>'height: 0px;', 'method' => 'PUT', 'route' => ['admin.posts.update', $post->id, \Illuminate\Support\Facades\Auth::user()->id]]) }}
                                    <input type="hidden" name="post_listing" value="true">
                                    <button name="posted" value="{!! $post->posted == 1 ? 0 : 1 !!}">{!! $post->posted == "1" ? "<i class='fa fa-unlock-alt'></i>" :  "<i class='fa fa-lock'></i>" !!}</button>
                                    {{ Form::close() }}
                                </span>

Route

    Route::put('posts/{id}/{author}', ['as' => 'admin.posts.update', 'uses' => 'PostsController@update']);

PostsController

if(isset($request['post_listing']) == true){
            $getUpdate = self::getUpdate($request->except(['_token', '_method']), $post->toArray());
            if($getUpdate){
                $post->update($request->except(['_token', 'public']));
                return back()->with('success', "L'article a bien été mis à jour.");
            }
        }

Ce que je veux

Je voudrais ne pas refresh la page avec le contenu de l'updare rafreshi

12 réponses


betaWeb
Réponse acceptée

@resethread la première partie de la réponse est valable, mais pas la seconde ! Pourquoi surcharger le front avec AngularJS ou vueJS juste pour faire de l'AJAX ? C'est stupide, c'est un très mauvais conseioll et surtout une très très très mauvaise pratique !

@corentin philippe Il te faut ajouter un event à la soumission du formulaire, puis appeler le script de traitement (donc une route spécifique vers ton controller) via une requête AJAX. je te conseille de regarder ce tutoriel afin de mieux comprendre ce qu'est l'AJAX https://www.grafikart.fr/formations/debuter-javascript/ajax (ça fait peur, mais c'est pas si difficile que cela ;) )

Pour traiter des formulaires sans recharger la page, tu dois bloquer la soumission du formulaire en javascript, envoyer les données en ajax avec un framework ( idéalement vuejs ou angularjs ), et avec ce même framework afficher le résultat du script PHP.

@betaWeb pourquoi surcharger le front avec un framework ? Si tu utilises souvent de l'ajax tu dois savoir que c'est assez compliqué sans framework. Perso j'ai bossé une fois dessus en vanilla, et je peux te dire qu'il y en aura pas deux. Voilà pourquoi un framework est plus que recommendé ( avec une préférence pour vuejs / vue-resource qui est de loin le plus simple ).

@resethread C'est que tu n'as pas les bonnes pratiques, il est très simple de travailler en AJAX avec du vanilla JS (en fouillant 10s sur Google) :

function createXHR()
{
    var xhr;
    if (window.ActiveXObject) {
        try {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        } catch(e) {
            alert(e.message);
            xhr = null;
        }
    } else {
        xhr = new XMLHttpRequest();
    }

    return xhr;
}

var xhr = createXHR();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        console.log(xhr.responseText);
    }
}
xhr.open('GET', 'http://api.monsupersite.fr/trouver_un_truc', true)
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send()

merci pour ta réponse j'ai fait :
JS

var getHttpRequest = function () {
    var httpRequest = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari,...
        httpRequest = new XMLHttpRequest();
        if (httpRequest.overrideMimeType) {
            httpRequest.overrideMimeType('text/xml');
        }
    }
    else if (window.ActiveXObject) { // IE
        try {
            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
            }
        }
    }
    if (!httpRequest) {
        alert('Abandon :( Impossible de créer une instance XMLHTTP');
        return false;
    }
    return httpRequest
}
var result = document.querySelector('#result')
var id = document.getElementById('form_id').value
var form = document.querySelector('#form_'+id)
form.addEventListener('submit', function (e) {
    e.preventDefault()
    result.innerHTML = 'Chargement...'
    var httpRequest = getHttpRequest()
    httpRequest.onreadystatechange = function () {
        if (httpRequest.readyState === 4) {
            result.innetHTML = ''
            if (httpRequest.status === 200) {
                result.innerHTML = httpRequest.responseText
            } else {
                alert('Impossible de contacter le serveur !')
            }
        }
    }
    httpRequest.open('POST', 'http://localhost/Lab/vmprod_update/admin/posts/listing/update', true)
    var data = new FormData(form)
    httpRequest.send(data)
})

ROUTE:

    Route::post('posts/listing/update', ['as' => 'admin.posts.update.listing', 'uses' => 'PostsController@updateListing']);

POSTSCONTROLLER:

public function updateListing(Request $request){
        if($request->json()){
           dd($request->all());
        }
    }

Mais j'ai plusieurs form sur une page: http://puu.sh/sQCes/3b0dceecf8.jpg
Le premier form marche bien mais les autre j'ai une erreur : http://puu.sh/sQChP/02ce9404f3.png

Cordialement, Corentin

L'erreur parle d'elle-même : la méthode HTTP n'est pas permise.
Une piste ici : https://laracasts.com/discuss/channels/general-discussion/methodnotallowedhttpexception

Tu peux essayer ceci :

Route::patch('posts/listing/update', 'PostsController@updateListing');

Dans la partie Network de la console développeur, lorsque tu submit, tu as combien de requêtes qui sont envoyées ?
Rassure-moi, l'ID (HTML) de tes forms ne sont pas tous identiques ?

Salut, excusez-moi si je n'apporte pas réellement de réponse au problème mais j'ai vu quelque chose d'horrible.

"pourquoi surcharger le front avec un framework ? Si tu utilises souvent de l'ajax tu dois savoir que c'est assez compliqué sans framework"
Si vous trouvez AJAX compliqué vous ne devez pas être développeur, mis à part que c'est verbeux dû aux problèmes de compatibilités des API (vive internet exploreur lolol).

Je suis totalement d'accord avec @betaWeb. Un framework javascript ne répond absolument pas à la demande "je veux faire de l'ajax simplement".
@resethread De plus, vous ne répondez absolument pas à la demande, vous ne faites que l'induire en erreur. Si vous faites cette stupide erreur qu'est d'installer un framework juste pour l'AJAX c'est votre problème mais évitez d'essayer de la transmettre aux autres.

Si vous souhaitez faire de l'AJAX plus "simplement" (surtout réduire le code et ne pas se prendre la tête avec la compatibilité) il existe des librairies (librairies et non framework) légères (contrairement à un framework) qui le permettent.
Par exemple axios qui permet beaucoup de choses (travailler avec les Promises...).

Pour ceux qui voudrait connaître une nouvelle méthode que l'objet XMLHttpRequest :
Il y a une nouvelle API qui est encore en stade expérimental.
Il s'agit d'utiliser la méthode fetch. Si vous souhaitez plus d'informations : MDN.
Il existe bien évidemment un polyfill pour ceux qui veulent l'utiliser dès aujourd'hui. Mais à noter elle est en stade expérimental donc amenée à être modifiée ou non.

@Emix +1
Je ne suis pas parti dans les explications mais c'est tout à fait ça.

non mais champs id ne sont pas les même

 {{ Form::open(['id' => 'form_'.$post->id, 'style'=>'height: 0px;', 'method' => 'PATCH']) }}
                                        <input type="hidden" name="posted" id="posted" value="{!! $post->posted == 1 ? 0 : 1 !!}">
                                        <input type="hidden" name="id" id="id" value="{!! $post->id !!}">
                                        <button type="submit">{!! $post->posted == "1" ? "<i class='fa fa-unlock-alt'></i>" :  "<i class='fa fa-lock'></i>" !!}</button>
                                    {{ Form::close() }}

et j'ai test ta route mais le probleme perciste

quand j'ai l'erreur aucun requette et pour la premiere il y a bien une requette

c'est bien quand je get l'id de la form mais pourtant il sont diferrent ....

Ne met pas la méthode PATCH sur ton formulaire !!
Et pour la value de l'input id, écris-le comme ça {{ $post->id }} et non comme ça {!! $post->id !!} (pourquoi tu échappes l'id ??)

Sa ne marche toujours pas :'(
HTML:

 {{ Form::open(['id' => 'form_'.$post->id, 'style'=>'height: 0px;', 'method' => 'POST']) }}
                                        <input type="hidden" name="posted" id="posted" value="{{ $post->posted == 1 ? 0 : 1 }}">
                                        <input type="hidden" name="id" id="id" value="{{ $post->id }}">
                                        <button id="test" type="submit">{!! $post->posted == "1" ? "<i class='fa fa-unlock-alt'></i>" :  "<i class='fa fa-lock'></i>" !!}</button>
                                    {{ Form::close() }}

JS:

var getHttpRequest = function () {
    var httpRequest = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari,...
        httpRequest = new XMLHttpRequest();
        if (httpRequest.overrideMimeType) {
            httpRequest.overrideMimeType('text/xml');
        }
    }
    else if (window.ActiveXObject) { // IE
        try {
            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
            }
        }
    }
    if (!httpRequest) {
        alert('Abandon :( Impossible de créer une instance XMLHTTP');
        return false;
    }
    return httpRequest
}
var id = document.getElementById('id').value
var result = document.querySelector('#result_'+id)
var form = document.querySelector('#form_'+id)
form.addEventListener('submit', function (e) {
    e.preventDefault()
    result.innerHTML = 'Chargement...'
    var httpRequest = getHttpRequest()
    httpRequest.onreadystatechange = function () {
        if (httpRequest.readyState === 4) {
            result.innetHTML = ''
            if (httpRequest.status === 200) {
                result.innerHTML = httpRequest.responseText
            } else {
                alert('Impossible de contacter le serveur !')
            }
        }
    }
    httpRequest.open('POST', 'http://localhost/Lab/vmprod_update/admin/posts/listing/update', true)
    var data = new FormData(form)
    httpRequest.send(data)
})

route+controller:

 Route::patch('posts/listing/update', 'PostsController@updateListing');

  public function updateListing(Request $request){
        if($request->json()){
           dd($request->all());
        }
    }

Erreur: MethodNotAllowedHttpException in RouteCollection.php line 218: