Simple (I hope) BoltForms questions - bolt-cms

How can I change the text on a submit button?
I vaguely remember the option that it is possible to direct users to a page after submission. Is that documented?

The submit button just behaves like any Symfony Forms field, so you can simply to this:
submit:
type: submit
options:
label: My Button Text
As for redirect, sort of. You can't redirect yet, but you can give different HTML.
{% set html_pre = '<h1>This will appear above the un-submitted form</h1>' %}
{% set html_post = '<p>Thank you for submitting your form<p>' %}
{{ boltforms('formname', html_pre, html_post) }}

Related

Django Admin: How to use the button to move to the selected URL?

I am very new to Django and trying to make my first project. I find it difficult to use the buttons I created to move to the selected URL.
Let's say my app is called TestForms and my models are: Patients, General, PST and ERBT. I would like to create two buttons - 'Previous' and 'Next' - which will be used to go to previous/next forms respectively. I try to do so using admin templates in django.
NOTE: I know changing built-in templates are not a very good idea, I will create new html file to extend this templates before doing changes on the server. For now I am doing it locally on my computer.
In submit_line.html I created two new buttons and they are like so:
{% if show_save_and_go_to_next_form %}<input type="submit" value="{% translate 'Next' %}" class="default" name="_gotonextform">{% endif %}
{% if show_save_and_go_to_previous_form %}<input type="submit" value="{% translate 'Previous' %}" class="default" name="_gotopreviousform">{% endif %}
This gives me two good-looking buttons on the site.
But these are just saving the results (working like 'Save' button), but not redirecting me to the next form as I would like to. When I am adding a new patient (admin/TestForms/patient/add/), after clicking on 'Next' I would like the server to save this patient and redirect me to admin/TestForms/general/add/ to be able to fullfil the next form, then save the changes and move on to admin/TestForms/PST/add/and so on.
I know I have to add the anchor, but I tried multiple times with different approaches and nothing worked. When I try to use <a href ...>, the button disappears. Also it is difficult for me to figure out how to move from one form to another and to disable the 'Previous' button on the first form and the 'Next' button on the last form.
Any suggestions how to achieve it?
The redirect needs to be done in your view, not in the template.
def your_view(request, *args, **kwargs):
# your code ...
if request.POST.get('_gotonextform'):
return redirect('admin/TestForms/general/add/')
else:
# do whatever you like if any other button was clicked
pass

Flask WTForms SelectField add placeholder or disabled option

I am working on a webpage using flask and wtforms. When opening the webpage, my selectfield should not hold any value (i.e. be blank, have placeholder saying "please choose an option" or something in that direction).
My form is defined like this in forms.py:
class Form(FlaskForm):
selectfield = SelectField('Title', choices=[])
I leave choices as an empty list because they are created from a database through the function get_choices:
# create instance of form
form = Form()
# run function to get data from db
form.selectfield.choices = get_choices()
Here it starts to get gnarly: Since the placeholder value should be empty (i.e. "") or something like "please choose" I don't want to have it in my database. So I add the value manually:
# append
form.selectfield.choices.append('Please choose')
The html part, where I render the form looks like this:
<form method="POST" action= {{ url_for('index') }}>
{{ form.csrf_token }}
{{ form.selectfield(class_="form-control", **{"onchange":"this.form.submit()"}) }}
</form>
What have I tried:
adding 'placeholder = "please choose"' here:
{{ form.selectfield(placeholder="please choose", class_="form-control", **{"onchange":"this.form.submit()"}) }}
(as suggested by Crast here: WTForms Can I add a placeholder attribute when I init a field?)
adding default="Please choose" to my Form class as suggested by Liu Yue (How do you set a default value for a WTForms SelectField?):
class Form(FlaskForm):
selectfield = SelectField('Title', choices=[], default="Please choose")
This works partly, but the Please Choose value should not be selectable which it still is.
I feel like I might be completely on a wrong path here, and maybe oversee a very simple feature. I really can't believe that such a popular feature is not available using wtforms.
I am thankful for any advice and guidance.

Django redirect to page with new context

