Flashdata not render in view - twig

im try print an alert report before a submit form.
The constroller check that entity was valid and inform the result:
$estado = Array();
if(count($errors) > 0){
$estado['alert'] = 'alert-error';
$estado['message'] = $errors->get(0);
}else{
$estado['alert'] = 'alert-success';
$estado['message'] = "Usuario creado correctamente";
}
$this->getRequest()->getSession()->getFlashBag()->add('status',$estado);
return $this->redirect($this->generateUrl('alta_usuario'));
So, in the view:
{% if app.session.flashbag.has('status') %}
<div class="alert {{ app.session.get('status').alert }}">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ app.session.get('status').message }}
</div>
{% endif %}
But Symfony fails with the next message:
Impossible to access an attribute ("alert") on a NULL variable ("")
In the profiler the Flashdata is:
status : [{"alert":"alert-error","message":{}}]
Two questions:
1) Why "message" is null ? the entity has an error and $errors->get(0) should be get the first error ?
2) Why can't access the $estado values from the view ?.
Any ideas ?.

This question is much similar as below link.
You can find the answer at
Am I using the Symfony flash variables the wrong way?

Related

Translate data from API in in template with an an other API

im doing a package tracker with PHP / TWIG , and would like to translate results in an other language, so i have a google translate APi
in my twig file i have this :
{% for item in item.origin_info.trackinfo %}
<div class="status-{{item.checkpoint_status}}">
<p> {{item.StatusDescription}}. </p>
<hr/>
{% endfor %}
And i would like to translate each {{ item.StatusDescription }}. Could you tell me how to do ?
my function to translate is :
function translation($str){
$url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=fr&dt=t&q=" . $str;
$result = file_get_contents($url);
$data = json_decode($result);
$traduction = $data[0][0][0];
$lang = $data[2];
return $traduction;
}
You could register a custom filter into twig which allows you to call global functions.
$twig = new \Twig\Environment($loader);
$twig->addFilter(new \Twig\TwigFilter('translate', 'translation'));
First parameter translate is what the filter will be called in twig, the second is your global function translation. You now can use this filter in any template, e.g.
{% for item in item.origin_info.trackinfo %}
<div class="status-{{item.checkpoint_status}}">
<p> {{ item.StatusDescription | translate }}. </p>
<hr/>
</div>
{% endfor %}
If you need more than one extra function, filter, test, ... you are better off with creating an extension. See documentation for more information on this.

Show select field based on some other select option in flask

I am creating a flask form where I need to show a dropdown based on some other dropdown select field in Flask. I was able to do it with HTML, but finding it difficult to do the same in Flask form.
routes.py :
class RegistrationForm(FlaskForm):
category = SelectField('Category', choices = [('Clothes', 'Clothes'), ('Watch', 'Watch')])
subcategory = SelectField('Sub Category', choices = [('USPA', 'USPA'), ('LEE', 'LEE'), ('FOSSIL', 'FOSSIL'), ('TITAN', 'TITAN')])
submit = SubmitField('Register')
HTML :
<form action="" method="post">
{{ form.hidden_tag() }}
<p>
<p>
{{ form.category.label }}<br>
{{ form.category }}<br>
{% for error in form.category.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.subcategory.label }}<br>
{{ form.subcategory }}<br>
{% for error in form.subcategory.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.submit() }}</p>
</form>
I want mapping link this :
Clothes : USPA, LEE
Watch : FOSSIL, TITAN
But in the form I am getting all the options. I need subcategory based on selected category.
Since this is dynamic functionality on the client side you will need to use Javascript.
Personally I think the easiest way to do this is pre configure your flask form statically:
class RegistrationForm(FlaskForm):
category = SelectField('Category', choices = [('Clothes', 'Clothes'), ('Watch', 'Watch')])
subcategory_clothes = SelectField('Sub Category', choices = [('USPA', 'USPA'), ('LEE', 'LEE')], validators=[Optional()])
subcategory_watches = SelectField('Sub Category', choices = [('Titan', 'Titan'), ('Fossil', 'Fossil')], validators=[Optional()])
submit = SubmitField('Register')
And then display either one or the other combo boxes dependent upon the value of the initial combo box, using Javascript if statement. You will need a javascript event hook to detect changes to category, or use a framework such as Vue.js.
An example of javascript hook is here https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onchange
You can add a javascript function, in HTML, to show either box depending on the value of the other checkbox:
<script>
function myFunction() {
let box_value = document.getElementById("category").value;
if (box_value === "Clothes") {
document.getElementById("subcategory_clothes").style.display = "initial"
document.getElementById("subcategory_watches").style.display = "none"
} else {
document.getElementById("subcategory_clothes").style.display = "none"
document.getElementById("subcategory_watches").style.display = "initial"
}
}
</script>
And you can add a render_keyword argument in Python so that it populates the event hook in HTML:
category = SelectField('Category', choices = [('Clothes', 'Clothes'), ('Watch', 'Watch')], render_kw={'onchange': "myFunction()"})

Symfony 4 How to add an attribute to a twig using jquery?

