Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ The rules for this file:
* YYYY-MM-DD date format (following ISO 8601)
* accompany each entry with github issue/PR number (Issue #xyz)
-->
## Version 1.X.X

### Authors
talagayev

### Added
- Added Drag & Drop option for file upload in `OpenMMDL Setup` (2026-02-28, PR#187)

### Fixed

### Changed

## Version 1.2.0

### Authors
Expand Down
9 changes: 9 additions & 0 deletions openmmdl/openmmdl_setup/static/openmmdl.css
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,12 @@ pre code { color: inherit; }
font-size: 13px;
color: #475569;
}

.om-filedrop { cursor: pointer; }
.om-filedrop .om-filedrop-label:empty::before {
content: "Drag & drop file here";
color: #94a3b8;
}
.om-filedrop.is-dragover .om-filedrop-label {
box-shadow: 0 0 0 2px rgba(15,23,42,0.25);
}
8 changes: 4 additions & 4 deletions openmmdl/openmmdl_setup/templates/AmberOptions.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{% extends "layout.html" %}
{% block title %}Prepare Amber Files{% endblock %}

{% macro fileinput(id, title) %}
<div class="input-group">
{% macro fileinput(id, title="") %}
<div class="input-group om-filedrop" data-file-input="{{ id }}">
<label class="btn btn-default btn-file input-group-addon" >
Browse... <input type="file" name="{{ id }}" id="{{ id }}" style="display: none" onchange="optionChanged()" />
</label>
<span id="{{ id }}_label" class="form-control" style="overflow: hidden;overflow-wrap: anywhere;" title="{{title}}"/>
<span id="{{ id }}_label" class="form-control om-filedrop-label" style="overflow: hidden; overflow-wrap: anywhere;" title="{{ title }}"></span>
</div>
{% endmacro %}

Expand Down Expand Up @@ -53,7 +53,7 @@
<div id="protOptions">
<div class="form-group">
<div class="row">
<div class="col-lg-4" style="padding-left: 30px">
<div class="col-lg-6" style="padding-left: 30px">
<label for="protLabel"> Receptor File (.pdb) </label>
{{ fileinput('protFile') }}
</div>
Expand Down
4 changes: 2 additions & 2 deletions openmmdl/openmmdl_setup/templates/configureAmberFiles.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{% extends "layout.html" %}

{% macro fileinput(id) %}
<div class="input-group">
<div class="input-group om-filedrop" data-file-input="{{ id }}">
<label class="btn btn-default btn-file input-group-addon">
Browse... <input type="file" name="{{ id }}" id="{{ id }}" style="display: none" {{'disabled' if disabled else ''}} onchange="optionChanged()" />
</label>
<span id="{{ id }}_label" class="form-control" />
<span id="{{ id }}_label" class="form-control om-filedrop-label"></span>
</div>
{% endmacro %}

Expand Down
4 changes: 2 additions & 2 deletions openmmdl/openmmdl_setup/templates/configurePdbFile.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{% extends "layout.html" %}

{% macro fileinput(id) %}
<div class="input-group">
<div class="input-group om-filedrop" data-file-input="{{ id }}">
<label class="btn btn-default btn-file input-group-addon">
<span title="Select File"style=" font-weight: 700;">Browse... </span>
<input type="file" name="{{ id }}" id="{{ id }}" style="display: none" onchange="optionChanged()"/>
</label>
<span id="{{ id }}_label" class="form-control"/>
<span id="{{ id }}_label" class="form-control om-filedrop-label"></span>
</div>
{% endmacro %}

Expand Down
71 changes: 71 additions & 0 deletions openmmdl/openmmdl_setup/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,77 @@
setTimeout(function() {animateSpinner()}, 1000)
}
</script>
<script>
/* File drag & drop */
(function() {
function wire(zone) {
var inputId = zone.getAttribute('data-file-input');
if (!inputId) return;
var input = document.getElementById(inputId);
if (!input) return;

function setDrag(active) {
if (active) zone.classList.add('is-dragover');
else zone.classList.remove('is-dragover');
}

// Click anywhere on the widget to open the file picker.
zone.addEventListener('click', function(e) {
if (input.disabled) return;
// Avoid double-triggering when clicking the native Browse label.
if (e.target && (e.target.tagName === 'INPUT')) return;
input.click();
});

zone.addEventListener('dragenter', function(e) {
if (input.disabled) return;
e.preventDefault();
setDrag(true);
});

zone.addEventListener('dragover', function(e) {
if (input.disabled) return;
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
setDrag(true);
});

zone.addEventListener('dragleave', function(e) {
setDrag(false);
});

zone.addEventListener('drop', function(e) {
if (input.disabled) return;
e.preventDefault();
setDrag(false);

var files = (e.dataTransfer && e.dataTransfer.files) ? e.dataTransfer.files : null;
if (!files || files.length === 0) return;

// Respect single-file inputs.
if (!input.multiple && files.length > 1) {
var dt = new DataTransfer();
dt.items.add(files[0]);
input.files = dt.files;
} else {
input.files = files;
}

// Trigger existing onchange handlers (optionChanged()).
input.dispatchEvent(new Event('change', { bubbles: true }));
});
}

document.addEventListener('DOMContentLoaded', function() {
var zones = document.querySelectorAll('.om-filedrop[data-file-input]');
for (var i = 0; i < zones.length; i++) wire(zones[i]);
});

// Prevent the browser from navigating away when dropping files outside dropzones.
window.addEventListener('dragover', function(e) { e.preventDefault(); });
window.addEventListener('drop', function(e) { e.preventDefault(); });
})();
</script>
</head>
<body>
<div class="container-fluid om-shell">
Expand Down
Loading