简体   繁体   中英

How can I update page content without reloading the page on Modal close?

I am trying to edit a post on a page, clicking on edit link opens a Modal, clicking on save button, saves the edited post in the database but I have to refresh the page to see that edited post on the screen. I want the screen to be updated as soon as the modal is closed but I don't want the page to be reloaded. How can I achieve this without reloading the page?

Views.py

def editTweet(request, post_id):
    postData = Posts.objects.filter(id = post_id)
    if request.method == "PUT":
        data = json.loads(request.body)
        print("data value is ", data)
    
        #updating data in the database where id = post_id
        Posts.objects.filter(id = post_id).update(postContent = data.get('postContent', None))

        print ("i'm inside PUT")
        return render(request, 'network/index.html')
    else:    
        print("i'm inside else")
        return JsonResponse([post.serialize() for post in postData], safe=False) 

JavaScript

function loadModal(id) {
    //load the modal
    var modal = document.getElementById("myModal");
    var btn = document.getElementById("editLink");
    var span = document.getElementsByClassName("close")[0];
    var saveBtn = document.getElementById("saveButton");



    //populate the modal with tweet content
    fetch(`/edit/${id}`)
    .then(response => response.json())
    .then(postDetails => {
       
        modal.style.display = "block";
        postDetails.forEach(element => { 
            document.querySelector('#editPostBox').value = `${element.postContent}`;
    })

    })
   
   
    // When the user clicks on <span> (x), close the modal
    span.onclick = function () {
        modal.style.display = "none";
    }

    saveBtn.onclick = function(){
        fetch(`/edit/${id}`, {
            method: 'PUT',
            body: JSON.stringify({
              postContent: document.querySelector('#editPostBox').value
            })
        })
    
        modal.style.display = "none";
    }



    // When the user clicks anywhere outside of the modal, close it
    window.onclick = function (event) {
        if (event.target == modal) {
            modal.style.display = "none";
        }
    }
}

HTML

<!--The Modal-->
<div id="myModal" class="modal">

    <!--Modal content-->
    <div class="modal-content">
        <div class="modal-header">
            <h4>Edit Your Post</h4>
            <span class="close">&times;</span>
        </div>
        <div class="modal-body">
                <textarea name="editPostBox" id="editPostBox"></textarea>
                <button class="saveButton" id="saveButton" type="submit" >Save</button> 
            </div>
    </div>
</div>

<!--Modal for Editing Tweets - End-->

<div class="firstSection">
    <div class="container">
        <div class="card">
            <form method="POST">{% csrf_token %}
                <textarea name="newPostBox" id="newPostBox" placeholder="What's happening?"></textarea>
                <button class="btn btn-primary" type="submit" id="postButton" onclick='newPostFunc();'>Tweet</button>
            </form>
        </div>
    </div>
</div>


{% for d in page_obj %}
<div class="secondSection">
    <div class="container">
        <div class="card">
            <h4><a href="profile/{{d.created_by}}" class="userNameClick">{{d.created_by}}</a></h4>
            <a href="#" onclick="loadModal('{{d.id}}');" id="editLink">Edit</a>
            <p>{{d.postContent}}</p>
            <small>{{d.dateAndTime}}</small>
            <small>Likes</small>
        </div>
    </div>
    {% endfor %}

After fetch, You can choose Post Card Element and change inner text of it. this is my solution.

  1. HTML: should have each id of cards in Second Section so that we can choose card element by its id. and add p tag (which will render contents) id or class so that we can find this element and change its innerText
<div class="secondSection">
    <div class="container">
        <div class="card" id="d.id">
            <h4><a href="profile/{{d.created_by}}" class="userNameClick">{{d.created_by}}</a></h4>
            <a href="#" onclick="loadModal('{{d.id}}');" id="editLink">Edit</a>
            <p id="contents">{{d.postContent}}</p>
            <small>{{d.dateAndTime}}</small>
            <small>Likes</small>
        </div>
    </div>
  1. JavaScript: after fetch, you can choose card element by its id, and then inside of the card element's children, find 'p tag'(which renders post's contents) and then update inner text of it.
    saveBtn.onclick = function(){
        const updatedValue =document.querySelector('#editPostBox').value;
        fetch(`/edit/${id}`, {
            method: 'PUT',
            body: JSON.stringify({
              postContent:updatedValue
            })
        }).then(response=>{
            // if update succeeds in backend
            const updatedCard = document.querySelector(`# SpecificCard Id `);
            const children = updatedCard.children; // find children elements all
            for(let i = 0 ; i < children.length; i ++ ){
                if(children[i].id==='contents'){ // find contents p tag 
                    children[i].innerText=updatedValue; // change inner text of p tag 
                    return;
                }
            }
            
        }
        )
    
        modal.style.display = "none";
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM