Browse Source

more work on linked resources: adding and displaying multiple resources

joel
Simon Bowie 2 years ago
parent
commit
7e4f8bf843
6 changed files with 304 additions and 39 deletions
  1. +10
    -9
      web/app/create.py
  2. +7
    -5
      web/app/resources.py
  3. +29
    -0
      web/app/static/js/main.js
  4. +250
    -0
      web/app/static/styles/custom.css
  5. +3
    -22
      web/app/templates/base.html
  6. +5
    -3
      web/app/templates/create.html

+ 10
- 9
web/app/create.py View File

@@ -49,15 +49,16 @@ def create_resource():
db.session.add(new_tool)
db.session.commit()

if request.form.get('linked_practice_id'):
tool = Resource.query.filter_by(type='tool').filter_by(name=name).first()
first_resource_id = tool.id
second_resource_id = request.form.get('linked_practice_id')
new_relationship = Relationship(first_resource_id=first_resource_id, second_resource_id=second_resource_id)

# add the new relationship to the database
db.session.add(new_relationship)
db.session.commit()
if request.form.getlist('linked_resources'):
for linked_resource in request.form.getlist('linked_resources'):
tool = Resource.query.filter_by(type='tool').filter_by(name=name).first()
first_resource_id = tool.id
second_resource_id = linked_resource
new_relationship = Relationship(first_resource_id=first_resource_id, second_resource_id=second_resource_id)

# add the new relationship to the database
db.session.add(new_relationship)
db.session.commit()

elif request.form.get('resource_type') == 'practice':
type = 'practice'

+ 7
- 5
web/app/resources.py View File

@@ -23,17 +23,19 @@ def get_resource(resource_id):
def get_linked_resources(resource_id):
relationships = Relationship.query.filter_by(first_resource_id=resource_id).all()
if relationships:
links = []
for relationship in relationships:
resource_id = relationship.second_resource_id
links = Resource.query.filter_by(id=resource_id).all()
return links
resource_id = relationship.second_resource_id
links.extend(Resource.query.filter_by(id=resource_id).all())
return links
else:
relationships = Relationship.query.filter_by(second_resource_id=resource_id).all()
if relationships:
links = []
for relationship in relationships:
resource_id = relationship.first_resource_id
links = Resource.query.filter_by(id=resource_id).all()
return links
links.extend(Resource.query.filter_by(id=resource_id).all())
return links

# function to delete a single resource
def delete_resource(resource_id):

+ 29
- 0
web/app/static/js/main.js View File

@@ -0,0 +1,29 @@
/*
# @name: main.js
# @version: 0.1
# @creation_date: 2022-04-07
# @license: The MIT License <https://opensource.org/licenses/MIT>
# @author: Simon Bowie <ad7588@coventry.ac.uk>
# @purpose: JavaScript functions for various functions
# @acknowledgements:
# https://stackoverflow.com/questions/67942546/bootstrap-5-select-dropdown-with-the-multiple-attribute-collapsed
*/

// Dynamic HTML forms based on dropdown menu
$("#resource_type").change(function() {
var $ = jQuery.noConflict();
var resource_type = $(this).val();
$(".resource_type_input").hide("fast", function() {
$("#resource_type_" + resource_type).show("slow");
});
});

// Testing a couple of ways to expand text
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl)
})

+ 250
- 0
web/app/static/styles/custom.css View File

@@ -1036,3 +1036,253 @@ main > .container {
--bs-bg-opacity: 1;
background-color: rgba(var(--bs-practice-rgb),var(--bs-bg-opacity))!important;
}

