Example #1
0
        internal static void TextAreaHelper(
            HtmlHelper htmlHelper, XcstWriter output, ModelMetadata metadata, string name, IDictionary <string, object> rowsAndColumns,
            HtmlAttribs?htmlAttributes, string?innerHtmlPrefix = null)
        {
            string fullName = htmlHelper.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

            if (String.IsNullOrEmpty(fullName))
            {
                throw new ArgumentNullException(nameof(name));
            }

            output.WriteStartElement("textarea");
            HtmlAttributeHelper.WriteId(fullName, output);
            output.WriteAttributeString("name", fullName);
            HtmlAttributeHelper.WriteAttributes(rowsAndColumns, output);

            bool explicitRowsAndCols = rowsAndColumns != implicitRowsAndColumns;

            // If there are any errors for a named field, we add the css attribute.

            string?cssClass = (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out ModelState modelState) &&
                               modelState.Errors.Count > 0) ? HtmlHelper.ValidationInputCssClassName : null;

            HtmlAttributeHelper.WriteClass(cssClass, htmlAttributes, output);
            HtmlAttributeHelper.WriteAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata), output);

            // name cannnot be overridden, and class was already written
            // explicit rows and cols cannot be overridden

            HtmlAttributeHelper.WriteAttributes(
                htmlAttributes,
                output,
                excludeFn: n => n == "name" || n == "class" || (explicitRowsAndCols && (n == "rows" || n == "cols")));

            string?value;

            if (modelState?.Value != null)
            {
                value = modelState.Value.AttemptedValue;
            }
            else if (metadata.Model != null)
            {
                value = Convert.ToString(metadata.Model, CultureInfo.CurrentCulture);
            }
            else
            {
                value = String.Empty;
            }

            // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
            // in case the value being rendered is something like "\r\nHello".

            output.WriteString((innerHtmlPrefix ?? Environment.NewLine) + value);

            output.WriteEndElement();
        }
Example #2
0
        public static void BooleanTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput)
        {
            XcstWriter output = DocumentWriter.CastElement(package, seqOutput);

            ViewDataDictionary viewData = html.ViewData;

            bool?value = null;

            if (viewData.Model != null)
            {
                value = Convert.ToBoolean(viewData.Model, CultureInfo.InvariantCulture);
            }

            if (viewData.ModelMetadata.IsNullableValueType)
            {
                output.WriteStartElement("select");

                string?className = DefaultEditorTemplates.GetEditorCssClass(new EditorInfo("Boolean", "select"), "list-box tri-state");

                HtmlAttributeHelper.WriteClass(className, null, output);
                HtmlAttributeHelper.WriteBoolean("disabled", true, output);

                foreach (SelectListItem item in DefaultEditorTemplates.TriStateValues(value))
                {
                    SelectInstructions.WriteOption(item, output);
                }

                output.WriteEndElement();
            }
            else
            {
                output.WriteStartElement("input");
                output.WriteAttributeString("type", "checkbox");

                string?className = DefaultEditorTemplates.GetEditorCssClass(new EditorInfo("Boolean", "input", InputType.CheckBox), "check-box");

                HtmlAttributeHelper.WriteClass(className, null, output);
                HtmlAttributeHelper.WriteBoolean("disabled", true, output);
                HtmlAttributeHelper.WriteBoolean("checked", value.GetValueOrDefault(), output);

                output.WriteEndElement();
            }
        }
Example #3
0
        public static void UrlTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput)
        {
            XcstWriter output = DocumentWriter.CastElement(package, seqOutput);

            ViewDataDictionary viewData = html.ViewData;

            output.WriteStartElement("a");
            output.WriteAttributeString("href", Convert.ToString(viewData.Model, CultureInfo.InvariantCulture));
            output.WriteString(output.SimpleContent.Convert(viewData.TemplateInfo.FormattedModelValue));
            output.WriteEndElement();
        }
Example #4
0
        GetHtml(HttpContext httpContext, XcstWriter output)
        {
            IAntiforgery antiforgery = GetAntiforgeryService(httpContext);

            AntiforgeryTokenSet tokenSet = antiforgery.GetAndStoreTokens(httpContext);

            output.WriteStartElement("input");
            output.WriteAttributeString("type", "hidden");
            output.WriteAttributeString("name", tokenSet.FormFieldName);
            output.WriteAttributeString("value", tokenSet.RequestToken);
            output.WriteEndElement();
        }
Example #5
0
        public static void ImageUrlTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput)
        {
            ViewDataDictionary viewData = html.ViewData;

            if (viewData.Model != null)
            {
                XcstWriter output = DocumentWriter.CastElement(package, seqOutput);

                output.WriteStartElement("img");
                output.WriteAttributeString("src", Convert.ToString(viewData.Model, CultureInfo.InvariantCulture));
                output.WriteEndElement();
            }
        }
