Load script tags from Child Component
See original GitHub issueHello, I am quite new to the world of Components and Django-Unicorn. (Btw: Great work keep it up!)
First to what I want to do:
I have a parent component that should only display 1 child component if a entered password is correct. The parent is a simple text-input field and a button to check the password.
While playing around I’ve encountered the following issue:
If I set the init value of the password check to True both components render as expected. And fully functionally. When I hide the child component initially and only load it when the password is correct though, the child component seems not able to execute its “onload” methods. Also a library imported via a <script> tag doesn’t load properly.
I am not at a loss whether it’s a Javascript or a limitation of Unicorn 😦
Here is some code as an example: Parent Component:
job = None
pw_correct = False
password = ''
def __init__(self, *args, **kwargs):
super().__init__(**kwargs)
self.job = kwargs.get("job")
def checkpw(self):
if self.password == self.job.password:
self.pw_correct = True
else:
self.pw_correct = False
Parent html:
{% load unicorn%}
<div>
{% if not pw_correct %}
<input type="password" unicorn:model="password"></input>
Enter Password to view files
<button unicorn:click="checkpw">Click</button>
{% endif %}
{% if pw_correct %}
{% unicorn 'proof' job=job parent=view %}
{% endif %}
</div>
Child Component:
from django_unicorn.components import UnicornView
from blattorder.models import Order, Proofing
from django.shortcuts import get_object_or_404
import json
class ProofView(UnicornView):
job = Order.objects.none()
proofs = Proofing.objects.none()
active = Proofing.objects.none()
jsonobject = {}
def __init__(self, *args, **kwargs):
super().__init__(**kwargs)
self.job = kwargs.get('job')
self.proofs = Proofing.objects.filter(job=self.job)
self.active = self.proofs[0]
def setactive(self, proofid):
self.active = get_object_or_404(Proofing, pk=proofid)
print(self.active.edit)
if self.active.edit:
self.jsonobject = json.loads(self.active.edit)
print(self.jsonobject)
self.call('setActiveId', str(self.active.edit) )
self.call('setURL', ('/bild/proof/'+ str(self.active.id)))
else:
self.call('setActiveId', '{}')
self.call('setURL', ('/bild/proof/'+ str(self.active.id)))
And Child Component html:
{% load unicorn %}
<div class="row ">
<script src="https://unpkg.com/markerjs2/markerjs2.js"></script>
<script>
function makeRequest(method, url, json) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
if(method=="post" && json){
xhr.send(JSON.stringify(json));
}else{
xhr.send();
}
});
}
let sourceImage, targetRoot, maState, url
url = '{% url 'blattproof' active.id %}';
{%if active.edit %}
maState = {{active.edit|safe}};
{% else %}
maState= {};
{% endif %}
// save references to the original image and its parent div (positioning root)
function setSourceImage(source) {
sourceImage = source;
console.log(source);
targetRoot = source.parentElement;
console.log(source.parentElement);
}
function showMarkerArea(target) {
const markerArea = new markerjs2.MarkerArea(sourceImage);
// since the container div is set to position: relative it is now our positioning root
// end we have to let marker.js know that
markerArea.targetRoot = targetRoot;
markerArea.addRenderEventListener((imgURL, state) => {
target.src = imgURL;
// save the state of MarkerArea
maState = state;
makeRequest('post', url, maState);
});
markerArea.show();
// if previous state is present - restore it
//maState=json
if (maState) {
markerArea.restoreState(maState);
}
}
function setActiveId(json){
maState = JSON.parse(json);
console.log(maState)
}
function setURL(urlstr){
url = urlstr;
console.log(url)
}
</script>
<div class="col-2 scrollbar scrollbar-black bordered-black square thin"style="width:450px;height:850px;overflow-y:scroll;">
{% for proof in proofs %}
<img src={{proof.image.url}} style="width:100%;" unicorn:click="setactive({{proof.id}})">
{% endfor %}
</div>
<div class='col'>
<div style="position: relative; display: flex; flex-direction: column; align-items: center; padding-top: 50px;">
<img style="height:800px;"
id="sourceImage"
class="invisible img-fluid"
src="{{active.image.url}}"
onload="setSourceImage(this);"
/>
<img
id="targetimage"
class="img-fluid"
src="{{active.image.url}}"
style="position: absolute; height:750px;"
onload="showMarkerArea(this);" />
</div>
</div>
</div>
Thanks in advance for your time and help!
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
Yes actually a configuration in the
Meta
class seems like a nicer way to do it. Especially in the case of a component that is re-used a lot.Hey Adam, yeah, theres lots going on ! lol Thanks for the reply and if you get a chance some time that would be great!