I am using Zurb's Foundation data-abide in a form and would like to disable the submit button until the form is valid (e.g. valid email address).
What's the best way to do this?
Thanks,
John
You can use javascript on your submit button to prevent the default behavior. Then you can listen for 'formvalid.zf.abide' and 'forminvalid.zf.abide' to submit or add custom error handling
<form data-abide novalidate id="testform">
<label>
Amount
<div class="input-group">
<span class="input-group-label">$</span>
<input class="input-group-field" id="exampleNumberInput" type="number" required pattern="number"/>
<span class="form-error" data-form-error-for="exampleNumberInput">Amount is required.</span>
</div>
</label>
</form>
.
//add event handler to your submit button to prevent the form submit
//and call abide validation
$('#submit').on('click', function(e){
e.preventDefault()
console.log('submit clicked')
$('#testform').foundation('validateForm')
})
//listen for the abide validation event and submit form
$(document).on('formvalid.zf.abide', function(event, form){
console.log('form is valid')
form.submit()
})
Related
How can I let livewire know that a model is a particular modal
I have this in my livewire component
public $itemname;
public function updateReceivedKg()
{
$this->validate([
'itemname' => 'required',
]);
dump($this->itemname)
}
On livewire view, I have this
#foreach($result->products as $index=>$data)
<form wire:submit.prevent="updateReceivedKg()">
<div class="input-group">
<input required wire:model.defer="itemname" type="text" class="form-control">
<span class="input-group-append">
<button type="submit" class="btn btn-sm btn-success">Update</button>
</span>
</div>
</form>
#endforeach
After generating the form, I have about 11 forms. The issue is that livewire always submit the last itemname that was entered. For example, if on the first form, I entered "Mango" and go to another form and enter "Apple", if I go back to the form which I have already written "Mango" and click the submit (without typing anything) button, if I dump the submitted form and check the itemname, it shows it is the Apple. This is wrong because I submitted the Mango form.
In normal Laravel, I have no issue with this type of form submission. It will detect which form I submitted.
Please how can I achieve the same result using Livewire
You have the same itemname for a lot of elements. You should probably append the index to the modelname.
public $itemname1;
public $itemname2; // etc..
#foreach($result->products as $index=>$data)
<form wire:submit.prevent="updateReceivedKg()">
<div class="input-group">
<input required wire:model.defer="itemname{{$index}}" type="text" class="form-control">
<span class="input-group-append">
<button type="submit" class="btn btn-sm btn-success">Update</button>
</span>
</div>
</form>
#endforeach
I want a user to be able to select from an existing list of options. If the option is not within the ones already in the database, though, they need to be able to add a new item, while remaining on the main form, because after having added the new item they need to be able to save the main form
I was using the JQuery library select2, which allows a tags:True option, thanks to which users can add a new item to a list if not present. Nevertheless, Django validates that field and if it finds an item which is not in the database is raises an error. My initial plan was that of capturing the new value in the view and then (saving first the form with commit=False), if it was not in the database, save it. But this is not doable without forcing Django not to validate the field, which I haven't managed to do.
Another option, which I'm currently investigating, is that of adding a modal pop-up containing the sub-form. Of course I'd like to avoid opening the sub-form in another page, which would work but would be quite non-user-friendly.
models.py:
class Venue(models.Model):
venue_name = models.CharField(max_length=30)
class performanceOfCompositionNoDb(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.SET_NULL, null=True, blank=True)
forms.py:
class VenueForm(forms.ModelForm):
class Meta:
model = Venue
fields = ['venue_name']
views.py:
def composition_edit_view(request, id=id):
form_composition = CompositionForm(request.POST or None, instance=obj)
form_venue = VenueForm(request.POST or None)
if request.method == "POST" and form_composition.is_valid():
form_composition.save()
context = {
'form_composition': form_composition,
'form_venue': form_venue
[...]
def venue_add_view(request):
form_venue = VenueForm(request.POST or None)
if form_venue.is_valid():
form_venue.save()
context = {
'form_venue': form_venue,
}
return render(request, "venue-add.html", context)
my template.html:
{% include '../venue-add.html'%}
<form id="compositionForm" action='.' enctype="multipart/form-data" method='POST'>
{{form_composition}}
<p>Add new venue</p>
<input class="button" type='submit' id='save' value='Save' />
</form>
venue-add.html:
<div class="reveal" id="addvenueModal" data-reveal>
<form action='.' enctype="multipart/form-data" method='POST'>
{% csrf_token %}
<div class="grid-container">
<div class="grid-x grid-padding-x">
{{ form_venue }}
</div>
<input class="button" type='submit' value='Save' />
</div>
</form>
</div>
I'm expecting to open the venue-add form when I click on the 'Add new venue' button, which happens. With the modal open and the new text input, I then click the 'submit' button of the modal. At that point I get a 'Validation error - ['ManagementForm data is missing or has been tampered with']'. I have other formsets in the main template, and it all works correctly if I don't add a new venue.
How can I solve this? Also, if there's a way of using the select2 library and add a new venue in a more dynamic way, do let me know! Thanks.
Testing with XHR
Using XHR gives the same ['ManagementForm data is missing or has been tampered with'] error in the response:
<div class="reveal" id="addVenue" data-reveal>
<form id="addVenueForm" action='.' onsubmit="addVenue(this); return false;" enctype="multipart/form-data" method='POST'>
{% csrf_token %}
<div class="grid-container">
<div class="grid-x grid-padding-x">
{{ form_venue }}
</div>
<input class="button" type='submit' value='Save' />
</div>
</form>
<script type="text/javascript"> "use strict";
function addVenue (oFormElement) {
var oReq = new XMLHttpRequest();
var data = new FormData(oFormElement)
oReq.onload = {}
oReq.onreadystatechange = function() {
if (oReq.readyState == XMLHttpRequest.DONE) {
var result = oReq.responseText;}
}
oReq.open("post", oFormElement.action, true);
oReq.send(data);
} </script>
As I said, I do have formsets (working correctly) in the main form from which I'm launching this modal. This modal doesn't contain any formset though, it's a simple one-field form, with its own csrf token.
Edit 2
OK, so upon further investigating I've found that the error springs from
return render(request, "compositions/composition_edit.html", context)
in the view.py. In other words, when I hit 'submit' in the modal, for some reason the 'submit' of the main form kicks in also, thus generating issues. How can I isolate the 'submit' of the modal and get the 'submit' of the main form not to kick in unless explicitly clicked?
I had to change the action of the modal form to the address I mapped in my urls.py (action='/venue-add/') for that form. That solved the issue.
Now, the newly-added items are not displayed in the main form unless I refresh the page, no matter ho many times I destroy/empty/repopulate the select2() dropdown list. I think this has to do with the fact that the data to the venue dropdown list is sent by the view at the loading of the main form, and that the context remains the same no matter what updates to the database have been made after the page loading.
For the above reason I'm investigating using an API on my own application and GET and POST data via an AJAX call, which still gives me issue. I'm opening another question for that though.
Lets say I have a model with 2 fields. With one field being a choice field of radio button Choice1, Choice2 and Other, the next being Other which is a textfield I want the "other" textbox to appar / enabled only when "Other" is selected in the radio button.
This question is not from the django-forms category. This applies more to the front-end category. Everything that is sent from the django server is static. Sure, you can write a form class and override the template for it. Also, you can connect the js script directly to the form class. It is convenient, but not canonical. Just, write the JS script or using JQuery, which will activate the field when you select a particular option.
I wrote for you a small example of how this can be do it.
I hope this helps you.
$('input[type=radio][name=choices]').change(function() {
$('input[type=text][name=other]').prop(
'disabled',
function(i, v) {
return !v;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<p><input name="choices" type="radio" value="choice1">Choice 1</p>
<p><input name="choices" type="radio" value="choice2">Choice 2</p>
<p><input name="other" type="text" disabled></p>
</form>
How can i create a html form that action attribute have 2 destination.I want when user click on submit bottom , check if user entered wrong data the page goes to another pages with window.location and if user insert the correct input goes to main page with the same instruction.
First of all, what do you mean by correct input?
Main form data validation occurs in server side, not client side. you'd better use client side just for simple verification, like for typos.
There is no need for 2 destination pages (as you call it so).
You may use the standard action attribute which is the page on the server to which you are sending your form data.
there, You have the option to decide which condition needs what action and send the data (and then the user) to the desired page / action.
Sample code for the form
<form id='myform' action='action.php' method='POST' target='formresponse'>
<label for='name' >Your Full Name*: </label><br/>
<input type='text' name='name' id='name' maxlength="50" /><br/>
<label for='email' >Email Address*:</label><br/>
<input type='text' name='email' id='email' maxlength="50" /><br/>
<input type='button' name='Submit' value='Submit' />
</form>
<iframe name='formresponse' width='300' height='200'></frame>
Multiple action
function SubmitForm()
{
document.forms['contactus'].action='action1.php';
document.forms['contactus'].target='frame_result1';
document.forms['contactus'].submit();
document.forms['contactus'].action='action2.php';
document.forms['contactus'].target='frame_result2';
document.forms['contactus'].submit();
return true;
}
I am looking to use Django to create a form with a password field that can be toggled to be hidden or shown. This functionality can be seen on MailChimp at https://login.mailchimp.com/signup. Does anyone know how such a field could be created?
it's just purely javascript :
<script type="text/javascript">
function reveal()
{
if(document.getElementById('box').checked)
{document.getElementById("pw").type='text';}
else
document.getElementById("pw").type='password';
}
</script>
<input type="checkbox" id="box" onclick ="reveal()">
<input type="password" id="pw">