How can I reset form after render template and hide modal - javascript

I have a django view and I render a template like this:
return render(request, 'submission/submit_url.html',
{'form': form, 'has_modal_info': 1})
On my template (submit_url), I get that variable "has_modal_info" and depending on the value (0 or 1) I decide to call or not my modal:
<!-- Modal content-->
<div class="modal-content">
{% if has_modal_info %}
{% include 'submission/finishing_modal.html' %}
<script>
var finishing_modal = $('#end-submission-modal');
finishing_modal.modal();
</script>
<script>
finishing_modal.on('hidden.bs.modal', function(e){
var id_url_form = $('#id_url_form');
id_url_form[0].reset();
console.log("Your event works!");
});
</script>
{% endif %}
</div>
</div>
</div>
The form I'm trying to reset:
<form id="id_url_form" action="{% url 'pages.submission.views.submit_url' %}" class="form-horizontal" method="post" enctype="multipart/form-data" name="url_form">
After rendering and submitting the form, I call my modal and try to "hook" the hidden event by resetting my form on that event for clearing all fields, but it doesn't work.
Tried Jquery trigger and a lot of possibilities but no success.
My opinion is that this happens because django render is Hooked my my modal call and can't clear the form, but I have no idea how to work this around.
Any suggestions?

Can you try this
id_url_form.each(function(){
$(this).val('')
}

Related

jQuery to close menu when form submitted / prevent function on error + update list with htmx

So what I have is a simple form with couple of fields that is located inside a menu, that slides in when I click button 'btn-openmenu'. I am trying to use htmx to dynamically update the page to show results instantly and also Javascript to control the menu where the form is located.
What I am trying to accomplish is that when the submit button on the form is pushed, it will submit the form and close the menu.
What happens now is that the menu closes okay when the form is submitted. What also can happen is that if the form is not valid and a error pops up, but the menu still closes and the form is never submitted.
Here is the html where form is located form (/items/new-item/):
{% load crispy_forms_tags %}
<form id="createnewitem"
hx-post="/items/new-item/">
{% csrf_token %}
{{ newcoreprocess|crispy }}
<div style="margin-top: 10px;">
<button type="submit" class="btn submit-new">Create item</button>
<a class="btn" id="clear">Clear</button>
</div>
</form>
<script>
$(document).ready(() => {
$('#clear').on('click', function () {
var form = $("#createnewitem");
form[0].reset();
})
})
</script>
<script>
$(document).ready(() => {
$('.submit-new').click(function () {
var pagecontent = $("#content");
var menu = $(".menu");
var buttonSpan = $("#btn_openmenu").find('span');
pagecontent.css('marginLeft', '0');
menu.css('width', '0');
buttonSpan.text('Close');
})
})
</script>
Here is the html where the menu is opened and updated list would be rendered (/items/):
<div class="items-content" id="itemcontent">
<div class="container-fluid">
<div class="row" id="items-list">
{% include 'items/items-list.html' %}
</div>
</div>
<button class="btn" id="btn_openmenu"
hx-get="/items/new-item/"
hx-target="#createitemmenu"
hx-swap="innerHTML">
<i class="fas fa-plus-circle" id="add-item-icon"></i><span class="spanicon" id="add-item-span">Create item</span>
</button>
<div class="menu">
<div class="container-fluid" id="createitemmenu">
</div>
</div>
</div>
<script>
$(document).ready(() => {
$('#btn_openmenu').on('click', function () {
var thisElement = $(this);
var buttonSpan = thisElement.find('span');
var pagecontent = $("#itemcontent");
var menu = $(".menu");
if(buttonSpan.text() === "Close"){
buttonSpan.text('Create item');
menu.css('width', '0');
pagecontent.css('marginLeft', '0');
}
else {
if(buttonSpan.text() === "Create item"){
buttonSpan.text('Close');
pagecontent.css('marginLeft', '20%');
menu.css('width', '20%');
}
}
})
})
</script>
And here is the list (/items/item-list/)
{% if items %}
<nav class="nav processnav flex-column" style="padding-top: 10px;">
{% for item in items %}
<a class="nav-link" href="#">{{ item.order }} {{ item.name }}</a>
{% endfor %}
</nav>
{% else %}
<div class="container-fluid mt-3">
<span>No created items</span>
</div>
{% endif %}
What is working:
menu opens correctly
htmx renders the form in the menu
form can be submitted and if valid, the menu will close
What is not working:
if errors on submit, it still closes the menu
I have tried to edit the function submit-new.click, but whatever I change in that, it stops working at all and this is only function I got to work with valid submit
htmx doesn't render the updated list where new item is created
I have tried to edit the hx-post in the form, but whatever I edit the new item submit stops working and it renders some other content to the place, where the form is located.
I think there are just little things I am missing, but I cannot seem to get it function the way I want. Any help for the issue?

Hide and show elements inside Django HTML template

I have 2 buttons orders, and suppliers., and want to show data in a Django web app when the corresponding button is clicked. To do this my home.html looks like
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".button_order").click(function(){
$(".myorders").show();
$(".mysupplier").hide();
});
$(".button_supplier").click(function(){
$(".myorders").hide();
$(".mysupplier").show();
});
});
</script>
syle.css looks like;
.myorders,
.mysupplier{
font-size: 25px;
display: none;
}
This works perfectly fine until I use normal data like;
<body>
{%block content %}
<button class="button_order" >ORDERS</button>
<button class="button_supplier" >SUPPLIER</button>
<p class="myorders" >
This is my order
</p>
<p class="mysupplier">
my supplier is cool
</p>
</body>
But when I try to use data into <p class="mysupplier"> or <p class="myorders" > from my databases, the hide property no longer works, like below part.
<p class="myorders">
{% for element in orders %}
{% for key,val in element.items %}
<ul><li>{{key}}:{{val}}</li></ul>
{% endfor %}
<hr class="new1">
{% endfor %}
</p>
I should get Order data from database only when ORDER button is clicked, but my server shows all data from before without even clicking the button. How to maintain hide and show the property of my data.
my views.py looks like
from django.shortcuts import render
client = MongoClient("mongodb://localhost:27017/")
db=client.inventory_data
def home(request):
collection_data_1 = db['orders']
orders = list(collection_data_1.find())
collection_data_2= db['suppliers']
suppliers = list(collection_data_2.find())
return render(request,'home.html',{'orders': orders,'suppliers':suppliers})
The loop in template is executed when rendering template. You pass all your data from view to template. if you just want to hide it from display add to your js:
<script>
$(document).ready(function(){
$(".mysupplier").hide();
$(".myorders").hide();
$(".button_order").click(function(){
$(".myorders").show();
$(".mysupplier").hide();
});
$(".button_supplier").click(function(){
$(".myorders").hide();
$(".mysupplier").show();
});
});
</script>
but if you would like to dynamicly fetch current data from db by pressing button i recommend use htmx (htmx.org)

