private MvcTag TagHelper(HtmlTextWriterTag htmlTag, string name, string errorClass = "invalid", IDictionary <string, object> htmlAttributes = null)
        {
            // tag
            MvcTag tag = new MvcTag(ViewContext, htmlTag);

            // attributes
            if (htmlAttributes != null)
            {
                tag.Builder.MergeAttributes(htmlAttributes);
            }

            // add the name if a form element
            if (new HtmlTextWriterTag[3] {
                HtmlTextWriterTag.Textarea, HtmlTextWriterTag.Input, HtmlTextWriterTag.Select
            }.Contains(htmlTag))
            {
                tag.Builder.Attributes.Add("name", name);
            }

            // model state error check
            if (!string.IsNullOrEmpty(errorClass))
            {
                ModelState state = GetState(ViewContext, name);
                if (state != null && state.Errors.Count > 0)
                {
                    tag.Builder.AddCssClass("invalid");
                }
            }

            // output to writer
            ViewContext.Writer.Write(tag.Builder.ToString(TagRenderMode.StartTag));

            // return tag
            return(tag);
        }
        /// <summary>
        /// Returns date select options dd/mm/yyyy
        /// </summary>
        /// <param name="format"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public MvcHtmlString Date(DateFormat format, string prefix = null)
        {
            DateTime      now          = DateTime.Now;
            StringBuilder options      = new StringBuilder();
            string        optionFormat = "<option value=\"{0}\" {1}>{2}</option>";
            string        selected     = "selected=\"selected\"";
            bool          havePrefix   = !string.IsNullOrEmpty(prefix);

            // container
            using (MvcTag container = new MvcTag(ViewContext, HtmlTextWriterTag.Div))
            {
                container.Builder.Attributes["class"] = "dates";

                // day
                if (format.HasFlag(DateFormat.Day))
                {
                    using (MvcTag day = new MvcTag(ViewContext, HtmlTextWriterTag.Select))
                    {
                        day.Builder.Attributes["name"] = string.Concat(prefix, havePrefix ? "_" : string.Empty, "day");
                        for (var i = 1; i < 32; i++)
                        {
                            options.AppendFormat(optionFormat, i, i == now.Day ? selected : string.Empty, i);
                        }
                        day.Builder.InnerHtml = options.ToString();
                        container.AddChildTag(day);
                        options.Clear();
                    }
                }

                // month
                if (format.HasFlag(DateFormat.Month))
                {
                    using (MvcTag month = new MvcTag(ViewContext, HtmlTextWriterTag.Select))
                    {
                        month.Builder.Attributes["name"] = string.Concat(prefix, havePrefix ? "_" : string.Empty, "month");
                        for (var i = 1; i < 13; i++)
                        {
                            options.AppendFormat(optionFormat, i, i == now.Month ? selected : string.Empty, CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(i));
                        }
                        month.Builder.InnerHtml = options.ToString();
                        container.AddChildTag(month);
                        options.Clear();
                    }
                }

                // year
                if (format.HasFlag(DateFormat.Month))
                {
                    using (MvcTag year = new MvcTag(ViewContext, HtmlTextWriterTag.Select))
                    {
                        year.Builder.Attributes["name"] = string.Concat(prefix, havePrefix ? "_" : string.Empty, "year");
                        int yearStart = now.Year - 100;
                        int yearEnd   = now.Year + 10;
                        for (var i = yearEnd; i > yearStart; i--)
                        {
                            options.AppendFormat(optionFormat, i, i == now.Year ? selected : string.Empty, i);
                        }
                        year.Builder.InnerHtml = options.ToString();
                        container.AddChildTag(year);
                    }
                }

                // return container
                return(new MvcHtmlString(container.Builder.ToString()));
            }
        }