วิธีจัดการช่องทำเครื่องหมายในรูปแบบ ASP.NET MVC?


246

ข้อควรระวัง: คำถามนี้มีอายุเกินเก้าปี!

ตัวเลือกที่ดีที่สุดของคุณคือค้นหาคำถามที่ใหม่กว่าหรือค้นหาคำตอบด้านล่างเพื่อค้นหา MVC รุ่นที่คุณต้องการเนื่องจากคำตอบมากมายที่นี่ล้าสมัยแล้ว

หากคุณพบคำตอบที่เหมาะกับเวอร์ชันของคุณโปรดตรวจสอบให้แน่ใจว่าคำตอบนั้นมีเวอร์ชั่นของ MVC ที่คุณใช้อยู่
(คำถามเดิมเริ่มด้านล่าง)


นี่ดูเหมือนจะแปลกสำหรับฉัน แต่เท่าที่ฉันสามารถบอกได้นี่เป็นวิธีที่คุณทำ

ฉันมีชุดของวัตถุและฉันต้องการให้ผู้ใช้เลือกอย่างน้อยหนึ่งรายการ สิ่งนี้บอกฉันว่า "แบบฟอร์มพร้อมช่องทำเครื่องหมาย" วัตถุของฉันไม่มีแนวคิดของ "เลือก" (พวกเขาเป็นพื้นฐานของ POCO ที่เกิดขึ้นจากการยกเลิกการโทร wcf) ดังนั้นฉันทำต่อไปนี้:

public class SampleObject{
  public Guid Id {get;set;}
  public string Name {get;set;}
}

ในมุมมอง:

