Ram Ram - 7 months ago 8
Javascript Question

Resizable stops working on div after its contents are updated

I am using jQuery UI's

resizable
function to make a div (bootstrap panel) that displays the contents of the file uploaded resizable. Resizable works on the div initially but after I update it with the contents of the file uploaded it stops working and the resizable cursor doesn't appear. This behavior can be observed in the snippet below and this jsfiddle.



$("#filePreview").resizable({
handles: "n, s",
minHeight: 100
});

function readFile(file) {
var reader = new FileReader();
reader.onload = readSuccess;

function readSuccess(evt) {
$('#filePreview').text(evt.target.result);
};
reader.readAsText(file);
}

$(document).on('change', '#inputFile', function() {
readFile(this.files[0]);
});

.preview-panel {
white-space: pre-line;
overflow-y: scroll;
min-height: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.theme.css" rel="stylesheet"/>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>

<div class="container">
<form class="form-inline">
<div class="form-group">
<label for="inputFile">File Input</label>
<input type="file" class="form-control" id="inputFile">
</div>
</form>
<div class="panel panel-default">
<div class="panel-heading">File Preview</div>
<div class="panel-body preview-panel" id="filePreview"></div>
</div>
</div>





I have seen questions on resizable for dynamically added elements and tried reinitializing resizable after the div is updated with the new file content but it didn't work. How do I make
resizable
work on the div even after its content changes to display the preview of the last uploaded file?

Answer

Have you tried "destroying" the resizable div before setting the text and then re-initializing it after setting the text?

function readFile(file) {
  var reader = new FileReader();
  reader.onload = readSuccess;

  function readSuccess(evt) {
    $('#filePreview').resizable('destroy');
    $('#filePreview').text(evt.target.result);
    $("#filePreview").resizable({
      handles: "n, s",
      minHeight: 100
    });
  };
  reader.readAsText(file);
}

I don't know if this is a quirk of the plugin, but you have to scroll to the top of the content in the div in order to see/use the resizable "handles".

EDIT: To fix the issue with the "handle" losing its position when scrolling, I've added a helper function to add a top value using the the scrollTop value of #filePreview + the height of the .preview-panel + an additional offset (27px in this case). Whenever the scroll event is triggered on #filePreview, I'm adjusting the position of the handle accordingly.

$("#filePreview").on('scroll', function() {
  adjustHandlePosition();
});

function adjustHandlePosition() {
  $('.ui-resizable-s').css('top', ($("#filePreview").scrollTop() + $('.preview-panel').height() + 27) + "px");
}

The adjustHandlePosition() method is also being called when the resize event occurs for #filePreview:

$("#filePreview").resizable({
  handles: "n, s",
  minHeight: 100,
  resize: function(event, ui) {
    adjustHandlePosition();
  }
});

Updated Fiddle

Comments