asp.net এমভিসি: কেন এইচটিএমএল.চেকবক্স অতিরিক্ত লুকানো ইনপুট তৈরি করছে


215

আমি কেবল লক্ষ্য করেছি যে Html.CheckBox("foo")একটিটির পরিবর্তে 2 ইনপুট উত্পন্ন করে, কেউ জানেন কেন এমন হয়?

<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" /> 


1
সম্ভাব্য সদৃশ প্রশ্নের মধ্যে এরিকভগের উত্তর চেকবক্স এবং লুকানো ক্ষেত্র উভয়ই জমা দিলে মডেল বাইন্ডার কী করে তাও ব্যাখ্যা করে।
থিওফিলাস

1
আমি এই জিনিসটি ঘৃণা করি এটি আমার jquery সঙ্গে ভর করছিল।
জেরি লিয়াং

2
এমভিসি দ্বারা অদ্ভুত বাস্তবায়ন। উভয় মান প্রেরণ মোটেই বোঝা যায় না। আমি অনুরোধটি পরীক্ষা করেছিলাম rom ["আমারচেকবক্স"] থেকে এবং এর মানটি সত্য, মিথ্যা। ডব্লিউটিএফ। আমাকে ভিউতে নিজেই নিয়ন্ত্রণটি লিখতে হয়েছিল।
নিক মাসাও

এটি যদি সত্যই অনাকাঙ্ক্ষিত হয় তবে এইচটিএমএল.চেকবক্স (...) ব্যবহার করবেন না এবং কেবল একটি চেকবক্সের জন্য এইচটিএমএল ইনপুট করুন
wnbates

উত্তর:


197

যদি চেকবক্সটি নির্বাচিত না হয় তবে ফর্ম ক্ষেত্রটি জমা দেওয়া হবে না। যে কারণে লুকানো ক্ষেত্রে সর্বদা মিথ্যা মান থাকে। যদি আপনি চেকবক্সটি চেক না করে ছেড়ে দেন তবে লুকানো ক্ষেত্র থেকে ফর্মটির এখনও মান থাকবে। এএসপি.এনইটি এমভিসি চেকবক্সের মানগুলি হ্যান্ডেল করে।

আপনি যদি তা নিশ্চিত করতে চান তবে ফর্মটিতে একটি চেকবাক্স এইচটিএমএল.হাইডেড নয়, দিয়ে রাখুন <input type="checkbox" name="MyTestCheckboxValue"></input>। চেকবক্সটি চেক না করে ছেড়ে দিন, ফর্মটি জমা দিন এবং সার্ভারের পাশে পোস্ট করা অনুরোধের মানগুলি দেখুন। আপনি দেখতে পাবেন যে কোনও চেকবক্সের মান নেই। আপনার যদি লুকানো ক্ষেত্র থাকে তবে এটিতে মান MyTestCheckboxValueসহ এন্ট্রি থাকবে false


52
আপনি যদি বাক্সটি চেক না করেন তবে অবশ্যই উত্তরটি মিথ্যা, আইটেমটি ফেরত পাঠানোর দরকার নেই। আমার মতে নির্বোধ নকশা।
মাফিন ম্যান

54
@ দ্য মমফিনম্যান: এটি মূর্খ বিকল্প নয়। আসুন বলুন যে আপনার দৃশ্যের মডেলটির কাছে সম্পত্তি বলা হয়েছে IsActive, যা trueকনস্ট্রাক্টারে শুরু করা হয়েছে। ব্যবহারকারী চেকবক্সটি নির্বাচন মুক্ত করে, তবে যেহেতু মানটি সার্ভারে প্রেরণ করা হয় না, তাই মডেল বাইন্ডার এটি গ্রহণ করে না, এবং সম্পত্তি মান পরিবর্তন করা হয় না। মডেল বাইন্ডার ধরে নেওয়া উচিত নয়, মানটি না পাঠানো হলে এটি মিথ্যাতে সেট করা হয়েছিল, কারণ এই মানটি না পাঠানো আপনার সিদ্ধান্ত হতে পারে।
লুকলেড

