2010-11-18 146 views
5

我試圖在現有的網站上工作,但我發現了一個錯誤,但我不確定它爲什麼是一個錯誤或者如何解決它。僅當HTML複選框元素被檢查時才提交?

該網站基本上列出了在一個城市出租的一些商業物業。有一個類從數據庫中獲取列表並從中創建一個對象。在每個對象中都有一個與該屬性相關聯的圖像數組。

當用戶編輯列表時,他們會得到一個編輯頁面,其中包含圖像列表以及旁邊的「刪除」複選框。複選框都具有相同的名稱,以便將它們提交回服務器時,應用程序獲取要刪除的圖像數組。

應該發生什麼,是應用程序具有開/關值的數組(其中on = delete),並且數組中每個值的索引都對應於列表對象中圖像的索引 - 當其中一個值爲「on」時,圖像陣列中與該「on」值對應的文件名將從文件系統中刪除,並且該圖像將從數據庫中刪除。

但是,當表單被提交時,應用程序只獲取一個只有選中複選框的0索引數組。所以,如果我要刪除設定了三個任意圖像,應用程序會得到

 
Array { 
    [0] => "on", 
    [1] => "on", 
    [2] => "on" 
} 

這顯然是行不通的,在上市第3個圖像將無論哪個複選框被設置刪除。

我該如何解決這個問題?我想避免命名每個複選框(delete_1delete_2delete_3等),因爲系統已經構建爲與所有具有相同名稱的複選框一起工作。有沒有辦法可以強制所有複選框以「開」或「關」提交?

回答

5

不,你不能強迫選中複選框提交,但你可以給他們唯一的值(而不是「全部」)以確定哪些被檢查而不改變名稱。

+0

真棒,不知道你能做什麼那。非常感謝(在允許的情況下會接受) – 2010-11-18 03:20:08

+0

omg,這是一個可怕的解決方案,絕對不是問題的答案。 – zerkms 2010-11-18 03:22:09

+2

@Steve我想避免以不同的方式命名它們,因爲這將不得不改變後端的行爲。我沒有意識到你可以提交除「開」或「關」以外的值 - 這將需要最小的更改 – 2010-11-18 03:22:29

6

沒有辦法給力,但你可以只具有相同名稱的複選框前面添加一個隱藏的權利和需要的值:

<input type="hidden" name="delete[42]" value="off" /> 
<input type="checkbox" name="delete[42]" value="on" /> 
+2

對不起,我試圖避免讓不同的na mes每個複選框。目前他們都只是名爲'delete',應用程序將它們作爲數組接收。我不認爲這種技術可以與他們的所有人同名 – 2010-11-18 03:18:44

+0

@Carson Myers:正如我所說的,你可以給**同名**複選框。不清楚你有什麼名字''。好點嗎? – zerkms 2010-11-18 03:20:12

+0

@Carson Myers:「我不認爲這種技術會起作用」---你爲什麼不試試? ;-) – zerkms 2010-11-18 03:21:16

1

如果你真的想要在on和off上返回一個數組,那麼你需要附加一個函數給表單提交,它將掃描所有帶有給定名稱的複選框,並將它們的值放入數組中。

在jQuery中,這將是這個樣子......

$('#yourForm').submit(function(){ 
    var array = new Array(); 
    $('input[name="nameOfCheckboxes"]').each(function(index){ 
     array[index] = $(this).value(); 
    } 
    var r = $.param(array); 
    $('#someHiddenFieldInForm').value(r); 
} 

(代碼是未經測試,當然)

+2

+1有效的解決方案,但JavaScript似乎矯枉過正這個問題 – 2010-11-18 03:46:26

+0

Javascript,真的嗎? – Stephen 2010-11-18 04:36:14

+0

你真的沒有什麼更好的事情可以抱怨嗎? Carson要求解決方案不需要改變現有的「功能」。他的問題不清楚他願意改變多少,使用JavaScript不需要修改現有的代碼。 – Jeremy 2010-11-18 17:28:10

1

你可以通過添加下面的jQuery解決這個問題:

$(function() { 
    $("#myform").submit(function(){ 
    $("input[name='delete']:not(:checked)").attr("checked","checked").val("off"); 
    }); 
}); 

myform是您的表單的ID,delete是複選框的名稱。

+1

我簡單地考慮過使用javascript,但是在這種情況下它似乎有點矯枉過正。這個問題被接受的答案涉及將foreach($ listing ['delete'] as $ index => $ state)''改爲'foreach($ listing ['delete'] as $ index)'',我認爲這是理想的我的解決方案。 +1雖然有效的解決方案 – 2010-11-18 03:46:08

+0

格特,就像你比我的好。 +1 – Jeremy 2010-11-18 03:49:29

+1

Javascript是一個黑客解決方案。 – Stephen 2010-11-18 04:36:40

1

弗雷德Nurk的解決方案是好的,我upvoted它。就我個人而言,當我遇到這種情況時,我總是給這些字段命名不同的名字。我使用一個通用的前綴,後跟一個下劃線,因此很容易識別,然後使用某種類型的ID。我會經常製作一組具有相同模式的字段,如「name_1」,「amount_1」,「foobar_1」,「name_2」,「amount_2」等。在字段中循環並將這些名稱分開很容易。 (在Java中,只是indexOf('_')。)

0

解決此問題的另一種方法是接受一個奇怪的HTML表單,並在聲明期間使用一個使用ternary operators的本地變量來捕獲它。

例如,給定一個複選框

<input type="checkbox" name="notify_users" id="notify_cb"> 

可以處理後這樣無論列入複選框值的:

// normal boolean value  
$notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on');  
// explicitly set a 1 or 0 
$notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on')? 1 : 0); 
// explicitly set 'yes' or 'no' 
$notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on')? 'yes' : 'no'); 

在我看來,這是最好添加額外的Javascript對於客戶來說,如果僅僅是因爲它稍微維持一點點(並且可以更清楚地知道繼任者/其他開發者能夠理解正在發生的事情)