未チェックのHTMLチェックボックスをPOST
質問
デフォルトでチェックされるチェックボックスがたくさんあります。私のユーザーはおそらくいくつかのチェックボックスのチェックを外し(もしあれば)、残りはチェックしたままにします。
チェックされているチェックボックスではなく、チェックされていないチェックボックスをフォームにPOSTする方法はありますか?
解決
異なるIDを持つチェックボックスの非表示入力を追加します。
<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">
この2つの入力要素の間にスペースや改行が入らないように注意してください!
this.previousSibling.previousSibling
を使用して<!> quot; upper <!> quot;を取得できます。要素。
PHPを使用すると、名前付きの非表示フィールドで0(設定なし)または1(設定)を確認できます。
私の個人的なお気に入りは、チェックボックスがオフの場合に使用されるのと同じ名前の隠しフィールドを追加することです。しかし、解決策は思ったほど簡単ではありません。
このコードを追加する場合:
<form>
<input type='hidden' value='0' name='selfdestruct'>
<input type='checkbox' value='1' name='selfdestruct'>
</form>
ブラウザは、ここで何をするかをあまり気にしません。ブラウザは両方のパラメータをサーバーに送信し、サーバーはそれらの処理を決定する必要があります。
たとえば、PHPは使用する最後の値を取ります(重複したHTTP GETクエリキーの信頼できる位置)
しかし、私が(Javaに基づいて)作業した他のシステムは、それを回避します-最初の値のみを提供します。 .NETは代わりに両方の要素を持つ配列を代わりに提供します
いつかnode.js、Python、Perlでこれをテストしてみます。
これに関する一般的な手法は、各チェックボックスとともに隠し変数を保持することです。
<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
上記は正確に質問に答えているわけではありませんが、同様の機能を実現する代替手段を提供します。
すべてのチェックボックスに隠しフィールドを作成する必要はありません。コードをコピーするだけです。
チェックされていない場合はチェックボックスの値を変更し、value
が0
を割り当て、チェックボックスがチェックされている場合は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を使用しないユーザーのフォームが壊れることを意味します。
サーバー上でどのチェックボックスが存在するかを知る方が良いので、投稿されたフォームの値(PHPでは$_POST
)にないものはチェックされていないことを推測できます。
$('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配列のみ。
私は実際に次のことをします。
チェックボックス入力と同じ名前の非表示の入力フィールドを使用
<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />
そして、私が投稿するとき、まず最初に$ _POST配列で取得された重複する値を削除し、それぞれの一意の値を表示すると推測します。
$posted = array_unique($_POST['checkbox_name']);
foreach($posted as $value){
print $value;
}
<!> quot;サーバーアプローチを使用しました。うまくいくようです-ありがとう。 <!>#8211; reach4thelasers 2009年12月1日15:19 <!> quot;オーナーに勧めたいです。引用されているように:javascriptソリューションはサーバーハンドラーに依存します(チェックしませんでした)
など
if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";
ここでの回答のほとんどは、JavaScriptを使用するか、入力コントロールを複製する必要があります。これは、サーバー側で完全に処理する必要がある場合があります。
この一般的な問題を解決するための(意図した)キーは、フォームの送信入力コントロールだと思います。
チェックボックスの未チェック値を正常に解釈して処理するには、次の知識が必要です。
- チェックボックスの名前
- フォームの送信入力要素の名前
フォームが送信されたかどうかを確認することで(値が送信入力要素に割り当てられます)、チェックされていないチェックボックス値はすべて想定できます。
例:
<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);
}
?>
各ページの読み込み時に初期データを読み込むことができますが、フォームが送信された場合にのみ変更する必要があります。チェックボックスの名前は事前にわかっているため、個別にトラバースおよび検査でき、個々の値が存在しない場合はチェックされていないことを示します。
最初にサムのバージョンを試しました。 良い考えですが、同じ名前のフォームに複数の要素が存在することになります。名前に基づいて要素を見つけるJavaScriptを使用すると、要素の配列が返されるようになります。
私は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]); }
この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
form.submitイベントをインターセプトし、送信前に逆チェックすることもできます
$('form').submit(function(event){
$('input[type=checkbox]').prop('checked', function(index, value){
return !value;
});
});
また、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)
リストデータ型を作成するには、区切り文字としてカンマを使用して文字列を(分割/展開)する必要があります。 (<=>)
チェックボックスが非表示要素の前にある場合、リストの最初のインデックスを取得し、チェックボックスが非表示要素の後にある場合、最後のインデックスを取得することができます。
この質問は古いものであり、非常に多くの回答がありますが、とにかくお金を差し上げます。 私の投票は、一部の人が指摘したように、フォームの「送信」イベントでのJavaScriptソリューションに対するものです。入力を2倍にしない(特にhtmlコードとphpコードを組み合わせた長い名前と属性がある場合) 、それらに0値(または「未チェック」ステータスを示すために必要なもの)を割り当て、それらの属性「チェック済み」を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);
}
})
});
この質問は3歳であることは知っていますが、かなりうまくいくと思う解決策を見つけました。
$ _ POST変数が割り当てられているかどうかを確認し、変数に保存できます。
$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';
isset()関数は、$ _ POST変数が割り当てられているかどうかを確認します。ロジックにより、割り当てられていない場合、チェックボックスはチェックされません。
私がやったことは少し違いました。最初に、チェックされていないすべてのチェックボックスの値を変更しました。 <!> quot; 0 <!> quot;に、それらをすべて選択したため、値が送信されます。
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;
POSTに 'checkboxname'の値がない場合は、気付かれなかったので、値を割り当てます。
ckeckboxの値の配列を作成し、値が存在するかどうかをチェックする関数を作成できます。存在しない場合は、チェックを外して値を割り当てることができます
Ajaxアクションの例は.val()の代わりにjQueryを使用した( ':checked');
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チェックボックスは、チェックボックスがチェックされている場合にのみ値をサーバーに送信するという悪い性質を持っています!つまり、他のサイトのサーバースクリプトは、正の値(チェック済み)または負の値(チェックなし)を保存できるように、Webページで可能なすべてのチェックボックスを事前に知っている必要があります。実際には、負の値のみが問題です(ユーザーが以前に(事前に)チェックした値をオフにした場合-この名前を送信する必要があることが事前にわからない場合、何も送信されないときにサーバーがこれを知る方法) UPDATEスクリプトを動的に作成するサーバー側スクリプトがある場合、チェック済みのY値と未チェック(未受信)のN値を設定するためにすべてのチェックボックスを受信する必要があるかわからないため、問題があります。
データベースに値「Y」および「N」を保存し、ページ上のチェックボックスおよびチェックなしチェックボックスでそれらを表すため、各値(チェックボックス)の非表示フィールドを「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>
1つのJavaScript onclickリスナーを使用し、Webページの各チェックボックスに対して関数check()を呼び出します。
function check(me)
{
if(me.checked)
{
me.previousSibling.previousSibling.value='Y';
}
else
{
me.previousSibling.previousSibling.value='N';
}
}
この方法では、「Y」または「N」の値が常にサーバー側のスクリプトに送信され、更新する必要のあるフィールドが認識され、checbox <!> quot; on <!> quot;を変換する必要はありません。値を「Y」に、または未受信チェックボックスを「N」に。
注:空白または改行も兄弟なので、ここでは.previousSibling.previousSibling.valueが必要です。間にスペースがない場合は、.previousSibling.valueのみ
以前のように明示的にonclickリスナーを追加する必要はありません。jQueryライブラリを使用して、ページ内のすべてのチェックボックスの値を変更する機能を持つクリックリスナーを動的に追加できます。
$('input[type=checkbox]').click(function()
{
if(this.checked)
{
$(this).prev().val('Y');
}
else
{
$(this).prev().val('N');
}
});
チェックボックスの問題は、チェックされていない場合、フォームに投稿されないことです。チェックボックスをオンにしてフォームを送信すると、フォームの処理に使用できる$ _POST変数のチェックボックスの値が取得されます。チェックされていない場合、値は$ _POST変数に追加されません。
PHPでは、通常、チェックボックス要素でisset()チェックを行うことでこの問題を回避できます。期待する要素が$ _POST変数に設定されていない場合、チェックボックスがチェックされておらず、値がfalseになる可能性があることがわかります。
if(!isset($_POST['checkbox1']))
{
$checkboxValue = false;
} else {
$checkboxValue = $_POST['checkbox1'];
}
ただし、動的フォームを作成した場合、チェックボックスの名前属性が常にわかるとは限りません。チェックボックスの名前がわからない場合、isset関数を使用して、 $ _POST変数とともに送信されました。
チェックされていないチェックボックスは送信されないため、これは一部のjavascriptでのみ実行できます。だから、例えば背後で、チェックボックスをオフにすると非表示フィールドが追加されます。 javascriptがなければ、これはできませんでした。
より良い回避策があります。
まず、チェックされているチェックボックスのみに名前属性を提供します。
次に、submit
をクリックして、JavaScript function
を使用して、すべての未チェックボックスをオンにします。
そのため、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>
@vishnuの回答のjQueryバージョン。
if($('#testName').is(":checked")){
$('#testNameHidden').prop('disabled', true);
}
jQuery 1.5以下を使用している場合は、.prop()ではなく.attr()関数を使用してください
このソリューションは、@ deswのソリューションに触発されています。
入力名が<!> quot; form style <!> quot;の場合、1つのchekboxがチェックされるとすぐにchekbox値と配列インデックスの関連付けが失われ、この<!> quot; dissociation <! > quot;チェックボックスがチェックされるたびに1単位ずつ。これは、たとえば、いくつかのフィールドで構成される従業員のようなものを挿入するためのフォームの場合です:
<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />
一度に3人の従業員を挿入し、最初と2番目の従業員が単一の場合、5要素のisSingle
配列になるため、3つの配列を一度に反復することはできません。たとえば、従業員をデータベースに挿入するため。
いくつかの簡単な配列後処理でこれを克服できます。サーバー側でPHPを使用していますが、これを行いました。
$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
if($isSingle=='yes'){
unset($areSingles[$j-1]);
}
$j++;
}
$areSingles = array_values($areSingles);
したがって、この解決策はこの質問に対してはやり過ぎですが、テーブル内の異なる行に対して何度も発生する同じチェックボックスがあれば役立ちました。チェックボックスが表す行と、チェックボックスの状態(チェック済み/未チェック)を知る必要がありました。
私がしたことは、チェックボックスの入力から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
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 [<!> quot; has-permissions-values <!> quot;]の形式で渡されます。 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);
});
チェックボックスを変更すると、関連する非表示フィールドの値が変更されます。サーバーでは、チェックボックスではなく非表示フィールドのみを見ることができます。
これが誰かがこの種の問題を抱えることを助けることを願っています。応援:)