Domanda

Ho un sacco di caselle di controllo selezionate per impostazione predefinita.I miei utenti probabilmente deselezioneranno alcune (se presenti) caselle di controllo e lasceranno il resto selezionato.

Esiste un modo per rendere il modulo POST le caselle di controllo che lo sono non controllato, piuttosto che quelli che Sono controllato?

È stato utile?

Soluzione

Aggiungi un input nascosto per la casella di controllo con un ID diverso:

<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>

Prima di inviare il modulo, disabilitare l'input nascosto in base alla condizione selezionata:

if(document.getElementById("testName").checked) {
    document.getElementById('testNameHidden').disabled = true;
}

Altri suggerimenti

La soluzione che mi è piaciuta di più finora è quella di mettere un input nascosto con lo stesso nome della casella che potrebbe non essere selezionata. Penso che funzioni in modo tale che se la casella di controllo non è selezionata, l'input nascosto ha ancora successo e inviato al server ma se la casella di controllo è selezionata sovrascriverà l'input nascosto prima di esso. In questo modo non è necessario tenere traccia di quali valori nei dati pubblicati dovrebbero provenire dalle caselle di controllo.

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

L'ho risolto usando JavaScript vanilla:

<input type="hidden" name="checkboxName" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">

Fai attenzione a non avere spazi o interruzioni di riga tra questi due elementi di input!

Puoi usare this.previousSibling.previousSibling per ottenere " upper " elementi.

Con PHP puoi controllare il campo nascosto nominato per 0 (non impostato) o 1 (impostato).

Il mio preferito personale è quello di aggiungere un campo nascosto con lo stesso nome che verrà utilizzato se la casella di controllo è deselezionata. Ma la soluzione non è così semplice come sembra.

Se aggiungi questo codice:

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

Il browser non si preoccuperà davvero di quello che fai qui. Il browser invierà entrambi i parametri al server e il server deve decidere cosa farne.

PHP ad esempio prende l'ultimo valore come quello da usare (vedi: Posizione autorevole di chiavi di query HTTP GET duplicate )

Ma altri sistemi con cui ho lavorato (basato su Java) lo fanno al contrario: ti offrono solo il primo valore. .NET invece ti darà invece un array con entrambi gli elementi

Proverò a provarlo con node.js, Python e Perl a volte.

Una tecnica comune attorno a questo è portare una variabile nascosta insieme a ciascuna casella di controllo.

<input type="checkbox" name="mycheckbox" />
<input type="hidden" name="mycheckbox.hidden"/>

Sul lato server, rileviamo prima l'elenco delle variabili nascoste e per ciascuna delle variabili nascoste, proviamo a vedere se la corrispondente voce della casella di controllo è stata inviata nei dati del modulo o meno.

L'algoritmo sul lato server dovrebbe probabilmente apparire come:

for input in form data such that input.name endswith .hidden
  checkboxName = input.name.rstrip('.hidden')
  if chceckbName is not in form, user has unchecked this checkbox

Quanto sopra non risponde esattamente alla domanda, ma fornisce un mezzo alternativo per ottenere funzionalità simili.

non è necessario creare un campo nascosto per tutte le caselle di controllo, basta copiare il mio codice. cambierà il valore della casella di controllo se non è selezionata l'opzione value assegnerà 0 e se la casella di controllo è selezionata, quindi assegnare 1 in <=>

$("form").submit(function () {

    var this_master = $(this);

    this_master.find('input[type="checkbox"]').each( function () {
        var checkbox_this = $(this);


        if( checkbox_this.is(":checked") == true ) {
            checkbox_this.attr('value','1');
        } else {
            checkbox_this.prop('checked',true);
            //DONT' ITS JUST CHECK THE CHECKBOX TO SUBMIT FORM DATA    
            checkbox_this.attr('value','0');
        }
    })
})

