Using jQuery datepicker with multiple django forms in one page - javascript

So I have a create announcement form and then an edit form for each announcement and each form has its own datepicker. My function for controlling the datepicker is:
$(function() {
$( ".datepicker" ).datepicker({
changeMonth: true,
changeYear: true,
});
});
Initially my issue was that using the datepicker in one of the edit forms would change the field in the create form since the ids were the same. I got around this by adding ids (in my forms.py) like so:
end_date = forms.DateField(label='Expires', widget=forms.TextInput(attrs={'class':'datepicker form-control', 'id':'end_date_create'}))
and
end_date = forms.DateField(label='Expires', widget=forms.TextInput(attrs={'class':'datepicker form-control', 'id':'end_date_edit'}))
to my createAnnouncement and EditAnnouncement forms. But since I have multiple edit forms per page, I still have the same issue where using the datepicker on any edit form changes the field of only the top edit form. I am using django widget tweaks to render my forms so it automatically generates HTML and ids and classes and everything. Each edit form is in a div with a unique id, but the form fields themselves are named the same thing across all the forms. Does anyone know how I could generate unique ids for my form fields with django widget tweaks? Or maybe there is some javascript or something I could add to my datepicker function that tells the datepicker to change the value of the field that is in the same div?
EDIT: My template looks like this:
{% if boardAnnouncements %}
<h3>Announcements</h3>
<div class="container" style="margin: 0px; padding: 0px;">
<ul>
{% for announcement in boardAnnouncements %}
<div class="row" style="padding-bottom: 10px;">
<li>
<div class="col-md-6">
<!-- display announcement content -->
</div>
<div class="col-md-6">
<!-- edit button calls javascript function to hide/unhide div with edit form in it -->
<i class="fa fa-pencil" aria-hidden="true"></i> Edit
</div>
</div>
<!-- each div gets unique id that corresponds to announcemt id -->
<div id="editann-{{announcement.id}}" class="hidden">
<form role="form" action="/editannouncement/{{announcement.id}}/" method="post">
<!-- display edit form with django widget tweaks -->
{% csrf_token %}
{% for field in editAnnouncement %}
{% if field.errors %}
<div class="form-group has-error">
<label class="col-sm-2 control-label" for="id_{{ field.name }}">
{{ field.label }}</label>
<div class="col-sm-10">
{{ field }}
<span class="help-block">
{% for error in field.errors %}
{{ error }}
{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="form-group">
<label class="col-sm-2 control-label" for="id_{{ field.name }}">{{ field.label }}</label>
<div class="col-sm-10">
{{ field }}
{% if field.help_text %}
<p class="help-block"><small>{{ field.help_text }}</small></p>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="edit_announcement" class="btn btn-primary">Save</button><br><br>
</div>
</div>
</form>
</li>
</div>
{% endfor %}
</ul>
</div>
{% endif %}
<div>
And the generated HTML for the edit forms is:
<div id="editann-1" class="unhidden">
<form class="ng-pristine ng-valid" role="form" action="/editannouncement/1/" method="post">
<input name="csrfmiddlewaretoken" value="AbTEZYmK1RF9yeom1C34IFFCj3EBrOD3" type="hidden">
<div class="form-group">
<label class="col-sm-2 control-label" for="id_description">Edit Description</label>
<div class="col-sm-10">
<textarea class="form-control" cols="40" id="id_description" name="description" rows="10"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="id_end_date">Expires</label>
<div class="col-sm-10">
<input class="datepicker form-control hasDatepicker" id="end_date_edit" name="end_date" type="text">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="edit_announcement" class="btn btn-primary">Save</button><br><br>
</div>
</div>
</form>
</div>
<div id="editann-2" class="unhidden">
<form class="ng-pristine ng-valid" role="form" action="/editannouncement/2/" method="post">
<input name="csrfmiddlewaretoken" value="AbTEZYmK1RF9yeom1C34IFFCj3EBrOD3" type="hidden">
<div class="form-group">
<label class="col-sm-2 control-label" for="id_description">Edit Description</label>
<div class="col-sm-10">
<textarea class="form-control" cols="40" id="id_description" name="description" rows="10"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="id_end_date">Expires</label>
<div class="col-sm-10">
<input class="datepicker form-control hasDatepicker" id="end_date_edit" name="end_date" type="text">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="edit_announcement" class="btn btn-primary">Save</button><br><br>
</div>
</div>
</form>
</div>
So to clarify each editann-# div has an edit form in it (and each edit form has a datepicker). Right now since the all the edit form "Expire" fields have id id_end_date the datepicker changes the value of the first edit form, no matter which datepicker I am using.

I came up with a solution involving some javascript and jQuery.
function unhide_announcement(divID, ID) {
var item = document.getElementById(divID);
if (item) {
/* hide/unhide div */
item.className=(item.className=='hidden')?'unhidden':'hidden';
/* give each end_date field a unique ID */
var newID = 'id_end_date' + ID;
item.querySelector('#id_end_date').id = newID;
/* datepicker functionality */
$(function() {
$( '#'+newID ).datepicker({
changeMonth: true,
changeYear: true,
});
})
}
}
Since each edit announcement form is in a unique div, I get that div first and then within the div there is only 1 edit announcement form so I change that id from id_end_date to id_end_date1 or whichever announcement id it is associated with. And then I changed the jQuery datepicker function I had to select by id instead of by class and it worked. So when I call it in my template it looks like this:
Edit
<div id="editann-{{announcement.id}}" class="hidden">
<!-- edit announcement form -->
<form>
...
</form>
</div>

You shouldn't have two of the same id on one page. ID's must be unique. That's what is creating the error.
To add more than one form on the page, you should use Formsets which will automatically make sure your id's are unique.
By removing the id attribute from your code I was able to make the datepickers work. See this working fiddle.
Note that I had to remove hasDatepicker class from the html you pasted as that's actually inserted by the datepicker function - if you leave it in it will create a conflict and the datepicker won't show up.

Related

How to validate input field with numbers only using javascript?

I am new to Javascript, I need to validate the input field. I wish to enter only numbers, not allowing alphabets or special characters. I need to show the error message below the input field. Validation rules for the input field are:
Should be numbers only
Numbers should be greater than 1 and less than available quantity.
I have form with three input fields, available quantity, quantity and bid price.
Validation on value entered on quantity field should be greater than 1 and less than the available quantity is working fine. But I need to enter only numbers using javascript.
What I have tried is
<form method="post" action="/truckianBidSave/{{id}}" id="reviewForm">
<input type="hidden" name="_token" value="{{csrf_token()}}" />
<input type="hidden" name="user_name" value="{{auth_user().first_name}}" />
<!-- <div class="form-group row">
<label class="col-sm-4 col-form-label">Select Milege Gap: </label>
<div class="col-sm-8">
<select class="form-select" name="mileage" id="mileage" onchange="getOption()">
<option>Select </option>
{% for p in product_data %}
<option value="{{p.number_of_products}},{{p.number_of_products_sold}},{{p.mileage_gap}}">{{p.mileage_gap}}</option>
{% endfor %}
</select>
</div>
</div>-->
<div class="form-group row">
{% set total=0 %}
{% set sold=0 %}
{% for p in product_data %}
{% set total =total+p.number_of_products %}
{% set sold=sold+p.number_of_products_sold %}
{% endfor %}
{% set available=total-sold %}
<label for="available" class="col-sm-4 col-form-label">Available Quantity: </label>
<div class="col-sm-8">
<input type="text" class="form-control" id="available" readonly name="available_qty" value={{available}} />
</div>
</div>
<div class="form-group row">
<label for="qty" class="col-sm-4 col-form-label"> Quantity: </label>
<div class="col-sm-8">
<input type="text" id="qty" name="qty" class="form-control" oninput="checkInput(this);" required />
<p id="qty-msg">
</p>
</div>
</div>
<div class="form-group row">
<label for="inputBid" class="col-sm-4 col-form-label">Enter Bid Price</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="inputBid" name="bid" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');"/>
</div>
</div>
<div class="form-group text-center">
<input type="submit" class="btn btn-primary" id="btn" name="send" value="Send" disabled="disabled">
</div>
</form>
Javascript code:
function checkInput(item)
{var available=document.getElementById("available");
var msg=document.getElementById("qty-msg");
if(parseInt(item.value)>parseInt(available.value) )
{
item.value='';
msg.innerHTML="* Value must be less than Availabe quantity "+available.value ;
msg.style.color="red";
}
else if(parseInt(item.value)<1)
{
item.value='';
msg.innerHTML="* Value must be greater than 1" ;
msg.style.color="red";
}
else if('/^[A-Za-z]+$/'.test(item.value))
{ alert('hi');
item.value='';
msg.innerHTML="* Only numbers allowed" ;
msg.style.color="red";
}
How to not allow alphabets and special characters in input filed using javascript.
Use this instead of your pattern
!(/^[0-9]{1,}$/.test(item.value))
It'll return true if the value contains a string, otherwise, it'll return false.
You may use <input type="number"> for the 'qty' input. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number for details.
A javascript filter like
document.getElementById('qty').addEventListener('keydown',
function(event){
if(!event.key.match(/^[0-9]$/)){
event.preventDefault();
}
}
);
is never perfectly safe, i.e., it will not work on some old browsers or mobile browsers.

Django: Get previous values of a multi-step form to dynamically display the fields of the next step

I am making a project in Django but Im not using Django built-in forms. Rather, I am using html and bootstrap to render forms. On a page, I want to create a quiz. I am doing this via a multi-step form where I input the number of questions on the first form. Then based upon this field, when I hit next, I want to have the same number of the fields for questions and corresponding answers to appear so that I can set them. For example, if I type 5 questions and hit next, it should have 5 fields for me to enter the questions and each question field should have 4 answer fields. Is there a way to dynamically do this?
Please help :(((( This is very important.
Thank you n here is my code snippet
{% block content %}
<div class="row">
<h2 style="color: darkblue;" class="text-center">Add a Quiz</h2>
</div>
<form action="" id="add_test_form" method="POST">
<!--This form will contain the quiz information-->
{% csrf_token %}
<div class="row">
<div class="form-row">
<div class="form-group col-md-6">
<label>Name of test</label>
<input type="text" class="form-control" name="test_name" required>
</div>
</div>
</div>
<div class="row">
<div class="form-row">
<div class="form-group col-md-6">
<label>Number of questions</label>
<input type="number" id="num_qu" class="form-control" name="test_num_questions" min="1"
oninput="validity.valid||(value='')" required>
</div>
</div>
</div>
<div class="row">
<div class="form-row">
<div class="form-group col-md-6">
<label>Time( Duration) in minutes</label>
<input type="number" class="form-control" name="test_duration" min="1"
oninput="validity.valid||(value='')" required>
</div>
</div>
</div>
<div class="row">
<div class="form-row">
<div class="form-group col-md-4">
<input type="button" value="Next" id="first_next" class="btn btn-primary btn-lg mb-10">
</div>
</div>
</div>
</form>
</div>
<script>
$(document).ready(function(){
$("#first_next").click(function(e){
var num_of_qu = $("#num_qu").val();
alert(num_of_qu);
});
});
</script>
{% endblock content %}

scripting error in django template creation

Im developing a code that performs multiple functions in the template and i have used scripts to check the functions using if else and for loops, but i am getting these kinds of errors, please help me know the reasons, thank you in advance
if you see at the end of the code inside the script tag the declaration of if else tag must be somewhat like the code below, but as soon as i save the code it gets unformatted and gives me errors
{% if messages %}
{% for message in messages %}
alert('{{message}}')
{% endfor %}
{% endif %}
Upload.html file
{% extends 'base.html' %} {% block content %}
<div class="form-group">
<label for="name" class="col-md-3 col-sm-3 col-xs-12 control-label">Select : </label>
<div class="col-md-8">
<select name="cars" id="cars">
<option value="">Select</option>
<option value="WithTime">AmpandFreq</option>
<option value="WithoutTime">Amplitude</option>
</select>
</div>
</div>
<div id="withtime" style="display:none">
<form action="/csvapp/upload/" method="POST" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-md-3 col-sm-3 col-xs-12 control-label">File: </label>
<div class="col-md-8">
<input type="file" name="csv_file" id="csv_file" required="True" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-3 col-sm-3 col-xs-12 col-md-offset-3" style="margin-bottom:10px;">
<button class="btn btn-primary"> <span class="glyphicon glyphicon-upload" style="margin-right:5px;"></span>Upload </button>
</div>
</div>
</form>
</div>
<div id="withouttime" style="display:none">
<form name="form" action="/csvapp/upload_withouttime/" method="POST" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-md-3 col-sm-3 col-xs-12 control-label">File: </label>
<div class="col-md-8">
<input type="file" name="csv_file" id="csv_file" required="True" class="form-control">
</div>
</div>
<div class="form-group">
<label for="name" class="col-md-3 col-sm-3 col-xs-12 control-label">Sampling Frequency: </label>
<div class="col-md-8">
<input type="text" name="sampfreq" id="sampfreq" required="True" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-3 col-sm-3 col-xs-12 col-md-offset-3" style="margin-bottom:10px;">
<button class="btn btn-primary"> <span class="glyphicon glyphicon-upload" style="margin-right:5px;"></span>Upload </button>
</div>
</div>
</form>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
{ %
if messages %
} { %
for message in messages %
}
alert('{{message}}') { % endfor %
} { % endif %
}
$('select').on('change', function() {
var a = $(this).val()
{ %
if a == "WithoutTime" %
} {
alert("inside")
$('#withtime').hide();
$('#withouttime').show();
} { %
else %
} {
$('#withtime').hide();
$('#withouttime').show();
}
})
</script>
{% endblock %}
After Searching and varying many internal settings I came to a simple conclusion for the errors and the requirement
In the command palette (ctrl-shift-p) select Install Extension and choose Django Template.
To get started on the extension...
Go to the Debug viewlet and select Launch Extension then hit run (F5). This will launch a second instance of Code with the extension from the first window loaded.
As you make changes, you can also reload (Ctrl+R or Cmd+R on Mac) the second Code window to load any changes.
for more information refer the link below
Django Template view[https://marketplace.visualstudio.com/items?itemName=bibhasdn.django-html]

(Laravel/JQuery UI) : Can't reset <select> and <textarea> on closing dialog

I am currently developing an application with Laravel 5.8 version and i use JQuery UI dialog as "pop-up" with some form to add datas in list.
So i have for example this type of form-popup :
<div class="dialog" id="addTr" data-open="{{ isset($_GET['popUpTr']) ? $_GET['popUpTr'] : 'close' }}" title="Ajouter une tranche">
<form method="POST" action="{{ route('tranches.store') }}">
#csrf
<input hidden type="text" name="ID_PROJET" value="{{ isset($projet->ID_PROJET) ? $projet->ID_PROJET : null }}">
<div class="row minimized">
<div class="col-3">
<span>Type contact</span><span class="required-star">*</span>
</div>
<div class="col-8">
<select name="TYPE_CONTACT_" class="form-control form-control-sm" id="select-typeContactAddTr" required>
<option value="">Aucun</option>
<!-- si le projet est reservé uniquement aux entreprises (ouverture projet = 2) -->
#if($projet->OUVERTURE_ == 2)
<option value="1" {{ old('TYPE_CONTACT_') == 1 ? 'selected' : null }}>Entreprises</option>
#else
#foreach($typesContact as $tp)
<option {{ old('TYPE_CONTACT_') == $tp->CLECOD ? 'selected' : null }} value="{{ $tp->CLECOD }}">{{ $tp->LIBCOD }}</option>
#endforeach
#endif
</select>
</div>
</div>
<div class="row minimized">
<div class="col-3">
<span>Numéro <span class="text-9">(numérique)</span></span><span class="required-star">*</span>
</div>
<div class="col-2">
<input name="CPT_TRANCHE" id="input-cptAddTr" maxlength="2" value="{{ old('CPT_TRANCHE') }}" type="text" class="form-control form-control-sm {{ $errors->first('CPT_TRANCHE') ? 'is-invalid' : '' }}" required>
</div>
</div>
<div class="row minimized">
<div class="col-3">
<span>Libellé</span><span class="required-star">*</span>
</div>
<div class="col-8">
<input name="LIBEL_TR" id="input-libelAddTr" type="text" value="{{ old('LIBEL_TR') }}" class="form-control form-control-sm" required>
</div>
</div>
<div class="row minimized">
<div class="col-3">
<span>De</span><span class="required-star">*</span>
</div>
<div class="col-5">
<input name="MT_SOUTIEN_MINI" id="montant-min-input" type="text" value="{{ old('MT_SOUTIEN_MINI') }}" class="form-control form-control-sm budget-input" required>
<span>€</span>
</div>
<div class="col-4">
<span>à</span><span class="required-star">*</span>
<input name="MT_SOUTIEN_MAXI" id="montant-max-input" type="text" value="{{ old('MT_SOUTIEN_MAXI') }}" class="form-control form-control-sm budget-input" required>
<span>€</span>
</div>
</div>
<div class="row minimized">
<div class="col-3">
<span>Montant réel</span>
</div>
<div class="col-8">
<input name="MT_REEL" id="montant-reel-input" value="{{ old('MT_REEL') }}" type="text" class="form-control form-control-sm budget-input">
<span>€</span>
</div>
</div>
<div class="row minimized">
<button class="btn btn-info" type="submit">Enregistrer</button>
<button class="btn btn-info cancel-button" type="reset">Annuler</button>
</div>
</form>
</div>
The idea is that if the user make an error in the data typing, the datas are returning with the error thanks to the old function of Laravel : https://laravel.com/docs/5.8/requests#old-input
The problem is that these datas have to be delete when the user close the pop-up or click on the "cancel" button.
So i have create function that load pop up and manage the user action on it. Here is the JS code using JQuery UI (last stable version) :
var loadTrPopUp = function(elementID) {
$(function() {
$("#" + elementID).dialog({
autoOpen: false,
modale: false,
resizable: false,
height: 420,
width: 650,
closeText:"",
close: function() {
console.log("close an reset tranche")
$('#select-typeContactAddTr option:first').prop('selected',true);
$("#montant-min-input").attr("value","")
$("#montant-max-input").attr("value","")
$("#montant-reel-input").attr("value","")
$("#input-cptAddTr").attr("value","")
$("#input-libelAddTr").attr("value","")
}
})
})
$(function() {
$(".cancel-button").on('click', function() {
$("#" + elementID).dialog("close");
})
})
}
For the simple <input> that works great and the field are reinitialize when the user close the pop up. But for others types of field like <textarea> or <select>, the datas are not reinitialize.
I search on how i can reinitialize these types of input and i have adapted my code but that still not working so i think that the problem come from the old function. But i'm not sure so if someone have an idea or can help me that would be great!
Thanks in advance for your help.

Checking inputs of form in django before submit

I am using Django and try to submit a form.
I have a "call-us" form and there is 3 fields.
I want to make this, If one of the fields is empty, and the user clicked on Submit button, don't send the info to View and warm the user that they must complete the required fields.
here is my form:
<form role="form" action="{% url "landingpages:callusthanks" %}" method="post" style="max-width: 500px;margin: 0 auto;margin-top: 30px;">
{% csrf_token %}
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-user"></i></div>
<input type="text" name="name" class="form-control" id="name" placeholder="Name">
</div>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-at"></i></div>
<input type="text" name="email" id="email" class="form-control" placeholder="Email">
</div>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-envelope-o"></i></div>
<textarea name="message" class="form-control" id="message" placeholder="Message"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-xs-6 col-xs-offset-6">
<button type="submit" class="form-control">Send</button>
</div>
</div>
</form>
As one option you can use jQuery validation and set the required fields like so:
$(document).ready(function(){
$("#your_form_id").validate({
rules :{
your_field : {
required : true
}
.....
},
messages :{
your_field : {
required : 'your_field is required'
}
.....
}
});
});
Edit: Just saw you said not to send to view. So, ignore this but I'll leave it for future reference on the off chance that it's useful.
Preferably, you could turn this into a form import it from forms.py and then send it to your view. You could then just set which fields are required.

Categories

Resources