asp.net-mvcjquery-mobilejquery-mobile-flipswitch

How to use JQuerymobile Flip Switch with strongly typed razor?


I want to use a flip switch for "Remember Me" option in my log in page. When posting the form, RememberMe property of the view model does not get the value from the flip switch.

View Model :

public class LogOnViewModel
{
    private bool _RememberMe;

    /*some other properties here...*/       

    [DisplayName("Remember Me?")]
    public Nullable<bool> RememberMe
    {
        get 
        { 
            return (_RememberMe);
        }
        set
        {
            _RememberMe = (value ?? false);
        }
    }        
}

View:

@model UI.Models.Authenticate.LogOnViewModel
@using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { data_ajax = "false" }))
{
    <div>
        <div data-role="fieldcontain">
            @Html.LabelFor(m => m.LoginUserName)
            @Html.TextBoxFor(m => m.LoginUserName)
        </div>
        <div data-role="fieldcontain">
            @Html.LabelFor(m => m.LoginPass)
            @Html.PasswordFor(m => m.LoginPass)
        </div>

            <select name="RememberMe.Value" id="Model.RememberMe.Value" data-role="slider">
                <option value="false">No</option>
                <option value="true" selected="">Yes</option>
            </select>



        <input type="submit" data-role="button" data-transition="none" value="Log on" />
    </div>

}

after the form post, RememberMe value is always false. How can I bind RememberMe Value to the fip switch properly?


Solution

  • Essentially the flip switch is a dropdown list with "data-role="slider"" html attribute and with just two options. So you can use it the same way as you'd do with DropDownList in MVC Razor to make it strongly typed/bind it to a bool.

    @Html.DropDownListFor(m => m.RememberMe, new List<SelectListItem>(){ new SelectListItem() { Text = "No", Value = "False" }, new SelectListItem() { Text = "Yes", Value = "True" }}, new { data_role = "slider" })
    

    The code above will bind it to RememberMe. It will support for selection (if you forexample pass the model with RememberMe as true will it select Yes). You can use this method/way of doing it with other JQuery mobile components too, just add the @data_role at the end with the proper value.

    You might notice data-notice is written with underscore. Normal dash won't compile but it gets generated as a dash in the html. You might want to create your own Html helper for simpler reuse. Create this class in your MVC project. Keeping the namespace will make you able nto use it with the @Html util (source: Html helper for boolean values in asp.net mvc)

    namespace System.Web.Mvc.Html
    {
        public static class JqueryMobileExtension
        {
            public static MvcHtmlString FlipSwitchFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
            {
                ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
                bool value = (bool)(metadata.Model ?? false);
    
                List<SelectListItem> items =
                    new List<SelectListItem>()
                        {
    
                            new SelectListItem() { Text = "No", Value = "False", Selected = (!value) },
                            new SelectListItem() { Text = "Yes", Value = "True", Selected = (value) }
                        };
    
                return htmlHelper.DropDownListFor(expression, items, new { @data_role = "slider" });
            }
        }
    }
    

    And you can use it like this:

    @Html.FlipSwitchFor(m => m.RememberMe)