user687554
user687554

Reputation: 11151

Bootstrap - Editing TextArea Behind Modal

I have a web page that uses Bootstrap 3. In this page, I need to have a text area that a person can put their answer in. The answer is to a story problem. The story problem appears in a modal dialog. The setup can be seen in this Bootply. The code looks like this:

<div class="container">
  <form>
    <div class="form-group">
      <label>Answer (<a id="showProblemLink" href="#">view problem</a>)</label>
      <textarea class="form-control" rows="7">      </textarea>
    </div>
  </form>

  <div id="problemModal" class="modal" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-body">
            <p>
            The local school wants a new playground.
            The lot they can use for the playground is shaped like a rectangle.
            The school has decided to let the students design the new playground.
            The students have decided that they want 1/4 of the playground to be a football field.
              Another 3/8 of the lot will be used for a basketball court.
              How much of the lot is remaining for the slides and swings?
            </p>
        </div>

        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>        
      </div>      
    </div>
  </div>  
</div>

My users want to be able to keep the story problem open in the modal window while they enter their answer. This will let them double-check their answer. The obvious answer is to have them re-open the dialog. But, apparently, this isn't good enough. I really need to keep the dialog open and let the user enter data in the text area behind/under it. Seems weird to me. But, that's what I gotta do.

My problem is, when I click on the textarea, the dialog disappears. I tried adding data-backdrop="false". While that kept dialog open, it didn't let me actually edit the textarea. What am I missing?

Upvotes: 5

Views: 3518

Answers (9)

Lo&#239;c B.
Lo&#239;c B.

Reputation: 113

You can deactivate the modal "force focus" (eg: prevent edition of external textarea) by removing the document event "focusin.modal":

$("#problemModal").on("shown.bs.modal", function() {
    $(document).off("focusin.modal");
});

If you want to keep the cursor focus on the textarea after the modal has been opened just add $("textarea").focus();

$("#problemModal").on("shown.bs.modal", function() {
    $(document).off("focusin.modal");
    $("textarea").focus();
});

Upvotes: 0

mrbm
mrbm

Reputation: 2194

A modal is per definition 'modal' aka 'always on top dialog', so all you have to do is to make it non-modal, use your html layout this can be done via jQuery :

$('#problemModal').removeClass('modal')
    .hide()
    .css('position','absolute')
    .css('top',0)
    .css('left',(screen.width - $('#problemModal').width())/2);
$("#showProblemLink").on("click", function() {
    $('#problemModal').show();
});

$('#modal-close-btn').click(function(){
    $('#problemModal').hide();
});

Here is a working Bootply as a demo.

Upvotes: 0

Jaqen H&#39;ghar
Jaqen H&#39;ghar

Reputation: 16824

Actually it is very simple to get exactly what you want.

enter image description here

What you are actually looking for is a Dialog and not a Modal.

Here is a working example using jQuery UI Dialog.


Explanation:

  • A modal is designed to block user interaction with the application.
  • A dialog looks and acts similar, but is designed to let the user continue interacting with the page (You can set it manually to block everything if you want)

Here is a SO discussion about it


Some details about the example:

By default a dialog is draggable by the header. I kept the example similar to your modal so I took out the header by using:

dialogClass: 'dialog-modal'

And

.dialog-modal .ui-dialog-titlebar {
  display:none;
}

To make the whole dialog draggable I used:

draggable: false

And

.parent().draggable();

If you actually do want a header, you can delete all these parts. Here is an example with a header

Upvotes: 4

Parvez Rahaman
Parvez Rahaman

Reputation: 4397

I have made a snippet here which can fulfil your need where i have manually input into the textarea using event.key and event.keyCode while the modal is shown.

var $text = $('#textarea');
var backEdit = false;
var $modal = $('#problemModal');
$("#showProblemLink").on("click", function() {
  $modal.modal('show');
});

$modal.on('shown.bs.modal', function() {
  backEdit = true;
})
$modal.on('hidden.bs.modal', function() {
  backEdit = false;
})
$(document).keypress(function(e) {
  if (backEdit) {
    var keyCode = e.keyCode;
    formatTextArea(keyCode);
  }
});

