Visualizza le caselle di jQuery UI finestre di dialogo e di fornire il pulsante Annulla

Sto cercando di risolvere, probabilmente, un problema molto comune e hanno preparato una semplificato caso di test dimostrazione, e i miei sforzi.

Sto cercando di visualizzare diversi jQuery UI finestre di dialogo, ciascuno con diverse caselle di controllo con lo stesso nome (frutti e candy nel mio test di codice riportato di seguito)

In ogni finestra di dialogo che ho 4 pulsanti: Salvare, Annullare, Selezionare tutti e Deselezionare tutti:

Visualizza le caselle di jQuery UI finestre di dialogo e di fornire il pulsante Annulla

I primi 3 pulsanti sono già al lavoro nel mio codice.

Il Aggiornamento pulsante, infatti,chiamata DataTable fnDraw() funzione, che parte sta già lavorando troppo. (E non voglio salvare le caselle di controllo, i valori del server di mezzo, mi piacerebbe fare tutto lato client – lo so, questo è possibile).

Il mio problema è nell’attuazione del Annullare pulsante per le finestre di dialogo:

1) probabilmente dovrei salvare un elenco di impostare attualmente caselle di controllo nella finestra di dialogo apri evento? E poi ripristinarli su Annullare fare clic su? C’è qualche elegante, jQuery, in modo che?

2) non so, come elaborare solo le caselle di controllo attualmente finestra di dialogo apri solo.

Qui di seguito la mia attuale codice di test, funziona istantaneamente, grazie a Google CDN:

<html>
<head>
<style type="text/css" title="currentStyle">
        @import "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css";
</style>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">

$(function() { 
        var buttons = {
                Cancel: cancel,
                Save: save,
                'Deselect All': deselect,
                'Select All': select
        };

        $('#fruits').dialog({ 
                autoOpen: false, 
                modal: true,
                buttons: buttons
        });

        $('#candy').dialog({ 
                autoOpen: false, 
                modal: true,
                buttons: buttons
        });
});

function update() {
        var boxes = new Array();
        $(':checkbox').each(function() {
                if ($(this).is(':checked')) {
                        boxes.push(
                                $(this).attr('name') + 
                                '=' +
                                $(this).val() 
                        );
                }
        });

        alert('boxes: ' + boxes.join('&'));
}

function select() {
        $(':checkbox').prop('checked', true);
}

function deselect() {
        $(':checkbox').prop('checked', false);
}

function save() {
        //XXX how to implement?
        $(this).dialog('close');
}

function cancel() {
        //XXX how to implement?
        $(this).dialog('close');
}

</script>
</head>
<body>

<p><input type="button" value="Select fruits" onclick="$('#fruits').dialog('open');"></p>
<div id="fruits" title="fruits">
<p><label><input type="checkbox" name="fruits" value="apple">apple</label></p>
<p><label><input type="checkbox" name="fruits" value="banana">banana</label></p>
<p><label><input type="checkbox" name="fruits" value="pear">pear</label></p>
</div>

<p><input type="button" value="Select candy" onclick="$('#candy').dialog('open');"></p>
<div id="candy" title="candy">
<p><label><input type="checkbox" name="candy" value="toffee">toffee</label></p>
<p><label><input type="checkbox" name="candy" value="fudge">fudge</label></p>
</div>

<p><input type="button" onclick="update();" value="Update"></p>

</body>
</html>

AGGIORNAMENTO: Grazie a mootinator il seguente codice funziona, ma ho ancora 2 problemi minori/domande:

1) e ‘ possibile utilizzare aprire evento, invece di custom openDialog()metodo?

2) il Mio Deselezionare Tutte e Selezionare Tutti i pulsanti modificare tutte le caselle di controllo a pagina invece di modificare solo quelli appartenenti al dialogo corrente. Mi chiedo come selezionare solo le seconde? (in qualche modo utilizzare $(this) in selectAll() e deselectAll())?

Ho provato

function selectAll() {
        $($(this) + ' :checkbox').prop('checked', true);
}

function deselectAll() {
        $($(this) + ' :checkbox').prop('checked', false);
}