Example #6
0
        internal static void WriteOption(SelectListItem item, XcstWriter output)
        {
            output.WriteStartElement("option");

            if (item.Value != null)
            {
                output.WriteAttributeString("value", item.Value);
            }

            HtmlAttributeHelper.WriteBoolean("selected", item.Selected, output);
            HtmlAttributeHelper.WriteBoolean("disabled", item.Disabled, output);

            output.WriteString(item.Text);
            output.WriteEndElement();
        }
Example #7
0
        static void WriteOptions(string?optionLabel, IEnumerable <SelectListItem> selectList, XcstWriter output)
        {
            // Make optionLabel the first item that gets rendered.

            if (optionLabel != null)
            {
                WriteOption(new SelectListItem {
                    Text     = optionLabel,
                    Value    = String.Empty,
                    Selected = false
                }, output);
            }

            // Group items in the SelectList if requested.
            // Treat each item with Group == null as a member of a unique group
            // so they are added according to the original order.

            var groupedSelectList = selectList.GroupBy <SelectListItem, int>(
                i => (i.Group is null) ? i.GetHashCode() : i.Group.GetHashCode());

            foreach (var group in groupedSelectList)
            {
                SelectListGroup?optGroup = group.First().Group;

                if (optGroup != null)
                {
                    output.WriteStartElement("optgroup");

                    if (optGroup.Name != null)
                    {
                        output.WriteAttributeString("label", optGroup.Name);
                    }

                    HtmlAttributeHelper.WriteBoolean("disabled", optGroup.Disabled, output);
                }

                foreach (SelectListItem item in group)
                {
                    WriteOption(item, output);
                }

                if (optGroup != null)
                {
                    output.WriteEndElement(); // </optgroup>
                }
            }
        }
Example #8
0
        static void CheckBoxHelper(
            HtmlHelper htmlHelper, IXcstPackage package, ISequenceWriter <XElement> output, ModelMetadata?metadata, string name, bool?isChecked, HtmlAttribs?htmlAttributes)
        {
            XcstWriter inputWriter  = DocumentWriter.CastElement(package, output);
            XcstWriter hiddenWriter = DocumentWriter.CastElement(package, output);

            bool explicitChecked = isChecked.HasValue;

            if (explicitChecked &&
                htmlAttributes != null &&
                htmlAttributes.ContainsKey("checked"))
            {
                htmlAttributes = htmlAttributes.Clone();
                htmlAttributes.Remove("checked"); // Explicit value must override dictionary
            }

            InputHelper(
                htmlHelper,
                inputWriter,
                InputType.CheckBox,
                metadata,
                name,
                value: "true",
                useViewData: !explicitChecked,
                isChecked: isChecked ?? false,
                setId: true,
                isExplicitValue: false,
                format: null,
                htmlAttributes: htmlAttributes);

            string fullName = Name(htmlHelper, name);

            // Render an additional <input type="hidden".../> for checkboxes. This
            // addresses scenarios where unchecked checkboxes are not sent in the request.
            // Sending a hidden input makes it possible to know that the checkbox was present
            // on the page when the request was submitted.

            hiddenWriter.WriteStartElement("input");
            hiddenWriter.WriteAttributeString("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
            hiddenWriter.WriteAttributeString("name", fullName);
            hiddenWriter.WriteAttributeString("value", "false");
            hiddenWriter.WriteEndElement();
        }
Example #9
0
        internal static void LabelHelper(
            HtmlHelper html, XcstWriter output, ModelMetadata metadata, string expression, string?labelText = null, HtmlAttribs?htmlAttributes = null)
        {
            string htmlFieldName = expression;

            string resolvedLabelText = labelText
                                       ?? metadata.DisplayName
                                       ?? metadata.PropertyName
                                       ?? htmlFieldName.Split('.').Last();

            if (String.IsNullOrEmpty(resolvedLabelText))
            {
                return;
            }

            string fullFieldName = html.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName);

            output.WriteStartElement("label");
            output.WriteAttributeString("for", TagBuilder.CreateSanitizedId(fullFieldName));
            HtmlAttributeHelper.WriteAttributes(htmlAttributes, output);
            output.WriteString(resolvedLabelText);
            output.WriteEndElement();
        }
