Bonjour,

Je suis en train de travailler sur un système de widget activable via un système drag and drop, un widget désactivé à la valeur 0 stocké dans un champ en base, et 1 si l'on veut l'activer, le système côté serveur fonctionne, maintenant j'aimerai faire en sorte quand on déplace un widget il change de valeur, j'utilise le framework cakePHP :

côté HTML :

<div class="contain">
<p><?= $this->Html->link('Ajouter un widget', array('action' => 'edit'), array('class' => 'button')); ?></p>
    <div class="bloc left">
        <div class="title">Widgets disponibles</div>
        <div class="content">
            <p>Glissez les widgets d'ici vers une colonne latérale a droite pour les activer. Remettez-les ici pour les désactiver.</p>
            <!-- Ici la liste des widget s -->
            <?php foreach ($listWidgets as $key => $widget): ?>
                <div class="portlet ui-widget-content draggable">
                    <?php if ($widget'Widget']'active'] == 0): ?>
                        <?php if (!empty($widget'Widget']'name'])): ?>
                           <div class="portlet-header"><?= $widget'Widget']'widget_name']; ?>: <?= $widget'Widget']'name']; ?></div>
                       <?php else: ?>
                            <div class="portlet-header"><?= $widget'Widget']'widget_name']; ?></div>
                        <?php endif ?>
                        <div class="portlet-content">
                            <?= $widget'Widget']'description']; ?>
                            <?= $this->Form->create('Widget', array('class' => 'form_widget', 'action' => 'edit', $widget'Widget']'id'])); ?>
                                <?= $this->Form->input('id', array('label' => false, 'type' => 'text', 'value' => $widget'Widget']'id'])); ?>
                                <?= $this->Form->input('active', array('label' => false, 'type' => 'text', 'value' => $widget'Widget']'active'])); ?>
                                <?= $this->Form->input('position', array('label' => false, 'type' => 'text', 'value' => $widget'Widget']'position'])); ?>
                                <?= $this->Form->input('name', array('label' => 'Titre :', 'value' => $widget'Widget']'name'])); ?>
                                <?php if ($widget'Widget']'widget_name'] == 'Pages' || $widget'Widget']'widget_name'] == 'Pages2'): ?>
                                    <?= $this->Form->input('id_posts', array('label' => 'IDs des pages à afficher (spéparé par des ,)', 'placeholder' => '12, 2, 3...', 'value' => $widget'Widget']'id_posts'])); ?>
                                <?php endif ?>
                           <p>
                            <?= $this->Html->image('loading.gif', array('class' => 'load')); ?>
                            <?= $this->Form->end('Enregistrer'); ?> </p>
                        </div>
                    <?php endif ?>
                </div>
            <?php endforeach ?>
        </div>
    </div>
    <div class="bloc right widget1">
        <div class="title">Zone principale de widget</div>
        <div class="content fantom droppable" id="footerWidget">
            <p>Apparaît dans le pied de page du site</p>
            <!-- Ici les widget activé dans la zone principale => footer -->
             <?php foreach ($widgetsZonePrinc as $key => $widgetPrincipal): ?>
            <div class="portlet ui-widget-content draggable">
            <?php if ($widgetPrincipal'Widget']'active'] == 1): ?>
                <?php if (!empty($widgetPrincipal'Widget']'name'])): ?>
                    <div class="portlet-header"><?= $widgetPrincipal'Widget']'widget_name']; ?>: <?= $widgetPrincipal'Widget']'name']; ?></div>
                <?php else: ?>
                    <div class="portlet-header"><?= $widgetPrincipal'Widget']'widget_name']; ?></div>
                <?php endif ?>
                    <div class="portlet-content">
                        <?= $widgetPrincipal'Widget']'description']; ?>
                        <?= $this->Form->create('Widget', array('class' => 'form_widget', 'action' => 'edit')); ?>
                        <?= $this->Form->input('id', array('label' => false, 'type' => 'text', 'value' => $widgetPrincipal'Widget']'id'])); ?>
                        <?= $this->Form->input('active', array('label' => false, 'type' => 'text', 'value' => $widgetPrincipal'Widget']'active'])); ?>
                        <?= $this->Form->input('position', array('label' => false, 'type' => 'text', 'value' => $widgetPrincipal'Widget']'position'])); ?>
                        <?= $this->Form->input('name', array('label' => 'Titre :', 'value' => $widgetPrincipal'Widget']'name'])); ?>
                        <?php if ($widgetPrincipal'Widget']'widget_name'] == 'Pages' || $widgetPrincipal'Widget']'widget_name'] == 'Pages2'): ?>
                                    <?= $this->Form->input('id_posts', array('label' => 'IDs des pages à afficher (spéparé par des ,)', 'placeholder' => '12, 2, 3...', 'value' => $widgetPrincipal'Widget']'id_posts'])); ?>
                        <?php endif ?>
                        <?= $this->Form->end('Enregistrer'); ?>
                    </div>
                </div>
                <?php endif ?>
            <?php endforeach ?>
            <p> </p>
        </div>
    </div>
    <div class="bloc right widget2 droppable">
        <div class="title">Zone secondaire de widget</div>
        <div class="content">
            <p>Apparaît dans la sidebar du site</p>
            <!-- Ici les widget activé dans la zone secondaire => sidebar -->
        </div>
    </div>
