menu

Questions & Answers

Updating the URLField of model with JavaScript

I have a page that displays some information about website admins such as username, skills, Instagram profile and bio. The admins are able to edit their profile information and the update is being saved using JavaScript fetch. When I click on the save button everything except the Instagram profile which is a URLField gets updated. For Instagram element to be updated I need to reload the page. How can I make it get updated without reloading the page? Everything is correct in the console log.

about.js:

document.addEventListener("DOMContentLoaded", function(){

    const button = document.querySelectorAll("#edit_profile")
    button.forEach(function(button){
        button.onclick = function(){
            const username = document.getElementById(`username_${memberID}`);
            const skills = document.getElementById(`skills_${memberID}`);
            const bio = document.getElementById(`bio_${memberID}`);
            var instagram = document.getElementById(`instagram_${memberID}`).href;

            let edit_username = document.createElement("textarea");
            edit_username.setAttribute("rows", "1");
            edit_username.innerHTML = username.innerHTML
            edit_username.id = `edit_username_${memberID}`;
            edit_username.className = `form-control username ${usernameID}`;
            
            let edit_skills = document.createElement("textarea");
            ...
            
            let edit_instagram = document.createElement("textarea");
            edit_instagram.setAttribute("rows","1");
            edit_instagram.innerHTML = instagram;
            edit_instagram.id = `edit_instagram_${memberID}`;
            edit_instagram.className = "form-control social-media";

            const saveButton = document.createElement("button");
            saveButton.innerHTML = "Save";
            saveButton.id = `saveButton_${memberID}`;
            saveButton.className = "btn btn-success col-3";
            saveButton.style.margin = "10px";
            
            document.getElementById(`edit_${memberID}`).append(edit_username);
            ...
            document.getElementById(`edit_${memberID}`).append(edit_instagram);
            document.getElementById(`edit_${memberID}`).append(saveButton);

            // When the save button is clicked
            saveButton.addEventListener("click", function(){
                edit_username = document.getElementById(`edit_username_${memberID}`);
                ...
                edit_instagram = document.getElementById(`edit_instagram_${memberID}`);
            
                fetch(`/edit_profile/${memberID}`,{
                    method: "POST",
                    body: JSON.stringify({
                        username: edit_username.value,
                        skills: edit_skills.value,
                        instagram: edit_instagram.value,
                        bio: edit_bio.value,
                    })
                })
                .then(response => response.json())
                .then(result => {
                    console.log(result);
                    if(result[`error`]){
                    cancel(memberID)
                    } 
                    else {
                        username.innerHTML = result.username;
                        secusername.innerHTML = result.username;
                        skills.innerHTML = result.skills;
                        instagram = result.instagram;
                        bio.innerHTML = result.bio;
                    }
                })
            })
        }
    });
})
  

about.html:

{% for member in team_members %}
      <div class="col" id="border">
<!--If user is admin, show edit button-->
        {% if user.is_superuser %}
        <div class="position-relative" id="edit_button_{{member.id}}" style="display: block;">
          <button class="btn btn-lg position-absolute top-0 end-0" id="edit_profile" data-id="{{member.id}}" data-username="{{member.username}}">
          <i class="fa fa-edit fa-solid" style="color: white; margin-right: 5px;"></i></button>
        </div>
        {% endif %}
        
        <!--Edit form-->
            <div class="form-group" id="edit_{{member.id}}">
            </div>
     
          <!--Display username,skills,socials and bio-->
            <div id="remove_{{member.id}}" style="display: block;">
              <h3 class="username" id="username_{{member.id}}">{{member.username}}</h3>
              <p class ="skills" id="skills_{{member.id}}">{{member.skills}}</p>
              <p><a class="social-media" href="{{member.instagram}}" id="instagram_{{member.id}}"><i class="fa-brands fa-instagram fa-solid" style="color: #e3c142; margin-right: 5px;"></i></a>
              <a class="social-media" href="{{member.itch_profile}}" id="itch_{{member.id}}"><i class="fa-brands fa-itch-io" style="color: #e3c142;"></i></a>
              <div class="bio">
                  <strong class="username" id="secusername_{{member.id}}"  style="font-size: large;">{{member.username}}, </strong><p id="bio_{{member.id}}">{{member.bio}}</p>
              </div>
            </div>
        </div>
      </div>
      {% endfor %}

views.py:

@csrf_exempt
def edit_profile(request, member_id):
    if request.method != "POST":
        return JsonResponse({"error": "POST request required."}, status=400)
    team_members = Team.objects.get(id = member_id)

    body_unicode = request.body.decode('utf-8')
    body = json.loads(body_unicode)
    username = body['username']
    skills = body['skills']
    instagram = body['instagram']
    itch_profile = body['itch_profile']
    bio = body['bio']
    Team.objects.filter(id=member_id).update(username=f'{username}',skills=f'{skills}',instagram=f'{instagram}',itch_profile=f'{itch_profile}',bio=f'{bio}')
    return JsonResponse({"message": "Successful", "username": username, "skills": skills, "instagram":instagram, "itch_profile":itch_profile, "bio": bio}, status=200)
Answers(1) :

You're assigning the instagram variable to the href attribute of the edit_instagram element, rather than its value. Since the fetch request is sending the value of the edit_instagram element, the Instagram URL will not be updated in the backend if the instagram variable is assigned to the href attribute.

So you can change the line of code where you assign the instagram variable to the following:

var instagram = document.getElementById(`instagram_${memberID}`).value;

Also, you need to update the 'instagram' element value after successful fetch call:

instagram.href = result.instagram;

This should update the Instagram URL field in the backend without requiring a page reload.