Meteor: Bootstrap Modal breaks when handlebars val

2019-01-29 09:54发布

问题:

I'm making a modal to handle payments, and I want to use some handlebars helpers to do form validation.

Here's the html:

<div class="modal fade" id="paymentModal" tabindex="-1" role="dialog" aria-labelledby="paymentModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                <form id="paymentModalForm" class="form-horizontal">
                    ...
                    <div class="form-group">
                        <div class="col-xs-offset-3 col-xs-9">
                            <!-- this session helper is a go-between with Session -->
                            <button {{session 'paymentFormInputsValid'}} type="submit" class="btn btn-primary">
                                Make Payment
                            </button>
                        </div>
                    </div>
                    ...
                </form>
            </div>
        </div>
    </div>
</div>

Here's the backing js:

Template.paymentModal.events({
    'keyup .paymentFormInput': function(e, t) {
        var valid = t.findAll('.paymentFormInput').every(function(item) {
            return !!item.value.trim();
        });
        Session.set('paymentFormInputsValid', valid ? '': 'disabled');
    }
});

paymentFormInputsValid is set correctly, but when that keyup event happens, the modal disappears, and the black .modal-backdrop remains and doesn't allow any changes. It simply locks the user out and the page has to be refreshed.

Also, I previously had the button with more semantic handlebars, like this:

<button {{#unless session 'paymentFormInputsValid'}}disabled{{/unless}}
    type="submit" class="btn btn-primary">
    Make Payment
</button>

but that broke the submit button, and made it display like this:

Very broken.

How can I get modals to play nice with handlebars? Should I just go with a different strategy for this form?

Thanks in advance!

Update

I now have this solution cobbled together. The template being inserted to my modal:

<template name="paymentModalButton">
    <button type="submit" class="btn btn-primary" {{paymentFormInputsValid}}>
        Make Payment
    </button>
</template>

<!-- In the appropriate place -->
<div class="form-group">
    <div class="col-xs-offset-3 col-xs-9">
        {{> paymentModalButton}}
    </div>
</div>

But, this still can't handle handlebars {{#if}} blocks, such as the one I wanted to use:

{{#unless session 'paymentFormInputsValid'}}disabled{{/unless}}

This still breaks the button rendering. It would be easier and more semantic to have this behavior, so if anyone can figure it out that would be delightful.

Update

I dug into the Elements, and here's what that button looks like.

<button <!--data:8trm3tvlatwn9qaw9--=""> type="submit" class="btn btn-primary"&gt;
    Make Payment
</button>

Frankly I can't make any sense of that and why it's breaking. It's being generated from this, which is valid and works in other contexts:

<button {{#unless session 'paymentFormInputsValid'}}disabled{{/unless}} type="submit" class="btn btn-primary">
    Make Payment
</button>

Thanks!

回答1:

<div class="modal fade" id="paymentModal" tabindex="-1" role="dialog" aria-labelledby="paymentModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                 {{> someOtherTemplate}}

It's a hack until the new blaze UI comes out.

The reason it fails is because as soon as the template changed, the entire template is redrawn, but the twitter bootstrap code is not applied.



回答2:

Here is an example of using Bootstrap modal's with Meteor's Spark rendering engine: http://modal-example.meteor.com/

Source: https://github.com/alanning/meteor-modal-example

As @BradM points out, this kind of thing hopefully won't be an issue once Blaze (Meteor's new rendering engine) is released.