db.session.add(new_tool) | db.session.add(new_tool) | ||||
db.session.commit() | db.session.commit() | ||||
if request.form.get('linked_practice_id'): | if request.form.getlist('linked_resources'): | ||||
tool = Resource.query.filter_by(type='tool').filter_by(name=name).first() | for linked_resource in request.form.getlist('linked_resources'): | ||||
first_resource_id = tool.id | tool = Resource.query.filter_by(type='tool').filter_by(name=name).first() | ||||
second_resource_id = request.form.get('linked_practice_id') | first_resource_id = tool.id | ||||
new_relationship = Relationship(first_resource_id=first_resource_id, second_resource_id=second_resource_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 | # add the new relationship to the database | ||||
db.session.add(new_relationship) | db.session.add(new_relationship) | ||||
db.session.commit() | db.session.commit() | ||||
elif request.form.get('resource_type') == 'practice': | elif request.form.get('resource_type') == 'practice': | ||||
type = 'practice' | type = 'practice' |
def get_linked_resources(resource_id): | def get_linked_resources(resource_id): | ||||
relationships = Relationship.query.filter_by(first_resource_id=resource_id).all() | relationships = Relationship.query.filter_by(first_resource_id=resource_id).all() | ||||
if relationships: | if relationships: | ||||
links = [] | |||||
for relationship in relationships: | for relationship in relationships: | ||||
resource_id = relationship.second_resource_id | resource_id = relationship.second_resource_id | ||||
links = Resource.query.filter_by(id=resource_id).all() | links.extend(Resource.query.filter_by(id=resource_id).all()) | ||||
return links | return links | ||||
else: | else: | ||||
relationships = Relationship.query.filter_by(second_resource_id=resource_id).all() | relationships = Relationship.query.filter_by(second_resource_id=resource_id).all() | ||||
if relationships: | if relationships: | ||||
links = [] | |||||
for relationship in relationships: | for relationship in relationships: | ||||
resource_id = relationship.first_resource_id | resource_id = relationship.first_resource_id | ||||
links = Resource.query.filter_by(id=resource_id).all() | links.extend(Resource.query.filter_by(id=resource_id).all()) | ||||
return links | return links | ||||
# function to delete a single resource | # function to delete a single resource | ||||
def delete_resource(resource_id): | def delete_resource(resource_id): |
/* | |||||
# @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) | |||||
}) |
--bs-bg-opacity: 1; | --bs-bg-opacity: 1; | ||||
background-color: rgba(var(--bs-practice-rgb),var(--bs-bg-opacity))!important; | 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; | |||||
} | |||||
} |
<!-- Bootstrap CSS --> | <!-- 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="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 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> | </head> | ||||
<body class="d-flex flex-column min-vh-100"> | <body class="d-flex flex-column min-vh-100"> | ||||
<!-- jQuery first, then Popper JS, then Bootstrap JS --> | <!-- 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://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 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> | <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> | ||||
$("#resource_type").change(function() { | <script src="{{ url_for('static',filename='js/main.js') }}"></script> | ||||
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> | |||||
</body> | </body> | ||||
</html> | </html> |
</div> | </div> | ||||
<div class="mb-3 mt-3"> | <div class="mb-3 mt-3"> | ||||
<label for="linked_practice_id">Linked practices</label> | <label for="linked_practice_id">Linked resources</label> | ||||
<select class="form-select" aria-label="Linked practices" name="linked_practice_id"> | <!--<select class="form-select" aria-label="Linked practices" name="linked_practice_id" multiple="multiple" id="linked_practice_id">--> | ||||
<option selected>Select a linked practice</option> | <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 %} | {% for practice_dropdown in practice_dropdown %} | ||||
<option value="{{ practice_dropdown['id'] }}">{{ practice_dropdown['name'] }}</option> | <option value="{{ practice_dropdown['id'] }}">{{ practice_dropdown['name'] }}</option> | ||||
{% endfor %} | {% endfor %} | ||||
</optgroup> | |||||
</select> | </select> | ||||
</div> | </div> | ||||
</div> | </div> |