ma ottenere errore di sintassi.

Visualizza le caselle di jQuery UI finestre di dialogo e di fornire il pulsante Annulla

<html>
<head>
<style type="text/css" title="currentStyle">
        @import "/css/demo_table_jui.css";
        @import "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css";
</style>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript" src="/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">

$(function() {
        var buttons = {
                Cancel: cancel,
                Save: save,
                'Deselect All': deselectAll,
                'Select All': selectAll
        };

        $('#openCandy').button();
        $('#openFruits').button();
        $('#update').button();

        $('#openCandy').click(function() {
                openDialog('#candy');
        });

        $('#openFruits').click(function() {
                openDialog('#fruits');
        });

        $('#fruits').dialog({
                autoOpen: false,
                modal:    true,
                buttons:  buttons
        });

        $('#candy').dialog({
                autoOpen: false,
                modal:    true,
                buttons:  buttons
        });
});

function update() {
        var boxes = new Array();
        $(':checkbox').each(function() {
                if ($(this).is(':checked')) {
                        boxes.push(
                                $(this).attr('name') +
                                '=' +
                                $(this).val()
                        );
                }
        });

        alert('boxes: ' + boxes.join('&'));
}

function selectAll() {
        $(':checkbox').prop('checked', true);
}

function deselectAll() {
        $(':checkbox').prop('checked', false);
}

function openDialog(sel) {
    $(sel).dialog('open');
    $(sel + ' :checkbox').each(function() {
        $(this).data('XXX', $(this).is(':checked'));
    });
}

function cancel() {
        $(this).find(':checkbox').each(function() {
            $(this).prop('checked', $(this).data('XXX'));
        });
        $(this).dialog('close');
}

function save() {
        $(this).dialog('close');
}

</script>
</head>
<body>

<p><input id="openFruits" type="button" value="Select fruits"></p>
<div id="fruits" title="fruits">
<p><label><input type="checkbox" name="fruits" value="apple">apple</label></p>
<p><label><input type="checkbox" name="fruits" value="banana">banana</label></p>
<p><label><input type="checkbox" name="fruits" value="pear">pear</label></p>
</div>

<p><input id="openCandy" type="button" value="Select candy"></p>
<div id="candy" title="candy">
<p><label><input type="checkbox" name="candy" value="toffee">toffee</label></p>
<p><label><input type="checkbox" name="candy" value="fudge">fudge</label></p>
</div>

<p><input id="update" type="button" onclick="update();" value="Update"></p>

</body>
</html>

UPDATE2: in Realtà io ho un 3 ° ed un problema più grande: la chiusura di X-pulsante nell’angolo superiore destro della finestra di dialogo non funziona come dovrebbe (si salva invece di cancellarlo).

Ho provato ad aggiungere vicino: annullare, per entrambe le finestre di dialogo, ma mi da l’errore di runtime Chrome:

Uncaught RangeError: Maximum call stack size exceeded
f.event.remove
f.event.remove
f.fn.extend.unbind
a.extend.destroy
a.extend.destroy
a.widget.close
a.widget.bridge.a.fn.(anonymous function)
e.extend.each
e.fn.e.each
a.widget.bridge.a.fn.(anonymous function)
cancel
a.Widget._trigger
a.widget.close
a.widget.bridge.a.fn.(anonymous function)
.....etc....

Su update3: Probabilmente perché l’ho chiamata $(this).una finestra di dialogo (“chiudi”) in un ciclo?

Non vedo un facile modo per risolvere il problema: se creo una funzione separata

function restore() {
        $(this).find(':checkbox').each(function() {
            $(this).prop('checked', $(this).data('XXX'));
        });
}

function cancel() {
        restore();
        $(this).dialog('close');
}

e passa come vicino: ripristino per le finestre di dialogo, quindi il Salvare pulsante pause



