reload content of html on dropdown selected

hi all,
I have a model as follow

class EsameObiettivo(models.Model):
    title = models.CharField(max_length=20,default=None,null=True,blank=True,)
    descrizione = models.TextField(default=None,null=True,blank=True,)
    score = models.JSONField(default=dict,null=True,blank=True,)
    @property
    def get_title(self):
        return self.title
    @property
    def get_score_id(self):
        return self.id

class Visita(models.Model):
    title = models.CharField(max_length=20,default=None,null=True,blank=True,)
    score = models.JSONField(default=dict,null=True,blank=True,)
    def __str__(self):
        return self.title

i would create a webpage with a dropdown menu of all “esameObiettivo” and if user select one of them change the printed score jsonscript on html page in order to let user compile score fields and post to code the jsonscript of answer. But each “esameObiettivo” has its score base

I hope explain well what I would like to do.

You have (at least) three ways of doing this:

  • Add a “select” button, and submit the selection of the dropdown as a form to re-render the page with the new data.

  • Use JavaScript to directly capture the “change” event triggered by the select field and issue an AJAX-style request to get the new data, then inject that data into the page.

  • Use HTMX to trigger a partial page refresh based upon the selection in the dropdown widget.

I’m trying with

<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script>
  $(document).ready(function() {
    $("#scoreList").change(function () {
      var pageURL = $(location).attr("href");
      alert(pageURL);
        const scoreListId = $(this).val();  // get the selected subject ID from the HTML dropdown list 
        $.ajax({                       // initialize an AJAX request
            type: "GET",
            url: pageURL,
            data: {
                'scoreList_id': scoreListId,     
                'csrfmiddlewaretoken': '{{ csrf_token }}',
            },
        });
    });
  });
</script>

and I have

@login_required(login_url='adminlogin')
@user_passes_test(is_admin_or_doctor)
def add_patient_visita_view(request,pk):
    print("----------------",pk, request)
    patient=models.Patient.objects.get(id=pk)
    patientForm=forms.PatientForm(instance=patient)  
    scoreList = [{'id': i.id, 'title':i.get_title} for i in models.EsameObiettivo.objects.all()]
    if request.method=='GET':
        visita=models.Visita.objects.all()
        visita=models.Visita.objects.all().filter(patient_id=patient.get_patient_id).latest('created')
        if visita:
            visitaForm=forms.PatientVisitaForm(instance=visita)
            visitaForm.id = None
        else:
            visitaForm=forms.PatientVisitaForm()

        mydict={'patientForm':patientForm,'visitaForm':visitaForm,'scoreList':scoreList}   

    elif request.method=='POST':
        print("REQUEST POST",request.POST)
        visitaForm=forms.PatientVisitaForm(request.POST)
        if visitaForm.is_valid():
            print("scrittura 1")

            visitaNew = visitaForm.save(commit=False)
            visitaNew.id = None
            visitaNew.patient_id = pk
            visitaNew.doctor_id = 1
            visitaNew.save()
            mydict={'patientForm':patientForm,'visitaForm':visitaForm,}
        else:
            print(visitaForm.errors)

    return render(request,'hospital/admin2patient/admin_add_patient_visita.html',context=mydict)

and with get I would reload just “‘scoreList’:scoreList” and not all other inputs already inserted in PatientVisitaForm how can I do?

There are a couple things here to point out:

There’s no need to supply the csrf_token on a GET because the GET request is considered a “safe” method.
(It’s not an error to supply it, it’s just not being checked.)

  • You’re not doing anything with the response from the GET. You need to have some code that processes the response and injects it into the page. In this case, by probably changing the value of the form widgets being updated. (Don’t forget to update any hidden fields like the id.)

  • Your view to retrieve this data should be a separate view that retrieves the specific data and returns it as a JSON object, not a fully-rendered page. Your JavaScript would accept this JSON object and use the values supplied to update the form fields.

