I want the user to be able to select a time period from the drop down then select the number of appointments needed with that time span and have it added to a list. I have been able to accomplish this with simply javascript and Html, but am at a loss as how to get all the values from the table after the user clicks 'submit'.
If I used Django's form API then the fields in the table would display as editable textboxes. Is there a way to make a form with labels/non-editable text instead of fields? That way I can edit the labels with javascript and the values will get passed to the view on Post.
I am new to Django so any suggestions are welcome.
Example
Forms.py Example - Not what I want:
class AppointmentForm(forms.Form):
TimePeriod = forms.IntegerField(label='Time Period')
Amount = forms.IntegerField(label='Amount')
AppointmentFormSet = formset_factory(AppointmentForm)
When I solved much more complex generated form, I just created view, which collected some data, set context and rendered template.
That template was "old style" form, with all the tags written by hands/loops and so, like
{% for p in pairs %}
<option name="name_{{p.id}}" value="{{p.val}}">
{% endfor %}
and
{% for v in vars %}
<input type="text" name="{{v.name}}" value="{{v.val}}">
{% endfor %}
and the form ended in view, where I was looping over request.POST and parsing it manually (mainly)
Not very Django way, but you can do ANYTHING with this approach (and shoot yourself to any leg any time you want too)
Presumably by "labels" you just mean non-editable text, so it could be a <div> or a <p> etc - in this case you will need to have a hidden input which mirrors the content of the label, i.e.
<div class="label">Text here</div>
<input type="hidden" name="form-field-name" value="Text here">
To achieve this in your form, use a forms.HiddenInput widget:
class AppointmentForm(forms.Form):
time_period = forms.IntegerField(widget=forms.HiddenInput)
Obviously the django form isn't going to render the way you need it to, so you'll need to render it using custom html, which will probably look something like this:
{% for field in form %}
<div class="label">{{ field.data }}</div>
{{ field }}
{% endfor %}
Related
I have a flask form that has some values for a given event. On submit I redirect the user to page where I take the values from the form and calculate some statistics about the event. The user can accept these values, and submit the event to the database, or click an edit button which will take them back to the form for them to modify the values. The issue is since the form has already been submitted, when they click edit and are redirected back to the form, all the values are gone. I want the values to stay because chances are they will only be modifying one or two fields and I don't want them to have to re-enter all of them. Any ideas how to do this?
You can let Flask-wtf generate the form automatically, and it can remember the user input. If you pass the form instance to your Jinja template like this:
form = SomeForm()
return render_template("template.html", form=form)
A minimal example of a form:
class SomeForm(FlaskForm):
name = TextField(label='name', default="")
save = SubmitField(label='Save', description="Save")
And in your Jinja template:
<form method="post" action="the url" class="form-inline">
<ul>
{% for field in form %}
<li>{{ field.label }} {{ field }}</li>
{% endfor %}
</ul>
</form>
You can use window.history.back();.
From History API: "This acts exactly as if the user clicked on the Back button in their browser toolbar"
This works because the browser saves the users inputs , all except for the type="password" ones
I have a requirement to render select field multiple times and each field will have pre-selected value.
Now My question is:
How can you dynamically set initial value of django form selectfield at the time of rendering django template??
my form:
class RequestProdApvr(forms.Form):
product = forms.ModelChoiceField(queryset=Product.objects.all().order_by('code'), label='', required=False)
I have to use this form in multiple row in my listview and pre-populate value based on saved data.
I searched SO for the solution and non of them met my requirement...
Django. Initial value of Choice Field dynamically
Dynamically set default form values in django
Hence I am posting separate question here...
You have to loop through select options and check if the current object is equals to backend options so you can mark it as selected:
<select name="field_name" class="form-control" id="id_field_name">
{% for id_obj, obj in form.field_name.field.choices %}
{% if obj == context_obj.property%}
<option value="{{id_obj}}" selected="">{{obj}}</option>
{% else %}
<option value="{{id_obj}}">{{obj}}</option>
{% endif %}
{% endfor %}
</select>
I guess it's what you were trying to achive.
I am us ing django Model Forms. When it catches an error it display right on top of the text field. Is there a way I could make it display it to the side of the text box instead?
I'm guessing your using one of Django's built in ways to display your form (i.e. https://docs.djangoproject.com/en/dev/topics/forms/#displaying-a-form-using-a-template). This is great, in that it makes it really easy to display a form with a single line, such as {{ form.as_p }}, however, by doing this you're giving up all of your control over how the form gets rendered. If you want that control back, you're going to have to write the HTML yourself.
That is, you'll need to do something like:
{% for field in form %}
<p>{% if field.error %} {{ field.error }} {% endif %}</p>
<p>{{ field.label }}</p>
<p>{{ field }}</p>
{% endfor %}
Of course, you'll need to change the formatting to suite your needs, but you can now directly change the HTML, and add classes or id's (to use in CSS) if you nee something more advanced.
Those error messages appearing under the widgets are just normal html elements which you can modify it's output with CSS. Take a read at Styling required or erroneous form rows.
Hope this helps!
Is it possible to change the display of inlines in order to change it to this? I was thinking of changing the admin template file "tabular.html", is it going to be possible or should I change something else?
Update
Ok, I've been trying to edit the tabular.html but my experience with Django isn't enough to understand how/where to make the necessary changes... Any clue of where I should start?
Shouldn't I be changing the CSS also?
I guess that {{ field.field }} automatically renders the dropdown menu (Django admin default) if I'm understand this correctly...
Update 2
I was able to change the second column to the functionality that I wanted but I think that for the first one it's going to be trickier... Current status
Update 3
One hack that I think would work is to display on each of the inlines only one of the options of the first field and then deactivate the "add another option". How can I iterate on the options in "tabular.html" ?
Update 4
I guess the trick should be done here... How can I iterate on the field choices in order to display only one choice per line?
{% for fieldset in inline_admin_form %}
{% for line in fieldset %}
{% for field in line %}
{{ field.get_choices_display }}
<td class="{{ field.field.name }}">
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
{% else %}
{{ field.field.errors.as_ul }}
{{ field.field }}
{% endif %}
</td>
{% endfor %}
{% endfor %}
{% endfor %}
Yes, you could change template of your InlineModelAdmin instance to your customized template, for example customized_inline.html. Simply copy django/django/contrib/admin/templates/admin/edit_inline/tabular.html to customized_inline.html in your template path as starting.
edit
Perhaps I was misunderstanding. If you want to change the rendering style of a form field, the normal way is to change its widget. In Django ModelAdmin and InlineModelAdmin, the main ways of customizing a field widget goes around BaseModelAdmin.formfield_for_dbfield method inside django/contrib/admin/options.py, reading the code and the doc when you want to change the widget of a form field.
For field having choices, you could simply set radio_fields in ModelAdmin/InlineModelAdmin instance to render the field as radio select instead of dropdown.
Furthermore, use OneToOneField instead of ForeignKey, or set extra and max_num in your InlineModelAdmin instance to prevent admin from rendering multiple rows of inline, like:
class SomeInlineAdmin(admin.TabularInline):
model = Foo
extra = 1
max_num = 1
I cannot open your second link, you could post things in the question instead of using a external link.
I have a user model, an item model, and a possession model to store data about a user possessing an item. When a user is logged in and viewing an item, I want to display an 'add to my items' button, unless the user already has the item.
I was trying this code in the template:
{% if not user.possession_set.filter(item=item.id) %}
<input type='submit' value='add to my items' />
{% endif %}
where
item is the foreign key name for the item object in my possession model and
item.id is the primary key for the item being displayed to the user
but I get this error:
Could not parse the remainder: '(item=item.id)'
I'm thinking I can't use the .filter() function since that is for querying the database? I found django's template filters, like this one:
http://docs.djangoproject.com/en/1.1/ref/templates/builtins/#get-digit
but there aren't any that can be combined to filter for a certain value of item. It seems I would have all the information in the template to do this, since I'm getting the user and it's possession_set, which should have the item field for each possession, so I'm thinking it's just a syntax thing?
Thanks for the help!
You could write a custom template filter for this.
def owns(user, id):
return not user.possession_set.filter(item=id)
Then, in your template:
{% load mystuff %}
{% if user|owns:item.id %}
Check the Django docs at http://docs.djangoproject.com/en/1.1/howto/custom-template-tags/ for more info. Not sure if passing item.id as the filter argument will work, though.
You can't use such complicated expressions in the template, only in the view. Compute the information, whether user can have this button in the view and pass a single True or False value to the template. For example:
in view
allow_addition = not user.possession_set.filter(item=item.id)
and in template:
{% if allow_addition %}
<input type='submit' value='add to my items' />
{% endif %}