Clicking the browser back button after getting the confirmation page

I have a page where I have to fill the student details for example name, email and department. Once I fill the details and click the submit my button it goes to next page and it shows the entered student details in the next page.
Here I have shown the code step by step.
The below code after entering the details and clicking the submit button.
<div class="top-space-20">
<input class="btn btn-info" type="button" onclick="submitEvent()" class="btn" value="submit my details">
</div>
This is the script code for clicking the submit my details button.
function submitEvent() {
form = document.createElement("form");
form.method = "POST";
form.action = "/confirmation";
}
Once I clicked the button it goes to backend and fetch some details and it displays the confirmation.html page.
#app.route("/confirm",methods=['GET','POST'])
def confirm():
"Confirming the event message"
response_value = request.args['value']
return render_template("confirmation.html", value=json.loads(response_value))
#app.route("/confirmation", methods=['GET', 'POST'])
def ssubmit_and_confirm():
"submit an event and display confirmation"
if request.method == 'POST':
return redirect(url_for('confirm', value=value))
The below code is the confirmation.html page
<body style="background-color:powderblue;">
<div class="panel panel-default" style="max-width:1000px;max-height: 800px;margin-left:auto;margin-right:auto;">
<div class="panel-heading " style="text-align: center;">submit student details</div>
<div class="panel-body" id="resultDiv">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-body">
<label class="col-md-8" for="Date:">Date:
{{ value }}</br> Time :{{value}}</label>
<label class="col-md-8" for="dateApplied"></label>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
<label class="col-md-8" for="student email:">
student email id:{{value}}</label>
</div>
</div>
</div>
</div>
</body>
So the problem here is once I come to the confirmation.html and if I click the browser back button it goes to the form and it lets me add the same details.
To avoid this I tried including this lines in the confirmation.html
</div>
<div><input type="hidden" id="reloadPage" /></div>
<script type="text/javascript">
$(document).ready(function() {
function reloadPage(){
location.reload(true); ; // RELOAD PAGE ON BUTTON CLICK EVENT.
// SET AUTOMATIC PAGE RELOAD TIME TO 5000 MILISECONDS (5 SECONDS).
var timerId = setInterval('refreshPage()', 5000);
}
});
function refreshPage() { clearInterval(timerId); location.reload(); }
</script>
But it's not working. I tried one more method which is given in the link
How to stop re submitting a form after clicking back button
This is also not working.
So what do I need is if I click the back button in the browser I should display the confirmation page only or it should tell this is not the authourized page.
Step 1:
On the form submission page, initially set the form submission value to false.
sessionStorage.setItem('form-submit', false)
Step 2:
And when submitting the form in previous page, check:
function submitEvent() {
formSubmitted = sessionStorage.getItem('form-submit')
if (!formSubmitted){
// Write your code here
}
}
Step 3:
On confirmation.html page, you can store a submission value in sessionStorage.
sessionStorage.setItem('form-submit', true)
You could add HTML5 history api. Use following code .
name = document.title
history.pushState(null,name,name)//add this code in your configuration.html file in document ready block
$(window).on("popstate",()=>{
//....Do whatever you want
/*If you want to display unauthorized page then
$(document).html("Unauthorized page")
*/
})
store the form data and reset the form just before the form data is sent to the server. Assuming that you are using $.ajax() to submit the form.
function submitEvent() {
form = document.createElement("form");
form.method = "POST";
form.action = "/confirmation";
// Add id attribute to the form
form.id = "student_details_form";
// Collect form data
// reset your form just before calling $.ajax() or $.post()
document.getElementById('student_details_form').reset();
// call $.ajax() or $.post()
$.ajax({
url: form.action,
// snipps
};
}

Django Template Value Passed to Javascript

I am working on a turn-based game where players can, but don't have to, gain ownership of certain spaces on the game board. My detail view in shows the spaces owned by each player, and I use a loop to display all owned spaces:
<small class="text-muted">Spaces Owned</small>
<div class="list-group list-group-flush">
{% for space in player.space_set.all %}
<a class="list-group-item" data-toggle="modal" data-target="#spaceModal" id="modalButton">
{{ space.name }}
</a>
{% endfor %}
</div>
I want to be able to populate a modal with all detailed information about whichever space is clicked on (hence why I'm using the anchor tag instead of a div, though I guess it might not matter as much). The modal would look something like this, though the goal is to populate it using appropriate IDs, etc using the response from the AJAX call instead of the template variables currently used as placeholders:
<div class="modal fade" id="spaceModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="wrapper">
<div class="box">
<h2>{{ space.name }}</h2>
<div class="float-left">{{ space.location }}</div>
<div class="float-right">{{ space.defense_points }}</div>
<br />
<div class="float-right">{{ space.attack_points }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
What I want to be able to do is use an AJAX call to populate the modal for each space as it is clicked. I have the server-side function set up okay and it is correctly returning the JSON needed when I process a simple get request (I'm using the following url pattern):
from django.urls import path
urlpatterns = [
path('<int:game>/space_data/<int:space>', get_space_data, name = 'get_space_data'),
]
with my views.py defined as:
def get_space_data(request,game,space):
game = Game.objects.get(pk=game)
space = game.space_set.get(location=space)
data = {
'name': space.name,
'location': space.location,
'defense_points': space.defense,
'attack_points': space.attack,
}
return JsonResponse(data)
Right now the JS that I'm using to test usage is the following:
<script>
$("#modalButton").click(function(){
var space = "{{ space }}"
console.log(space)
alert('Modal Button Clicked')
})
</script>
Summary
Essentially all I want to be able to do, which I can't figure out how to do, is pass the space variable to the JS code so that I can build the appropriate AJAX call within the last script code.
To touch on what Daniel wrote, what I was asking was simply how to pass Django template data to a JQuery script, which I would then use in an AJAX call. I figured it out, though, and will post my answer here instead of just deleting the question.
The modal pop-up anchor tag should look like this:
<small class="text-muted">Spaces Owned</small>
<div class="list-group list-group-flush">
{% for space in player.space_set.all %}
<a class="list-group-item" data-toggle="modal" data-target="#spaceModal" id="modalButton" data-location="{{ space.location }}">
{{ space.name }}
</a>
{% endfor %}
</div>
and the resulting JQuery code is as follows:
<script>
$("#modalButton").click(function(){
console.log($(this).data('location'))
alert('Modal Button Clicked')
})
</script>
From this I will be able to add an actual AJAX call to the script and pull the data as needed.
in this way you send the variables to the js to use them in the ajax
{% block scripts %}
<script>
var name = {{space.name}}
var location = {{space.location}}
</script>
<!-- JS Template -->
<script src="{% static 'folder/name.js' %}"></script>
{% endblock scripts %}
and your js
$.ajax({
url: url,
method: "",
data: {
"name" : name,
"location":location
},
success: function (_response) {
},
)

Flask jinja2 update div content without refresh page

Need achieve some features like [http://webonise.co.uk/][1] when click on contact,resume,resources link will update (location URL&div content) but without refresh the page.
Flask view function
#app.route('/')
def index():
flash('Welcome')
return render_template('index.html')
Under index.html is extends base.html
{% block content %}
{{super()}}
<section class="content">
<i class="mdi-event"></i>Event
<i class="mdi-contact"></i>Contact
<div class="board">
{# dynamic template #}
{# without using {{% include 'event.html' %}} #}
</div>
</section>
{%- endblock %}
How can i dynamic rendar event.html / contact.html content when different link is click and rendar under {# dynamic template #} without refresh the page ?
<!--event.html-->
<ul class="list">
<li>
<h3>123</h3>
<p>abc</p>
</li>
</ul>
What I try
import jinja2 Environment but still no idea how to achieve this
env = Environment(autoescape=True,
loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
#app.route('/')
def index():
board = env.get_template('event.html')
flash('Welcome Home Tyler')
return render_template('index.html', board=board)
Is there really need ajax technique get/post method to achieve all this?
You can use Flask-Sijax which helps you add Sijax support to your Flask app. Sijax is a python/jquery library that makes AJAX easy to use on your web applications. Alternatively you could do this:
<script>
$(document).ready( function() {
$('#next').click(function() {
$.ajax("{{ url_for('yourroute') }}").done(function (reply) {
$('#container').html(reply);
});
});
});
</script>
<input type="button" id="next" value="Next" />
<div id="container"></div>

Categories

Resources