Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form inside Modal #44

Open
jedielson opened this issue Oct 18, 2016 · 2 comments
Open

Form inside Modal #44

jedielson opened this issue Oct 18, 2016 · 2 comments

Comments

@jedielson
Copy link

How can we have an structure like this?

<modal title="Modal title">
    <form asp-controller="Controller" asp-action="Action" method="post">
        <modal-body>

            <div class="form-horizontal">
                <div class="form-group">
                    <label asp-for="Nome" class="control-label col-md-2">Nome:</label>
                    <div class="col-md-10">
                        <input asp-for="Nome" type="text" class="form-control" />
                    </div>
                </div>
            </div>

        </modal-body>
        <modal-footer>
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
        </modal-footer>
    </form>
</modal>

The modal was correctly generated, but the form was removed (as expected).
I've tried to create another custom helper to form like

/// <summary>
    /// A Bootstrap modal dialog
    /// </summary>
    [RestrictChildren("modal-body", "modal-footer", "form")]
    public class ModalTagHelper : TagHelper
    {
        /// <summary>
        /// The title of the modal
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// The Id of the modal
        /// </summary>
        public string Id { get; set; }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var modalContext = new ModalContext();
            context.Items.Add(typeof(ModalTagHelper), modalContext);

            await output.GetChildContentAsync();

            var template =
$@"<div class='modal-dialog' role='document'>
    <div class='modal-content'>
      <div class='modal-header'>
        <button type = 'button' class='close' data-dismiss='modal' aria-label='Close' modal-close-action><span aria-hidden='true'>&times;</span></button>
        <h4 class='modal-title' id='{context.UniqueId}Label'>{Title}</h4>
      </div>
        <div class='modal-body'>";

            output.TagName = "div";
            output.Attributes.SetAttribute("role", "dialog");
            output.Attributes.SetAttribute("id", Id);
            output.Attributes.SetAttribute("aria-labelledby", $"{context.UniqueId}Label");
            output.Attributes.SetAttribute("tabindex", "-1");
            var classNames = "modal fade";
            if (output.Attributes.ContainsName("class"))
            {
                classNames = string.Format("{0} {1}", output.Attributes["class"].Value, classNames);
            }
            output.Attributes.SetAttribute("class", classNames);
            output.Content.AppendHtml(template);
            if (modalContext.Body != null)
            {
                output.Content.AppendHtml(modalContext.Body);
            }
            output.Content.AppendHtml("</div>");
            if (modalContext.Footer != null)
            {
                output.Content.AppendHtml("<div class='modal-footer'>");
                output.Content.AppendHtml(modalContext.Footer);
                output.Content.AppendHtml("</div>");
            }

            output.Content.AppendHtml("</div></div>");
        }
    }

    /// <summary>
    /// The modal-footer portion of Bootstrap modal dialog
    /// </summary>
    [HtmlTargetElement("modal-footer", ParentTag = "modal")]
    [HtmlTargetElement("modal-footer", ParentTag = "form")]
    public class ModalFooterTagHelper : TagHelper
    {
        /// <summary>
        /// Whether or not to show a button to dismiss the dialog. 
        /// Default: <c>true</c>
        /// </summary>
        [HtmlAttributeName("show-dismiss")]
        public bool ShowDismiss { get; set; } = true;

        /// <summary>
        /// The text to show on the Dismiss button
        /// Default: Cancel
        /// </summary>
        [HtmlAttributeName("dismiss-text")]
        public string DismissText { get; set; } = "Cancel";

        /// <summary>
        /// A classe CSS a ser aplicada no botão de dismiss.
        /// Não é necessário aplicar btn
        /// </summary>
        [HtmlAttributeName("dismiss-css-class")]
        public string DismissCssClass { get; set; } = "btn-default btn-100";


        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            if (ShowDismiss)
            {
                output.PreContent.AppendFormat(@"<button type='button' class='btn {0}' data-dismiss='modal' modal-close-action>{1}</button>", DismissCssClass, DismissText);
            }
            var childContent = await output.GetChildContentAsync();
            var footerContent = new DefaultTagHelperContent();
            if (ShowDismiss)
            {
                footerContent.AppendFormat(@"<button type='button' class='btn {0}' data-dismiss='modal' modal-close-action>{1}</button>", DismissCssClass, DismissText);
            }
            footerContent.AppendHtml(childContent);
            var modalContext = (ModalContext)context.Items[typeof(ModalTagHelper)];
            modalContext.Footer = footerContent;
            output.SuppressOutput();
        }
    }

    /// <summary>
    /// The modal-body portion of a Bootstrap modal dialog
    /// </summary>
    [HtmlTargetElement("modal-body", ParentTag = "modal")]
    [HtmlTargetElement("modal-body", ParentTag = "form")]
    public class ModalBodyTagHelper : TagHelper
    {
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var childContent = await output.GetChildContentAsync();
            var modalContext = (ModalContext)context.Items[typeof(ModalTagHelper)];
            modalContext.Body = childContent;
            output.SuppressOutput();
        }
    }

But had no success...

How can I fix it?

@dpaquette
Copy link
Owner

Excellent question. I will need to think through this a little. I don't know the answer off the top of my head

@mguinness
Copy link

@jedielson Keep the form in modal-body and the button outside in modal-footer. Then you can either use the new HTML5 form attribute or just add the following to your button to trigger the submit:

<button type="button" onclick="document.forms[0].submit()">Save changes</button>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants