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🫣)
Related
I have a custom button in the a header next to a "cart" link. Website uses AJAX cart. When an item is added to cart, the cart link enlarges to include nr of items in cart. This causes the cart link to overflow and overlap the custom button next to it. Essentially what I'm trying to achieve is to add a margin to the custom button when an item is added to cart and the cart link is expanded. My first thought was to wrap both in a div and use CSS flex to adjust the sizing of both, however, and please correct me if I'm wrong, I thought it would be quicker to just write a script that would add a margin to my custom button. Definitely didn't turn out to be the quicker way as I've been stuck on it for hours now - any help would be greatly appreciated. I've browsed through similar posts and couldn't find a result that I want - any help would be greatly appreciated (I'm still new to JS and jQuery but learning). Below is the code and some of the things that I've tried.
HTML - header
<div class="header--menu">
<div class="custom-btn-container">
Quick Order
</div>
{%
render 'framework--x-menu',
js_class: 'XMenu',
align: menu_alignment,
overlap_parent: 1,
handle: menu
%}
</div>
{% endif %}
<div class="header--cart">
{% render 'snippet-cart', cart_icon: cart_icon %}
</div>
</div>
HTML - cart
{% if settings.cart--type == 'drawer' %}
<div
class="cart--open-right off-canvas--open"
data-off-canvas--open="right-sidebar"
data-off-canvas--view="cart"
aria-haspopup=”menu”
>
{% endif %}
<a
class="header--cart-link"
data-item="accent-text"
href="{{ routes.cart_url }}"
aria-label="{{ 'layout.header.cart' | t }}"
>
{% if cart_icon == 'text' %}
{{ 'layout.header.cart' | t }}
{% elsif cart_icon == 'bag' %}
{% render 'framework--icons', icon: 'bag' %}
{% else %}
{% render 'framework--icons', icon: 'cart' %}
{% endif %}
<span class="header--cart-number" data-item-count="{{ cart.item_count }}">
(<span class="cart--external--total-items">{{ cart.item_count }}</span>)
</span>
</a>
{% if settings.cart--type == 'drawer' %}
</div>
{% endif %}
And these are some of the scripts that I've tried:
window.onload = () => {
if (jQuery('.header--cart-number').data('item-count') != '0') {
$(".custom-button").css('margin-right', '10px');
}
}
The above is nearly what I'm after, but only works after refreshing the page.
document.ajaxComplete = () => {
if (jQuery('.header--cart-number').data('item-count') != '0') {
$(".custom-button").css('margin-right', '10px');
}
}
similar story
$(document).ajaxSuccess(function() {
if (jQuery('.header--cart-number').data('item-count') != '0') {
$(".custom-button").css('margin-right', '10px');
}
}
This didn't do anything whatsoever.
I'm sure I'm missing something small, but it's driving me mad. Again, any help will be greatly appreciated!
Best,
J
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.
In my html template have error messages for form validation like below:
{% for field in form %}
<span class="text-danger small">{{ field.errors }}</span>
{% endfor %}
If I want to use sweet alert for that how can I do it
If I use like below it will give a empty alert when page loads but when the error happens it will give an empty alert like the when pages loading how can I pass those data into sweet alert what did I do wrong?
{% for field in form %}
<span class="text-danger small">{{ field.errors }}</span>
<script>
var a = "{{ field.errors }}"
swal(a)
</script>
{% endfor %}
Error has occurred because the error message with double quotes is enclosed within double quotes.
You can either enclose it in template literal or single quotes to execute without error.
var a = `<ul class="errorlist"><li>Enter a valid email address.</li></ul>`;
console.log(a);
Form errors are provided by form.errors in django so, insert error in dict errordict={} and return errordict to template
In views.py
errodict={}
for f in form.errors:
self.errordict[f] = '.'.join(form.errors[f])
In template
{% if errodict %}
<script>
var r="{{ errodict }}";
alert('error:'+r)
</script>
{{ errodict}}
{% endif %}
Below is my flash messages using Jinja2. {{ message }} is where I want to have disappear after a few seconds.
<div class='messages' id='messages'>
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<li class='messages'> {{ message }} </li>
{% endfor %}
{% endif %}
{% endwith %}
</div>
This is my javascript. I am new to using javascript so I might not be properly using it.
message = document.getElementsByClassName('li.messages')
setTimeout(function(){
$('li.messages').fadeOut();}, 5000);
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.