public static string RenderFormGroupRadioButton(HtmlHelper html, RadioButtonModel inputModel, LabelModel labelModel)
        {
            string validationMessage = "";
            string radioType = "form-icon";

            if (inputModel.displayValidationMessage)
            {
                string validation = html.ValidationMessage(inputModel.htmlFieldName).ToHtmlString();
                validationMessage = new HelpText(validation, inputModel.validationMessageStyle).ToHtmlString();
            }

            if (labelModel == null && inputModel.RadioType != InputRadioCheckBoxType._NotSet)
                radioType = inputModel.RadioType.ToName();

            var label = RenderControl.RenderLabel(html, labelModel ?? new LabelModel
            {
                htmlFieldName = inputModel.htmlFieldName,
                metadata = inputModel.metadata,
                innerInputType = InputType.Radio,
                innerInputModel = inputModel,
                innerValidationMessage = validationMessage,
                htmlAttributes = new { @class= $"form-radio {radioType} form-text" }.ToDictionary()
            });

            bool fieldIsValid = true;

            if (inputModel != null)
                fieldIsValid = html.ViewData.ModelState.IsValidField(inputModel.htmlFieldName);

            return new FormGroup(null, label, FormGroupType.CheckBoxLike, fieldIsValid).ToHtmlString();
        }
        public static HtmlString RenderCheckBox(HtmlHelper html, CheckBoxModel model)
        {
            model.htmlAttributes.MergeHtmlAttributes(html.GetUnobtrusiveValidationAttributes(model.htmlFieldName, model.metadata));

            var mergedHtmlAttrs = string.IsNullOrEmpty(model.id) ? model.htmlAttributes : model.htmlAttributes.AddOrReplace("id", model.id);

            string validationMessage = "";

            if (model.displayValidationMessage)
            {
                string validation = html.ValidationMessage(model.htmlFieldName).ToHtmlString();
                validationMessage = new HelpText(validation, model.validationMessageStyle).ToHtmlString();
            }

            return new HtmlString(html.CheckBox(model.htmlFieldName, model.isChecked, mergedHtmlAttrs.FormatHtmlAttributes()).ToHtmlString() + validationMessage);
        }
        public static HtmlString RenderTextArea(HtmlHelper html, TextAreaModel model)
        {
            string validationMessage = "";

            if (model.displayValidationMessage)
            {
                string validation = html.ValidationMessage(model.htmlFieldName).ToHtmlString();
                validationMessage = new HelpText(validation, model.validationMessageStyle).ToHtmlString();
            }

            model.htmlAttributes.MergeHtmlAttributes(html.GetUnobtrusiveValidationAttributes(model.htmlFieldName, model.metadata));

            if (!string.IsNullOrEmpty(model.id))
                model.htmlAttributes.AddOrReplace("id", model.id);

            if (!string.IsNullOrEmpty(model.placeholder))
                model.htmlAttributes.Add("placeholder", model.placeholder);

            model.htmlAttributes.AddOrMergeCssClass("class", "form-control");

            string htmlTextArea = html.TextArea(model.htmlFieldName, model.value, model.rows, model.columns, model.htmlAttributes.FormatHtmlAttributes()).ToHtmlString() + validationMessage;

            TagBuilder inputWrapper = null;

            if (!string.IsNullOrEmpty(model.inputElementWrapper))
            {
                inputWrapper = new TagBuilder(model.inputElementWrapper);

                if (model.inputElementWrapperAttributes != null)
                    inputWrapper.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(model.inputElementWrapperAttributes));

                inputWrapper.InnerHtml = htmlTextArea;
            }

            string htmlString = inputWrapper != null
                ? inputWrapper.ToString(TagRenderMode.Normal)
                : htmlTextArea;

            return new HtmlString(htmlString);
        }
        public static HtmlString RenderDatePicker(HtmlHelper html, DatePickerModel model)
        {
            var combinedHtml = "{0}{1}{2}";
            var addOn = new TagBuilder("span");
            var container = new TagBuilder("div");
            var addOnPrependString = "";
            var addOnPrependIcon = "";
            var addOnAppendIcon = "";

            var htmlAttributes = new
            {
                @type = "text"
            }.ObjectToHtmlAttributesDictionary();

            model.htmlAttributes.MergeHtmlAttributes(html.GetUnobtrusiveValidationAttributes(model.htmlFieldName, model.metadata));

            if (!string.IsNullOrEmpty(model.id))
                model.htmlAttributes.Add("id", model.id);

            if (!string.IsNullOrEmpty(model.placeholder))
                model.htmlAttributes.Add("placeholder", model.placeholder);

            if (model.size != Size._NotSet)
                model.htmlAttributes.AddOrMergeCssClass("class", $"input-{model.size.ToName()}");

            model.htmlAttributes.AddOrMergeCssClass("class", "date-picker");
            model.htmlAttributes.AddOrMergeCssClass("class", "form-control");

            if (!string.IsNullOrEmpty(model.dateFormat))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.dateFormat), model.dateFormat);

            if (model.weekStart != 0)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.weekStart), model.weekStart.ToString());

            if(model.autoclose)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.autoclose), model.autoclose.ToString().ToLower());

            if(model.calendarWeeks)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.calendarWeeks), model.calendarWeeks.ToString().ToLower());

            if(model.clearBtn)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.clearBtn), model.clearBtn.ToString().ToLower());

            if(!string.IsNullOrEmpty(model.container))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.container), model.container);

            if(model.datesDisabled.Any())
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.datesDisabled), new JavaScriptSerializer().Serialize(model.datesDisabled));

            if(model.daysOfWeekDisabled.Any())
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.daysOfWeekDisabled), new JavaScriptSerializer().Serialize(model.daysOfWeekDisabled));

            if (model.daysOfWeekHighlighted.Any())
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.daysOfWeekHighlighted), new JavaScriptSerializer().Serialize(model.daysOfWeekHighlighted));

            if (!string.IsNullOrEmpty(model.defaultViewDate))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.defaultViewDate), model.defaultViewDate);

            if(model.disableTouchKeyboard)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.disableTouchKeyboard), model.disableTouchKeyboard.ToString().ToLower());

            if(!model.enableOnReadonly)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.enableOnReadonly), model.enableOnReadonly.ToString().ToLower());

            if (model.endDate != null)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.endDate), model.endDate.ToString());

            if(!model.forceParse)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.forceParse), model.forceParse.ToString().ToLower());

            if(model.immediateUpdates)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.immediateUpdates), model.immediateUpdates.ToString().ToLower());

            if (!model.keyboardNavigation)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.keyboardNavigation), model.keyboardNavigation.ToString().ToLower());

            if(!string.IsNullOrEmpty(model.language))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.language), model.language);

            if(model.multidate)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.multidate), model.multidate.ToString().ToLower());

            if(!string.IsNullOrEmpty(model.multidateSeparator))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.multidateSeparator), model.multidateSeparator);

            if(!string.IsNullOrEmpty(model.orientation))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.orientation), model.orientation);

            if(!model.showOnFocus)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.showOnFocus), model.showOnFocus.ToString().ToLower());

            if(model.startDate != null)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.startDate), model.startDate.ToString());

            if(model.startView != 0)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.startView), model.startView.ToString());

            if(!string.IsNullOrEmpty(model.title))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.title), model.title);

            if(!string.IsNullOrEmpty(model.todayBtn))
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.todayBtn), model.todayBtn);

            if (model.todayHighlight)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.todayHighlight), model.todayHighlight.ToString().ToLower());

            if(model.toggleActive)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.toggleActive), model.toggleActive.ToString().ToLower());

            if(model.zIndexOffset != 10)
                model.htmlAttributes.AddOrReplace(model.HtmlAttr(() => model.zIndexOffset), model.zIndexOffset.ToString());

            htmlAttributes.MergeHtmlAttributes(model.htmlAttributes.FormatHtmlAttributes());

            var input = html.TextBox(model.htmlFieldName, model.value, model.format, htmlAttributes).ToHtmlString();

            container.AddOrMergeCssClass("input-group");
            //container.AddOrMergeCssClass("date-picker");
            addOn.AddCssClass("input-group-addon");

            addOn.InnerHtml = new Icon(Icons.Calendar, Size.Lg).ToHtmlString();
            addOnAppendIcon = addOn.ToString();

            if (!string.IsNullOrEmpty(model.prependString) || model.iconPrepend != Icons._not_set || !string.IsNullOrEmpty(model.iconPrependCustomClass))
            {
                if (!string.IsNullOrEmpty(model.prependString))
                {
                    addOn.InnerHtml = model.prependString;
                    addOnPrependString = addOn.ToString();
                }

                if (model.iconPrepend != Icons._not_set)
                {
                    addOn.InnerHtml = new Icon(model.iconPrepend, model.iconPrependIsWhite).ToHtmlString();
                    addOnPrependIcon = addOn.ToString();
                }

                if (!string.IsNullOrEmpty(model.iconPrependCustomClass))
                {
                    var i = new TagBuilder("i");
                    i.AddCssClass(model.iconPrependCustomClass);
                    addOn.InnerHtml = i.ToString(TagRenderMode.Normal);
                    addOnPrependIcon = addOn.ToString();
                }
            }

            container.InnerHtml = addOnPrependIcon + addOnPrependString + "{0}" + addOnAppendIcon;
            combinedHtml = container.ToString(TagRenderMode.Normal) + "{1}{2}";

            var helpText = model.helpText != null ? model.helpText.ToHtmlString() : string.Empty;
            var validationMessage = "";

            if (model.displayValidationMessage)
            {
                var validation = html.ValidationMessage(model.htmlFieldName).ToHtmlString();
                validationMessage = new HelpText(validation, model.validationMessageStyle).ToHtmlString();
            }

            string htmlTextBox = string.Format(combinedHtml, input, helpText, validationMessage);

            TagBuilder inputWrapper = null;

            if (!string.IsNullOrEmpty(model.inputElementWrapper))
            {
                inputWrapper = new TagBuilder(model.inputElementWrapper);

                if (model.inputElementWrapperAttributes != null)
                    inputWrapper.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(model.inputElementWrapperAttributes));

                inputWrapper.InnerHtml = htmlTextBox;
            }

            string htmlString = inputWrapper != null
                ? inputWrapper.ToString(TagRenderMode.Normal)
                : htmlTextBox;

            return new HtmlString(htmlString);
        }
        public static HtmlString RenderTextBox(HtmlHelper html, TextBoxModel model, bool isPassword)
        {
            var combinedHtml = "{0}{1}{2}";

            model.htmlAttributes.MergeHtmlAttributes(html.GetUnobtrusiveValidationAttributes(model.htmlFieldName, model.metadata));

            if (!string.IsNullOrEmpty(model.id))
                model.htmlAttributes.Add("id", model.id);

            if (!string.IsNullOrEmpty(model.placeholder))
                model.htmlAttributes.Add("placeholder", model.placeholder);

            if(model.size != Size._NotSet)
                model.htmlAttributes.AddOrMergeCssClass("class", $"input-{model.size.ToName()}");

            model.htmlAttributes.AddOrMergeCssClass("class", "form-control");

            var input = isPassword
                ? html.Password(model.htmlFieldName, null, model.htmlAttributes.FormatHtmlAttributes()).ToHtmlString()
                : html.TextBox(model.htmlFieldName, model.value, model.format, model.htmlAttributes.FormatHtmlAttributes()).ToHtmlString();

            // account for appendString, prependString, and AppendButtons
            if (!string.IsNullOrEmpty(model.prependString) || !string.IsNullOrEmpty(model.appendString) || model.iconPrepend != Icons._not_set
                || model.iconAppend != Icons._not_set || !string.IsNullOrEmpty(model.iconPrependCustomClass) || !string.IsNullOrEmpty(model.iconAppendCustomClass))
            {
                var appendPrependContainer = new TagBuilder("div");
                appendPrependContainer.AddOrMergeCssClass("input-group");
                appendPrependContainer.AddOrMergeCssClass("mar-btm");

                var addOnPrependString = "";
                var addOnAppendString = "";
                var addOnPrependIcon = "";
                var addOnAppendIcon = "";

                var addOn = new TagBuilder("span");
                addOn.AddCssClass("input-group-addon");

                if (!string.IsNullOrEmpty(model.prependString))
                {
                    addOn.InnerHtml = model.prependString;
                    addOnPrependString = addOn.ToString();
                }

                if (!string.IsNullOrEmpty(model.appendString))
                {
                    addOn.InnerHtml = model.appendString;
                    addOnAppendString = addOn.ToString();
                }

                if (model.iconPrepend != Icons._not_set)
                {
                    addOn.InnerHtml = new Icon(model.iconPrepend, model.iconPrependIsWhite).ToHtmlString();
                    addOnPrependIcon = addOn.ToString();
                }

                if (model.iconAppend != Icons._not_set)
                {
                    addOn.InnerHtml = new Icon(model.iconAppend, model.iconAppendIsWhite).ToHtmlString();
                    addOnAppendIcon = addOn.ToString();
                }

                if (!string.IsNullOrEmpty(model.iconPrependCustomClass))
                {
                    var i = new TagBuilder("i");
                    i.AddCssClass(model.iconPrependCustomClass);
                    addOn.InnerHtml = i.ToString(TagRenderMode.Normal);
                    addOnPrependIcon = addOn.ToString();
                }

                if (!string.IsNullOrEmpty(model.iconAppendCustomClass))
                {
                    var i = new TagBuilder("i");
                    i.AddCssClass(model.iconAppendCustomClass);
                    addOn.InnerHtml = i.ToString(TagRenderMode.Normal);
                    addOnAppendIcon = addOn.ToString();
                }

                appendPrependContainer.InnerHtml = addOnPrependIcon + addOnPrependString + "{0}" + addOnAppendString + addOnAppendIcon;
                combinedHtml = appendPrependContainer.ToString(TagRenderMode.Normal) + "{1}{2}";
            }

            var helpText = model.helpText != null ? model.helpText.ToHtmlString() : string.Empty;
            var validationMessage = "";

            if (model.displayValidationMessage)
            {
                var validation = html.ValidationMessage(model.htmlFieldName).ToHtmlString();
                validationMessage = new HelpText(validation, model.validationMessageStyle).ToHtmlString();
            }

            string htmlTextBox = string.Format(combinedHtml, input, helpText, validationMessage);

            TagBuilder inputWrapper = null;

            if (!string.IsNullOrEmpty(model.inputElementWrapper))
            {
                inputWrapper = new TagBuilder(model.inputElementWrapper);

                if (model.inputElementWrapperAttributes != null)
                    inputWrapper.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(model.inputElementWrapperAttributes));

                inputWrapper.InnerHtml = htmlTextBox;
            }

            string htmlString = inputWrapper != null
                ? inputWrapper.ToString(TagRenderMode.Normal)
                : htmlTextBox;

            return new HtmlString(htmlString);
        }
        public static HtmlString RenderSelectElement(HtmlHelper html, SelectElementModel model, InputType inputType)
        {
            string combinedHtml = "{0}{1}{2}";
            string input = string.Empty;

            if (model.selectedValue != null)
            {
                foreach (var item in model.selectList)
                {
                    if (item.Value == model.selectedValue.ToString())
                        item.Selected = true;
                }
            }

            model.htmlAttributes.MergeHtmlAttributes(html.GetUnobtrusiveValidationAttributes(model.htmlFieldName, model.metadata));

            if (!string.IsNullOrEmpty(model.id)) model.htmlAttributes.AddOrReplace("id", model.id);

            if (model.size != Size._NotSet)
                model.htmlAttributes.AddOrMergeCssClass("class", $"input-{model.size.ToName()}");

            model.htmlAttributes.AddOrMergeCssClass("class", "form-control");

            // build html for input

            if (inputType == InputType.DropDownList)
                input = html.DropDownList(model.htmlFieldName, model.selectList, model.optionLabel, model.htmlAttributes.FormatHtmlAttributes()).ToHtmlString();

            if (inputType == InputType.ListBox)
                input = html.ListBox(model.htmlFieldName, model.selectList, model.htmlAttributes.FormatHtmlAttributes()).ToHtmlString();

            // account for appendString, prependString, and AppendButtons

            if (!string.IsNullOrEmpty(model.prependString) || !string.IsNullOrEmpty(model.appendString))
            {
                var appendPrependContainer = new TagBuilder("div");
                var addOn = new TagBuilder("span");

                string addOnPrependString = "";
                string addOnAppendString = "";
                string addOnPrependButtons = "";
                string addOnAppendButtons = "";

                appendPrependContainer.AddOrMergeCssClass("input-group");
                addOn.AddCssClass("input-group-addon");

                if (!string.IsNullOrEmpty(model.prependString))
                {
                    addOn.InnerHtml = model.prependString;
                    addOnPrependString = addOn.ToString();
                }

                if (!string.IsNullOrEmpty(model.appendString))
                {
                    addOn.InnerHtml = model.appendString;
                    addOnAppendString = addOn.ToString();
                }

                appendPrependContainer.InnerHtml = addOnPrependButtons + addOnPrependString + "{0}" + addOnAppendString + addOnAppendButtons;
                combinedHtml = appendPrependContainer.ToString(TagRenderMode.Normal) + "{1}{2}";
            }

            string helpText = model.helpText != null ? model.helpText.ToHtmlString() : string.Empty;
            string validationMessage = "";

            if (model.displayValidationMessage)
            {
                string validation = html.ValidationMessage((string)model.htmlFieldName).ToHtmlString();
                validationMessage = new HelpText(validation, model.validationMessageStyle).ToHtmlString();
            }

            string inputElement = string.Format(combinedHtml, input, helpText, validationMessage);

            TagBuilder inputWrapper = null;

            if (!string.IsNullOrEmpty(model.inputElementWrapper))
            {
                inputWrapper = new TagBuilder(model.inputElementWrapper);

                if (model.inputElementWrapperAttributes != null)
                    inputWrapper.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(model.inputElementWrapperAttributes));

                inputWrapper.InnerHtml = inputElement;
            }

            string htmlString = inputWrapper != null
                ? inputWrapper.ToString(TagRenderMode.Normal)
                : inputElement;

            return new HtmlString(htmlString);
        }