21
এটি কোনও ক্ষতিহীন চেকবাক্স দিয়ে শুরু হয় এবং তারপরে আপনি এটি জানার আগে আমাদের দেখার অবস্থা থাকে তবে এটিএসপি.নেট এমভিসিফোর্মে রূপান্তরিত হয়।
মাফিন ম্যান

4
@LukLed আপনার মন্তব্যে দেরি করে উত্তর দিচ্ছে ... আমি মনে করি যে যুক্তিটি ত্রুটিযুক্ত কারণ যদি আপনার ভিউ মডেলটিতে কোনও প্রকারের প্রকারের সম্পত্তি থাকে এবং ফর্মটিতে কোনও ইনপুট না থাকে তবে ডিফল্ট মান 0 হয় কারণ এটি পরিবর্তন করার কোনও মান আসে নি। একই যে কোনও অন্য সম্পত্তি সঙ্গে যায়, একটি স্ট্রিংয়ের জন্য ডিফল্ট মান শূন্য হয়। আপনি যদি কোনও মান না প্রেরণ করেন তবে তা বাতিল। কনস্ট্রাক্টরে কোনও সম্পত্তি সত্য হিসাবে সেট করার উদাহরণে, এটি সত্যই সত্য একটি খারাপ ডিজাইনের সিদ্ধান্ত এবং এটি এখন HTTP জমিতে চেকবক্সগুলি কীভাবে কাজ করে তা প্রকাশ পায়।
মাফিন ম্যান

8
এই ছায়াযুক্ত যুক্তিটি অক্ষম চেকবক্সগুলির জন্য বিরতি দেয় - তারা falseচেক করা হলেও মান পাঠায় এবং তা বিভ্রান্তিকর। অক্ষম চেকবাক্সগুলিতে কোনও মানই প্রেরণ করা উচিত নয়, যদি এএসপি.এনইটি ডিফল্ট এইচটিটিপি আচরণের সাথে সামঞ্জস্য করতে চায়।
জাস্টামার্টিন

31

লুকানো ইনপুট যুক্ত করা রোধ করতে আপনি কোনও সহায়ক লিখতে পারেন:

using System.Web.Mvc;
using System.Web.Mvc.Html;

public static class HelperUI
{
    public static MvcHtmlString CheckBoxSimple(this HtmlHelper htmlHelper, string name, object htmlAttributes)
    {
        string checkBoxWithHidden = htmlHelper.CheckBox(name, htmlAttributes).ToHtmlString().Trim();
        string pureCheckBox = checkBoxWithHidden.Substring(0, checkBoxWithHidden.IndexOf("<input", 1));
        return new MvcHtmlString(pureCheckBox);
    }
}

এটা ব্যবহার করো:

@Html.CheckBoxSimple("foo", new {value = bar.Id})

4
এটি আমাকে কেবল এক মিনিটের জন্য @using Your.Name.Spaceছড়িয়ে দিয়েছে ঠিক তেমন ক্ষেত্রে যদি ... আপনার সহায়ক যদি কোনও নেমস্পেসে থাকে তবে আপনার .cshtml রেজার ভিউ ফাইলের শীর্ষে যুক্ত করতে ভুলবেন না ।
ooXei1sh

3
@ ooXei1sh হয় তা হয়, বা আপনার মতামতাকারীর নাম System.Web.Mvc.Htmlদর্শনে সমস্ত মতামত অ্যাক্সেসযোগ্য রাখার জন্য রাখুন
লূক

1
আপনি যদি এটি কোনও ফর্ম পোস্টব্যাকের জন্য বা ফর্ম মানগুলির সাথে অজ্যাক্সের মাধ্যমে পোস্ট করার জন্য ব্যবহার করতে চান তবে আপনাকে চেকবাক্সের অন্বেষণ ইভেন্টের মাধ্যমে মানটি সত্য বা মিথ্যাতে নির্ধারণ করতে হবে। @ এইচটিএমএল.চেকবক্সসিম্পল (এক্স => মডেল.ফু, নতুন {মান = মডেল Fফু, অনচেঞ্জ = "টগলচেক (এটি)"})। তারপরে জাভাস্ক্রিপ্ট ফাংশনে টগল কমপ্লিটড (এল) {ভের্কড = $ (এল) .আইস (': চেকড'); $ ( '# ফু') Val (চেক করা)। }
8১