Example #10
0
        internal static void ObjectTemplate(HtmlHelper html, IXcstPackage package, ISequenceWriter <object> seqOutput, TemplateHelpers.TemplateHelperDelegate templateHelper)
        {
            ViewDataDictionary viewData      = html.ViewData;
            ModelMetadata      modelMetadata = viewData.ModelMetadata;

            if (modelMetadata.Model is null ||
                viewData.TemplateInfo.TemplateDepth > 1)
            {
                MetadataInstructions.DisplayTextHelper(html, seqOutput, modelMetadata);
                return;
            }

            var filteredProperties = DisplayInstructions.DisplayProperties(html);
            var groupedProperties  = filteredProperties.GroupBy(p => p.GroupName());

            bool createFieldset = groupedProperties.Any(g => g.Key != null);

            foreach (var group in groupedProperties)
            {
                XcstWriter?fieldsetWriter = null;

                if (createFieldset)
                {
                    fieldsetWriter = DocumentWriter.CastElement(package, seqOutput);

                    fieldsetWriter.WriteStartElement("fieldset");
                    fieldsetWriter.WriteStartElement("legend");
                    fieldsetWriter.WriteString(group.Key);
                    fieldsetWriter.WriteEndElement();
                }

                foreach (ModelMetadata propertyMeta in group)
                {
                    XcstWriter?fieldWriter = null;

                    if (!propertyMeta.HideSurroundingHtml)
                    {
                        XcstDelegate <object>?memberTemplate =
                            DisplayInstructions.MemberTemplate(html, propertyMeta);

                        if (memberTemplate != null)
                        {
                            memberTemplate(null !/* argument is not used */, fieldsetWriter ?? seqOutput);
                            continue;
                        }

                        XcstWriter labelWriter = fieldsetWriter
                                                 ?? DocumentWriter.CastElement(package, seqOutput);

                        labelWriter.WriteStartElement("div");
                        labelWriter.WriteAttributeString("class", "display-label");
                        labelWriter.WriteString(propertyMeta.GetDisplayName() ?? String.Empty);
                        labelWriter.WriteEndElement();

                        fieldWriter = fieldsetWriter
                                      ?? DocumentWriter.CastElement(package, seqOutput);

                        fieldWriter.WriteStartElement("div");
                        fieldWriter.WriteAttributeString("class", "display-field");
                    }

                    templateHelper(
                        html,
                        package,
                        fieldWriter ?? fieldsetWriter ?? seqOutput,
                        propertyMeta,
                        htmlFieldName: propertyMeta.PropertyName,
                        templateName: null,
                        membersNames: null,
                        DataBoundControlMode.ReadOnly,
                        additionalViewData: null
                        );

                    if (!propertyMeta.HideSurroundingHtml)
                    {
                        fieldWriter !.WriteEndElement(); // </div>
                    }
                }

                if (createFieldset)
                {
                    fieldsetWriter !.WriteEndElement(); // </fieldset>
                }
            }
        }
Example #11
0
        static void SelectInternal(
            HtmlHelper htmlHelper, XcstWriter output, ModelMetadata?metadata, string?optionLabel, string name, IEnumerable <SelectListItem>?selectList,
            bool allowMultiple, HtmlAttribs?htmlAttributes)
        {
            ViewDataDictionary viewData = htmlHelper.ViewData;

            string fullName = viewData.TemplateInfo.GetFullHtmlFieldName(name);

            if (String.IsNullOrEmpty(fullName))
            {
                throw new ArgumentNullException(nameof(name));
            }

            bool usedViewData = false;

            // If we got a null selectList, try to use ViewData to get the list of items.

            if (selectList is null)
            {
                selectList   = GetSelectData(htmlHelper, name);
                usedViewData = true;
            }

            object?defaultValue = (allowMultiple) ?
                                  htmlHelper.GetModelStateValue(fullName, typeof(string[]))
            : htmlHelper.GetModelStateValue(fullName, typeof(string));

            // If we haven't already used ViewData to get the entire list of items then we need to
            // use the ViewData-supplied value before using the parameter-supplied value.

            if (defaultValue is null)
            {
                if (metadata is null)
                {
                    if (!usedViewData &&
                        !String.IsNullOrEmpty(name))
                    {
                        defaultValue = viewData.Eval(name);
                    }
                }
                else
                {
                    defaultValue = metadata.Model;
                }
            }

            if (defaultValue != null)
            {
                selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
            }

            output.WriteStartElement("select");
            HtmlAttributeHelper.WriteId(fullName, output);
            output.WriteAttributeString("name", fullName);
            HtmlAttributeHelper.WriteBoolean("multiple", allowMultiple, output);

            // If there are any errors for a named field, we add the css attribute.

            string?cssClass = (viewData.ModelState.TryGetValue(fullName, out ModelState modelState) &&
                               modelState.Errors.Count > 0) ? HtmlHelper.ValidationInputCssClassName : null;

            var validationAttribs = htmlHelper.GetUnobtrusiveValidationAttributes(
                name, metadata
#if !ASPNETMVC
                , excludeMinMaxLength: !allowMultiple
#endif
                );

            HtmlAttributeHelper.WriteClass(cssClass, htmlAttributes, output);
            HtmlAttributeHelper.WriteAttributes(validationAttribs, output);

            // name cannnot be overridden, and class was already written

            HtmlAttributeHelper.WriteAttributes(htmlAttributes, output, excludeFn: n => n == "name" || n == "class");

            WriteOptions(optionLabel, selectList, output);

            output.WriteEndElement(); // </select>
        }
