Пост снят в формате HTML флажки

У меня есть куча флажков, которые проверяются по умолчанию. Мои пользователи, вероятно, снимут несколько (если таковые имеются) флажков и оставят остальные.

есть ли способ сделать форму POST флажками, которые являются не проверил, а не те, которые are проверил?

30 ответов


добавить скрытый вход для флажка с другим идентификатором:

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

перед отправкой формы отключите скрытый ввод на основе проверенного условия:

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

решение, которое мне понравилось больше всего, - это поместить скрытый ввод с тем же именем, что и флажок, который может не быть проверен. Я думаю, что это работает так, что если флажок не установлен, скрытый ввод все еще успешен и отправлен на сервер, но если флажок установлен, он переопределит скрытый ввод перед ним. Таким образом, вам не нужно отслеживать, какие значения в разнесенных данных ожидались от флажков.

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

Я решил его, используя простой (родной) javascript:

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

будьте осторожны, чтобы не иметь пробелов или разрывов линий между этими двумя входными элементами!

вы можете использовать это.previousSibling.previousSibling, чтобы получить "верхние" элементы.

С помощью PHP вы можете проверить именованное скрытое поле на 0 (не установлено) или 1 (установлено).


общей техникой вокруг этого является перенос скрытой переменной вместе с каждым флажком.

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

на стороне сервера мы сначала обнаруживаем список скрытых переменных, и для каждой из скрытых переменных мы пытаемся увидеть, отправлена ли соответствующая запись флажка в данных формы или нет.

алгоритм на стороне сервера, вероятно, будет выглядеть так:

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

вышеуказанное точно не отвечает на вопрос, но обеспечивает альтернативные средства достижения аналогичной функциональности.


мой личный фаворит, чтобы добавить скрытое поле с тем же именем, которое будет использоваться, если флажок снят. Но решение не так просто, как может показаться.

Если вы добавите этот код:

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

браузер не будет действительно заботиться о том, что вы здесь делаете. Браузер отправит оба параметра на сервер, и сервер должен решить, что с ними делать.

PHP, например, принимает последнее значение в качестве используемого (см.: авторитетная позиция дубликатов ключей HTTP GET query)

но другие системы, с которыми я работал (на основе Java), делают это так - они предлагают вам только первое значение. .NET вместо этого даст вам массив с обоими элементами вместо

Я попытаюсь проверить это с помощью node.js, Python и Perl когда-нибудь.


вам не нужно создавать скрытое поле для всех флажков, просто скопируйте мой код. он изменит значение флажка, если не установлен флажок value назначить 0 и если флажок установлен, то назначить value на 1

$("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');
        }
    })
})

вы можете сделать некоторый Javascript в событии отправки формы. Это все, что вы можете сделать, хотя нет никакого способа заставить браузеры делать это сами по себе. Это также означает, что ваша форма будет ломаться для пользователей без Javascript. Лучше знать на сервере, какие флажки есть, чтобы вы могли вывести, что те, которые отсутствуют в разнесенных значениях формы ($_POST в PHP) не отмечены.


Я бы на самом деле сделать следующее.

имейте мое скрытое поле ввода с тем же именем с флажком input

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

а затем, когда я публикую, я сначала удаляю дубликаты значений, подобранных в массиве $_POST, atfer, которые отображают каждое из уникальных значений.

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

Я получил это от поста удалить дубликаты значений из массива