12

চেক বক্সটি চেক করে জমা দেওয়া হলে এটি সম্পাদন করুন

if ($('[name="foo"]:checked').length > 0)
    $('[name="foo"]:hidden').val(true);

পড়ুন


8

ম্যানুয়াল পদ্ধতিটি হ'ল:

bool IsDefault = (Request.Form["IsDefault"] != "false");

1
এবং এটি কি আপনাকে চেকবক্সের ধরণের মান এবং গোপন প্রকারের মানের জন্য নিশ্চয়তা দেয়?
ব্রায়ান সুইভিনে

1
এটা অপ্রাসঙ্গিক। যখন চেকবক্সটি চেক করা হয় না, এটি পোস্ট করে না। সুতরাং লুকানো বাক্সে 'মিথ্যা' থাকবে। যদি চেকবাক্সটি 'সত্য, সত্য' এর মানটি ফিরে আসে (আমার মনে হয়), এবং এটি 'মিথ্যা' সমান হয় না।
ভালামাস

16
না, যখন চেকবক্সটি চেক করা হয়, সত্য এবং মিথ্যা উভয়ই পোস্ট করা হয় কারণ চেকবক্স এবং লুকানো ক্ষেত্রগুলি উভয়ই ফেরত পাঠানোর বৈধ নিয়ন্ত্রণ are এমভিসি বাইন্ডার তারপরে পরীক্ষা করে দেখায় যে প্রদত্ত নামভীর জন্য সত্য মানটি বিদ্যমান এবং যদি তাই হয় তবে এটি সত্য মানের পছন্দ করে। পোস্ট করা ডেটা দেখে আপনি এটি পরীক্ষা করতে পারেন। একক নামের বিপরীতে এর সত্য এবং মিথ্যা উভয় মান থাকবে।
জাফরযৌসফি

এটি আমাকে একবার পেয়েছে, আমি পরীক্ষা করছিলাম যে মানটি == সত্য
টেরি কার্নান

8

এটি আলেকজান্ডার ট্রফিমভের সমাধানের দৃ strongly়ভাবে টাইপিত সংস্করণ:

using System.Web.Mvc;
using System.Web.Mvc.Html;

public static class HelperUI
{
    public static MvcHtmlString CheckBoxSimpleFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes)
    {
        string checkBoxWithHidden = htmlHelper.CheckBoxFor(expression, htmlAttributes).ToHtmlString().Trim();
        string pureCheckBox = checkBoxWithHidden.Substring(0, checkBoxWithHidden.IndexOf("<input", 1));
        return new MvcHtmlString(pureCheckBox);
    }
}

4

সমন্বিত ব্যবহার করুন, এটি দুটি সম্ভাব্য পোস্ট মানগুলির সাথে কাজ করবে: "মিথ্যা" বা "সত্য, মিথ্যা"।

bool isChecked = Request.Form["foo"].Contains("true");

1

লুকানো ইনপুট স্টাইলযুক্ত চেকবক্সগুলিতে সমস্যা তৈরি করছিল। তাই আমি চেকবক্সযুক্ত ডিভের বাইরে লুকানো ইনপুট রাখার জন্য একটি এইচটিএমএল সহায়ক সাহায্যকারী এক্সটেনশন তৈরি করেছি।

