У мене завантажено прапорець, які встановлені за замовчуванням. Мої користувачі, ймовірно, знімуть прапорець (якщо такі є), і залиште прапорець.
Чи є спосіб зробити форму POST прапорцями, які не перевіряються, а не тими, які перевіряються?
У мене завантажено прапорець, які встановлені за замовчуванням. Мої користувачі, ймовірно, знімуть прапорець (якщо такі є), і залиште прапорець.
Чи є спосіб зробити форму POST прапорцями, які не перевіряються, а не тими, які перевіряються?
Відповіді:
Додати прихований вхід для прапорця з іншим ідентифікатором:
<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;
}
checkbox
елемента жахлива? Вони є двійковим контролем, вони повинні надсилати двійкові значення.
Рішення, яке мені найбільше сподобалось, - це поставити прихований вхід з тим самим іменем, що і прапорець, який не може бути встановлений. Я думаю, що це працює так, що якщо прапорець не встановлений, прихований вхід все ще успішний і надсилається на сервер, але якщо прапорець встановлений, він замінить прихований вхід перед ним. Таким чином, вам не потрібно буде відслідковувати, які значення у розміщених даних очікувались надходити у прапорці.
<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">
Будьте обережні, щоб між цими двома вхідними елементами не було пробілів чи розривів!
Ви можете використовувати this.previousSibling.previousSibling
для отримання "верхніх" елементів.
За допомогою PHP ви можете перевірити назване приховане поле на 0 (не встановлено) або 1 (встановити).
<fieldset name='fs1'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> <fieldset name='fs2'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset>
* Припустимо, що там були нові рядки. Вони, здається, не працюють у блоках коду міні-розмітки
previousElementSibling
замість previousSibling
. Він підтримується майже скрізь , і він ігнорує текстові вузли.
Мій особистий фаворит - додати приховане поле з тим же ім’ям, яке буде використано, якщо прапорець не встановлений. Але рішення не таке просте, як може здатися.
Якщо ви додали цей код:
<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.
request.getParameterValues
Загальна техніка навколо цього - переносити приховану змінну разом із кожним прапорцем.
<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
і якщо прапорець встановлений , то правонаступник 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');
}
})
})
$('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 у події подання форми. Це все, що ви можете зробити, хоча немає можливості браузерам це зробити самостійно. Це також означає, що ваша форма порушиться для користувачів без Javascript. Краще - знати на сервері, які прапорці існують, тож можна зробити висновок, що ті, які відсутні у розміщених значеннях форми ( $_POST
у PHP), не відмічені.
$_REQUEST
є хорошою практикою, оскільки вона дозволяє повторно використовувати код, якщо ваш сценарій підтримує обидва способи.
Я б насправді зробив наступне.
Попросіть моє приховане поле з тим самим іменем із введенням прапорця
<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;
}
Я отримав це з публікації видалити дублікати значень з масиву
checkbox_name[]
кожне значення буде вводитися в масив, який ви зможете витягнути. Наприклад: $_POST['checkbox_name'][0]
і так далі із збільшенням кількості полів, що мали таку саму назву. Інший приклад - якщо у вас було названо три поля, field_name[]
ви можете отримати друге значення, field_name
як $_POST['field_name'][1]
. Його призначення може бути дивовижним, якщо у вас є кілька полів, що мають однакову назву.
"Я пішов із серверним підходом. Здається, працює добре - дякую. - достигаю4thelasers 1 грудня '09 о 15:19" Я хотів би рекомендувати це від власника. Як цитується: рішення JavaScript залежить від того, як обробник сервера (я його не перевіряв)
як от
if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";
Я знаю, що цьому питанню 3 роки, але я знайшов рішення, яке, на мою думку, працює досить добре.
Ви можете перевірити, чи призначена змінна $ _POST, і зберегти її у змінній.
$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';
функція isset () перевіряє, чи призначена змінна $ _POST. За логікою, якщо він не призначений, то прапорець не встановлений.
Більшість відповідей тут вимагає використання 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, вона працює для мене. Ось мій код:
/ * Видалити поля '.hidden', якщо є оригінал, використовуйте значення '.hidden', якщо ні. * / foreach ($ _POST ['frmmain'] як $ field_name => $ значення) { // Подивіться лише на елементи, що закінчуються на ".hidden" if (! substr ($ field_name, -strlen ('. hidden'))) { перерва; } // отримати ім'я без '.hidden' $ real_name = substr ($ ключ, strlen ($ field_name) - strlen ('. приховано')); // Створіть "підроблене" оригінальне поле зі значенням у ".hidden", якщо оригіналу не існує if (! array_key_exists ($ real_name, $ POST_copy)) { $ _POST [$ real_name] = значення $; } // Видаліть елемент '.hidden' unset ($ _ POST [$ field_name]); }
Мені також подобається рішення, що ви просто опублікуєте додаткове поле для введення, використовуючи 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
атрибута типу. Отже, перший індекс списку, якщо прапорець був перед прихованим елементом, і останній індекс, якщо прапорець був після прихованого елемента.
Для серверного сервера, де всі події об'єднані комою (ASP.NET / IIS) Вам потрібно буде (розділити / вибухнути) рядок, використовуючи кому як роздільник для створення типу даних списку. ( []
)
Тепер ви можете спробувати схопити перший індекс списку, якщо прапорець був раніше прихованим елементом, і схопити останній індекс, якщо прапорець був після прихованого елемента.
Я використовую цей блок 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
Я бачу, що це питання давнє і на нього є так багато відповідей, але я все одно віддаю свою копійку. Я голосую за рішення Javascript у події "подати" форми, як дехто зазначив. Ніякого подвоєння входів (особливо якщо у вас довгі імена та атрибути з PHP-кодом, змішаним з html), жодне серверне занепокоєння (що вимагало б знати всі назви полів та перевіряти їх по одному), просто дістаньте всі неперевірені елементи , призначте їм значення 0 (або все, що вам потрібно вказати статус "не перевірено"), а потім змініть їх атрибут "перевірено" на істинне
$('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);
}
})
});
Що я робив, було трохи інакше. Спершу я змінив значення всіх відмічених прапорців. До "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;
маємо на увазі, якщо у POST немає значення "checkboxname", воно було відмічено таким чином, призначте значення.
ви можете створити масив значень ckeckbox і створити функцію, яка перевіряє, чи існують значення, якщо немає, це розуми не перевірені, і ви можете призначити значення
Прикладом дій Ajax є (': перевірено') використовується jQuery замість .val ();
var params = {
books: $('input#users').is(':checked'),
news : $('input#news').is(':checked'),
magazine : $('input#magazine').is(':checked')
};
парами отримають значення в ПРАВИЛЬНОМУ ТА ЛІЖНОМУ ..
Поле правки зазвичай представляє двійкові дані, які зберігаються в базі даних у вигляді значень Так / Ні, Y / N або 1/0. HTML-прапорці мають поганий характер для надсилання значень на сервер, лише якщо прапорець встановлений! Це означає, що серверний скрипт на іншому сайті повинен заздалегідь знати, які всі можливі прапорці на веб-сторінці, щоб мати можливість зберігати позитивні (відмічені) або негативні (неперевірені) значення. Насправді проблематичні лише негативні значення (коли користувач знімає попередньо (попередньо) перевірене значення) - як сервер може знати це, коли нічого не надсилається, якщо він не знає заздалегідь, що це ім'я слід надіслати). Якщо у вас є серверний скрипт, який динамічно створює сценарій UPDATE, виникає проблема, оскільки ви не знаєте, які всі прапорці повинні бути отримані для того, щоб встановити значення Y для перевірених та N значення для неперевірених (не отриманих).
Оскільки я зберігаю значення "Y" і "N" у своїй базі даних і представляю їх через відмічені та невірно встановлені прапорці на сторінці, я додав приховане поле для кожного значення (прапорець) зі значеннями "Y" і "N", а потім використовую прапорці лише для візуального представлення та використовуйте просту функцію JavaScript check (), щоб встановити значення, якщо відповідно до вибору.
<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>
використовувати один слухач onclick JavaScript та функцію виклику () для кожної прапорці на моїй веб-сторінці:
function check(me)
{
if(me.checked)
{
me.previousSibling.previousSibling.value='Y';
}
else
{
me.previousSibling.previousSibling.value='N';
}
}
Таким чином значення "Y" або "N" завжди надсилаються до скрипту на стороні сервера, він знає, які поля слід оновити, і немає необхідності в перетворенні значення checbox "на" у "Y" або не отримане прапорець у "N" '.
ПРИМІТКА: пробіл або нова лінія - це також рідний брат, тому тут мені потрібна .previousSibling.previousSibling.value. Якщо між цим простором немає місця. SamoprepreSSbling.value
Вам не потрібно явно додавати слухач onclick, як раніше, ви можете використовувати бібліотеку jQuery для динамічного додавання слухача кліків з функцією, щоб змінити значення для всіх прапорців на вашій сторінці:
$('input[type=checkbox]').click(function()
{
if(this.checked)
{
$(this).prev().val('Y');
}
else
{
$(this).prev().val('N');
}
});
Усі відповіді чудові, але якщо у вас є декілька прапорців у формі з однаковою назвою, і ви хочете опублікувати статус кожного прапорця. Тоді я вирішив цю проблему, поставивши приховане поле з прапором (ім'я, пов’язане з тим, що я хочу).
<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);
});
тепер при зміні будь-якого прапорця він змінить значення пов’язаного прихованого поля. А на сервері ви можете шукати лише приховані поля замість прапорців.
Сподіваюся, це допоможе комусь із подібними проблемами. привіт :)
Проблема з прапорцями полягає в тому, що якщо вони не встановлені, вони не розміщуються з вашою формою. Якщо ви встановите прапорець і опублікуєте форму, ви отримаєте значення прапорця в змінній $ _POST, яку ви можете використовувати для обробки форми, якщо вона не встановлена, до змінної $ _POST значення не додається.
У PHP ви зазвичай можете обійти цю проблему, зробивши прапорець isset () на своєму елементі прапорця. Якщо елемент, який ви очікуєте, не встановлений у змінній $ _POST, то ми знаємо, що прапорець не встановлений і значення може бути помилковим.
if(!isset($_POST['checkbox1']))
{
$checkboxValue = false;
} else {
$checkboxValue = $_POST['checkbox1'];
}
Але якщо ви створили динамічну форму, то ви не завжди будете знати атрибут імені ваших прапорців, якщо ви не знаєте імені прапорця, ви не можете використовувати функцію isset, щоб перевірити, чи це надіслано змінна $ _POST.
Є кращий спосіб вирішення. Перш за все надайте атрибут імені лише тим прапорцям, які встановлені. Потім при натисканні 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>
Це рішення натхнене рішенням @ desw.
Якщо ваші вхідні імена в "стильовій формі", ви втратите асоціацію індексу масиву зі своїми значеннями chekbox, як тільки перевіряється одна чекбокс, збільшуючи цю "дисоціацію" на одну одиницю щоразу, коли чекбокс перевіряється. Це може бути випадок форми для вставки чогось подібного до співробітників, складеного, наприклад, деякими полями:
<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />
Якщо ви вставите одразу трьох співробітників, і перший, і другий одиничні, ви отримаєте 5-елементний isSingle
масив, тож ви не зможете одразу повторити три масиви, наприклад, , вставити співробітників у базу даних.
Ви можете подолати це за допомогою простого масиву післяобробки. Я використовую PHP на стороні сервера, і я зробив це:
$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
if($isSingle=='yes'){
unset($areSingles[$j-1]);
}
$j++;
}
$areSingles = array_values($areSingles);
Тож це рішення є надмірним для цього питання, але воно допомогло мені, коли у мене був той самий прапорець, який багато разів траплявся для різних рядків у таблиці. Мені потрібно було знати рядок, який позначено прапорець, а також знати стан прапорця (відмічено / відмічено).
Що я зробив, це зняти атрибут імені з моїх вхідних прапорців, дати їм все той же клас і створити прихований вхід, який би містив 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 ["has-permissions-values"]. У PHP розшифруйте рядок у масив, і у вас з'явиться асоціативний масив, у якому є кожен рядок та значення true / false для кожного відповідного прапорця. Тоді дуже легко пройтись і порівняти з поточними значеннями бази даних.