Bonjour,

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

Ce que je fais

HTML

{{ Form::open(['id' => 'form_'.$post->id, 'style'=>'height: 0px;', 'method' => 'POST']) }}
   {{ Form::hidden('posted', $post->posted == 1 ? 0 : 1, ['id' => 'form_posted_'.$post->id]) }}
   {{ Form::hidden('id', $post->id) }}
   <button onclick="submitForm('{{$post->id}}')" id="form_button_{{$post->id}}">{!! $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
}
function submitForm(id) {
    var result = document.getElementById('form_button_'+id)
    var previousState = new String(result.innerHTML)
    var form = document.querySelector('#form_' + id)
    form.addEventListener('submit', function (e) {
        e.preventDefault()
        result.innerHTML = '<i class="fa fa-spinner fa-pulse"></i><span class="sr-only">Loading...</span>'
        var httpRequest = getHttpRequest()
        httpRequest.onreadystatechange = function () {
            if (httpRequest.readyState === 4) {
                result.innetHTML = ''
                if (httpRequest.status === 200) {
                    console.log(document.getElementById('form_button_'+id))
                    if(previousState[16] == "u"){
                        result.innerHTML = "<i class='fa fa-lock'></i>";
                        document.getElementById('form_posted_'+id).value = '1'
                    }
                    if(previousState[16] == "l"){
                        result.innerHTML = "<i class='fa fa-unlock-alt'></i>";
                        document.getElementById('form_posted_'+id).value = '0'
                    }
                } 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)
    })
}

Ce que je veux

Je veux un nouveau envoie

Ce que j'obtiens

http://puu.sh/sTJWU/b3ce9ca19a.png
Ha chaque fois que je click sur le btn il ne me double les div... 1,2,4,6 et apres ducoup sa crash

21 réponses


Bonsoir,
jQuery t'aiderait à simplifier ton code.

Cependant, peux-tu inspecter déjà le code html au chargement de la page?

Ensuite tu lances une callback en réaction au clic.
Dans cette callback tu ajoutes un élement au submit du formulaire qui contient le bouton.. Mais si tu recliques tu rajoutes un listener sur le submit...

Je suis perplexe et perdu. Je ne comprends pas le sens de ton code.

Peux-tu exprimer ce que tu veux faire fonctionnellement et l'implémentation technique que tu as essayé de faire?

Nous pourrons ensuite t'aiguiller.

cordialement

Merci, dans un premier lieu pour ta réponse, j'essaie d'envoyer un formulaire sans refresh la page et donc ensuite update le code HTML dans le formulaire.
Coridialement, DixOr

Bonjour je te conseille vivement d'utiliser Jquery dans ce-cas là un $.post() te fera une requête ajax plus simple
La petite doc qui va bien
Ensuite, pour ton Dom Jquery aussi te facilitera la tâche avec les Append Add empty etc ...
ça fait jamais de mal un petit oppen classroom
Mais pense à supprimer tes éléments avant de les ajouter sinon effectivement ils vont s'ajouter à l'infinie

@Pominus, @antho07 il faut vraiment arrêter de proposer jQuery à tout bout de champs comme "la solution miracle".

@corentin philippe à la lecture de ton code, je constate que tu essayes, mais que tu ne sais pas trop ce que tu fais (ex. Ajouter de nouveaux éléments HTML à la volée alors qu'il suffirait de les afficher / cacher via CSS ...).

Tu ne devrais pas utiliser le JS inline dans ton HTML, ce n'est pas la meilleure pratique qui soit. D'autant plus que tu envoies l'id du post en hidden, pourquoi ne pas simplement l'utiliser ?

PHP :

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

JS :

var forms = document.querySelectorAll('.post_form'), id;

Array.prototype.forEach.call(forms, function (form) {   
    form.onsubmit = function (e) {
        e.preventDefault();

        id = form.elements["id"].value;

        submitForm(id);

        return false;
    }
});

Attention, dans ta fonction submitForm(), à aucun moment tu ne vérifies si l'argument id est bien défini et non null.

j'ai l'erreure suivante: MethodNotAllowedHttpException in RouteCollection.php line 218: et je ne comprend pas tres bien le code js :/

Je plussoie @betaWeb, si c'est pour utiliser jQuery pour l'ajax, il y a d'autres librairies telles que axios qui le font encore mieux

MethodNotAllowedHttpException c'est une erreur de laravel quand tu appelles une page par exemple en post et qu'elle n'est définie que en get : la méthode n'est pas permise

la route est bien definie en post

Donc tu as peut-être deux routes identiques, ou autres. Quoi qu'il en soit, il y a conflit quelque part.
Et comme on dit en dev, 99% des bugs trouvent leur source entre la chaise et le clavier ;)

va dans terminal et fait "php artisan route:list" pour voir l'ensemble des routes sur laravel

tu saurais poster les headers de la requête en l'inspectant dans l'onglet "network" de l'inspecteur ?

et la partie General ?

General, c est a dire ?

de la requête

Attend j'ai du mal comprendre, t'es redirigé sur le methodnotallowed ? (pck l'ajax call est bon)

Edit : je pense que l'erreur vienne du faite que tu as mal compris les événements

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

Faut que tu déplaces ton submitForm('{{$post->id}}') dans l'événement submit du form =>

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

Et ensuite, ton submitForm il doit gérer l'événement, pas ajouter l'événement au listener :

function submitForm(e) {
    var source = event.target || event.srcElement;
    var id =  source.dataset['id'];
    var result = document.getElementById('form_button_'+id)
    var previousState = new String(result.innerHTML)
    var form = document.querySelector('#form_' + id)
    e.preventDefault()
    result.innerHTML = '<i class="fa fa-spinner fa-pulse"></i><span class="sr-only">Loading...</span>'
    var httpRequest = getHttpRequest()
    httpRequest.onreadystatechange = function () {
      if (httpRequest.readyState === 4) {
        result.innetHTML = ''
        if (httpRequest.status === 200) {
          console.log(document.getElementById('form_button_'+id))
          if(previousState[16] == "u"){
          result.innerHTML = "<i class='fa fa-lock'></i>";
          document.getElementById('form_posted_'+id).value = '1'
          }
          if(previousState[16] == "l"){
          result.innerHTML = "<i class='fa fa-unlock-alt'></i>";
          document.getElementById('form_posted_'+id).value = '0'
          }
        } 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)
}

Après tu peux améliorer le script grandement car tu as dans "source" le formulaire (grâce à "e")

J'ai l'erreur suivante:

MethodNotAllowedHttpException in RouteCollection.php line 218:

A quel moment ?

quand je clique sur le btn

l'url affichée change-t-elle ?