using System;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace YourNameSpace
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString CustomCheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string labelText)
        {
            //get the data from the model binding
            var fieldName = ExpressionHelper.GetExpressionText(expression);
            var fullBindingName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
            var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);
            var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            var modelValue = metaData.Model;

            //create the checkbox
            TagBuilder checkbox = new TagBuilder("input");
            checkbox.MergeAttribute("type", "checkbox");
            checkbox.MergeAttribute("value", "true"); //the visible checkbox must always have true
            checkbox.MergeAttribute("name", fullBindingName);
            checkbox.MergeAttribute("id", fieldId);

            //is the checkbox checked
            bool isChecked = false;
            if (modelValue != null)
            {
                bool.TryParse(modelValue.ToString(), out isChecked);
            }
            if (isChecked)
            {
                checkbox.MergeAttribute("checked", "checked");
            }

            //add the validation
            checkbox.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(fieldId, metaData));

            //create the outer div
            var outerDiv = new TagBuilder("div");
            outerDiv.AddCssClass("checkbox-container");

            //create the label in the outer div
            var label = new TagBuilder("label");
            label.MergeAttribute("for", fieldId);
            label.AddCssClass("checkbox");

            //render the control
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(outerDiv.ToString(TagRenderMode.StartTag));
            sb.AppendLine(checkbox.ToString(TagRenderMode.SelfClosing));
            sb.AppendLine(label.ToString(TagRenderMode.StartTag));
            sb.AppendLine(labelText); //the label
            sb.AppendLine("<svg width=\"10\" height=\"10\" class=\"icon-check\"><use xlink:href=\"/icons.svg#check\"></use></svg>"); //optional icon
            sb.AppendLine(label.ToString(TagRenderMode.EndTag));
            sb.AppendLine(outerDiv.ToString(TagRenderMode.EndTag));

            //create the extra hidden input needed by MVC outside the div
            TagBuilder hiddenCheckbox = new TagBuilder("input");
            hiddenCheckbox.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
            hiddenCheckbox.MergeAttribute("name", fullBindingName);
            hiddenCheckbox.MergeAttribute("value", "false");
            sb.Append(hiddenCheckbox.ToString(TagRenderMode.SelfClosing));

            //return the custom checkbox
            return MvcHtmlString.Create(sb.ToString());
        }

ফলাফল

<div class="checkbox-container">
    <input checked="checked" id="Model_myCheckBox" name="Model.myCheckBox" type="checkbox" value="true">
    <label class="checkbox" for="Model_myCheckBox">
        The checkbox label
        <svg width="10" height="10" class="icon-check"><use xlink:href="/icons.svg#check"></use></svg>
    </label>
</div>
<input name="Model.myCheckBox" type="hidden" value="false">

0

এটি একটি বাগ না! সার্ভারে ফর্ম পোস্ট করার পরে এটি সর্বদা একটি মান থাকার সম্ভাবনা যুক্ত করে। আপনি যদি jQuery এর সাথে চেকবক্স ইনপুট ক্ষেত্রগুলি নিয়ে কাজ করতে চান তবে প্রপ পদ্ধতিটি ('পরীক্ষিত' সম্পত্তিটিকে প্যারামিটার হিসাবে পাস করুন) ব্যবহার করুন। উদাহরণ:$('#id').prop('checked')


0

আপনি আপনার মডেলটির নির্মাতাকে এরকমভাবে আরম্ভ করার চেষ্টা করতে পারেন:

public MemberFormModel() {
    foo = true;
}

এবং আপনার দৃষ্টিতে:

@html.Checkbox(...)
@html.Hidden(...)

0

আমি যখন একটি ওয়েবগ্রিড পেয়েছিলাম তখন সত্যিই এটির কারণগুলির কারণগুলি পেয়েছি। ওয়েবগ্রিডে বাছাই করা লিঙ্কগুলি দ্বিগুণ আপ ক্যোরিস্ট্রিং বা x = সত্য এবং x = মিথ্যে x = সত্য, মিথ্যাতে পরিণত হবে এবং এর জন্য চেকবাক্সে পার্স ত্রুটি ঘটবে।

আমি ক্লায়েন্টের পাশের লুকানো ক্ষেত্রগুলি মুছতে jQuery ব্যবহার করে শেষ করেছি:

    <script type="text/javascript">
    $(function () {
        // delete extra hidden fields created by checkboxes as the grid links mess this up by doubling the querystring parameters
        $("input[type='hidden'][name='x']").remove();
    });
    </script>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.