hi guys i have a form with a checkbox that if checked needs to display an additional bunch of fields, is it possible to tell the form to wrap some fields in one div and the rest in another div? this way I can play around client-side with javascript, I also want to do it client-side for styling purposes,
any help will be greatly appreciated
thanks in advance
Yes, you can render fields manually and add any styles you like.
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="{{ form.sender.id_for_label }}">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
{{ form.cc_myself }}
</div>
Also, check out this neat article on the subject.
Related
I am new to shopify theme development and I'm building a theme from scratch to gain experience. I'm having trouble with the 'add to cart' button on my product page. Even though I have various product options for a product, I am only displaying the 'size' options as radio buttons and then I take an input quantity and add it to the cart. The problem I am facing right now, is that the cart only adds 1 item at a time, So even if I input 3 or 4 as my quantity, the cart only adds 1 as the quantity.
here's my code:
{% form 'product', product %}
<div>
<p class="option-title">Size</p>
<div class="line"></div>
<div class="options">
{% for product_option in product.options_by_name['Size'].values %}
<input type="radio" id = "{{ product_option }}" name="size" value="{{ product_option }}" >
<label for="{{ product_option }}">{{ product_option }}</label>
{% endfor %}
</div>
</div>
<div class="line"></div>
<div class="quantity-add">
<div class="input-quantity">
<input class="input-quantity" type="number" min="1" placeholder="1">
<input type="hidden" name="id" data-productid="{{ product.variants[0].id }}" value="{{ product.variants[0].id }}" data-variant-title="{{ product.variants[0].title }}" />
</div>
<div class="cart-button">
<button class="cart-btn" type="submit" value="Add To Cart">ADD</button>
</div>
</div>
{% endform %}
Any help will be much appreciated. I am so lost regarding how I should fix it.
It should work fine if you add the proper name and value attribute to your input element:
<input name="quantity" value="3">
This would add the selected variant ID three times to the cart.
How can I combine radio-button inside a dropdown select form.
I'll be grateful for your help.
My codes:
index.html
<div class="card-header">
<div class="container">
<div class="row">
<form class="col-md-4">
<select class="form-control select2" >
<option>Select Major Head</option>
{% for major in majors %}
<option>{{ major.pk }}: {{ major.description }}</option>
{% endfor %}
</select>
<button type="button">Display!</button>
</form>
</div>
</div>
</div>
This might not be the best approach, but you can try something like this:
<form class="col-md-4" action="{{ your_url_here }}" method="post">
{% csrf_token %}
<select class="form-control select2" >
<option>Select Major Head</option>
{% for major in majors %}
<option value="{{ major.pk }}">{{ major.pk }}: {{ major.description }}</option>
{% endfor %}
</select>
<input type="submit" value="Select">
</form>
Yes, you need to write a Django form to process the data. You can read more about forms here. The value="{{ major.pk }}" part gives Django views an attribute to recognize, which you are going to use later.
After having filled out the form, you can get the data in your views as such:
def page_objects(request):
if request.method == 'POST':
form = YourForm(request.POST)
if form.is_valid():
answer = form.cleaned_data['value']
Forms are not the easiest thing to do as you need to create your own views and forms, both backend and frontend. You may also try out other form helper libraries like django crispy forms, but that really depends on how much you want to rely on bootstrap and other UI libraries.
I'm using Django's generic editing views CreateView, UpdateView, etc. together with the auto-generated HTML forms and it works fine:
# views.py
class TagCreate(CreateView):
template_name = 'app/tag_form.html'
model = Tag
fields = ['name', 'description', 'color']
class TagUpdate(UpdateView):
model = Tag
fields = ['name', 'description', 'color']
<!-- app/tag_form.html -->
{% extends 'app/base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% endblock %}
Now, I want to customize the generated form {{ form.as_p }} with bootstrap:
{% extends 'app/base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="nameInput">Name</label>
<input class="form-control" type="text" id="nameInput" placeholder="Name" value="{{ tag.name }}">
</div>
<div class="form-group">
<label for="descrInput">Description</label>
<input class="form-control" type="text" id="descrInput" placeholder="Description" value="{{ tag.description }}">
</div>
<div class="form-group">
<label for="colorInput">Color</label>
<input class="form-control" type="color" id="colorInput" placeholder="Color" value="{{ tag.color }}">
</div>
<input type="submit" value="Save">
</form>
{% endblock %}
The page renders nicely exactly how I want it to, but when I click the "Save" button, nothing happens and the data is no longer saved, nor am I forwarded to the detail view like I was before.
I tried following the Django documentation on how to render fields manually; again, it's rendered correctly, but the data isn't saved.
How can I properly customize forms and still use my generic editing views?
Edit: My full code his here.
Following the documentation you have to access the form inputs manually and django will populate them accordingly in the template.
{% extends 'app/base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="nameInput">Name</label>
{{ form.name }}
</div>
<div class="form-group">
<label for="descrInput">Description</label>
{{ form.description }}
</div>
<div class="form-group">
<label for="colorInput">Color</label>
{{ form.color }}
</div>
<input type="submit" value="Save">
</form>
{% endblock %}
From there, to add classes, you will have to override the CreateView get_form in order to add in what we need:
class TagCreate(CreateView):
template_name = 'app/tag_form.html'
model = Tag
fields = ['name', 'description', 'color']
def get_form(self, form_class):
form = super(TagCreate, self).get_form(form_class)
form.fields['name'].widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Name' })
form.fields['description'].widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Description' })
form.fields['color'].widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Color' })
return form
Although, this would be a lot cleaner if using ModelForms
in your form input tag set the "name" attribute, field name as value
something like this:
...
<input class="form-control" type="text" id="nameInput" placeholder="Name" name="name" value="{{ tag.name }}">
...
<input class="form-control" type="text" id="descrInput" placeholder="Description" name="description" value="{{ tag.description }}">
...
<input class="form-control" type="color" id="colorInput" placeholder="Color" name="color" value="{{ tag.color }}">
...
I've been having trouble adding HTML for Form Control to my Django form. I know (from other features) that I have Bootstrap properly integrated into the project. No fields are showing when I try to integrate form control into the page.
The form has two fields: 1) a file field, and 2) a boolean field. Below is my HTML (I don't include the submit button after/closing tags.
<form id='name' action = "" method="POST" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<div class="col-md-4">
<!-- {{ form }} --> #Note that when this is not commented out and when the lines below are commented out, the form works correctly, but obviously with no form control.
{% for field in form.visible_fields %}
{% if field.auto_id == "file" %}
<div class="form-group{% if field.errors%} has-error{% endif %}">
<div class="col-sm-5 col-md-4 col-xs-8 col-lg-4 col-xl-4">
<label for="file">File input</label>
<input type="file" class="form-control-file" id="file" aria-describedby="fileHelp">
<small id="fileHelp" class="form-text text-muted">Test</small>
<div class="input-group">
<div class="input-group-addon">$</div>
{{field}}
</div>
{{ field.errors }}
</div>
</div>
{% else %}
{% endif %}
{% endfor %}
Any help would be greatly appreciated!
I am trying to put {{field.id}} in the the HTML input attributes but it doesn't work. What is the correct way to do this?
<input type="text" class="form-control" id="{{field.id}}">
I also tried:
<input type="text" class="form-control" id={{field.id}}>
Heres my full code:
{% for field in wizard.form %}
<div class="row">
<label class="col-xs-4" for={{field.id_for_label}}>{{ field.label }}</label>
<div class="col-xs-2">
<div class="form-group">
<input type="text" class="form-control" id="{{field.id}}">
{{field.id}}
</div>
</div>
</div>
{% endfor %}
You can get the generated id of a form field like so:
{{ field.auto_id }}
This is a duplicate of https://stackoverflow.com/a/3765016/1637351
Edit:
Though I don't understand why you're trying to put the id value as the name attribute. That will result in the rendered html being
<input name="id_field_name" />
I would be taken care of automatically if using the field template tag.
Instead, I'd try a different approach than you're using, using django_widget_tweaks to programmatically add attributes.
For example, in your template...
{% for field in wizard.form %}
<div class="row">
<label class="col-xs-4" for={{field.auto_id}}>{{ field.label }}</label>
<div class="col-xs-2">
<div class="form-group">
{{field|attr:'class:form-control}}
</div>
</div>
</div>
{% endfor %}
This will automatically generate the input for each field with class='form-control' as part of the tag. The id/name will automatically be taken care of by rendering field.