<%
    using (Html.BeginForm())
    {
%>
  <%foreach (var o in ViewData.Model) {%>
    <%=Html.CheckBox(o.Id)%>&nbsp;<%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

และในคอนโทรลเลอร์นี่เป็นวิธีเดียวที่ฉันจะเห็นว่าผู้ใช้ตรวจสอบวัตถุใด:

public ActionResult ThisLooksWeird(FormCollection result)
{
  var winnars = from x in result.AllKeys
          where result[x] != "false"
          select x;
  // yadda
}

มันประหลาดในตอนแรกและประการที่สองสำหรับรายการเหล่านั้นที่ผู้ใช้ตรวจสอบ FormCollection แสดงรายการค่าเป็น "จริงเท็จ" แทนที่จะเป็นเพียงแค่ความจริง

เห็นได้ชัดว่าฉันขาดอะไรบางอย่าง ฉันคิดว่าสิ่งนี้ถูกสร้างขึ้นโดยมีแนวคิดอยู่ในใจว่าวัตถุในคอลเล็กชันที่ดำเนินการภายในรูปแบบ html นั้นได้รับการอัปเดตโดยใช้UpdateModel()หรือผ่าน ModelBinder

แต่วัตถุของฉันไม่ได้ตั้งค่าสำหรับสิ่งนี้ หมายความว่านี่เป็นวิธีเดียวหรือไม่ มีวิธีอื่นที่จะทำหรือไม่


2
ผู้อื่นอาจพบว่าโซลูชันนี้มีประโยชน์: stackoverflow.com/questions/3291501/…
Aaron

คำตอบ:


262

Html.CheckBox กำลังทำสิ่งแปลก ๆ - ถ้าคุณดูแหล่งที่มาในหน้าผลลัพธ์คุณจะเห็นว่ามี <input type="hidden" />ที่สร้างอยู่ข้างช่องทำเครื่องหมายแต่ละช่องซึ่งจะอธิบายค่า "จริงเท็จ" ที่คุณเห็นสำหรับองค์ประกอบฟอร์มแต่ละรายการ

ลองสิ่งนี้ซึ่งใช้ได้กับ ASP.NET MVC Beta แน่นอนเพราะฉันเพิ่งลอง

วางสิ่งนี้ไว้ในมุมมองแทนที่จะใช้ Html.CheckBox ():

<% using (Html.BeginForm("ShowData", "Home")) {  %>
  <% foreach (var o in ViewData.Model) { %>
    <input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
    <%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

ช่องทำเครื่องหมายของคุณถูกเรียกทั้งหมดselectedObjectsและvalueแต่ละช่องทำเครื่องหมายเป็น GUID ของวัตถุที่เกี่ยวข้อง

จากนั้นโพสต์ไปยังการกระทำของตัวควบคุมต่อไปนี้ (หรือสิ่งที่คล้ายกันที่ทำสิ่งที่มีประโยชน์แทน Response.Write ()

public ActionResult ShowData(Guid[] selectedObjects) {
    foreach (Guid guid in selectedObjects) {
        Response.Write(guid.ToString());
    }
    Response.End();
    return (new EmptyResult());
}

ตัวอย่างนี้จะเขียน GUID ของกล่องที่คุณเลือก ASP.NET MVC แมปค่า GUID ของช่องทำเครื่องหมายที่เลือกลงในGuid[] selectedObjectsพารามิเตอร์สำหรับคุณและแม้กระทั่งแยกวิเคราะห์สตริงจากคอลเลกชัน Request.Form ไปยังวัตถุ GUID ที่เริ่มต้นซึ่งฉันคิดว่าค่อนข้างดี


ได้! นี่คือสิ่งที่ฉันต้องทำเพื่อแอปพลิเคชันของฉันด้วยเช่นกัน!
Adhip Gupta

70
WTF ช่องป้อนข้อมูลที่ซ่อนอยู่ด้วยชื่อ SAME เป็นตัวควบคุม ViewState 2.0!
Simon_Weaver

3
นี่ก็มีอยู่ในรุ่น 1.0 ดูคำตอบ @ andrea-balducci ที่ส่งมาเพื่อให้คุณมีวิธีที่ชาญฉลาดในการจัดการกับสิ่งนี้ หากช่องไม่ได้ตรวจสอบข้อความที่เกิดขึ้นควรจะดึง 'เท็จ' - วิธีแก้ปัญหาที่ดีที่จะบัญชีสำหรับเบราว์เซอร์ที่ตายแล้วสมอง ...
ไบรอัน Rehbein

77
เซอร์ไพร์ส? WTF? อินพุตที่ซ่อนอยู่มีชื่อเดียวกับช่องทำเครื่องหมาย - หากไม่ได้ทำเครื่องหมายในช่องที่มีชื่อเหมือนกันค่านั้นจะไม่ถูกโพสต์ในขณะที่ค่าของโพสต์ที่ถูกซ่อนจะถูกโพสต์ ครั้งแรกที่เบราว์เซอร์พบองค์ประกอบที่มีชื่อจะใช้ค่านั้นและละเว้นองค์ประกอบอื่น ๆ ทั้งหมดที่มีชื่อเดียวกัน สิ่งนี้รับประกันว่าจะมีการส่งค่า: จริงถ้ามีการทำเครื่องหมายในช่องทำเครื่องหมาย (หากพบว่าอยู่เหนือองค์ประกอบที่ซ่อนอยู่) และเท็จถ้าไม่ได้ทำเครื่องหมายที่ช่องทำเครื่องหมาย (ช่องทำเครื่องหมายว่างเปล่าจะถูกเพิกเฉย wtf ที่แท้จริงคือเหตุผลที่ไม่มีใครชี้เรื่องนี้
nerraga

19
@nerraga: คุณผิด: เป็น html ที่ถูกต้องที่จะมีองค์ประกอบหลายรูปแบบที่มีชื่อเดียวกัน และถ้าเป็นเช่นนั้นองค์ประกอบทั้งหมดจะถูกโพสต์และฉันไม่แน่ใจว่ามีการกำหนดลำดับจริง ๆ (แต่น่าจะเป็นเพียงการเรียงลำดับหน้าเว็บในทางปฏิบัติ) การใช้คำว่า "false" เป็นค่าที่ค่อนข้างทำให้เข้าใจผิดใช่แล้วมันเป็น WTF - ทางเลือกที่ดีกว่าและทำให้เข้าใจผิดน้อยกว่าจะเป็นสิ่งที่ "มีอยู่" หรือโทเค็นที่ไม่มีความหมายเช่นเส้นประ
Eamon Nerbonne

95

HtmlHelper เพิ่มอินพุตที่ซ่อนอยู่เพื่อแจ้งให้ผู้ควบคุมทราบเกี่ยวกับสถานะที่ไม่ได้ตรวจสอบ ดังนั้นเพื่อให้สถานะการตรวจสอบที่ถูกต้อง:

bool bChecked = form[key].Contains("true");

1
นี่เป็นวิธีที่ง่ายที่สุดในการแก้ไขปัญหานี้และเป็นสิ่งที่ฉันมักจะใช้ จะช่วยให้คุณใช้วิธีการช่วยเหลือและบัญชีสำหรับพฤติกรรม ASP.NET MVCs
Nick Daniels

8
.. หรือในกรณีที่ไม่ได้ตรวจสอบ: bool bChecked = form [key] .Equals ("false"); การทำ. Contains ("false") ล้มเหลวเนื่องจากค่าที่แท้จริงคือ "true, false"
มาร์คโรบินสัน

54

ในกรณีที่คุณสงสัยว่าทำไมพวกเขาจึงใส่เขตข้อมูลที่ซ่อนไว้ในชื่อเดียวกับช่องทำเครื่องหมายเหตุผลดังต่อไปนี้:

ความคิดเห็นจากซอร์สโค้ด MVCBetaSource \ MVC \ src \ MvcFutures \ Mvc \ ButtonsAndLinkExtensions.cs

แสดง<input type="hidden".../>ช่องทำเครื่องหมายเพิ่มเติม ที่อยู่นี้สถานการณ์ที่ไม่มีการทำเครื่องหมายในช่องทำเครื่องหมายจะไม่ส่งในคำขอ การส่งอินพุตที่ซ่อนอยู่ทำให้สามารถทราบได้ว่ามีช่องทำเครื่องหมายปรากฏบนหน้าเว็บเมื่อมีการส่งคำขอ

ฉันเดาเบื้องหลังพวกเขาจำเป็นต้องรู้สิ่งนี้สำหรับการผูกกับพารามิเตอร์ในวิธีการดำเนินการของคอนโทรลเลอร์ จากนั้นคุณสามารถมีบูลีน tri-state ฉันคิดว่า (ผูกไว้กับพารามิเตอร์บูล nullable) ฉันไม่ได้ลอง แต่ฉันหวังว่านั่นคือสิ่งที่พวกเขาทำ


4
ใช่สิ่งนี้มีประโยชน์ในสถานการณ์ที่คุณมีกริดเพจ ฯลฯ และคุณต้องการยกเลิกการเลือกรายการที่ก่อนหน้านี้ถูกเลือกในวัตถุธุรกิจบางอย่าง
RichardOD

49

คุณควรใช้<label for="checkbox1">Checkbox 1</label>เพราะผู้ใช้สามารถคลิกที่ข้อความป้ายกำกับรวมถึงช่องทำเครื่องหมายได้ด้วยตนเอง นอกจากนี้ยังมีสไตล์ที่ง่ายขึ้นและอย่างน้อยใน IE จะถูกเน้นเมื่อคุณแท็บผ่านการควบคุมของหน้า

<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>

นี่ไม่ใช่แค่ 'โอ้ฉันสามารถทำมันได้' มันเป็นการปรับปรุงประสบการณ์ผู้ใช้ที่สำคัญ แม้ว่าผู้ใช้บางคนจะไม่ทราบว่าพวกเขาสามารถคลิกที่ป้ายกำกับได้หลายคน


27

ฉันประหลาดใจที่คำตอบเหล่านี้ไม่ได้ใช้คุณสมบัติ MVC ที่สร้างขึ้นสำหรับสิ่งนี้

ฉันเขียนโพสต์บล็อกเกี่ยวกับสิ่งนี้ที่นี่ซึ่งแม้แต่ลิงค์ป้ายกำกับกับช่องทำเครื่องหมาย ฉันใช้โฟลเดอร์EditorTemplateเพื่อทำสิ่งนี้ด้วยวิธีที่สะอาดและเป็นโมดูล

คุณจะพบไฟล์ใหม่ในโฟลเดอร์ EditorTemplate ที่มีลักษณะดังนี้:

@model SampleObject

@Html.CheckBoxFor(m => m.IsChecked)
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(m => m.IsChecked, Model.Id)

ในมุมมองที่แท้จริงของคุณไม่จำเป็นต้องวนซ้ำสิ่งนี้เพียงแค่โค้ด 1 บรรทัด:

@Html.EditorFor(x => ViewData.Model)

เยี่ยมชมบล็อกโพสต์ของฉันสำหรับรายละเอียดเพิ่มเติม


1
ขอบคุณ! Everboyd ยังคงใช้รูปแบบเก่า ๆ และเมื่อคุณส่งคุณสามารถเข้าถึงโมเดลโดยไม่มีคอลเลกชันนี้ [] และ request.form ขยะ - นี่คือสิ่งที่ฉันกำลังมองหา +1และ + เบียร์
Piotr Kula

2
นี่ควรเป็นคำตอบที่ดีที่สุดสำหรับคำถาม ง่ายมากและใช้งานง่าย
Johan Gunawan

ต้องดิ้นรนหาเวลาหาคำตอบที่สง่างามก่อนที่ฉันจะพบคำตอบนี้ มันมีอายุไม่กี่ปี แต่ก็ยังคงใช้ได้อย่างสมบูรณ์ในปี 2559! หากใช้ในหลายกรณีให้ใช้ SelectListItem ในตัวเป็นประเภททั่วไปซึ่งเหมาะอย่างยิ่งกับเรื่องนี้
Phil

SampleObject เป็นรายการหรือไม่ เช่น @ModelType List (Of Type)
JoshYates1980

25

นี่คือสิ่งที่ฉันได้ทำ

ดู:


<input type="checkbox" name="applyChanges" />

ควบคุม:


var checkBox = Request.Form["applyChanges"];

if (checkBox == "on")
{
...
}

ฉันพบวิธีการของ Html. * helper ที่ไม่ค่อยมีประโยชน์ในบางกรณีและฉันก็ทำได้ดีกว่าด้วย HTML แบบเก่า นี่เป็นหนึ่งในนั้นอีกอันที่นึกถึงคือปุ่มตัวเลือก

แก้ไข: นี่เป็นตัวอย่าง 5 ซึ่งเห็นได้ชัดว่า YMMV ระหว่างเวอร์ชัน


1
ฉันแค่ต้องการเพิ่มตัวอย่างอื่น: Object.Property =! String.IsNullOrEmpty (Request.Form ["NAME"]);
Gup3rSuR4c

หากไม่ถูกตรวจสอบก็จะไปยกเว้น
Xulfee

10

ดูเหมือนว่าพวกเขากำลังเลือกที่จะอ่านค่าแรกเท่านั้นดังนั้นนี่คือ "true" เมื่อมีการทำเครื่องหมายในช่องทำเครื่องหมายและ "false" เมื่อรวมเฉพาะค่าที่ซ่อนอยู่ รหัสนี้ดึงได้ง่ายเช่นนี้:

model.Property = collection["ElementId"].ToLower().StartsWith("true");

8

@Dylan Beattie ผู้ยิ่งใหญ่ค้นหา !!! ฉันขอบคุณมาก เพื่อขยายให้กว้างยิ่งขึ้นเทคนิคนี้ยังใช้งานได้อย่างสมบูรณ์แบบด้วยวิธีการดูโมเดล MVC เจ๋งมากมันฉลาดพอที่จะผูกอาเรย์ของ Guids เข้ากับทรัพย์สินด้วยชื่อเดียวกันของวัตถุ Model ที่ผูกติดกับ View ตัวอย่าง:

ViewModel:

public class SampleViewModel
{
    public IList<SampleObject> SampleObjectList { get; set; }
    public Guid[] SelectedObjectIds { get; set; }

    public class SampleObject
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
}

ดู:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
    <thead> 
        <tr>
            <th>Checked</th>
            <th>Object Name</th>
        </tr>
    </thead> 
<% using (Html.BeginForm()) %>
<%{%>                    
    <tbody>
        <% foreach (var item in Model.SampleObjectList)
           { %>
            <tr>
                <td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
                <td><%= Html.Encode(item.Name)%></td>
            </tr>
        <% } %>
    </tbody>
</table>
<input type="submit" value="Submit" />
<%}%>                    

ควบคุม:

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult SampleView(Guid id)
    {
        //Object to pass any input objects to the View Model Builder 
        BuilderIO viewModelBuilderInput = new BuilderIO();

        //The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
        SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);

        return View("SampleView", viewModel);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SampleView(SampleViewModel viewModel)
    {
        // The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
        return View();
    }

ใครก็ตามที่คุ้นเคยกับปรัชญาของ View Model จะเปรมปรีดิ์การทำงานเช่นนี้!


ขอบคุณ SampleViewModel ของคุณช่วยลดความสับสนในคำตอบเดิม
รัฐสภา

6

ฉันต้องการจะชี้ให้เห็นว่าคุณสามารถตั้งชื่อช่องทำเครื่องหมายแต่ละชื่อด้วยชื่ออื่นและมีชื่อส่วนนั้นของพารามิเตอร์ actionresults

ตัวอย่าง,

ดู:

 <%= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232

 <%= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422

ควบคุม:

public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
    ...
}

ค่าจากมุมมองถูกส่งผ่านไปยังแอ็คชันเนื่องจากชื่อเหมือนกัน

ฉันรู้ว่าวิธีนี้ไม่เหมาะกับโครงการของคุณ แต่ฉันคิดว่าฉันจะทิ้งความคิดนั้นไป


5
<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>

จากตัวควบคุม:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection fc)
    {

         var s = fc["checkbox1"];

         if (s == "on")
         {
             string x = "Hi";
         }
    }

4

ปัญหานี้เกิดขึ้นในรุ่น 1.0 เช่นกัน Html.Checkbox () ทำให้มีการเพิ่มฟิลด์อื่นที่ซ่อนอยู่ด้วยชื่อ / รหัสเดียวกันกับช่องทำเครื่องหมายเดิมของคุณ และขณะที่ฉันพยายามโหลดอาร์เรย์ช่องทำเครื่องหมายโดยใช้ document.GetElemtentsByName () คุณสามารถเดาได้ว่าสิ่งต่าง ๆ เกิดความสับสน มันแปลกประหลาด


4

จากสิ่งที่ฉันสามารถรวบรวมได้แบบจำลองไม่ต้องการที่จะคาดเดาว่า checked = true หรือ false ฉันได้รับสิ่งนี้โดยการตั้งค่าแอตทริบิวต์ในองค์ประกอบช่องทำเครื่องหมายด้วย jQuery ก่อนส่งแบบฟอร์มดังนี้:

 $('input[type="checkbox"]').each(function () {
       $(this).attr('value', $(this).is(':checked'));
 }); 

ด้วยวิธีนี้คุณไม่จำเป็นต้องมีองค์ประกอบที่ซ่อนอยู่เพียงเพื่อเก็บค่าของช่องทำเครื่องหมาย


4

ฉันรู้ว่าคำถามนี้ถูกเขียนขึ้นเมื่อ MVC3 ไม่ได้ออกมา แต่สำหรับทุกคนที่มาที่คำถามนี้และกำลังใช้ MVC3 คุณอาจต้องการวิธีที่ "ถูกต้อง" ในการทำเช่นนี้

ในขณะที่ฉันคิดว่าทำทั้งหมด

Contains("true");

เป็นสิ่งที่ดีและสะอาดและทำงานได้กับ MVC ทุกรุ่นปัญหาคือว่ามันไม่ได้คำนึงถึงวัฒนธรรม (เช่นถ้ามันสำคัญในกรณีของบูล)

วิธี "ถูกต้อง" เพื่อหาค่าของบูลอย่างน้อยใน MVC3 คือการใช้ ValueProvider

var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));

ฉันทำสิ่งนี้ในเว็บไซต์ของลูกค้าเมื่อฉันแก้ไขการอนุญาต:

var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();

foreach (var key in allPermissionsBase)
{
     // Try to parse the key as int
     int keyAsInt;
     int.TryParse(key.Replace("permission_", ""), out keyAsInt);

     // Try to get the value as bool
     var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}

ทีนี้ความสวยงามของสิ่งนี้คือคุณสามารถใช้มันกับอะไรก็ได้ที่เรียบง่ายและมันก็จะถูกต้องตามวัฒนธรรม (คิดเงินเงินทศนิยม ฯลฯ )

ValueProvider คือสิ่งที่ใช้เมื่อคุณสร้างแบบฟอร์มการดำเนินการเช่นนี้:

public ActionResult UpdatePermissions(bool permission_1, bool permission_2)

แต่เมื่อคุณพยายามสร้างรายการเหล่านี้แบบไดนามิกและตรวจสอบค่าคุณจะไม่มีวันรู้รหัส ณ เวลารวบรวมดังนั้นคุณต้องดำเนินการทันที


มีเหตุผลที่คุณใช้ Request.Params แทนการเพิ่มพารามิเตอร์ FormCollection ให้กับวิธีการหรือไม่
SwissCoder

ไม่มีเหตุผลฉันไม่เห็นประโยชน์ใด ๆ กับอีกทางหนึ่ง
Dan VanWinkle

1
ขออภัยมีเหตุผลจริงๆ เพิ่งดูรหัสของฉันและฉันใช้วิธีนี้สำหรับการโทรที่แตกต่างกัน 5 ครั้งและฉันไม่รู้สึกอยากผ่าน FormCollection จากแต่ละวิธี นี่เป็นวิธีที่ง่ายที่สุดในการรับกุญแจโดยไม่จำเป็นต้องผ่านสิ่งใด ๆ
Dan VanWinkle

ใช่ฉันใหม่กับ MVC และฉันอ่านบางที่ดีกว่าโดยทั่วไปในการใช้ FormCollection แทนที่จะเป็น Request.Params เหมือนกับการใช้แบบจำลองที่พิมพ์แทน FormCollection (ดังนั้นจริงๆแล้วมันจะเป็นการดีที่สุดที่จะใช้แบบจำลอง ฉันสังเกตเห็นสิ่งอื่น ๆ ของรหัสไม่ได้ใช้เช่นตัวแปร allPermissions และ keyAsInt ขอบคุณสำหรับคำตอบ.
SwissCoder

3

วิธีที่ง่ายที่สุดที่จะทำคือ ...

คุณตั้งชื่อและค่า

<input type="checkbox" name="selectedProducts" value="@item.ProductId" />@item.Name

จากนั้นในการส่งคว้าค่าของช่องทำเครื่องหมายและบันทึกในอาร์เรย์ int จากนั้นฟังก์ชั่น LinQ ที่เหมาะสม แค่นั้นแหละ..

[HttpPost]
        public ActionResult Checkbox(int[] selectedObjects)
        {
            var selected = from x in selectedObjects
                           from y in db
                           where y.ObjectId == x
                           select y;                   

            return View(selected);
        }

3

เช่นเดียวกับคำตอบของ nautic20 เพียงใช้รายการกล่องกาเครื่องหมายการผูกแบบเริ่มต้น MVC ที่มีชื่อเดียวกับคุณสมบัติการรวบรวมของสตริง / int / enum ใน ViewModel อย่างนั้นแหละ.

แต่ประเด็นหนึ่งจำเป็นต้องชี้ให้เห็น ในแต่ละองค์ประกอบของช่องทำเครื่องหมายคุณไม่ควรใส่ "Id" ลงไปซึ่งจะส่งผลต่อการผูกมัดแบบจำลอง MVC

รหัสต่อไปนี้จะใช้สำหรับการรวมโมเดล:

 <% foreach (var item in Model.SampleObjectList)
       { %>
        <tr>
            <td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
            <td><%= Html.Encode(item.Name)%></td>
        </tr>
 <% } %>

รหัสต่อไปนี้จะไม่ผูกพันกับรูปแบบ (ความแตกต่างที่นี่เป็นรหัสที่ได้รับมอบหมายสำหรับแต่ละช่องทำเครื่องหมาย)

<% foreach (var item in Model.SampleObjectList)
       { %>
        <tr>
            <td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
            <td><%= Html.Encode(item.Name)%></td>
        </tr>
<% } %>

ขอบคุณสำหรับการตอบรับ แต่คำถามนี้juuuustบิตเก่า อายุหกขวบประมาณ คุณอาจต้องการแก้ไขและระบุ MVC เวอร์ชันที่คุณใช้ ที่จะช่วยให้ทุกคนที่ใช้รุ่นที่ใหม่กว่าค้นหาคำตอบนี้

ฉันสองที่ การลบ ID ที่ไม่ซ้ำกันสามารถแก้ไขปัญหานี้ได้หลังจากปวดศีรษะและกัดฟันมาก
Ody

รุ่นของ MVC ที่ฉันใช้คือ. net MVC 4.0 สำหรับปัญหานี้
ChinaHelloWorld

2

นี่คือสิ่งที่ฉันทำเพื่อหลวมค่าสองเท่าเมื่อใช้ Html.CheckBox (...

Replace("true,false","true").Split(',')

มีการตรวจสอบ 4 กล่องไม่ถูกตรวจสอบไม่ถูกตรวจสอบตรวจสอบว่ามันเป็นจริงเท็จเท็จเท็จจริงจริงเท็จเป็นจริงเท็จเท็จจริง สิ่งที่ฉันต้องการ


0

แล้วเรื่องแบบนี้ล่ะ?

bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
    ModelState.AddModelError(”chkHuman”, Nice try.”);

0

เมื่อใช้ช่องทำเครื่องหมาย HtmlHelper ฉันชอบทำงานกับข้อมูลในช่องทำเครื่องหมายที่โพสต์เป็นอาร์เรย์ ฉันไม่รู้ว่าทำไมจริง ๆ ฉันรู้ว่าวิธีการอื่น ๆ ใช้งานได้ แต่ฉันคิดว่าฉันชอบที่จะใช้สตริงที่คั่นด้วยเครื่องหมายจุลภาคเป็นอาร์เรย์ให้มากที่สุด

ดังนั้นการทำ 'ตรวจสอบ' หรือการทดสอบจริงจะเป็น:

//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true"); 

ทำการตรวจสอบที่ผิดพลาดจะเป็น:

//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true"); 

ความแตกต่างที่สำคัญคือการใช้GetValuesเช่นนี้ส่งกลับเป็นอาร์เรย์


0

เพียงทำสิ่งนี้กับ$(document).ready:

$('input:hidden').each(function(el) {
    var that = $(this)[0];
    if(that.id.length < 1 ) {

        console.log(that.id);
        that.parentElement.removeChild(that);

    }
});

2
น่าเสียดายที่คุณอาจได้ผลลัพธ์แปลก ๆ ที่ฝั่งเซิร์ฟเวอร์สำหรับผู้ที่ปิด JavaScript (ปลั๊กอิน NoScript, โทรศัพท์มือถือเก่า, Lynx ... )
ArIck

0

ทางออกของฉันคือ

<input type="checkbox"  id="IsNew-checkbox"  checked="checked" />     
<input type="hidden"  id="IsNew" name="IsNew" value="true"  />      
<script language="javascript" type="text/javascript" >     
  $('#IsNew-checkbox').click(function () {    
      if ($('#IsNew-checkbox').is(':checked')) {    
          $('#IsNew').val('true');    
      } else {    
          $('#IsNew').val('false');    
       }    
  });   
</script>  

มากขึ้นคุณสามารถค้นหาได้ที่นี่: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a- ถูกต้องบูล /


คุณไม่จำเป็นต้องใช้ Javascript สำหรับสิ่งนี้ ... var isChecked = formData [key] .Contains ("true");
Jammer

0

ฉันมีปัญหาเกือบเหมือนกัน แต่ค่าตอบแทนของคอนโทรลเลอร์ถูกบล็อกด้วยค่าอื่น ๆ

พบวิธีแก้ไขปัญหาที่เรียบง่าย แต่ดูเหมือนจะค่อนข้างหยาบ

ลองพิมพ์Viewbag.ในตัวควบคุมของคุณและตอนนี้คุณให้ชื่อเหมือนViewbag.Checkbool

ตอนนี้สลับไปที่มุมมองและลองสิ่ง@Viewbag.Checkboolนี้คุณจะได้รับค่าจากตัวควบคุม

พารามิเตอร์ตัวควบคุมของฉันมีลักษณะเช่นนี้:

public ActionResult Anzeigen(int productid = 90, bool islive = true)

และช่องทำเครื่องหมายของฉันจะอัปเดตดังนี้:

<input id="isLive" type="checkbox" checked="@ViewBag.Value" ONCLICK="window.location.href = '/MixCategory/Anzeigen?isLive=' + isLive.checked.toString()" />

0

ใช้ @ mmacaulay ฉันมาด้วยสิ่งนี้เพื่อบูล:

// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");

หากทำเครื่องหมายว่าใช้งานอยู่ = จริง

หากไม่ได้ทำเครื่องหมาย active = false

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.