function formatTextArea(keycode) {
  var val = $text.val();
  var caretPos = $text[0].selectionStart;
  var textAreaTxt = $text.val();
  $text.val(textAreaTxt.substring(0, caretPos) + String.fromCharCode(keycode) + textAreaTxt.substring(caretPos));
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
  <form>
    <div class="form-group">
      <label>Answer (<a id="showProblemLink" href="#">view problem</a>)</label>
      <textarea class="form-control" rows="7" id="textarea"></textarea>
    </div>
  </form>

  <div id="problemModal" class="modal" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-body">
          <p>
            The local school wants a new playground. The lot they can use for the playground is shaped like a rectangle. The school has decided to let the students design the new playground. The students have decided that they want 1/4 of the playground to be a football
            field. Another 3/8 of the lot will be used for a basketball court. How much of the lot is remaining for the slides and swings?
          </p>
        </div>

        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Aaron Young
Aaron Young

Reputation: 16

An alternative solution would be to use Popover, and on a focus event of the textarea you have a "modal-like" feature.

The benefit to this is that you retain the ability to keep users focused on which textarea belongs to which story as when you remove the overlay you have the potential of losing context of where the modal was needed, or users doing things like opening multiple modals, etc.

http://getbootstrap.com/javascript/#popovers

Upvotes: 0

Jay McVety
Jay McVety

Reputation: 196

It took a little fiddling as this is an odd problem, but here's the solution I came up with.

I made a textarea inside the modal that is hidden from view and will capture any typing done while the modal is open. When the user closes the modal, focus is sent back to the real textarea.

HTML (slightly modified):

<div class="container">
  <form>
    <div class="form-group">
      <label>Answer (<a id="showProblemLink" href="#">view problem</a>)    </label>
      <textarea id="outside-modal" class="form-control" rows="7">          </textarea>
    </div>
  </form>

  <div id="problemModal" class="modal" tabindex="-1" role="dialog" data-backdrop="false">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-body">
            <p>
              The local school wants a new playground.
              The lot they can use for the playground is shaped like a rectangle.
              The school has decided to let the students design the new playground.
              The students have decided that they want 1/4 of the playground to be a football field.
              Another 3/8 of the lot will be used for a basketball court.
              How much of the lot is remaining for the slides and swings?
            </p>
            <textarea id="inside-modal"></textarea>
        </div>

        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>        
      </div>      
    </div>
  </div>  
</div>`

CSS:

textarea#inside-modal {
  position:absolute;
  left:-4000px;
}

jQuery:

$("#showProblemLink").on("click", function() {
    //show the modal
  $('#problemModal').modal('show');
  //fill the hidden textarea with the real textarea's contents
  $('#problemModal textarea#inside-modal').val($('textarea#outside-modal').val());
  //capture user input in modal and send to outside textarea
  $('#problemModal textarea#inside-modal').on('input',function(e) {
    //fill the outside textarea with the inside textarea's contents
    $('textarea#outside-modal').val($('textarea#inside-modal').val());
  }).focus();
});
//when modal closed, send focus back to textarea
$("#problemModal").on('hidden.bs.modal',function() {
  $('textarea#outside-modal').focus();
});

See this bootply

Upvotes: 0

Callum
Callum

Reputation: 855

Some solutions I could think of for this would be to either:

  1. move your answer textarea to the dialog that has the question in it.

  2. or to use a popover instead of a modal.

So here is my example of using a popover rather than a modal.

Stackoverflow snippet, which looks terrible because it's missing all the bootstrap styling so check the bootply link:

$(".pop-div > a").popover({
  html: true,
  placement: "left",
  trigger: "click",
  title: function() {
    return $(this).siblings('.pop-title').text()
  },
  content: function() {
    return $(this).siblings('.pop-content').text()
  }
});
.pop-div {
  display: inline;
}
.pop-title,
.pop-content {
  display: none;
}
.popover-title {
  font-size: 15px;
}
.popover-content {
  font-size: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
  <form>
    <div class="form-group">
      <label>Answer (
        <div class="pop-div">
          <a href="javascript:void(0);">view problem</a>
          <div class="pop-title">Question</div>
          <div class="pop-content">
            <p>
              The local school wants a new playground. The lot they can use for the playground is shaped like a rectangle. The school has decided to let the students design the new playground. The students have decided that they want 1/4 of the playground to be a football
              field. Another 3/8 of the lot will be used for a basketball court. How much of the lot is remaining for the slides and swings?
            </p>
          </div>
        </div>
        )</label>
      <textarea class="form-control" rows="7"></textarea>
    </div>
  </form>
</div>

Upvotes: 1

Robin Carlo Catacutan
Robin Carlo Catacutan

Reputation: 13679

My problem is, when I click on the textarea, the dialog disappears. I tried adding data-backdrop="false".

It's because you're not actually clicking the textarea, you were clicking an overlay element which would close the modal when clicked.

I'm not sure if removing the overlay element would able you to input on the text area, but even so I don't think that's a good idea(removing the overlay and able you to do something behind while the modal is still up).

So what I suggest is to: Have a button on the modal when clicked it should show another textarea. And when you input something on the textarea it would update the contents inside the main text area.

So here's the new modal:

enter image description here enter image description here

See working example.

Upvotes: 2

SD.
SD.

Reputation: 9549

What you are trying to achieve is not easily possible.

  • Hiding modal background - easy
  • Moving whole modal div - medium
  • Making the text area behind the modal take the focus - very hard

I understand you want to save space on the page, that's why I would suggest the cleanest option and closest to what you are trying to achieve: Bootstrap Collapse

DEMO here

enter image description here

Upvotes: 2

Related Questions