Puoi eseguire alcuni Javascript nell'evento di invio del modulo. Questo è tutto ciò che puoi fare, non c'è modo di convincere i browser a farlo da soli. Significa anche che il modulo verrà interrotto per gli utenti senza Javascript. Meglio sapere sul server quali caselle di controllo ci sono, quindi puoi dedurre che quelli assenti dai valori dei moduli pubblicati ($_POST in PHP) sono deselezionati.

$('input[type=checkbox]').on("change",function(){
    var target = $(this).parent().find('input[type=hidden]').val();
    if(target == 0)
    {
        target = 1;
    }
    else
    {
        target = 0;
    }
    $(this).parent().find('input[type=hidden]').val(target);
});

                      

<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>

Se si lascia fuori il nome della casella di controllo, questa non viene superata. Solo l'array test_checkbox.

In realtà farei quanto segue.

Ho il mio campo di input nascosto con lo stesso nome con l'input della casella di controllo

<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />

e poi quando inserisco rimuovo prima di tutto i valori duplicati raccolti nell'array $ _POST, quindi visualizzo ciascuno dei valori univoci.

  $posted = array_unique($_POST['checkbox_name']);
  foreach($posted as $value){
    print $value;
  }

L'ho preso da un post rimuovi valori duplicati dall'array

