Codemirror content not visible in bootstrap modal until it is clicked

时间秒杀一切 提交于 2020-01-02 00:48:17

问题


I am using codemirror 3 with bootstrap. In my bootstrap modal, there is a textarea, and i am replacing it with codemirror. I am using task_name_editor.setValue('initial value') to initialise codemirror with an input. The problem is that the content is there, but it is not visible until it is clicked or any key is pressed while it is focused.

I tried Marijn's answer to a similar question, but i don't know where to place task_name_editor.refresh()

I tried placing it where i show the modal -

$('#edit_task_modal').modal('show');
task_name_editor.setValue('initial value');
task_name_editor.refresh();

even then, it is not working Please can anyone show how to fix this problem ?


回答1:


A cleaner solution perhaps?

Bootstrap modals have an event that fires after the modal is shown. In Bootstrap 3, this is shown.bs.modal.

modal.on('shown.bs.modal', function() {
    // initialize codemirror here
});



回答2:


I figured it has something to do with viewport size change while tabs are hidden and shown again. So the following worked for me:

1) Listen for clicks over the tabs 2) On click, call refresh() on all CM editors or just the one inside a tab, as you prefer

It's important to note that refresh() must be called with a small time-out, otherwise in some browsers (i got this in Chrome), the editor is displayed, but with some invalid offsets.

Try something like this:

$(document).ready(function() {
    $("#your_nav_tabs a").click(function(e) {
        if(window.codeMirrorInstances != null) { // window.codeMirrorInstances must be initialized and tracked manually
            $.each(window.codeMirrorInstances, function(index, cm) {
                setTimeout(function() {
                    cm.refresh();
                }, 100);
            });
        }

        return false;
    });
});



回答3:


With help from this question, I was able to get a CodeMirror editor, which was sitting in an inactive bootstrap 3 tab and therefore not completely initialized, and refresh it when the tab is clicked. Maybe someone finds it useful.

Coffeescript version:

$('a[data-toggle="tab"]').on 'shown.bs.tab', (e) ->
  target = $(e.target).attr("href") # activated tab
  $(target + ' .CodeMirror').each (i, el) ->
    el.CodeMirror.refresh()



回答4:


If you initialize editor on modal shown event, problem will be solved. Just put this script on parent page.

$('#myModal').on('shown', function () {
    CodeMirror.fromTextArea(document.getElementById('MyTextArea'), { mode: 'xml', lineNumbers: true });
});



回答5:


You can now use the Code Mirror addon Auto Refresh: https://codemirror.net/doc/manual.html#addon_autorefresh

Just include the script dependency

<script src="../display/autorefresh.js" %}"></script>
Which now gives you the option "autoRefresh" to auto refresh just once right after displaying the content.
var myCodeMirror = CodeMirror.fromTextArea(myTextArea,{
  autoRefresh: true,
});

The docs also state its a 250ms time delay after showing the hidden content. You can increase that delay if you are loading a lot of content.




回答6:


I'm having a similar issue with regards to bootstrap in general (not specifically with modals). However, my solution was to make sure I created the codemirror editor as early as possible (rather than on the document's ready event). I'm guessing this has something to do with the way bootstrap calculates the widths and heights in the grid.

<body>
    <!-- my page content -->

    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>

    <script type="text/javascript">
        // Create the code editor here rather than on document.ready
        editor = CodeMirror(...);
    </script>
</body>



回答7:


I was having a very similar problem with CodeMirror: if it was initialized while it wasn't the active bootstrap tab, it wouldn't show any content. My workaround was the opposite from @pbergqvist - to initialize the CodeMirror control as late as possible, i.e., after the tab in question was selected. Using TypeScript, it looks kind of like this:

var tabClicked = $.Deferred();
$('#scriptTab').click(() => tabClicked.resolve());
$.ajax('/api/script')
    .done(script => {
        this.tabClicked.done(() => {
            setTimeout(()=> {
                var codeMirror = CodeMirror.fromTextArea($('#script')[0]);
                codeMirror.getDoc().setValue(script);
            }, 10);
        });
    })
    .fail(err=> console.error('Error retrieving script: ' + JSON.stringify(err)));

Hope this helps someone.




回答8:


(angular,bootstrap) I just solved it with a simple timeout, like this:

<button class="btn btn-default pull-right margin" data-toggle="modal" data-target="#codesnippetmodal" ng-click="getcodesnippet(module)">
 open modal
</button>

and then in my controller:

$scope.getcodesnippet = function(module) {
    var clientmodule = {
        clientid: $rootScope.activeclient.id,
        moduleid: module.id
    }
    Data.post('getCodesnippet', {
        clientmodule: clientmodule
    }).then(function(results) {

        codesnippet_editor.setValue(results.codesnippet);
        setTimeout(function() {
            codesnippet_editor.refresh();
        }, 500);
    });
}



回答9:


to avoid getting refreshed every time (meaning position and changes lost) i strongly advise for using like this:

$('#meinetabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) 
{
    if (var5 !=="5")
         {
            editor_htaccess.refresh();
         }
    var5 = "5";
})  

Its under MIT license because i am such a nice person



来源:https://stackoverflow.com/questions/17086538/codemirror-content-not-visible-in-bootstrap-modal-until-it-is-clicked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!