/// <summary> /// Finishes off writing the HTML for the field to the view context writer /// </summary> public void Dispose() { if (_containsSection) { _writer.Write(HelperDefinitions.EndField().ToHtmlString()); } }
/// <summary> /// Render a flow form header. /// </summary> /// <param name="heading">The heading of the form</param> /// <param name="instructions">Any instructions that should be shown at the top of the form</param> /// <param name="logo">A URL to an image to use as a logo for the form</param> /// <param name="logoAlt">The alt text for the logo; required if logo is specified</param> /// <param name="legislation">Legislative text to show with the form</param> /// <param name="copyright">A copyright statement for the form; usually in the form of something like: @Html.CheckBoxFor(m => m.Copyright) @Html.LabelFor(m => m.Copyright, "You will accept!")</param> /// <returns>An IHtmlString object that will render the header</returns> public IHtmlString Header(string heading, IHtmlString instructions = null, string logo = null, string logoAlt = null, IHtmlString legislation = null, IHtmlString copyright = null) { if (!string.IsNullOrEmpty(logo) && string.IsNullOrEmpty(logoAlt)) { throw new ApplicationException("Logo specified for flow form header, but no alt text; please specify alt text."); } return(HelperDefinitions.Header(heading, instructions, logo, logoAlt, legislation, copyright)); }
/// <summary> /// Finishes off writing the HTML for the section to the view context writer /// </summary> public void Dispose() { // Generate the html for the end of the section from the class compiled from the Razor template _writer.Write(HelperDefinitions.EndSection(_omitDl, _nested, HasParent).ToHtmlString()); if (HasParent) { _parentField.Dispose(); } }
public FlowFormField(TextWriter writer, bool containsSection, string labelHtml, string elementHtml, string errorHtml = "", bool isValid = true, IHtmlString hint = null, string tip = null, bool hideTip = true, string hintClass = null, string parentClass = null, bool displayFieldName = true) { _containsSection = containsSection; _writer = writer; var generatedSection = HelperDefinitions.BeginField(containsSection, displayFieldName ? new HtmlString(labelHtml) : null, new HtmlString(elementHtml), new HtmlString(errorHtml), isValid, hint, tip, hideTip, hintClass, parentClass); _writer.Write(generatedSection.ToHtmlString()); }
public FlowFormMessage(TextWriter writer, MessageType messageType, string heading, IHtmlString message = null) { _writer = writer; _writer.Write(HelperDefinitions.BeginMessage(messageType.ToDescription(), heading).ToHtmlString()); if (message != null) { _writer.Write(message.ToHtmlString()); _writer.Write(HelperDefinitions.EndMessage().ToHtmlString()); } }
public FlowFormSection(HtmlHelper <TModel> htmlHelper, bool nested, string heading, string id = null, IHtmlString hint = null, string hintClass = null, bool optional = false, IHtmlString instructions = null, bool omitDl = false, FlowFormField parentField = null) { // Starts a section in a flow form // The instance variables allow the form to maintain state for child sections and fields // and to allow the writer to accumulate the output for the section _htmlHelper = htmlHelper; _nested = nested; _omitDl = omitDl; _parentField = parentField; _writer = htmlHelper.ViewContext.Writer; // Generate the html for the beginning of the section from the class compiled from the Razor template var generatedSection = HelperDefinitions.BeginSection(nested, heading, id, hint, hintClass, optional, instructions, omitDl, HasParent); _writer.Write(generatedSection.ToHtmlString()); }
private bool GetErrors <TProperty>(Expression <Func <TModel, TProperty> > expression, out string errorHtml) { var state = GetModelState(expression); errorHtml = ""; var isValid = true; if (state != null && state.Errors.Count > 0) { var s = new StringBuilder(); state.Errors.ForEach(error => s.Append(" " + (error.ErrorMessage.Trim().EndsWith(".") ? error.ErrorMessage.Trim() : error.ErrorMessage.Trim() + "."))); errorHtml = HelperDefinitions.ErrorHtml(s.ToString().Trim()).ToHtmlString(); isValid = false; } return(isValid); }
public FlowFormField RadioFor(Expression <Func <TModel, bool?> > expression, string falseLabel = "No", string trueLabel = "Yes", FieldConfiguration fieldConfiguration = null) { fieldConfiguration = fieldConfiguration ?? new FieldConfiguration(); if (fieldConfiguration.As != null & fieldConfiguration.As != ElementType.RadioButtons) { throw new ApplicationException(string.Format("FieldConfiguration{{ As = {0} }} not valid for field: {1} (which defaults to RadioButton)." , fieldConfiguration.As.Value, expression)); } // var metadata = ModelMetadata.FromLambdaExpression(expression, _htmlHelper.ViewData); var value = expression.Compile().Invoke(_htmlHelper.ViewData.Model); var elementHtml = HelperDefinitions.BooleanRadioNullable(expression.GetFieldName(), value, falseLabel, trueLabel).ToString(); elementHtml = (fieldConfiguration.Before ?? "") + elementHtml + (fieldConfiguration.After ?? ""); return(new FlowFormField(_writer, false, LabelHtml(expression, fieldConfiguration), elementHtml, null, true, fieldConfiguration.Hint, fieldConfiguration.Tip, fieldConfiguration.HideTip, fieldConfiguration.HintClass, fieldConfiguration.ParentClass, fieldConfiguration.DisplayFieldName)); }
/// <summary> /// Outputs the rest of the navigation area. /// </summary> public void Dispose() { _writer.Write(HelperDefinitions.EndNavigation().ToHtmlString()); }
/// <summary> /// Returns an IHtmlString object that will output a HTML reset button. /// </summary> /// <param name="value">The string message to show on the button</param> /// <param name="id">The id of the button</param> /// <param name="name">The name of the button</param> /// <param name="classes">Any classes to add to the button</param> /// <returns>IHtmlString object that will output a HTML reset button</returns> public IHtmlString Reset(string value, string id = null, string classes = null, string name = null) { return(HelperDefinitions.Submit(value, id, classes, name, true)); }
public FlowFormNavigation(TextWriter writer) { _writer = writer; _writer.Write(HelperDefinitions.BeginNavigation().ToHtmlString()); }
/// <summary> /// Outputs the rest of the navigation area. /// </summary> public void Dispose() { _writer.Write(HelperDefinitions.EndMessage().ToHtmlString()); }
private string RenderGrid(Grid grid, bool readOnly = false) { return(HelperDefinitions.Grid(grid.Id, grid.Choices, grid.Prompts, grid.Values, "%prompt% / %choice%", "Summary", readOnly).ToString()); }
private FlowFormField FieldFor <TProperty>(Expression <Func <TModel, TProperty> > expression, bool containsSection, FieldConfiguration fieldConfiguration = null) { /* * Renders a field for a non-boolean property of the model */ fieldConfiguration = fieldConfiguration ?? new FieldConfiguration(); if (fieldConfiguration.HideIfNull && fieldConfiguration.ReadOnly && GetValue(expression) == null) { return(null); } var htmlAttrs = Helper.ObjectToDictionary(fieldConfiguration.HtmlAttributes); var type = ElementType.Text; var grid = default(Grid); var selectList = default(MultiSelectList); var metadata = ModelMetadata.FromLambdaExpression(expression, _htmlHelper.ViewData); // Label var labelHtml = LabelHtml(expression, fieldConfiguration); if (fieldConfiguration.ReadOnly) { labelHtml = labelHtml.ReReplace(@"</?label.*?>", "", RegexOptions.IgnoreCase); } if (fieldConfiguration.ReadOnly && expression.ReturnType.Name != "Grid`1") { var value = (GetValue(expression) ?? "?"); var fi = value.GetType().GetField(value.ToString()); var attributes = fi != null ? (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false) : new DescriptionAttribute[] { }; var stringValue = (attributes.Length > 0) ? attributes[0].Description : value.ToString(); return(new FlowFormField(_writer, containsSection, labelHtml, (new HtmlString(stringValue)).ToString(), parentClass: fieldConfiguration.ParentClass)); } var validators = metadata.GetValidators(_htmlHelper.ViewContext.Controller.ControllerContext); var classes = new ClassBuilder(); if (htmlAttrs.ContainsKey("class")) { classes.Add((string)htmlAttrs["class"]); } if (metadata.IsRequired && (!metadata.ModelType.IsEnum || fieldConfiguration.Exclude == null || fieldConfiguration.Exclude.Length == 0)) { classes.Add("required"); } else { labelHtml = labelHtml.Replace("</label>", " <em>(Optional)</em></label>"); } switch (metadata.DataTypeName) { case "Digits": case "CreditCard": classes.Add(metadata.DataTypeName.Replace("-", "").ToLower()); break; case "IPAddress": classes.Add("ip-address"); break; case "MultilineText": type = ElementType.TextArea; break; } switch (metadata.ModelType.Name) { case "Double": classes.Add("number"); break; case "Int32": classes.Add("integer"); break; case "Email": classes.Add("email"); break; case "Password": type = ElementType.Password; break; case "Date": classes.Add("date"); break; case "HttpPostedFileBase": htmlAttrs["type"] = "file"; break; } if (metadata.ModelType.IsEnum && metadata.ModelType.IsDefined(typeof(FlagsAttribute), false)) { type = ElementType.Select; var list = (IEnumerable <object>)EnumInfo.CreateList(metadata.ModelType, fieldConfiguration.Exclude); var selectedValues = GetSelectedEnums((Enum)metadata.Model, fieldConfiguration.Exclude).ToList(); selectList = new MultiSelectList(list, "Value", "Display", selectedValues); } else if (metadata.ModelType.IsEnum || ( metadata.ModelType.IsGenericType && metadata.ModelType.GetGenericTypeDefinition().FullName == "System.Nullable`1" && metadata.ModelType.GetGenericArguments()[0].IsEnum ) || ( typeof(IEnumerable).IsAssignableFrom(metadata.ModelType) && !typeof(string).IsAssignableFrom(metadata.ModelType) && metadata.ModelType.GetGenericArguments()[0].IsEnum ) ) { type = ElementType.Select; var list = (IEnumerable <object>)EnumInfo.CreateList(metadata.ModelType.IsGenericType ? metadata.ModelType.GetGenericArguments()[0] : metadata.ModelType, fieldConfiguration.Exclude); var selectedValues = GetSelected(metadata.Model); selectList = new MultiSelectList(list, "Value", "Display", selectedValues); } foreach (var rule in validators.SelectMany(v => v.GetClientValidationRules())) { switch (rule.ValidationType) { case "range": classes.Add(string.Format("range([{0},{1}])", rule.ValidationParameters["min"], rule.ValidationParameters["max"])); break; case "min": classes.Add(string.Format("min({0})", rule.ValidationParameters["min"])); break; case "max": classes.Add(string.Format("max({0})", rule.ValidationParameters["max"])); break; case "regex": classes.Add(string.Format("match(/{0}/)", rule.ValidationParameters["pattern"])); break; case "length": case "maxlength": if (type == ElementType.Text || type == ElementType.Password) { htmlAttrs["maxlength"] = rule.ValidationParameters["max"]; } else { classes.Add(string.Format("maxlength({0})", rule.ValidationParameters["max"])); } break; case "minlength": classes.Add(string.Format("minlength({0})", rule.ValidationParameters["min"])); break; case "rangelength": classes.Add(string.Format("rangelength([{0},{1}])", rule.ValidationParameters["min"], rule.ValidationParameters["max"])); break; case "equalto": classes.Add(string.Format("equalTo('#{0}')", rule.ValidationParameters["other"].ToString().Split('.')[1])); labelHtml = labelHtml.Replace(" <em>(Optional)</em>", ""); break; case "existsin": type = ElementType.Select; selectList = GetSelectListFromCollection(expression, metadata, rule); break; case "grid": grid = GetGrid(expression, metadata, rule); break; case "notrequired": labelHtml = labelHtml.Replace(" <em>(Optional)</em>", ""); break; case "filetype": classes.Add(string.Format("accept('{0}')", rule.ValidationParameters["extension"])); fieldConfiguration.Tip = fieldConfiguration.Tip ?? string.Format("Filetype must be: {0}", rule.ValidationParameters["pretty-extension"]); break; } } if (classes.ToString().Trim() != "") { htmlAttrs["class"] = classes.ToString(); } if (fieldConfiguration.As.HasValue) { var validOverride = false; var overrideErrorMessage = ""; switch (type) { case ElementType.Select: switch (fieldConfiguration.As.Value) { case ElementType.Checkboxes: case ElementType.RadioButtons: case ElementType.Text: type = fieldConfiguration.As.Value; validOverride = true; break; } break; case ElementType.Text: switch (fieldConfiguration.As.Value) { case ElementType.Checkboxes: case ElementType.RadioButtons: case ElementType.Select: if (fieldConfiguration.PossibleValues != null) { selectList = fieldConfiguration.PossibleValues; type = fieldConfiguration.As.Value; validOverride = true; } else { overrideErrorMessage = "I was expecting a list."; } break; } break; } if (!validOverride) { throw new ApplicationException(string.Format("FieldConfiguration{{ As = {0} }} not valid for field: {1} (which defaults to {2}). {3}", fieldConfiguration.As.Value, expression, type, overrideErrorMessage)); } } var elementHtml = string.Empty; var errorHtml = string.Empty; var isValid = true; if (grid != null) { elementHtml = RenderGrid(grid, fieldConfiguration.ReadOnly); isValid = GetErrors(expression, out errorHtml); } else { switch (type) { case ElementType.Text: elementHtml = _htmlHelper.TextBoxFor(expression, htmlAttrs).ToHtmlString(); break; case ElementType.Password: elementHtml = _htmlHelper.PasswordFor(expression, htmlAttrs).ToHtmlString(); break; case ElementType.TextArea: elementHtml = _htmlHelper.TextAreaFor(expression, htmlAttrs).ToHtmlString(); break; case ElementType.Select: if (typeof(IEnumerable).IsAssignableFrom(metadata.ModelType) && !typeof(string).IsAssignableFrom(metadata.ModelType)) { elementHtml = _htmlHelper.ListBoxFor(expression, selectList, htmlAttrs).ToHtmlString(); } else { elementHtml = _htmlHelper.DropDownListFor(expression, selectList, fieldConfiguration.Label, htmlAttrs).ToHtmlString(); } break; case ElementType.Checkboxes: case ElementType.RadioButtons: // TODO: Use HTML Attributes var typeString = type == ElementType.Checkboxes ? "checkbox" : "radio"; elementHtml += HelperDefinitions.BeginInputList(typeString); elementHtml += string.Join("", selectList.Select(i => HelperDefinitions.InputListItem(typeString, expression.GetFieldName(), i.Value, i.Text, i.Selected).ToString())); elementHtml += HelperDefinitions.EndInputList(); break; } isValid = GetErrors(expression, out errorHtml); } elementHtml = (fieldConfiguration.Before ?? "") + elementHtml + (fieldConfiguration.After ?? ""); return(new FlowFormField(_writer, containsSection, labelHtml, elementHtml, errorHtml, isValid, fieldConfiguration.Hint, fieldConfiguration.Tip, fieldConfiguration.HideTip, fieldConfiguration.HintClass, fieldConfiguration.ParentClass, fieldConfiguration.DisplayFieldName)); }
/// <summary> /// Render a flow form footer. /// </summary> /// <param name="area">The Area or Department within the University that is responsible for the form</param> /// <param name="id">The ID of the form as registered in the forms finder</param> /// <param name="date">The date the form was last registered</param> /// <returns>An IHtmlString object that will render the footer</returns> public IHtmlString Footer(string area = null, string id = null, string date = null) { return(HelperDefinitions.Footer(area, id, date)); }
/// <summary> /// Render flow form steps. /// </summary> /// <param name="steps">A list of objects representing the steps in the form; object properties: {Name, Url}</param> /// <param name="current">The current step the user is on</param> /// <param name="maxComplete">The maximum step the user has completed thus far</param> /// <param name="showLinks">Whether or not to show links against the steps</param> /// <param name="stopLinksAtMaxComplete">Whether or not to show only links to completed steps</param> /// <returns></returns> public IHtmlString Steps(IList <Step> steps, int current, int maxComplete, bool showLinks = false, bool stopLinksAtMaxComplete = false) { return(HelperDefinitions.Steps(steps, current, maxComplete, showLinks, stopLinksAtMaxComplete)); }