I have this bit of code:
{% for i in list %}
<button>{{i}}</button>
{% endfor %}
How do I redirect to a new page and pass it value of i as a context, so that it will be like this:
<h3> You chose {{i}} </h3>
It doesn't have to be a button, in fact I'd prefer if it could be <span> with sort of the same functionality as in AngularJS ng-click
Do I need to send a request with button click and then handle it in views.py? Can I do this without a form?
I would prefer if it just redirected me to .../page?i='whatever'
I can do it with
<span>Click</span>
But what's the preferred Django way of doing it?
Do I need to send a request with button click and then handle it in
views.py?
Yes , you would need to create a view to handle that request that will be of type GET and will have data i inside it.
Can I do this without a form?
Yes of course you can and hence your approach of making it a link rather than a button is better and is the way it should/is done in most of the cases. But there is nothing Djangoish in this approach , its just the way it should be done...
I would prefer if it just redirected me to .../page?i='whatever' I can
do it with
Go ahead and do this way its fine.
<span>Click</span>
How do I redirect to a new page and pass it value of i as a context, so that it will be like this <h3> You chose {{i}} </h3>:
def link(request):
i = request.GET.get('i',None)
render_to_response('your_html_template', {"i": i}, RequestContext(request))

CSRF error django 1.8 i18n internationalization

Hi I have django internationalization working on my django site. That is if i browse ".../en/foo/bar" and ".../nb/foo/bar" they work fine. But i am trying to get a drop down menu to automatically change the language but i get csrf error.
base.html
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}"/>
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"
{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go"/>
</form>
I however have another form in the same html but I do not but {% csrf_token %} in it. I rather place#csrf_exempt` on the view that handles the form.
I dont know whether having both froms on on html is what is causing the problem.
So what id did was that i created my own set_language view just like in django.veiws.i18n and places the #csrf_exempt on it.
#csrf_exempt
def set_language(request):
"""
Redirect to a given url while setting the chosen language in the
session or cookie. The url and the language code need to be
specified in the request parameters.
Since this view changes how the user will see the rest of the site, it must
only be accessed as a POST request. If called as a GET request, it will
redirect to the page in the request (the 'next' parameter) without changing
any state.
"""
print 'I am in setlang'
next = request.POST.get('next', request.GET.get('next'))
if not is_safe_url(url=next, host=request.get_host()):
print 'not safe'
next = request.META.get('HTTP_REFERER')
if not is_safe_url(url=next, host=request.get_host()):
next = '/'
response = http.HttpResponseRedirect(next)
if request.method == 'POST':
lang_code = request.POST.get('language', None)
if lang_code and check_for_language(lang_code):
if hasattr(request, 'session'):
request.session[LANGUAGE_SESSION_KEY] = lang_code
else:
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN)
return response
Though the CSRF validation error is solved the form has no effect when i change the language and submit. it just stays on the same page. it appears that if not is_safe_url(url=next, host=request.get_host()) is always true. I am not sure what i am doing wrong now
I just realised that my form sends a GET request to the view instead of a post so request.method is GET how and why is this so? The form data does not get to the view at all in this case but they submit when i leave the action attribute of the form blank. The the form submits to the view that called the page. Submitting to a specific view is not working as the request somehow becomes a get request
With first problem - csrf error, there is no simple solution (if you want csrf working, not bypassed) because we can't tell what is happening here - maybe some cookie-related issue.
But second problem is simple to solve. There is bug in django. In simple words, django won't translate url (change prefix in front of URL or translate whole URL) when user is changing language, so user will be redirected to old, not translated URL with old language prefix. That will cause to switch back to old language after redirection.
Solution to that problem is already submitted to django and will be available in django 1.9, but you can get code of that view from github and put it instead of your current language switching view.
Here is full commit for that fix, there is new function called translate_url in urlresolvers that is used in fixed view.

When to use as_hidden in Django, and why not just display: none; in CSS?

I'm struggling to understand why and when you would make a form "hidden" in a Django app.
For example, when would you place a form in your template as
{{ form.as_hidden }}
and what is the practical difference between that, and placing it in a hidden <div>, like
<div style="display: none;">
{{ form.as_hidden }}
</div>
?
Django doesn't render entire forms as hidden so {{ form.as_hidden }} will not render anything.
Now if you want to talk about when to render fields of forms as_hidden, then we're in business.
Why you want to render fields as hidden inputs (it's what formfield.as_hidden does) is when you want to send a value to the client, store and get it back to your view since they are sent back to the server when the form is submitted.