2 Replies
  1. 1

    Ho fatto un paio di modifiche al codice. Probabilmente il più semplice cosa da fare (non necessariamente il migliore) sarebbe quello di salvare lo stato in una variabile globale. (Una soluzione più efficace potrebbe coinvolgere solo di salvare lo stato a fianco la finestra di stato/opzioni).

    AGGIORNAMENTO: Ripulita la soluzione per memorizzare lo stato iniziale sulla casella di controllo nel DOM, anziché in una variabile globale.

    http://jsfiddle.net/rhdNH/8/

    Ho aggiunto un custom aprire la funzione di facilitare il salvataggio di stato, e ha completato la funzione di cancellazione. Puoi anche pulire l ‘”originale” proprietà ogni volta che si chiude utilizzando removeProp, ma non è strettamente necessario.

    Ecco le modifiche che si fanno per il punto #1 (aperto:openDialog), al fine di non chiamare openDialog direttamente.

    $('#fruits').dialog({ 
        autoOpen: false, 
        modal: true,
        buttons: buttons,
        open: openDialog
    });
    
    $('#candy').dialog({ 
        autoOpen: false, 
        modal: true,
        buttons: buttons,
        open: openDialog
    });

    E questo è ciò che il vostro selezionare/deselezionare dovrebbe assomigliare ad agire solo sulla finestra di dialogo apri:

    function select() {
        $(':checkbox', this).prop('checked', true);
    }
    
    function deselect() {
        $(':checkbox', this).prop('checked', false);
    }

    E qui è openDialog a cura di utilizzare this invece il selettore di jQuery:

    function openDialog() {
        $(':checkbox', this).each(function() {
            $(this).prop('original', $(this).is(':checked'));
        });
    }
    
    function cancel() {
            $(this).find('input[type="checkbox"]').each(function() {
                $(this).prop('checked', $(this).prop('original'));
            });
            $(this).dialog('close');
    }
    • Grazie. Così si salva la casella di controllo states come in originale=”true” nelle caselle di controllo di se stessi? Perché “originale”, è un nome arbitrario?
    • Sì, del tutto arbitraria.
    • Solo un’altra nota, è possibile utilizzare .data invece di .prop per essere più standardsy: stackoverflow.com/questions/432174/… – non Si deve incorrere in perdite di memoria memorizzazione di un semplice valore booleano in un arbitrario proprietà di se.
    • Grazie, con voi aiuto ci sono quasi, ma si prega di dare un’occhiata al mio aggiornati domanda.
    • Per il secondo punto: $(':checkbox', this).prop('checked', true);. Guarderò l’altro.
    • Ho trovato questo funziona troppo: $(this).find(‘:casella di controllo”).prop(‘checked’, true);
    • Sì. Aggiornata la mia risposta. È potrebbe trattare con il tasto x rimuoverla. stackoverflow.com/questions/896777/…
    • Grazie, una bella soluzione
    • Mi piacerebbe fare un punto di legare il tasto Esc per il pulsante annulla invece di chiudere la finestra di dialogo se si può.
    • Purtroppo tasto Esc non funziona correttamente, o si salva, invece di cancellarlo
    • Giusto, bisogna aggiungere closeOnEscape: false per la finestra di dialogo parametri. Quindi creare un evento keydown e gestire l’evento.che == 27 manualmente.

  2. 0
    1. Nella vostra funzione di salvataggio dovresti chiamare il tuo script lato server (utilizzando AJAX – check jQuery docs qui) e salvare lo stato di ogni casella di controllo (se questo è che cosa siete disposti a fare, naturalmente)
    2. In funzione di cancellazione avevo appena bastone con la chiusura della finestra di dialogo, dato che non c’è bisogno di cambiare nulla. Il rollback delle modifiche apportate da salvare è inutile dal momento che si può sempre controllare /unckech caselle di controllo desiderate e salvare di nuovo.
    3. Come elaborare solo le caselle di controllo attualmente finestra di dialogo apri solo – assegnare un id univoco per il div contenitore e utilizzare $('#div_id input[type="checkbox"]') selettore
    • Scusate, ma i vostri suggerimenti 1. e 2. non fa per me – perché non voglio passare per il server. Vorrei utilizzare (e salvare) la casella di controllo delle informazioni sul client e questo funziona già vedere il Datatable questione link nella mia domanda corrente.

Lascia un commento