Django bootstrap alerts not working as expected - javascript

I need help with this.
I'm trying to make my app looks better with bootstrap alert, I have one alert to add an item and other alert to delete an item.
When I add an item my alert looks great and work fine but when I delete the item it's not working properly.. Only shows my message with no bootstrap alert....
What am I doing wrong?
Here's what I got:
<div class="container">
{% if messages %}
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
{% for message in messages %}
<p{% if message.tags == "success" %} class="alert alert-success "{% endif %}>{{ message }}</p>
{% if message == 'danger' %}
<p{% if message.tags == 'danger' %} class="alert alert-danger"{% endif %}>{{ message }}</p>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
Views for my success msg
messages.success(request, 'Has been added!.')
Views for my danger msg
messages.error(request, 'Has been deleted!.')
Thanks in advance..!
EDIT
I solved my problem as Silvio answered to my question. worked great with every bootstrap alert but the alert-danger to make it work I had to edit my settings.py to something like this:
from django.contrib.messages import constants as message_constants
MESSAGE_TAGS = {message_constants.DEBUG: 'debug',
message_constants.INFO: 'info',
message_constants.SUCCESS: 'success',
message_constants.WARNING: 'warning',
message_constants.ERROR: 'danger',}

As an update to the author's question, only the tags that are being overridden need to be listed in settings:
https://docs.djangoproject.com/en/4.0/ref/contrib/messages/#message-tags
In this case (Bootstrap looking for "danger", but Django providing "error"):
from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
messages.ERROR: 'danger',
}

I guess you are using the wrong HTML markup for Bootstrap:
{% if messages %}
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
{% for message in messages %}
<div class="alert alert-{{ message.tags }}" role="alert">
<p>{{ message }}</p>
</div>
{% endfor %}
</div>
</div>
{% endif %}
Note that you were using a <p> tag instead of a <div>. Also maybe you can use the {{ message.tags }} directly.

Related

Time gap between message.errors in django

I created a Django app with a form. when the form is submitted and found error, messages.error(request, e) is called, where e is the error text.
the real code
for field, errors in form.errors.items():
print('Field: {} Errors: {}'.format(field, ','.join(errors)))
e = 'Field: {} Errors: {}'.format(field, ','.join(errors))
messages.error(request, e)
if I have multiple errors, multiple error boxes pops up at same time, but I want to make a time difference of .5seconds between each error popup.
I saw time.sleep(0.5) but the issue is it just takes timegap inside forloop not in gap between the popup. There might be a JS fix, I would like to know how
here's my html code
{% if messages %}
{% for message in messages %}
{% if message.tags == 'alert-success' %}
<!-- Toast -->
<div data-toast data-toast-text="{{ message }}"
data-toast-gravity="top" data-toast-position="right" data-toast-className="success"
data-toast-duration="2000" class="noty-tost d-none rounded shadow bg-success"></div>
{% endif %}
{% if message.tags == 'alert-danger' %}
<!-- Toast -->
<div data-toast data-toast-text="{{ message }}"
data-toast-gravity="top" data-toast-position="right" data-toast-className="danger"
data-toast-duration="5000" class="noty-tost d-none rounded shadow bg-danger"></div>
{% endif %}
{% endfor %}
{% endif %}
$(document).ready(function () {
$('.noti-toast').click()
});
// used to trigger it(using toastify.js from a template, i don't really know much about it, but it works🫣)

Any ideas why error pop up is not interactable when you're not logged in but it's interactable after you logged in on Flask?

If the user is not logged in the popup is not interactable but once the user logs in it can be interacted with, not sure why this actually happens and it doesn't seem like it's a JavaScript problem, couldn't find any solutions to it by searching around. I wonder what could cause this behavior on Flask
HTML + Jinja2 :
<body>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
{% if category == "soft-error" %}
<div class="toast" id="toast">
<div class="toast-content">
<div class="close-btn">
<a class="wa-close icon-pos" id="close-btn"></a>
</div>
<div class="message">
<div class="text-content">
<p class="text text-1" id="txt-hide">Error</p>
<span class="text text-2" id="txt-hide-2">{{ message }}</span>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock%}
</body>
JavaScript :
const closeBtn = document.getElementById('close-btn');
const toast = document.getElementById("toast");
closeBtn.addEventListener('click', () => {
toast.parentNode.removeChild(toast);
});
setTimeout(function() {
toast.parentNode.removeChild(toast);
}, 5000);

how to hide blank property field from orders in shopify