</div>

côté jquery :

(function(){
     // Récupère les valeurs des champs
    var id = $('#WidgetId').val();
    var active = $('#WidgetActive').val();
    var position = $('#WidgetPosition').val();
    var name = $('#WidgetName').val();
    $('.draggable').draggable({
        containment: 'content',
        stack: '#footerWidget',
        snap: '#footerWidget',
        cursor: 'move',
        revert: true
    });
    $('.droppable').droppable({
        accept: '.draggable',
        drop : handleDrop
    });
    function handleDrop(event, ui){
        var current = ui.draggable; // Récupère l'élément courant
        var resultat = $('.widget1');
        console.log(current);
        $(this).droppable('disable');
        current.draggable('option', 'revert', false);
        current.fadeOut();
        $.post("widgets/edit", { id: 2, active: 1 }, function(data){
            console.log(data);
        }, 'json');
        resultat.append(current.html());
    }
    function myHelper(event){
        return '<div class="fantom"></div>';
    }
    $('.content').selectable();

})(jQuery);

C'est le côté ajax qui fait tout planter, et comme id je ne récupère que l'id 1 alors que je récupère la valeur des champs qui affiche bien le bon id.

Donc un pti coup de main ne sera pas de refu^^ Merci d'avance

6 réponses


antho07
Réponse acceptée

rajoute dans la la méthode edit:

$this->autoRender = false;

Bonjour, que fait l'action widgets/edit ? , le lien est-il bon?
Que renvoit data ?

$.post("widgets/edit", { id: 2, active: 1 }, function(data){
            console.log(data);
        }, 'json');
        resultat.append(current.html());

Ici l'append est bien indépendant de la requête?

cordialement

Merci de ta réponse, Oui l'append est bien dépendant de la requête, l'action widgets/edit permet d'ajouter et éditer un widget, dans cette action je vérifie si on a à faire à une requête de type ajax alors je fais un save que sur les champs id et active envoyé ultérieurement via la requête ajax, data ne renvoi rien du tout. Voici l'action edit :

/**
     * Permet d'ajouter/editder un widget
     **/
    public function admin_edit($id = null){
        // J'ai des données
        if (!empty($this->request->data)){
            if ($this->request->is('ajax')) {
                $activeWidget = $this->Widget->save($this->request->data);
                echo json_encode($activeWidget);
            }else{
                $this->Widget->save($this->request->data);
                $this->Session->setFlash("Le widget a bien été édité", "flash");
                return $this->redirect(array('action' => 'index'));
            }
        }else if ($id){
            $this->request->data = $this->Widget->findById($id);
        }
    }

Je pense que le lien est bon car la modification en base se fait bien via ajax mais l'inspecteur m'indique une erreur de la requête, voici le preview de l'inspecteur :

{"Widget":{"id":"3","active":"1"}}{"code":500,"url":"\/web_site_2410201301\/admin\/widgets\/edit","name":"Viewfile"C:\\wamp\\www\\web_site_2410201301\\app\\View\\Widgets\\json\\admin_edit.ctp"ismissing."}

Merci ça fonctionne, puis-je avoir une petite explication?

Bonjour,

le fonctionnement normal de cakePhp est de chargé une vue après avoir appelé le controller..
Là tu es en ajax, tu ne veux pas appeler de vue, donc avec cette instruction tu lui dis ne pas en charger automatiquement.

D'accord :) Merci beaucoup !