An htmx version of this would have you render just the form portion as html, and the JavaScript would replace the form in the DOM with what the view has returned. But again, you’re not rendering a complete page - just the portion to be replaced from the original. But you don’t need to use HTMX to do this. You could handle this within your own JavaScript.

many many thanks

just last question
can you suggest me how to render a response from GET? can you suggest some lines then I continue improve it on my own
many thanks

I don’t have any specific resources to share.

You can search the internet for tutorials, blogs, and other resources. You might want to start with “Updating DOM JavaScript”.

MDN is always a good resource - you might want to start with DOM scripting introduction - Learn web development | MDN

thank your help:
i’m trying a lot in the last hours but I cannot reach results

basically I would like that if user select an option from dropdown, automatically the page must create list of field with the parameter inside the EsameObiettivo.score json structure:
Jsonfield is like
{[“question1”:“question1”, “answer”:“”],[“question2”:“question2”, “answer2”:“”],…}
so the field are

text with question1 - input text field for answer1
text with question1 - input text field for answer2

I’m trying with this view:

@login_required(login_url='adminlogin')
@user_passes_test(is_admin_or_doctor)
def add_patient_visita_view(request,pk):
    print("----------------",pk, request)
    patient=models.Patient.objects.get(id=pk)
    patientForm=forms.PatientForm(instance=patient)  
    scoreList = [{'id': i.id, 'title':i.get_title} for i in models.EsameObiettivo.objects.all()]
    if request.method=='GET':
        if request.GET.get('scoreList_id'):
            scoreQuestion = models.EsameObiettivo.objects.get(id=request.GET.get('scoreList_id'))
            mydict={'scoreQuestion': scoreQuestion.score}
        else:
            visita=models.Visita.objects.all()
            visita=models.Visita.objects.all().filter(patient_id=patient.get_patient_id).latest('created')
            if visita:
                visitaForm=forms.PatientVisitaForm(instance=visita)
            else:
                visitaForm=forms.PatientVisitaForm()
            scoreQuestion = {}
            mydict={'patientForm':patientForm,'visitaForm':visitaForm,'scoreList':scoreList,'scoreQuestion': scoreQuestion}   

    elif request.method=='POST':
        print("REQUEST POST",request.POST)
        visitaForm=forms.PatientVisitaForm(request.POST)
        if visitaForm.is_valid():
            visitaNew = visitaForm.save(commit=False)
            visitaNew.id = None
            visitaNew.patient_id = pk
            visitaNew.doctor_id = 2
            visitaNew.save()
            mydict={'patientForm':patientForm,'visitaForm':visitaForm,'scoreList':scoreList}
        else:
            scoreQuestion = {} #1
            mydict={'patientForm':patientForm,'visitaForm':visitaForm,'scoreList':scoreList,'scoreQuestion': scoreQuestion}  

    
    #return HttpResponseRedirect(reverse('update-patient', kwargs={"pk": pk}))
    return render(request,'hospital/admin2patient/admin_add_patient_visita.html',context=mydict)

and ajax function:

<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script>
  $(document).ready(function() {
    $("#scoreList").change(function () {
      var pageURL = $(location).attr("href");
        const scoreListId = $(this).val();  // get the selected subject ID from the HTML dropdown list 
        $.ajax({                       // initialize an AJAX request
            type: "GET",
            url: pageURL,
            data: {
                'scoreList_id': scoreListId,
                //'csrfmiddlewaretoken': '{{ csrf_token }}',
            },
        });
    });
  });
</script>

but never return new value. Initially I trying imposing scoreQuestion to a simple number instead of json structure that would change the number in

{% if scoreQuestion %}
<p id="idtemp">{{ scoreQuestion }}</p>
{% else %}
<p>none</p>
 {% endif %}

You are not showing any code here that implements the suggestions mentioned above at reload content of html on dropdown selected - #4 by KenWhitesell

You need to do those things.