Шаблон логического редактора MVC3 с несколькими элементами управления для одного и того же свойства

Я использую С#, MVC3, Razor и Zurb Foundation 4.

У меня есть собственный шаблон редактора для логических значений, который будет отображать разные пользовательские интерфейсы для разных устройств ввода. (видимость контролируется классами CSS hide-for/show-for)

Проблема в том, что поскольку все эти элементы пользовательского интерфейса всегда находятся на странице, только значения в первом из них будут привязаны к модели при обратной отправке.

Поэтому мне нужно либо найти способ фактического удаления HTML для скрытых div, либо найти способ использовать истинное значение любого из трех элементов (все они по умолчанию имеют значение false, поэтому тот, который установлен в true, будет видимым)

Это мой Boolean.cshtml:

@model bool

@using System.Web.UI.WebControls
@using Helpers

<div class="hide-for-small">
    <div class="hide-for-touch">
        <div class="editor-field">
            @Html.CheckBoxFor(model => model)
        </div>
    </div>
</div>
<div class="show-for-small">
    <div class="hide-for-touch">
        <div class="editor-field">
            @{
                List<BoolString> ynb = new List<BoolString>();
                ynb.Add(new BoolString(false, "No"));
                ynb.Add(new BoolString(true, "Yes"));
            }
            @Html.DropDownListFor(model => model, new SelectList(ynb, "Value", "Description"))
        </div>
    </div>
</div>
<div class="show-for-touch">
    <div class="switch round">
        <input id='@ViewData.TemplateInfo.HtmlFieldPrefix + ".Off"' name='@ViewData.TemplateInfo.HtmlFieldPrefix' type='radio' checked />
        <label for='@ViewData.TemplateInfo.HtmlFieldPrefix + ".Off"' onclick=''>Off</label>

        <input id='@ViewData.TemplateInfo.HtmlFieldPrefix + ".On"' name='@ViewData.TemplateInfo.HtmlFieldPrefix' type='radio' />
        <label for='@ViewData.TemplateInfo.HtmlFieldPrefix + ".On"' onclick=''>On</label>
    </div>
</div>

В настоящее время флажок работает нормально, а раскрывающийся список - нет. (Я всегда получаю false для свойства моей модели к тому времени, когда я возвращаюсь к контроллеру). Если я перемещаю раскрывающийся список перед флажком, раскрывающийся список работает, а флажок - нет.

Обратите внимание, что я еще не уверен насчет сенсорного элемента, поэтому он все равно может быть неправильным. Я не беспокоюсь о том, чтобы заставить это работать, пока я не разобрался с этой проблемой.


person Steve    schedule 07.06.2013    source источник


Ответы (1)


Я придумал подход грубой силы, синхронизирующий каждый из входных данных с использованием javascript и jquery. Пожалуйста, напишите, если вы найдете лучший способ

ИСПЫТАТЕЛЬНАЯ ФОРМА

@using BooleanEditorTemplate.Controllers
@model bool

@{ var modelname = "mmm"; }

@using(Html.BeginForm("Index","Home")){
<div class="hide-for-small">
    <div class="hide-for-touch">
        <div class="editor-field">
            @Html.CheckBox(modelname, Model)
        </div>
    </div>
</div>
<div class="show-for-small">
    <div class="hide-for-touch">
        <div class="editor-field">
            @{
                List<BoolString> ynb = new List<BoolString>();
                ynb.Add(new BoolString(false, "No"));
                ynb.Add(new BoolString(true, "Yes"));
            }
            @Html.DropDownList(modelname, new SelectList(ynb, "Value", "Description"))
        </div>
    </div>
</div>
<div class="show-for-touch">
    <div class="switch round">
        <input id='@modelname' name='@modelname' type='radio' checked  value="on"/>
        <label for='@modelname' onclick=''>Off</label>

        <input id='@modelname' name='@modelname' type='radio' value="off"/>
        <label for='@modelname' onclick=''>On</label>
    </div>
</div>
<input type="submit" value="OK"/>
}

СЦЕНАРИЙ ТЕСТА

<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script>
    $(function () {

        $('[name="@modelname"]').change(
            function () {


                var id = $(this).attr("id");
                var name = $(this).attr("name");                
                var checked = false;
                switch (this.type)
                {
                    case 'checkbox':
                        checked = $(this).is(":checked");
                        break;
                    case 'select-one':
                        checked = $(this).val().toUpperCase() == 'TRUE';
                        break;
                    case 'radio':
                        checked = $('input[type="radio"][name=' + name + ']:checked').val().toUpperCase() === 'ON';
                        break;
                }

                //checkbox
                $('input[type="checkbox"][name="' + name + '"]').prop('checked', checked);

                //select the select-one
                if (checked)
                    $('select[name="' + name + '"]').val('True');
                else
                    $('select[name="' + name + '"]').val('False');

                //select the proper radio
                if (checked)
                    $('input[type="radio"][name='+ name +'][value="on"]').prop("checked", true);
                else
                    $('input[type="radio"][name=' + name + '][value="off"]').prop("checked", true);

            });
    });
</script>

и моя настройка тестового контроллера/классов

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View("Index",true);
    }

    [HttpPost]
    public ActionResult Index(Boolean mmm)
    {
       return null;
    } 
}

public class BoolString
{
    public bool Value { get; set; }
    public string Description { get; set; }
    public BoolString(bool val, string desc)
    {
        this.Value = val;
        this.Description = desc;
    }
}

Так что это работает на моей коробке. Мне пришлось внести несколько изменений, так как я не проверял это в рамках редактора. Несомненно, вам придется сделать еще несколько, чтобы адаптировать его обратно в рамках вашей структуры.

person monkeyhouse    schedule 09.06.2013
comment
Как говорится, пришлось внести некоторые коррективы. Хорошая идея, хотя, и теперь все работает. - person Steve; 10.06.2013