I have created a gift note functionality which store notes but the problem is it is showing title on orders even though textarea is blank could you please help to get rid of this problem
if textarea is blank still order page is showing "cart note:"
{% if line_item.properties != empty %}
<ul class="CartItem__PropertyList">
{% for property in line_item.properties %}
{% assign first_character_in_key = property.first | truncate: 1, '' %}
{% if property.last == blank or first_character_in_key == '_' %}
{% continue %}
{% endif %}
<li class="CartItem__Property">{{ property.first }}: <p class="cart_note_txt">{{ property.last }}</p></li>
{% endfor %}
</ul>
{% endif %}
<textarea class="gift_note_pro" maxlength="300" name="properties[Cart Note]" style="display:none;" placeholder="Add a note">
</textarea>
Can someone help me to get rid of this problem ?

Show and hide text of different posts

I have several posts each of them composed of three parts : a title, a username/date and a body. What I want to do is to show the body when I click on either the title or the username/date and hide it if I click on it again. What I've done so far works but not as expected because when I have two or more posts, it only shows the body of the last post even if I click on another post than the last one. So my goal is only to show the hidden text body corresponding to the post I'm clicking on. Here is my code:
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Test page{% endblock %}</h1>
<a class="action" href="{{ url_for('main_page.create') }}">New</a>
{% endblock %}
{% block content %}
{% for post in posts %}
<article class="post">
<header>
<script language="JavaScript">
function showhide(newpost)
{var div = document.getElementById(newpost);
if (div.style.display !== "block")
{div.style.display = "block";}
else {div.style.display = "none";}}
</script>
<div onclick="showhide('newpost')">
<h1>{{ post['title'] }}</h1>
<div class="about">by {{ post['username'] }} on {{ post['created'].strftime('%d-%m-%Y') }}</div>
</div>
</header>
<div id="newpost">
<p class="body">{{ post['body'] }}</p>
</div>
</article>
{% if not loop.last %}
<hr>
{% endif %}
{% endfor %}
{% endblock %}
Of course I looked for a solution as much as I could but I'm kind of stuck plus I'm a complete beginner in HTML/JS/CSS. And one last thing, I'm currently using Python's framework Flask. Thank you by advance.
You need to give each of your posts a unique id for your approach to work.
Change your code to
<div id="{{post_id}}">
<p class="body">{{ post['body'] }}</p
</div>
where post_id is that post's unique id e.g. its id in the database you are using that you pass to the template in your view. Then, change the call to the onclick event handler to
<div onclick="showhide('{{post_id}}')">
If you don't have a unique id you can also use the for loop's index: replace all post_id instances above with loop.index. See Jinja's for loop docs for more information.

How do I populate dynamically a StringField with the value of a SelectField in Wtforms

in a wtforms, I would like my SelectField to fill up with its selected value a StringField.
I use flask, bootstrap, and python 3.7
My HTML code is as follow:
{% block body %}
<h3>Edit Bloomberg ticker details</h3>
{% from "includes/forms/_form_helpers.html" import render_field %}
<div class="form-group" id="company_id" onchange="myFunction(event)">
{{render_field(form.company_names, class_="form-control")}}
</div>
<div class="form-group" id="isin_id">
{{render_field(form.isin_id, class_="form-control")}}
</div>
<script>
function myFunction(e) {
document.getElementById("isin_id").value = e.target.value
}
</script>
{% endblock %}
And the pyhon behind is as follow:
class DefTickerForm(_Form):
choices_companies = [(1,'Facebook'), (2, 'Google') ]
company_names = _SelectField(label='Company names:', choices=choices_companies, coerce=int)
isin_id = _StringField(label='isin_id', validators=[_validators.DataRequired], default=-1)
I would like that when the user select 'Facebook', the isin SelectField to be equal to 1. But so far it does nothing.
Note that if if code:
alert(e.target.value)
I get the wanted value. so issue is to set the TextField value.
my render field code is as followed (from a youtube tutorial):
{% macro render_field(field) %}
{{ field.label }}
{{ field(**kwargs)|safe }}
{% if field.errors %}
{% for error in field.errors %}
<span class="help-inline"> {{ error }}</span>
{% endfor %}
{% endif %}
{% endmacro %}
Any help would be much apreciated as google isn't so good on these.
Best
apparently TextField only accepts strings (I guess obvious if you are used to javascript)
so code working is as follow in case someone get he same problem:
<div class="form-group" onchange="myFunction(event)">
{{render_field(form.company_names, class_="form-control")}}
</div>
<div class="form-group">
{{render_field(form.isin_id, class_="form-control")}}
</div>
<script>
function myFunction(e) {
var x = e.target.value;
alert(x);
document.getElementById("isin_id").value = x.toString();
}
</script>
As a note, Jinja or anyway my render, use the fields names as default IDs (wich i realised using Chrome inpector. Meaning I didn't have to add an id for each Div. Anyway that is the thoughts of a beginenr in Javascripts.

Categories

Resources