.drop {
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.drop.open {
z-index: 100;
}
.drop.open .drop-screen {
z-index: 100;
display: block;
}
.drop.open .drop-options {
z-index: 200;
max-height: 200px;
}
.drop.open .drop-display {
z-index: 200;
border-color: #465;
}
.drop select {
display: none;
}
.drop .drop-screen {
position: fixed;
width: 100%;
height: 100%;
background: #000;
top: 0px;
left: 0px;
opacity: 0;
display: none;
z-index: 1;
}

.link {
text-align: center;
margin: 20px 0px;
color:#8CACD7;
}

.drop .drop-display {
position: relative;
padding: 0px 20px 5px 5px;
border: 4px solid #444;
width: 100%;
background: #FFF;
z-index: 1;
margin: 0px;
font-size: 16px;
min-height: 58px;
}
.drop .drop-display:hover:after {
opacity: 0.75;
}
.drop .drop-display:after {
font-family: 'Material Icons';
content: "\e5c6";
position: absolute;
right: 10px;
top: 12px;
font-size: 24px;
color: #444;
}
.drop .drop-display .item {
position: relative;
display: inline-block;
border: 2px solid #333;
margin: 5px 5px -4px 0px;
padding: 0px 25px 0px 10px;
overflow: hidden;
height: 40px;
line-height: 36px;
}
.drop .drop-display .item .btnclose {
color: #444;
position: absolute;
font-size: 16px;
right: 5px;
top: 10px;
cursor: pointer;
}
.drop .drop-display .item .btnclose:hover {
opacity: 0.75;
}
.drop .drop-display .item.remove {
-webkit-animation: removeSelected 0.2s, hide 1s infinite;
animation: removeSelected 0.2s, hide 1s infinite;
-webkit-animation-delay: 0s, 0.2s;
animation-delay: 0s, 0.2s;
}
.drop .drop-display .item.add {
-webkit-animation: addSelected 0.2s;
animation: addSelected 0.2s;
}
.drop .drop-display .item.hide {
display: none;
}
.drop .drop-options {
background: #444;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25);
position: absolute;
width: 100%;
max-height: 0px;
overflow-y: auto;
transition: all 0.25s linear;
z-index: 1;
}
.drop .drop-options a {
display: block;
height: 40px;
line-height: 40px;
padding: 0px 20px;
color: white;
position: relative;
max-height: 40px;
transition: all 1s;
overflow: hidden;
}
.drop .drop-options a:hover {
background: #465;
cursor: pointer;
}
.drop .drop-options a.remove {
-webkit-animation: removeOption 0.2s;
animation: removeOption 0.2s;
max-height: 0px;
}
.drop .drop-options a.add {
-webkit-animation: addOption 0.2s;
animation: addOption 0.2s;
}
.drop .drop-options a.hide {
display: none;
}

@-webkit-keyframes pop {
from {
-webkit-transform: scale(0);
transform: scale(0);
}
to {
-webkit-transform: scale(1);
transform: scale(1);
}
}

@keyframes pop {
from {
-webkit-transform: scale(0);
transform: scale(0);
}
to {
-webkit-transform: scale(1);
transform: scale(1);
}
}
@-webkit-keyframes removeOption {
from {
max-height: 40px;
}
to {
max-height: 0px;
}
}
@keyframes removeOption {
from {
max-height: 40px;
}
to {
max-height: 0px;
}
}
@-webkit-keyframes addOption {
from {
max-height: 0px;
}
to {
max-height: 40px;
}
}
@keyframes addOption {
from {
max-height: 0px;
}
to {
max-height: 40px;
}
}
@-webkit-keyframes removeSelected {
from {
-webkit-transform: scale(1);
transform: scale(1);
}
to {
-webkit-transform: scale(0);
transform: scale(0);
}
}
@keyframes removeSelected {
from {
-webkit-transform: scale(1);
transform: scale(1);
}
to {
-webkit-transform: scale(0);
transform: scale(0);
}
}
@-webkit-keyframes addSelected {
from {
-webkit-transform: scale(0);
transform: scale(0);
}
to {
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes addSelected {
from {
-webkit-transform: scale(0);
transform: scale(0);
}
to {
-webkit-transform: scale(1);
transform: scale(1);
}
}
@-webkit-keyframes hide {
from, to {
max-height: 0px;
max-width: 0px;
padding: 0px;
margin: 0px;
border-width: 0px;
}
}
@keyframes hide {
from, to {
max-height: 0px;
max-width: 0px;
padding: 0px;
margin: 0px;
border-width: 0px;
}
}

+ 3
- 22
web/app/templates/base.html View File

@@ -23,6 +23,7 @@
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link href="{{ url_for('static',filename='styles/custom.css') }}" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.14.0-beta2/css/bootstrap-select.min.css" integrity="sha512-mR/b5Y7FRsKqrYZou7uysnOdCIJib/7r5QeJMFvLNHNhtye3xJp1TdJVPLtetkukFn227nKpXD9OjUc09lx97Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>

<body class="d-flex flex-column min-vh-100">
@@ -149,28 +150,8 @@
<!-- jQuery first, then Popper JS, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script>
$("#resource_type").change(function() {
var resource_type = $(this).val();
$(".resource_type_input").hide("fast", function() {
$("#resource_type_" + resource_type).show("slow");
});
});
</script>
<script>
// Initialize tooltips
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>

<script>
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl)
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.14.0-beta2/js/bootstrap-select.min.js" integrity="sha512-FHZVRMUW9FsXobt+ONiix6Z0tIkxvQfxtCSirkKc5Sb4TKHmqq1dZa8DphF0XqKb3ldLu/wgMa8mT6uXiLlRlw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="{{ url_for('static',filename='js/main.js') }}"></script>
</body>

</html>

+ 5
- 3
web/app/templates/create.html View File

@@ -70,12 +70,14 @@
</div>

<div class="mb-3 mt-3">
<label for="linked_practice_id">Linked practices</label>
<select class="form-select" aria-label="Linked practices" name="linked_practice_id">
<option selected>Select a linked practice</option>
<label for="linked_practice_id">Linked resources</label>
<!--<select class="form-select" aria-label="Linked practices" name="linked_practice_id" multiple="multiple" id="linked_practice_id">-->
<select name="linked_resources" id="linked_resources" aria-label="Linked resources" class="selectpicker" data-live-search="true" multiple>
<optgroup label="Practices">
{% for practice_dropdown in practice_dropdown %}
<option value="{{ practice_dropdown['id'] }}">{{ practice_dropdown['name'] }}</option>
{% endfor %}
</optgroup>
</select>
</div>
</div>

Loading…
Cancel
Save