" Sono andato con l'approccio del server. Sembra funzionare bene, grazie. & # 8211; reach4thelasers, 1 dicembre 2009 alle 15:19 " Vorrei raccomandarlo dal proprietario. Come citato: la soluzione javascript dipende da come il gestore del server (non l'ho verificato)

come

if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";

La maggior parte delle risposte qui richiede l'uso di JavaScript o controlli di input duplicati. A volte questo deve essere gestito interamente sul lato server.

Credo che la chiave (prevista) per risolvere questo problema comune sia il controllo di input per l'invio del modulo.

Per interpretare e gestire con successo i valori non selezionati per le caselle di controllo, devi conoscere quanto segue:

  1. I nomi delle caselle di controllo
  2. Il nome dell'elemento di input di invio del modulo

Controllando se il modulo è stato inviato (un valore è assegnato all'elemento di input di invio), tutti i valori della casella di controllo non selezionata possono essere assunti .

Ad esempio:

<form name="form" method="post">
  <input name="value1" type="checkbox" value="1">Checkbox One<br/>
  <input name="value2" type="checkbox" value="1" checked="checked">Checkbox Two<br/>
  <input name="value3" type="checkbox" value="1">Checkbox Three<br/>
  <input name="submit" type="submit" value="Submit">
</form>

Quando si utilizza PHP, è abbastanza banale rilevare quali caselle di controllo sono state spuntate.

<?php

$checkboxNames = array('value1', 'value2', 'value3');

// Persisted (previous) checkbox state may be loaded 
// from storage, such as the user's session or a database.
$checkboxesThatAreChecked = array(); 

// Only process if the form was actually submitted.
// This provides an opportunity to update the user's 
// session data, or to persist the new state of the data.

if (!empty($_POST['submit'])) {
    foreach ($checkboxNames as $checkboxName) {
        if (!empty($_POST[$checkboxName])) {
            $checkboxesThatAreChecked[] = $checkboxName;
        }
    }
    // The new state of the checkboxes can be persisted 
    // in session or database by inspecting the values 
    // in $checkboxesThatAreChecked.
    print_r($checkboxesThatAreChecked);
}

?>

I dati iniziali possono essere caricati su ogni caricamento della pagina, ma devono essere modificati solo se il modulo è stato inviato. Poiché i nomi delle caselle di controllo sono noti in anticipo, possono essere attraversati e ispezionati singolarmente, in modo che l'assenza dei loro valori individuali indichi che non sono stati controllati.

Ho provato prima la versione di Sam. Buona idea, ma causa la presenza di più elementi nel modulo con lo stesso nome. Se usi javascript che trova elementi in base al nome, ora restituirà una matrice di elementi.

Ho elaborato l'idea di Shailesh in PHP, funziona per me. Ecco il mio codice:

/* Delete '.hidden' fields if the original is present, use '.hidden' value if not. */
foreach ($_POST['frmmain'] as $field_name => $value)
{
    // Only look at elements ending with '.hidden'
    if ( !substr($field_name, -strlen('.hidden')) ) {
        break;
    }

    // get the name without '.hidden'
    $real_name = substr($key, strlen($field_name) - strlen('.hidden'));

    // Create a 'fake' original field with the value in '.hidden' if an original does not exist
    if ( !array_key_exists( $real_name, $POST_copy ) ) {
        $_POST[$real_name] = $value;
    }

    // Delete the '.hidden' element
    unset($_POST[$field_name]);
}

Uso questo blocco di jQuery, che aggiungerà un input nascosto al momento dell'invio a ogni casella di controllo non selezionata. Ti garantirà sempre l'invio di un valore per ogni casella di controllo, ogni volta, senza ingombrare il markup e rischiare di dimenticare di farlo su una casella di controllo che aggiungi in seguito. È anche indipendente da qualunque stack di back-end (PHP, Ruby, ecc.) Che stai utilizzando.

// Add an event listener on #form's submit action...
$("#form").submit(
    function() {

        // For each unchecked checkbox on the form...
        $(this).find($("input:checkbox:not(:checked)")).each(

            // Create a hidden field with the same name as the checkbox and a value of 0
            // You could just as easily use "off", "false", or whatever you want to get
            // when the checkbox is empty.
            function(index) {
                var input = $('<input />');
                input.attr('type', 'hidden');
                input.attr('name', $(this).attr("name")); // Same name as the checkbox
                input.attr('value', "0"); // or 'off', 'false', 'no', whatever

                // append it to the form the checkbox is in just as it's being submitted
                var form = $(this)[0].form;
                $(form).append(input);

            }   // end function inside each()
        );      // end each() argument list

        return true;    // Don't abort the form submit

    }   // end function inside submit()
);      // end submit() argument list

Puoi anche intercettare l'evento form.submit e invertire il controllo prima di inviare

$('form').submit(function(event){
    $('input[type=checkbox]').prop('checked', function(index, value){
        return !value;
    });
});

Mi piace anche la soluzione di pubblicare semplicemente un campo di input aggiuntivo, l'uso di JavaScript mi ​​sembra un po' complicato.

A seconda di ciò che usi per il tuo backend, dipenderà da quale input verrà eseguito per primo.

Per un backend server in cui viene utilizzata la prima occorrenza (JSP) è necessario effettuare le seguenti operazioni.

  <input type="checkbox" value="1" name="checkbox_1"/>
  <input type="hidden" value="0" name="checkbox_1"/>


Per un server backend in cui viene utilizzata l'ultima occorrenza (PHP, Rails) dovresti fare quanto segue.

  <input type="hidden" value="0" name="checkbox_1"/>
  <input type="checkbox" value="1" name="checkbox_1"/>


Per un back-end server in cui tutte le occorrenze sono archiviate in un tipo di dati elenco ([],array).(Python/Zope)

Puoi pubblicare nell'ordine che preferisci, devi solo provare a ottenere il valore dall'input con il file checkbox attributo tipo.Quindi il primo indice dell'elenco se la casella di controllo era prima dell'elemento nascosto e l'ultimo indice se la casella di controllo era dopo l'elemento nascosto.


Per un backend di server in cui tutte le occorrenze sono concatenate con una virgola (ASP.NET / IIS) dovrai (dividere / esplodere) la stringa utilizzando una virgola come delimitatore per creare un tipo di dati di elenco.([])

Ora puoi provare a prendere il primo indice dell'elenco se la casella di controllo era prima dell'elemento nascosto e prendere l'ultimo indice se la casella di controllo era dopo l'elemento nascosto.

Backend parameter handling

fonte dell'immagine

Vedo che questa domanda è vecchia e ha così tante risposte, ma darò comunque il mio penny. Il mio voto è per la soluzione javascript sull'evento "submit" del modulo, come alcuni hanno sottolineato. Nessun raddoppio degli input (specialmente se hai nomi e attributi lunghi con codice php mescolato con html), nessun problema sul lato server (che richiederebbe conoscere tutti i nomi dei campi e controllarli uno per uno), basta recuperare tutti gli elementi non selezionati , assegnare loro un valore 0 (o qualsiasi altra cosa sia necessaria per indicare uno stato "non verificato") e quindi modificare il loro attributo "controllato" su vero

    $('form').submit(function(e){
    var b = $("input:checkbox:not(:checked)");
    $(b).each(function () {
        $(this).val(0); //Set whatever value you need for 'not checked'
        $(this).attr("checked", true);
    });
    return true;
});

in questo modo avrai un array $ _POST come questo:

Array
(
            [field1] => 1
            [field2] => 0
)
$('form').submit(function () {
    $(this).find('input[type="checkbox"]').each( function () {
        var checkbox = $(this);
        if( checkbox.is(':checked')) {
            checkbox.attr('value','1');
        } else {
            checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
            checkbox.prop('disabled', true);
        }
    })
});

So che questa domanda ha 3 anni, ma ho trovato una soluzione che penso funzioni piuttosto bene.

Puoi verificare se la variabile $ _POST è assegnata e salvarla in una variabile.

$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';

la funzione isset () controlla se la variabile $ _POST è assegnata. Per logica se non è assegnato, la casella non è selezionata.

Quello che ho fatto è stato un po 'diverso. Innanzitutto ho modificato i valori di tutte le caselle di controllo non selezionate. A & Quot; 0 & Quot ;, quindi selezionali tutti, in modo che il valore venga inviato.

function checkboxvalues(){
  $("#checkbox-container input:checkbox").each(function({ 
    if($(this).prop("checked")!=true){
      $(this).val("0");
      $(this).prop("checked", true);
    }
  });
}

Preferirei fascicolare $ _POST

if (!$_POST['checkboxname']) !$_POST['checkboxname'] = 0;

pensa, se il POST non ha il valore "checkboxname", è stato deselezionato, quindi assegnare un valore.

puoi creare un array dei tuoi valori ckeckbox e creare una funzione che controlla se esistono valori, in caso contrario, si preoccupa che non siano selezionati e puoi assegnare un valore

L'esempio sulle azioni Ajax è (': checked') usato jQuery invece di .val ();

            var params = {
                books: $('input#users').is(':checked'),
                news : $('input#news').is(':checked'),
                magazine : $('input#magazine').is(':checked')
            };

i parametri avranno valore in VERO O FALSO ..

Le caselle di controllo in genere rappresentano i dati binari memorizzati nel database come valori Sì / No, S / N o 1/0. Le caselle di controllo HTML hanno una cattiva natura per inviare valore al server solo se la casella di controllo è selezionata! Ciò significa che lo script del server su un altro sito deve sapere in anticipo quali sono tutte le possibili caselle di controllo sulla pagina Web per poter memorizzare valori positivi (selezionati) o negativi (non selezionati). In realtà solo i valori negativi sono un problema (quando l'utente deseleziona il valore precedentemente (pre) controllato - come può il server sapere questo quando non viene inviato nulla se non sa in anticipo che questo nome dovrebbe essere inviato). Se disponi di uno script lato server che crea in modo dinamico uno script UPDATE, c'è un problema perché non sai quali caselle di controllo devono essere ricevute per impostare il valore Y per il valore selezionato e N per quello non selezionato (non ricevuto).

Poiché memorizzo i valori 'Y' e 'N' nel mio database e li rappresento tramite caselle di controllo selezionate e deselezionate nella pagina, ho aggiunto un campo nascosto per ciascun valore (casella di controllo) con i valori 'Y' e 'N', quindi uso le caselle di controllo solo per la rappresentazione visiva e utilizzare il semplice controllo della funzione JavaScript () per impostare il valore di if in base alla selezione.

<input type="hidden" id="N1" name="N1" value="Y" />
<input type="checkbox"<?php if($N1==='Y') echo ' checked="checked"'; ?> onclick="check(this);" />
<label for="N1">Checkbox #1</label>

usa un listener onclick JavaScript e chiama il controllo funzione () per ogni casella di controllo sulla mia pagina web:

function check(me)
{
  if(me.checked)
  {
    me.previousSibling.previousSibling.value='Y';
  }
  else
  {
    me.previousSibling.previousSibling.value='N';
  }
}

In questo modo i valori 'Y' o 'N' vengono sempre inviati allo script lato server, sa quali sono i campi che devono essere aggiornati e non c'è bisogno di convertire checbox " su " valore in "Y" o casella di controllo non ricevuta in "N".

NOTA: anche gli spazi bianchi o la nuova riga sono di pari livello, quindi qui ho bisogno di .previousSibling.previousSibling.value. Se non c'è spazio tra allora solo .previousSibling.value


Non è necessario aggiungere esplicitamente listener onclick come prima, è possibile utilizzare la libreria jQuery per aggiungere dinamicamente listener di clic con funzione per modificare il valore di tutte le caselle di controllo nella pagina:

$('input[type=checkbox]').click(function()
{
  if(this.checked)
  {
    $(this).prev().val('Y');
  }
  else
  {
    $(this).prev().val('N');
  }
});

Il problema con le caselle di controllo è che se non sono selezionate, non vengono pubblicate con il modulo. Se selezioni una casella di controllo e pubblichi un modulo otterrai il valore della casella di controllo nella variabile $ _POST che puoi utilizzare per elaborare un modulo, se è deselezionato nessun valore verrà aggiunto alla variabile $ _POST.

In PHP normalmente si aggira questo problema facendo un controllo isset () sull'elemento checkbox. Se l'elemento che ti aspetti non è impostato nella variabile $ _POST, allora sappiamo che la casella di controllo non è selezionata e il valore può essere falso.

if(!isset($_POST['checkbox1']))
{
     $checkboxValue = false;
} else {
     $checkboxValue = $_POST['checkbox1'];
}

Ma se hai creato un modulo dinamico, non conoscerai sempre l'attributo name delle tue caselle di controllo, se non conosci il nome della casella di controllo, non puoi utilizzare la funzione isset per verificare se questo ha stato inviato con la variabile $ _POST.

Questo può essere realizzato esclusivamente con alcuni javascript, poiché le caselle di controllo non selezionate non vengono trasmesse. Quindi hai bisogno di JavaScript che ad es. dietro le quinte aggiunge campi nascosti deselezionando una casella. Senza javascript questo non potrebbe essere fatto.

Esiste una soluzione alternativa migliore. Prima di tutto fornire l'attributo name solo alle caselle che sono selezionate. Quindi, fai clic su submit, tramite JavaScript function seleziona tutte le caselle non selezionate. Quindi quando form collection solo quelli verranno recuperati in name quelli che hanno <=> proprietà.

  //removing name attribute from all checked checkboxes
                  var a = $('input:checkbox:checked');
                   $(a).each(function () {
                       $(this).removeAttr("name");        
                   });

   // checking all unchecked checkboxes
                   var b = $("input:checkbox:not(:checked)");
                   $(b).each(function () {
                       $(this).attr("checked", true);
                   });

Vantaggio: Non è necessario creare ulteriori caselle nascoste e manipolarle.

@cpburnz ha capito bene ma con troppi codici, ecco la stessa idea usando meno codice:

JS:

// jQuery OnLoad
$(function(){
    // Listen to input type checkbox on change event
    $("input[type=checkbox]").change(function(){
        $(this).parent().find('input[type=hidden]').val((this.checked)?1:0);
    });
});

HTML (annota il nome del campo usando un nome di array):

<div>
    <input type="checkbox" checked="checked">
    <input type="hidden" name="field_name[34]" value="1"/>
</div>
<div>
    <input type="checkbox">
    <input type="hidden" name="field_name[35]" value="0"/>
</div>
<div>

E per PHP:

<div>
    <input type="checkbox"<?=($boolean)?' checked="checked"':''?>>
    <input type="hidden" name="field_name[<?=$item_id?>]" value="<?=($boolean)?1:0?>"/>
</div>

versione jQuery della risposta di @ vishnu.

if($('#testName').is(":checked")){
    $('#testNameHidden').prop('disabled', true);
}

Se si utilizza jQuery 1.5 o versioni precedenti, utilizzare la funzione .attr () anziché .prop ()

Questa soluzione è ispirata a quella di @ desw.

Se i nomi di input sono in " stile modulo " perderete l'associazione dell'indice di array con i valori di chekbox non appena viene selezionata una chekbox, incrementando questa " dissociazione quot; di un'unità ogni volta che viene controllato un chekbox. Questo può essere il caso di un modulo per inserire qualcosa come dipendenti composti da alcuni campi, ad esempio:

<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />

Nel caso in cui si inseriscano tre dipendenti contemporaneamente e il primo e il secondo siano singoli, si otterrà un array isSingle a 5 elementi, quindi non sarà possibile iterare contemporaneamente attraverso i tre array per, ad esempio, inserire dipendenti in un database.

Puoi superarlo con un semplice postprocessing di array. Sto usando PHP sul lato server e ho fatto questo:

$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
  if($isSingle=='yes'){
    unset($areSingles[$j-1]);
  }
  $j++;
}
$areSingles = array_values($areSingles);

Quindi questa soluzione è eccessiva per questa domanda, ma mi ha aiutato quando avevo la stessa casella di controllo che si era verificata più volte per diverse righe in una tabella. Avevo bisogno di conoscere la riga rappresentata dalla casella di controllo e anche conoscere lo stato della casella (selezionata / deselezionata).

Quello che ho fatto è stato togliere l'attributo name dai miei input da checkbox, dare loro tutti la stessa classe e creare un input nascosto che avrebbe tenuto l'equivalente JSON dei dati.

HTML

 <table id="permissions-table">
    <tr>
	<td>
	    <input type="checkbox" class="has-permission-cb" value="Jim">
	    <input type="checkbox" class="has-permission-cb" value="Bob">
	    <input type="checkbox" class="has-permission-cb" value="Suzy">
	</td>
    </tr>
 </table>
 <input type="hidden" id="has-permissions-values" name="has-permissions-values" value="">

Javascript da eseguire all'invio del modulo

var perms = {};
$(".has-permission-checkbox").each(function(){
  var userName = this.value;
  var val = ($(this).prop("checked")) ? 1 : 0
  perms[userName] = {"hasPermission" : val};
});
$("#has-permissions-values").val(JSON.stringify(perms));

La stringa json verrà passata con il modulo come $ _POST [" has-autorizzazioni-valori "]. In PHP, decodifica la stringa in un array e avrai un array associativo che ha ogni riga e il valore vero / falso per ogni casella di controllo corrispondente. È quindi molto semplice esaminare e confrontare i valori correnti del database.

Tutte le risposte sono ottime, ma se hai più caselle di controllo in un modulo con lo stesso nome e vuoi pubblicare lo stato di ciascuna casella. Quindi ho risolto questo problema posizionando un campo nascosto con la casella di controllo (nome correlato a ciò che voglio).

<input type="hidden" class="checkbox_handler" name="is_admin[]" value="0" />
<input type="checkbox" name="is_admin_ck[]" value="1" />

quindi controlla lo stato di modifica della casella di controllo tramite il codice jquery seguente:

$(documen).on("change", "input[type='checkbox']", function() {
    var checkbox_val = ( this.checked ) ? 1 : 0;
    $(this).siblings('input.checkbox_handler').val(checkbox_val);
});

ora cambiando qualsiasi casella di controllo, cambierà il valore del relativo campo nascosto. E sul server puoi guardare solo ai campi nascosti anziché alle caselle di controllo.

Spero che questo possa aiutare qualcuno ad avere questo tipo di problema. tifo :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top