As an example we have a log in view with 'username', 'password' and 'country' fields and a 'login'.
How can one invoke the action related to the 'login' button when pressing enter on any of the inputs in a group.? For instance, all inputs within a container of some sort (div, form, fieldset, etc).
To get your form controls trigger the sumbit action you could define your controls of type submit.
...
{{input type="submit" ...}}
...
<button type="submit">...</button>
...
or the more elegant way is to having your parent view catch all the events and trigger the submit once, but this depends how nested your view is.
Hope it helps
Put your action on your form tag, like so:
<form {{action yourAction on="submit"}}>
{{input text}}
{{input text}}
<button type="submit"></button>
</form>
This will cause your event to fire whenever the form is submit (by clicking the button, by hitting enter in a field, etc.
Related
I've created an app, and on the CreateView page, the Submit button works fine to create a new S Reference. I also created an error message if the input value matches an existing Reference. I created button in the error message part and tried to link it to update the page to update these reference fields, like primary contact. I tried many options but have not got right code for the argument with pk or id to get individual record update page.
this is the url in error message.
I tried quite few pk, id options, none of them works.
'pk'=self.pk;
{'pk'=self.pk};
object.id
some code as below
models.py
class LNOrder(models.Model):
reference_number = models.CharField(max_length=15,blank=True, null=True, unique=True, error_messages={'unique':"This reference already exists."})
primary_contact = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
urls.py
urlpatterns = [
path('lfcnotifier', LNCreateView.as_view(), name='lnorder_create'),
path('lfcnotifier/<int:pk>', LNDetailView.as_view(), name='lnorder_detail'),
path('lfcnotifier/<int:pk>/update/', LNUpdateView.as_view(), name='lnorder_update'),
]
template
<div class="input-group mb-3">
<div class="input-group-prepend w-225px">
<label class="input-group-text w-100">S Reference</label>
</div>
<input name="reference_number" type="text" class="form-control" placeholder="Enter your S Reference"/>
<button class="btn btn-primary cardshadow " data-toggle="tooltip" title="Click to submit" style="width:200px;" type="submit">submit</button>
{%for field in form %}
{% for error in field.errors %}
{{ error }} Update Request
{% endfor %}
{% endfor %}
Views.py
class LNCreateView(SuccessMessageMixin,LoginRequiredMixin,CreateView):
model = LNOrder
template_name = 'lfcnotifier/lnorder_create.html'
form_class = LNOrderForm
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
I expect when users click on Update Request button, it'll open the update page to edit the individual reference.
but I got message "Could not parse the remainder: '=self.pk' from ''pk'=self.pk'".
I get slightly different messages when I try the above different options.
I would like to have the right code for the URL to update the page when the Update Request button is clicked.
Thanks,
Additional background, I only put some of template code here to save space. They are in form section. If I use the following code
Update Request
instead of
Update Request
it can open the full list page without issue. I can go to update page from full list page without issue. But I want to open update page from here directly other than have one more step.
This is all kinds of confused.
For a start, you can't use a string on the left-hand side of an expression, either in pure Python or in Django templates.
But secondly, you don't have anything called self there. What you do have would be passed from the view; however it's not clear from the code you have posted which actual view this is. It doesn't seem to be that CreateView, because you are linking to the update. But assuming it's actually the LNDetailView, and assuming that that actually is a DetailView, you have access to the current object in the template exactly as object.
So you would do:
{% url 'lnorder_update' pk=object.pk %}
However again, this makes no sense to actually do. You can't submit a form via an a. You need a <form> element with a button.
I have django form, then for each field I set initial value. How can I make POST request in my view.py (like after pressing submit button) without rendering the form. I just need to send these initial values as POST request to another url.
You can create the form in HTML and set display:none is style attributee of each field. It will hide the form from front-end and when you click on submit button it will send all data in POST request.
<form method='post'>
<input name='field_name' style='display:none' value='abc'>
<input type='submit' value='submit'>
</form>
Above code will show only submit button on front-end and by clicking on it, it will send value of input field in POST request.
I'm using django-webtest to automate functional tests for a Django application. One of my ModelForms has multiple submit buttons. The template, using django-crispy-forms, looks like this:
<form action="" method="post">
{% csrf_token %}
<p>
{{ person_form|crispy }}
<br><br>
{{ admin_form|crispy }}
</p>
<button id="SaveButton" type="submit" name="save_data" class="btn btn-lg btn-primary">Save</button>
<button id="VerifyButton" type="submit" name="verify_data" class="btn btn-lg btn-primary">Verify</button>
</form>
When I submit the form manually from the webpage by clicking on the Save button, the request.POST that is passed into the corresponding view method contains the 'save_data' tag that I use to decide what to do in the code.
However, when I create a django-webtest testcase to do the same, the 'save_data' tag is absent, even if I specify it in form.submit() as follows:
def test_schools_app_access_school_admin_record(self):
school_index = self.app.get(reverse('schools:school_index'),
user=self.school_admin)
assert self.school_name in school_index
school_page = school_index.click(self.school_name)
assert 'View School Administrator' in school_page
school_admin_page = school_page.click('View School Administrator')
person_form = school_admin_page.forms[1]
assert person_form['person-name'].value == self.school_admin_name
# TODO: Figure out how to pass name='save_data' while submitting
person_form['person-email'] = self.school_admin_email
response = person_form.submit(name='save_data', value='save')
# Verify that the field has been updated in the database
person = Person.objects.get(name=self.school_admin_name)
assert self.school_admin_email in person.email
How do I get django-webtest to include the name of the submit button in request.POST ?
Also, since I have multiple forms on the same page, I'm currently using response.forms[1] to select the form of interest. But I would like to use the form id instead. I couldn't locate in the Django documentation how to assign the form id (not field id) to a ModelForm. Could someone help me with this?
I'm using Django 1.7, django-webtest 1.7.8, WebTest 2.0.18 and django-crispy-forms 1.4.0.
I figured out that I'd made a typo in my code snippet because of which my code was not working.
In this fragment
person_form['person-email'] = self.school_admin_email
response = person_form.submit(name='save_data', value='save')
I should have value='Save' instead of 'save'.
With this corrected, the response does contain the name 'save_data'.
I'm new to django and for practice I'm trying to program my own version of the all familiar 'todo list' app.
I have some page that displays all todo list items the user has entered, along with a button to edit each one. The edit button sends the user to another page with a form to enter in the changes to the item.
It's possible for the user to change everything about the item. Obviously request.POST gives me all the information the user just put into the form, but I want this information to rewrite the info of the item they originally clicked on. So how do I write the view code to find out what that original item was?
I guess I could format my form submit button to:
<button type="submit" name="save" value={{ item.pk }}>Save</button>
and get the primary key that way
but lets say I had passed two items to the edit page and I wanted to give the user the ability to combined them. Again, I could figure out what those items were by doing:
<button type="submit" name="save" value='{{ item1.pk }} {{ item2.pk }}'>Save</button>
then
request['save'].split(' ')
this seems kinda stupid though. Is there some other, less brute force, way?
like a:
request.tell_me_all_items_passed_to_the_template
kind of thing?
In case someone else has the same question
So instead of doing this:
template
<form method="post" action="/list/saving/">
<!--- form fields --->
<button type="submit" name="save" value='{{ item.pk }}'>Save</button>
</form>
url.py
(r'^list/saving/$', save)
views.py
def save(request):
....
item = Item.objects.get(pk=request.POST['save'])
....
do this:
template
<form method="post" action="{% url todolist.views.save item.pk %}">
<!--- form fields --->
<button type="submit" name="save">Save</button>
</form>
url.py
(r'^list/saving/(\d+)/$', save)
views.py
def save(request, pk):
....
item = Item.objects.get(pk=pk)
....
More info on url reversing
If you really need to, just use hidden inputs. But, this is unnecessary anyways. The user may be able to change "everything" about the item, but they can't change the pk (or at least they shouldn't be able to... don't give them the option to). The pk is what Django uses to identify an object, so this is already handled for you. Not sure what the issue here is.
I have a django form with two different submit buttons, on the view where the form is submitted to I need to know what submit button was pressed and take different actions accordingly.
From what I have read the submit button's name or id should be somewhere in the request.POST dictionary, but it not there!
This is a fragment of my form:
<form id="editPaperForm" action="{{paper.editURL}}" method="POST">
<input type="submit" name="savePaperButton" id="savePaperButton" value="Save and Send Later"/>
<input type="submit" name="sendPaperButton" id="sendPaperButton" value="Save and send"/>
...
</form>
In the view:
...
if 'sendPaperButton' in request.POST:
return applicants_confirmSend(request, paperID)
else:
return applicants_home(request)
sendPaperButton is never in the request.POST, and neither is the other one, should I be looking somewhere else?
The only idea I have is to add a hidden field and modify it via javascript before sending the form but that seems kind of redundant since I'm pretty sure that data should be there somewhere...
Thanks!
Don't forget to add the name and value parameters to your "button" or "input type=submit" fields of the form. I've had the same problem once and it drove me crazy.
In short, as request.POST contains a dict, you need a key and a value. The key corresponds to the name parameter of your button, and the dict's value to the button's value.
<button type="submit" value="preview">Preview</button>
won't be reflected in request.POST (there's no key for the POST dictionary!), whereas
<button type="submit" value="preview" name="preview">Preview</button>
will have a key "preview" with value "preview".
For some reason, in Chrome, when I had two buttons using <input/> tags, it would actually treat the button I didn't click as an input. That way, when I tested something like 'sendPaperButton' in request.POST, it would return the opposite of what I wanted.
I changed these to <button></button> tags and it worked fine.