Example #12
0
        internal static void ValidationMessageHelper(
            HtmlHelper htmlHelper, XcstWriter output, ModelMetadata modelMetadata, string expression, string?validationMessage,
            HtmlAttribs?htmlAttributes, string?tag)
        {
            ViewDataDictionary viewData = htmlHelper.ViewData;

            string      modelName   = viewData.TemplateInfo.GetFullHtmlFieldName(expression);
            FormContext?formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();

            if (!viewData.ModelState.ContainsKey(modelName) &&
                formContext is null)
            {
                return;
            }

            ModelState?          modelState  = viewData.ModelState[modelName];
            ModelErrorCollection?modelErrors = modelState?.Errors;

            ModelError?modelError = (modelErrors is null || modelErrors.Count == 0) ? null
            : (modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]);

            if (modelError is null &&
                formContext is null)
            {
                return;
            }

            if (String.IsNullOrEmpty(tag))
            {
                tag = htmlHelper.ViewContext.ValidationMessageElement;
            }

            string validationClass = (modelError != null) ?
                                     HtmlHelper.ValidationMessageCssClassName
            : HtmlHelper.ValidationMessageValidCssClassName;

            output.WriteStartElement(tag !);
            HtmlAttributeHelper.WriteClass(validationClass, htmlAttributes, output);

            if (formContext != null)
            {
                bool replaceValidationMessageContents = String.IsNullOrEmpty(validationMessage);

                if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
                {
                    output.WriteAttributeString("data-valmsg-for", modelName);
                    output.WriteAttributeString("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
                }
            }

            // class was already written

            HtmlAttributeHelper.WriteAttributes(htmlAttributes, output, excludeFn: n => n == "class");

            if (!String.IsNullOrEmpty(validationMessage))
            {
                output.WriteString(validationMessage);
            }
            else if (modelError != null)
            {
                output.WriteString(GetUserErrorMessageOrDefault(modelError, modelState));
            }

            output.WriteEndElement();
        }
Example #13
0
        public static void ValidationSummary(
            HtmlHelper htmlHelper, XcstWriter output, bool includePropertyErrors = false, string?message = null, HtmlAttribs?htmlAttributes = null,
            string?headingTag = null)
        {
            if (htmlHelper is null)
            {
                throw new ArgumentNullException(nameof(htmlHelper));
            }

            FormContext?formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();

            if (htmlHelper.ViewData.ModelState.IsValid)
            {
                if (formContext is null)
                {
                    // No client side validation

                    return;
                }

                // TODO: This isn't really about unobtrusive; can we fix up non-unobtrusive to get rid of this, too?

                if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled &&
                    !includePropertyErrors)
                {
                    // No client-side updates

                    return;
                }
            }

            string validationClass = (htmlHelper.ViewData.ModelState.IsValid) ?
                                     HtmlHelper.ValidationSummaryValidCssClassName
            : HtmlHelper.ValidationSummaryCssClassName;

            output.WriteStartElement("div");
            HtmlAttributeHelper.WriteClass(validationClass, htmlAttributes, output);

            if (formContext != null)
            {
                if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
                {
                    if (includePropertyErrors)
                    {
                        // Only put errors in the validation summary if they're supposed to be included there

                        output.WriteAttributeString("data-valmsg-summary", "true");
                    }
                }
            }

            // class was already written

            HtmlAttributeHelper.WriteAttributes(htmlAttributes, output, excludeFn: n => n == "class");

            if (!String.IsNullOrEmpty(message))
            {
                if (String.IsNullOrEmpty(headingTag))
                {
                    headingTag = htmlHelper.ViewContext.ValidationSummaryMessageElement;
                }

                output.WriteStartElement(headingTag !);
                output.WriteString(message);
                output.WriteEndElement();
            }

            output.WriteStartElement("ul");

            bool empty = true;

            IEnumerable <ModelState> modelStates = GetModelStateList(htmlHelper, includePropertyErrors);

            foreach (ModelState modelState in modelStates)
            {
                foreach (ModelError modelError in modelState.Errors)
                {
                    string?errorText = GetUserErrorMessageOrDefault(modelError, modelState: null);

                    if (!String.IsNullOrEmpty(errorText))
                    {
                        empty = false;

                        output.WriteStartElement("li");
                        output.WriteString(errorText);
                        output.WriteEndElement();
                    }
                }
            }

            if (empty)
            {
                output.WriteStartElement("li");
                output.WriteAttributeString("style", "display:none");
                output.WriteEndElement();
            }

            output.WriteEndElement(); // </ul>
            output.WriteEndElement(); // </div>
        }