I'm trying to do a form with symfony 4. It works fine. But I have a problem.
I have a field to write a comment. By default, it's not required.
However, I would like to change this using jquery.
This is what I tried to do.
Here, it's my twig:
<div class="information" id="informationForm">
{{ form_row(recordForm.category) }}
{{ form_row(recordForm.information) }}
{{ form_label(recordForm.comment) }}
{{ form_widget(recordForm.comment, {'attr': {'class': 'comment'}}) }}
{{ form_errors(recordForm.comment) }}
<button id="add_information_button" class="btn btn-primary">Ajouter un renseignement</button>
<button id="count_div" class="btn btn-primary">Compter</button>
<button class="remove_information_button btn btn-primary">Supprimer un renseignement</button>
</div>
Here it's the javascript:
$('.information')
.on("change", ".record_to_information_form_information", function (event) {
event.preventDefault();
var $commentState = $(this).find('option:selected').data('comment')
//Test: to know if i received the attribute
console.log($commentState)
if($commentState===false){
//the field isn't required
// {{ form_widget(recordForm.comment, {'attr': {'required': 'false'}}) }}
}else{
//the field is required
// {{ form_widget(recordForm.comment, {'attr': {'required': 'true'}}) }}
}
})
;
Do you have any suggestions?
You can toggle required property value from your jQuery code.
I assume that data-comment attribute has type boolean and it's always set, so your toggle statement can look as follows:
$('.information')
.on("change", ".record_to_information_form_information", function (event) {
event.preventDefault();
var $commentState = $(this).find('option:selected').data('comment');
//Test: to know if i received the attribute
console.log($commentState);
$('.comment').prop('required', $commentState);
});
If you need to do something else in your if-else statement, you can just leave your condition as you provided in sample:
if ($commentState === false) {
//the field isn't required
$('.comment').prop('required', false);
} else {
//the field is required
$('.comment').prop('required', true);
}

How to get user_token value from the URL

In an OpenCart framework version, 3.0.2.x, for the
URL = http://localhost/moreshop/admin/index.php?route=account/apisync&user_token=FARboCmeZHqQl8bITE3SRTenJscadbYc
I need to get the URL value from the parameter user_token that is written in the .twig format
Previously with OpenCart version 2.3.x.x, this was written in the .tpl file as
<input type="hidden" name="token" id="token" value="<?php echo $_GET['token']; ?>"/>
I had tried to assign the value =
{{ app.request.query.all }}
{{ app.request.query.get('user_token') }}
{{ app.request.get('user_token') }}
{{ _GET.user_token }}
But all the above value assigned with null. So how do I get the value of the user_token and assign into value=?
You should define it in your controller file:
$data['user_token'] = $this->session->data['user_token'];
Than you can call it in twig file:
<input type="hidden" name="User_token" id="user_token" value="{{ user_token }}"/>
you also can try call it {{ _GET.token }}
Alternative Solution: (This is not the exact solution to the question posted )
I had used JavaScript to catch hold of the user_token value and then pass it to AJAX in order to redirect to the particular URL
function getUrlParameter(sParam) {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&'),
sParameterName, i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];
}
}
};
var user_token = getUrlParameter('user_token');
console.log(user_token);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

Simple Pyramid app: using query params for routing to edit page

I am trying to make a simple Pyramid app, and having a hell of a time figuring out what part of the syntax I'm missing. What's happening is I have an edit page for my model, and I can not figure out how to pass in the id of the entry I'm editing.
My view reads like this:
#view_config(route_name='action', match_param='action=edit', renderer='string')
def update(request):
this_id = request.matchdict.get('id', -1)
entry = Entry.by_id(this_id)
if not entry:
return HTTPNotFound()
form = EntryUpdateForm(request.POST, entry)
if request.method == 'POST' and form.validate():
form.populate_obj(entry)
return HTTPFound(location=request.route_url('blog', id=entry.id, slug=entry.slug))
return {'form': form, 'action': request.matchdict.get('action')}
I have created an edit template, it looks like this, and is working for the create page, which uses a different model:
{% extends "templates/layout.jinja2" %}
{% block body %}
<h2>Create a Journal Entry</h2>
<form action="" method="POST">
{% for field in form %}
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<p>{{ field.label }}: {{ field }}</p>
{% endfor %}
<p><input type="submit" name="submit" value="Submit" /></p>
</form>
{% endblock %}
And the link I have made to the template looks like:
Edit Entry
Which yields the url http://0.0.0.0:6543/journal/edit?id=1. This is new and weird to me, because I'm used to Rails, where the url would look like http://0.0.0.0:6543/journal/1/edit but poking around and reading the Pyramid blogr tutorial, this seems like how Pyramid likes to have routes. Unfortunately, it still gives me a 404. It seems like I am successful passing the id of the entry into a query string, but somehow I am not telling the edit page to be at that location.
Thanks for any help you can give.
I can't see where the problem is as this minimal example works, if you navigate your browser to localhost:8080/journal/edit?id=723
#!/usr/bin/env python
from pyramid.response import Response
from pyramid.view import view_config
from pyramid.config import Configurator
from waitress import serve
#view_config(route_name="root", renderer="string")
def root_view(request):
return "root_view", request.params
#view_config(route_name='action', match_param='action=edit', renderer="string")
def action_view(request):
return "action_view", request.params
if __name__ == '__main__':
config = Configurator()
config.add_route('root', '')
config.add_route('action', '/journal/{action}')
config.scan()
app = config.make_wsgi_app()
serve(app)
Maybe you have some other problem with your routes. Can you paste them here all? Are you sure you do not have another function named update in your view?
Aside from that, you are completely free to build your routes as you wish with Pyramid.
config.add_route('action2', '/different/edit/{id}')
config.add_route('action3', '/someother/{id}/edit')
I personally would rather use one of the schemes above than the match_param predicate...

Resources