$('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>

Если вы опустите имя флажка, он не будет передан. Только массив test_checkbox.


сначала я попробовал версию Сэма. Хорошая идея, но это заставляет быть несколько элементов в форме с тем же именем. Если вы используете любой javascript, который находит элементы на основе name, он теперь вернет массив элементов.

Я разработал идею Shailesh в PHP, она работает для меня. Вот мой код:

/* 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]);
}

большинство ответов здесь требуют использования JavaScript или дублирующих элементов управления вводом. Иногда это необходимо обрабатывать полностью на стороне сервера.

Я считаю, что (предполагаемый) ключ к решению этой общей проблемы-это контроль ввода формы.

трактовать неотмеченных для галочки успешно вы должны иметь знания о следующих:

  1. названия флажков
  2. имя элемент ввода представления формы

проверив, была ли отправлена форма (значение назначено элементу ввода отправки), любые непроверенные значения флажка могут быть предположить.

например:

<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>

при использовании PHP довольно тривиально определить, какие флажки были отмечены.

<?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);
}

?>

начальные данные могут быть загружены при каждой загрузке страницы, но должны быть изменены только в том случае, если форма был представлен. Поскольку имена флажков известны заранее, их можно просматривать и проверять по отдельности, так что отсутствие их индивидуальных значений указывает на то, что они не проверяются.


Я использую этот блок jQuery, который добавит скрытый ввод во время отправки к каждому непроверенному флажку. Это гарантирует, что вы всегда получите значение, представленное для каждого флажка, каждый раз, не загромождая свою разметку и рискуя забыть сделать это на флажке, который вы добавляете позже. Это также агностик для любого бэкэнд-стека (PHP,Ruby и т. д. ты употребляешь.

// 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

вы также можете перехватить форму.отправить событие и обратная проверка перед submit

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

Я вижу, что этот вопрос старый и имеет так много ответов, но я все равно дам свой Пенни. Мой голос за решение javascript в событии "отправить" формы, как некоторые указали. Нет удвоения входных данных (особенно если у вас есть длинные имена и атрибуты с php-кодом, смешанным с html), нет проблем на стороне сервера (что потребует знать все имена полей и проверять их по одному), просто извлеките все непроверенные элементы, назначьте им значение 0 (или все, что вам нужно, чтобы указать " не checked 'status), а затем измените свой атрибут "checked" на true

    $('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;
});

таким образом, у вас будет массив $_POST следующим образом:

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);
        }
    })
});

мне также нравится решение, которое вы просто публикуете дополнительное поле ввода, используя JavaScript, кажется мне немного хакерским.

в зависимости от того, что вы используете для серверной части будет зависеть от того, какой вход идет первым.

для серверной части, где используется первое вхождение (JSP), вы должны сделать следующее.

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


Для серверной части сервера, где используется последнее вхождение (PHP, Rails), вы должны сделать следующий.

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


для серверной части сервера, где все вхождения хранятся в типе данных списка ([],array). (Python / Zope)

вы можете опубликовать, в каком порядке вам нравится, вам просто нужно попытаться получить значение из ввода с помощью checkbox атрибут type. Таким образом, первый индекс списка, если флажок был перед скрытым элементом, и последний индекс, если флажок был после скрытого элемента.


Для серверная часть сервера, где все вхождения объединены запятыми (ASP.NET / IIS) Вам нужно будет (разделить/взорвать) строку, используя запятую в качестве разделителя для создания типа данных списка. ([])

теперь вы можете попытаться захватить первый индекс списка, если флажок был до скрытого элемента и захватить последний индекс, если флажок был после скрытого элемента.

Backend parameter handling

Источник изображения


то, что я сделал немного по-другому. Сначала я изменил значения всех непроверенных флажков. В "0", затем выберите их все, чтобы значение было отправлено.

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

Я бы предпочел сопоставить $_POST

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

его сознании, если пост не будет иметь ''value checkboxname, он был unckecked так, знамение значение.

вы можете создать массив ваших значений ckeckbox и создать функцию, которая проверяет, существуют ли значения, если нет, это возражает, что не отмечено, и вы можете присвоить значение


пример действий Ajax ( ': checked') используется вместо jQuery .val ();

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

params получит значение в TRUE или FALSE..


флажки обычно представляют двоичные данные, которые хранятся в базе данных как значения Yes/No, Y / N или 1/0. HTML-флажки имеют плохой характер для отправки значения на сервер, только если флажок установлен! Это означает, что сценарий сервера на другом сайте должен заранее знать, какие все возможные флажки на веб-странице, чтобы иметь возможность хранить положительные (проверенные) или отрицательные (непроверенные) значения. На самом деле только отрицательные значения являются проблемой (когда пользователь снимает ранее (предварительно)проверенное значение - как сервер знаете, это когда ничего не передается, если он не знает заранее, что это имя должно быть отправлено). Если у вас есть сценарий на стороне сервера, который динамически создает сценарий обновления, есть проблема, потому что вы не знаете, какие все флажки должны быть получены, чтобы установить значение Y для проверенных и значение N для непроверенных (не полученных).

поскольку я храню значения " Y " и "N" в своей базе данных и представляю их через флажки checked и unchecked на странице, я добавил скрытое поле для каждого значения (флажок) с значениями " Y " и " N " затем используйте флажки только для визуального представления и используйте простую функцию JavaScript check (), чтобы установить значение if в соответствии с выбором.

<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>

использовать один JavaScript функция onclick слушателя и вызвать функция проверить() для каждого checkboxe на моей веб-странице:

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

таким образом, значения " Y " или " N "всегда отправляются в сценарий на стороне сервера, он знает, какие поля должны быть обновлены, и нет необходимости в преобразовании значения checbox" on в " Y "или не получен флажок в "N".

Примечание: пробел или новая строка также является братом, поэтому здесь мне нужно .previousSibling.previousSibling.значение. Только если между ними нет пространства .previousSibling.значение


вам не нужно явно добавлять прослушиватель onclick, как раньше, вы можете использовать библиотеку jQuery для динамического добавления прослушивателя кликов с функцией изменения значения для всех флажков на Вашей странице:

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

проблема с флажками заключается в том, что если они не установлены, то они не разносятся с вашей формой. Если вы установите флажок и опубликуете форму, вы получите значение флажка в переменной $_POST, которую вы можете использовать для обработки формы, если он не установлен, значение не будет добавлено к переменной $_POST.

в PHP вы обычно обходите эту проблему, выполняя проверку isset () на вашем элементе checkbox. Если ожидаемый элемент не установлен в $_POST переменная тогда мы знаем, что флажок не установлен, и значение может быть false.

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

но если вы создали динамическую форму, вы не всегда будете знать атрибут name ваших флажков, если вы не знаете имя флажка, то вы не можете использовать функцию isset, чтобы проверить, было ли это отправлено с переменной $_POST.


Это может быть выполнено только с помощью некоторого javascript, так как непроверенные флажки не передаются. Поэтому вам нужен javascript, который, например, за кулисами добавляет скрытые поля при снятии флажка. Без javascript это невозможно сделать.


есть лучшее решение. Прежде всего укажите атрибут name только для тех флажков, которые установлены. Затем нажмите submit, через JavaScript function вы отмечаете все непроверенные флажки . Так что когда ты submit только те, которые будут извлечены в form collection те, кто name собственность.

  //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);
                   });

преимущество: Нет необходимости создавать дополнительные скрытые ящики и манипулировать ими.


@cpburnz получил это право, но много кода, вот та же идея, используя меньше кода:

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 (обратите внимание на имя поля, используя имя массива):

<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>

и для PHP:

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

jQuery версия ответа @vishnu.

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

если вы используете jQuery 1.5 или ниже, пожалуйста, используйте .функция attr () вместо .prop ()


Это решение вдохновил один @desw по.

Если ваши входные имена находятся в" стиле формы", вы потеряете ассоциацию индекса массива со своими значениями чекбокса, как только один чекбокс будет проверен, увеличивая эту" диссоциацию " на одну единицу каждый раз, когда чекбокс проверяется. Это может быть случай формы для вставки чего-то вроде сотрудников, состоящих из некоторых полей, например:

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

в случае, если вы вставляете трех сотрудников сразу и первый и второй являются одиночными, вы получите 5-элемент isSingle array, поэтому вы не сможете перебирать сразу три массива, чтобы, например, вставить сотрудников в базу данных.

вы можете преодолеть это с помощью простой постобработки массива. Я использую PHP на стороне сервера, и я сделал это:

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

таким образом, это решение является излишним для этого вопроса, но это помогло мне, когда у меня был тот же флажок, который произошел много раз для разных строк в таблице. Мне нужно знать строке флажок лице, а также знать состояние checkbox (checked или unchecked).

то, что я сделал, это снять атрибут name с моих входных данных флажка, дать им все тот же класс и создать скрытый вход, который будет содержать эквивалент JSON данные.

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 для запуска в форме submit

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));

строка json будет передана с формой как $_POST ["имеет-разрешения-значения"]. В PHP декодируйте строку в массив, и у вас будет ассоциативный массив, который имеет каждую строку и значение true/false для каждого соответствующего флажка. Тогда очень легко пройти и сравнить текущие значения базы данных.


все ответы отличные, но если у вас есть несколько флажков в форме с тем же именем, и вы хотите опубликовать статус каждого флажка. Затем я решил эту проблему, установив скрытое поле с флажком (имя, связанное с тем, что я хочу).

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

затем контролируйте состояние изменения флажка ниже кода jquery:

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

теперь при изменении любого флажка он изменит значение связанного скрытого поля. А на сервере можно смотреть только на hidden поля вместо флажков.

надеюсь, это поможет кому-то иметь этот тип проблемы. cheer:)


вы можете добавить скрытые элементы перед отправкой формы.

$('form').submit(function() {
  $(this).find('input[type=checkbox]').each(function (i, el) {
    if(!el.checked) {
      var hidden_el = $(el).clone();
      hidden_el[0].checked = true;
      hidden_el[0].value = '0';
      hidden_el[0].type = 'hidden'
      hidden_el.insertAfter($(el));
    }
  })
});