I have django application with quiz model:
class Quiz(models.Model):
name = models.CharField(max_length=50)
topic = models.CharField(choices=TOPICS, max_length=50)
number_of_questions = models.IntegerField(validators=[MinValueValidator(1)])
time = models.IntegerField(help_text="duration of quiz in minutes", default=5)
pass_score = models.IntegerField(help_text="score required to pass in %", default=90, validators = [MaxValueValidator(100), MinValueValidator(0)])
difficulty = models.CharField(choices=DIFFICULTY_CHOICES, max_length=10)
I get it in view:
def quiz_view(request, pk):
quiz = models.Quiz.objects.get(pk=pk)
return render(request, 'quizes/quiz.html', {'obj':quiz})
Then I get data of obj in html:
{% for obj in object_list %}
<button data-pk="{{ obj.pk }}" data-name="{{ obj.name }}" data-topic="{{ obj.topic }}" data-questions="{{ obj.number_of_questions }}" data-difficulty="{{ obj.difficulty }}" data-time="{{ obj.time }}" data-pass="{{ obj.pass_score }}">
{{ obj.name }}
</button>
{% endfor %}
<div id="modal"></div>
Then I get data from button in javascript forEach method:
let modal = document.getElementById('modal')
const modalBtns = [...document.getElementsByClassName('modal-button')]
modalBtns.forEach(modalBtn => modalBtn.addEventListener('click', ()=>{
const pk = modalBtn.getAttribute('data-pk')
const name = modalBtn.getAttribute('data-name')
const topic = modalBtn.getAttribute('data-topic')
const numQuestions = modalBtn.getAttribute('data-questions')
const difficulty = modalBtn.getAttribute('data-difficulty')
const passScore = modalBtn.getAttribute('data-pass')
const time = modalBtn.getAttribute('data-time')
if(modal.classList.contains('close-modal')){
modal.classList.remove('close-modal')
}
modal.classList.add('open-modal')
modal.innerHTML = `
<p >Are you sure you want to open</p><p ><b>${name}?</b></p>
<ul >
<li>Topic: ${topic}</li>
<li>Questions: ${numQuestions}</li>
<li>Difficulty: ${difficulty}</li>
<li>Score to pass: ${passScore}%</li>
<li>Time to solve: ${time} min</li>
</ul>
<div >
<button onclick="close_modal()">Close</button>
<button id='start_button' onclick="startQuiz()">Yes</button>
</div>
`
}))
So when user clicks on button it sets open-modal:
.open-modal{
visibility: visible !important;
}
And we can see it. Then when I click 'proceed-button', I should get pk by running startQuiz():
function startQuiz(){
console.log(pk)
}
But I get an error: `'pk' is not defined'.
Can I somehow get pk from forEach method?
CodePudding user response:
i found your problem. You can't use a const
. Constants have a block scope. Use parameters instead. A snippet of your javascript could be:
let modal = document.getElementById('modal')
const modalBtns = [...document.getElementsByClassName('modal-button')]
modalBtns.forEach(modalBtn => modalBtn.addEventListener('click', ()=>{
const pk = modalBtn.getAttribute('data-pk')
const name = modalBtn.getAttribute('data-name')
const topic = modalBtn.getAttribute('data-topic')
const numQuestions = modalBtn.getAttribute('data-questions')
const difficulty = modalBtn.getAttribute('data-difficulty')
const passScore = modalBtn.getAttribute('data-pass')
const time = modalBtn.getAttribute('data-time')
if(modal.classList.contains('close-modal')){
modal.classList.remove('close-modal')
}
modal.classList.add('open-modal')
modal.innerHTML = `
<p >Are you sure you want to open</p><p ><b>${name}?</b></p>
<ul >
<li>Topic: ${topic}</li>
<li>Questions: ${numQuestions}</li>
<li>Difficulty: ${difficulty}</li>
<li>Score to pass: ${passScore}%</li>
<li>Time to solve: ${time} min</li>
</ul>
<div >
<button onclick="close_modal()">Close</button>
<button id='start_button' onclick="startQuiz(${pk})">Yes</button>
</div>
`
}))
function startQuiz(pk){
console.log(pk)
}
With some value types it can happen that it doesn't work properly. If it doesn't work, write a comment with the type of pk
.