how can i add a file in my front end vuejs and download my file from my backend django rest framework with v-model in vuejs
my modele is article ,
class Article(models.Model):
conference = models.ForeignKey(Conference,related_name='articles',on_delete=models.CASCADE)
title =models.CharField(max_length=50)
Auteur =models.CharField(max_length=50)
resume =models.TextField()
motcles =models.TextField()
create_by = models.ForeignKey(User, related_name='articles',on_delete=models.CASCADE)
fichier = models.FileField(upload_to='uploads',blank=True, null=True)
def __str__(self):
return self.title
this code is about how i add a new article , i should here add how to enter a file
<form v-on:submit.prevent="submitArticle()">
<div class="field">
<label class="label">Title</label>
<div class="control">
<input type="text" class="input" v-model="article.title">
</div>
</div>
<div class="field">
<label>Auteur</label>
<div class="control">
<input type="title" class="input" v-model="article.Auteur">
</div>
</div>
<div class="field">
<label class="label">Resume</label>
<div class="control">
<textarea type="text" class="input" v-model="article.resume"></textarea>
</div>
</div>
<div class="field">
<label>motcles</label>
<div class="control">
<input type="title" class="input" v-model="article.motcles">
</div>
</div>
<div id="app">
<a
href="#"
#click.prevent="
downloadItem({
url:
'https://test.cors.workers.dev/?https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
label: 'example.pdf',
})
"
>
download
</a>
</div>
<div class="field">
<div class="control">
<button class="button is-link">submit</button>
</div>
</div>
</form>
this is how i enter my article
submitArticle() {
console.log('submitArticle')
const conferenceID = this.$route.params.id
this.errors = []
if (this.article.title === '') {
this.errors.push('The title must be filled out')
}
if (this.article.resume === '') {
this.errors.push('The content must be filled out')
}
if (!this.errors.length) {
axios
.post(`/api/v1/add-article/${conferenceID}/`, this.article)
.then(response => {
this.article.title = ''
this.article.Auteur = ''
this.article.resume = ''
this.article.motcles = ''
this.articles.push(response.data)
})
.catch(error => {
console.log(error)
})
please i need a help how to add and download a file ?
Related
I have these two models :
class Payment(models.Model):
admin = models.ForeignKey(User,on_delete=models.PROTECT)
client_seller = models.ForeignKey(ClientCompany,on_delete=models.PROTECT,blank=True)
next_payment = models.OneToOneField(NextPayment,blank=True,null=True,related_name='next_payments',on_delete=models.PROTECT)
#others
class NextPayment(models.Model):
next_payment = models.DateTimeField()
status = models.BooleanField(default=True)
I want to create NextPayment instance before Payment instance will be create , and assign the NextPayment object to Payment > next_payment field ! here is my views.py
#login_required
def create_payment(request):
main_form = PaymentForm()
next_paymentform = NextPaymentForm()
next_payment= request.GET.get('next_payment')
print(next_payment)
if request.method == 'POST' and request.is_ajax():
main_form = PaymentForm(request.POST)
next_paymentform = NextPaymentForm(request.POST)
if main_form.is_valid():
main_obj = main_form.save(commit=False)
main_obj.admin = request.user
if next_payment:
date_next = next_paymentform(next_payment=next_payment)
#date_next = NextPayment(next_payment=next_payment,status=True) also tried this
date_next.save()
main_obj.next_payment= date_next
main_obj.save()
else:
main_obj.save()
data = {
'id':main_obj.id
}
return JsonResponse({'success':True,'data':data})
else:
return JsonResponse({'success':False,'error_msg':main_form.errors,'next_paymentform':next_paymentform.errors})
return render(request,'payments/pay.html',{'main_form':main_form,'next_paymentform':next_paymentform})
my forms.py
class NextPaymentForm(forms.ModelForm):
next_payment = forms.DateTimeField(input_formats=['%Y-%m-%dT%H:%M'],widget=forms.DateTimeInput(attrs={'type':'datetime-local','class':'form-control'}),required=False)
class Meta:
model = NextPayment
fields = ['next_payment']
class PaymentForm(forms.ModelForm):
class Meta:
model = Payment
fields = ['client_seller','type_of_payment','price','note']
here is my template
<form action="" method="POST" id="create-payment-form">{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="form-group">
<i class="fas fa-user-check"></i>
<label>name </label>
{{ main_form.client_seller | add_class:'form-control' | append_attr:'onchange:currentPaymentBalance();' }}
</div>
</div>
<!-- /.col -->
<div class="col-md-6">
<div class="form-group">
<i class="fas fa-money-check-alt"></i>
<label>number</label>
<input type="number" class="form-control" disabled id="balance_client">
</div>
<!-- /.form-group -->
</div>
<div class="col-md-6">
<div class="form-group">
<i class="far fa-handshake"></i>
<label> type</label>
{{ main_form.type_of_payment | add_class:'form-control' }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<i class="fas fa-money-check-edit-alt"></i>
<label> price</label>
{{ main_form.price }}
</div>
</div>
<div class="col-md-12 col-12">
<div class="form-group text-center ">
<i class="far fa-comment-dots"></i>
<label class="">note</label>
{{ main_form.note | add_class:'form-control' }}
</div>
</div>
<div class="col-md-6 justify-content-center">
<div class="form-group">
<i class="fas fa-quote-right"></i>
<label> next payment</label>
{{ next_paymentform.next_payment }}
</div>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
<div class="card-footer">
<div class="row justify-content-center">
<button type="submit" class="btn btn-lg btn-success">زیادکردن</button>
</div>
</div>
</form>
next_payment prints None! but it wasn't None
but doesn't work, and only saves the main form! I need to check if the next_payment exists then create an instance of NextPayment and assign that new instance to the Payment model?
any idea is much appreciated.
thank you in advance...
Since your form is sending a POST request you have to change
next_payment= request.GET.get('next_payment')
to
next_payment= request.POST.get('next_payment')
I'm following an outdate django e-commerce course using django and stripe. The course is about 4 years old so a lot has changed with django and stripe, which has allowed me to do a ton of research on both. I'm at the end of the tutorial and have run into an issue while creating the checkout page and more importantly using stripe to 'Create Charge'. I am receiving the following error message:
django.utils.datastructures.MultiValueDictKeyError
django.utils.datastructures.MultiValueDictKeyError: 'stripeToken'
I read in the documentation for Creating Charge which states
token = request.POST['stripeToken'] # Using Flask
is for Flask (I think), however when i remove ['stripeToken'], I receive this error message:
stripe.error.InvalidRequestError stripe.error.InvalidRequestError:
Request req_kikB88HKbEkq9W: Could not find payment information
I need a way to pass Stripe the payment information when the form is submitted. Also, I came across this post but the publisher was receiving error message do to multiple forms
view.py
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
# Create your views here.
#login_required
def checkout(request):
publish_key = settings.STRIPE_PUBLISHABLE_KEY
if request.method == 'POST':
token = request.POST['stripeToken']
stripe.Charge.create(
amount=999,
currency='usd',
description='Example charge',
source=token,
statement_descriptor='Custom descriptor',
)
context = {'publish_key': publish_key}
template = 'checkout.html'
return render(request, template, context)
checkout.html
{% extends 'base.html' %}
{% block content %}
<div class="col-sm-6 offset-md-3">
<h4 class="mb-3">Billing address</h4>
<form id="payment-form" action="" method="post">{% csrf_token %}
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName">First name</label>
<input type="text" class="form-control" id="firstName" required style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVQ4EaVTO26DQBD1ohQWaS2lg9JybZ+AK7hNwx2oIoVf4UPQ0Lj1FdKktevIpel8AKNUkDcWMxpgSaIEaTVv3sx7uztiTdu2s/98DywOw3Dued4Who/M2aIx5lZV1aEsy0+qiwHELyi+Ytl0PQ69SxAxkWIA4RMRTdNsKE59juMcuZd6xIAFeZ6fGCdJ8kY4y7KAuTRNGd7jyEBXsdOPE3a0QGPsniOnnYMO67LgSQN9T41F2QGrQRRFCwyzoIF2qyBuKKbcOgPXdVeY9rMWgNsjf9ccYesJhk3f5dYT1HX9gR0LLQR30TnjkUEcx2uIuS4RnI+aj6sJR0AM8AaumPaM/rRehyWhXqbFAA9kh3/8/NvHxAYGAsZ/il8IalkCLBfNVAAAAABJRU5ErkJggg=="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%;" required/>
<div class="invalid-feedback">
Valid first name is required.
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastName">Last name</label>
<input type="text" class="form-control" id="lastName" required />
<div class="invalid-feedback">
Valid last name is required.
</div>
</div>
</div>
<div class="mb-3">
<label for="email">Email <span class="text-muted"></span></label>
<input type="email" class="form-control" id="email" placeholder="you#example.com" required />
<div class="invalid-feedback">
Please enter a valid email address for shipping updates.
</div>
</div>
<div class="mb-3">
<label for="address">Address</label>
<input type="text" class="form-control" id="address" placeholder="1234 Main St" required />
<div class="invalid-feedback">
Please enter your shipping address.
</div>
</div>
<div class="mb-3">
<label for="address2">Address 2 <span class="text-muted"></span></label>
<input type="text" class="form-control" id="address2" placeholder="Apartment or suite" />
</div>
<div class="row">
<div class="col-md-5 mb-3">
<label for="city">City</label>
<input type="text" class="form-control" id="city" required />
<div class="invalid-feedback">
Zip code required.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="state">State</label>
<select class="custom-select d-block w-100" id="state" required>
<option value="">Choose...</option>
<option>California</option>
</select>
<div class="invalid-feedback">
Please provide a valid state.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="zip">Zip</label>
<input type="text" class="form-control" id="zip" required />
<div class="invalid-feedback">
Zip code required.
</div>
</div>
</div>
<hr class="mb-4">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="same-address">
<label class="custom-control-label" for="same-address">Shipping address is the same as my billing address</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="save-info">
<label class="custom-control-label" for="save-info">Save this information for next time</label>
</div>
<hr class="mb-4">
<h4 class="mb-3">Payment</h4>
<div class="d-block my-3">
<label for="card-element">Credit or debit card</label>
<div id="card-element" class="form-control" style='height: 2.4em; padding-top: .7em;'>
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<hr class="mb-4">
<button class="btn btn-outline-success btn-lg btn-block" type="submit">Continue to checkout</button>
</form>
</div>
{% endblock %}
app.js
// Create a Stripe client.
const stripe = Stripe('{{ publish_key }}');
// Create an instance of Elements.
const elements = stripe.elements();
// Create an instance of the card Element.
const card = elements.create('card', {});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', ({error}) => {
const displayError = document.getElementById('card-errors');
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
// Create a token or display an error when the form is submitted.
const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const {token, error} = await stripe.createToken(card);
if (error) {
// Inform the customer that there was an error.
const errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
// Send the token to your server.
stripeTokenHandler(token);
}
});
// Submit the form with the token ID.
const stripeTokenHandler = (token) => {
// Insert the token ID into the form so it gets submitted to the server
const form = document.getElementById('payment-form'),
hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
I am using js plugin to upload image, first time when i select image from the plugin the form gets submitted. The issue is that i select the image first time but then i don't want that image and i click on it again to upload another image, the form does not get validated and fails to submit.
views.py
class SelectObituaryView(LoginRequiredMixin, TemplateView):
template_name = "website/obituary_select.html"
def get_context_data(self, **kwargs):
context = super(SelectObituaryView, self).get_context_data(**kwargs)
church_id = self.request.session.get('church_id', None)
if church_id:
samples = ObituarySample.objects.filter(organization__id=church_id)
context['obituary_samples'] = samples
context['church_cover'] = self.request.session.get('church_cover', None)
return context
#transaction.atomic
def post(self, request):
print("Entered function")
try:
data = request.POST.copy()
data['organization'] = request.session.get('church_id', None)
data['slug'] = data['name'].replace(' ', '-')
data['funeral_time'] = data['funeral_time'].replace(" ", "")
data['viewing_time'] = data['viewing_time'].replace(" ", "")
if len(request.FILES.getlist('gallery')) > 10:
messages.error(request, "Max gallery images limit exceeded.")
return HttpResponseRedirect(
reverse('obituary:create', kwargs={'sample_obituary_id': request.POST.get('obituary_sample')}))
obituary_form = ObituaryForm(data=data, files=request.FILES)
# print("obituary form data",data)
print("before is valid")
if obituary_form.is_valid():
print("Inside is_valid")
obituary_instance = obituary_form.save(commit=False)
obituary_instance.image = obituary_instance.obituary_sample.background
obituary_instance.user = request.user
obituary_instance.save()
obituary_instance.update_slug_with_id()
#override profile_image
#imageName = os.path.basename(obituary_instance.profile_image.path)
imgArr = os.path.split(obituary_instance.profile_image.path)
image_data = request.POST['profile_image1']
b = json.loads(image_data)
head, data = b["output"]["image"].split(',')
binary_data = a2b_base64(data)
print(binary_data)
with open(obituary_instance.profile_image.path, 'wb+') as fh:
myfile = File(fh)
myfile.write(binary_data)
imprinted_image_path = apps.obituary.utils.imprint(obituary_instance, obituary_instance.obituary_sample)
# Save imprinted image in db
with open(imprinted_image_path, 'rb') as f:
data = f.read()
file_postfix = datetime.now().strftime("%Y%m%d-%H%M%S")
obituary_instance.image.save("%s%s.jpg" % ('obituary', file_postfix), ContentFile(data))
for gallery_image in request.FILES.getlist('gallery'):
GalleryImage.objects.create(obituary=obituary_instance, image=gallery_image)
return HttpResponseRedirect(reverse('obituary:preview', kwargs={'obituary_id': obituary_instance.id}))
else:
print("else")
messages.error(request, constants.OPERATION_UNSUCCESSFUL)
return HttpResponseRedirect(
reverse('obituary:create', kwargs={'sample_obituary_id': request.POST.get('obituary_sample')}))
except Exception as e:
print(e)
print("except")
messages.error(request, "Unable to create, Please try again.")
return HttpResponseRedirect(
reverse('obituary:create', kwargs={'sample_obituary_id': request.POST.get('obituary_sample')}))
html
{% extends "website/base.html" %}
{% load static %}
{% block javascript %}
<script>
// Submit post on submit
{# $('#create_obit').on('submit', function(event){#}
{# event.preventDefault();#}
{# alert("Aamixsh");#}
{# });#}
$("#create_obit").submit(function(evt){
//evt.preventDefault();
if($(this).find('input[name="profile_image"]').val() != "") {
$(this).find('input[name="profile_image"]').attr('name','profile_image1');
$(this).find(".slim").find('input[type="file"]').attr('name','profile_image');
return true;
}
});
$(document).ready(function(){
$('input[type="text"]').attr( 'autocomplete', 'off' );
$('.dateReadonly').attr( 'readonly', 'true' );
});
</script>
{% endblock %}
{% block body_block %}
<!-- Banner Area Start -->
<div class="banner-area">
<div class="overlay"></div>
<div class="img-holder">
<div class="holder"><img src="{{ church_cover }}" alt=""></div>
</div>
<div class="caption">
<div class="holder">
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="banner">
<h2>Fill in Loved Ones Details</h2>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="section-space">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="row">
<h3 class="heading-title">Create an Obituary</h3>
<form class="setting-form" id="create_obit" action="{% url 'obituary:select' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset>
<div class="col-xs-12">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Name: <input type="text" maxlength="50" name="name" placeholder="Name*" class="form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Funeral Address: <input type="text" maxlength="50" name="address" placeholder="Funeral Address*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Date of Birth: <input type="text" id="datepicker1" name="date_of_birth" placeholder="Date of Birth*" class="dateReadonly form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Date of Death: <input type="text" id="datepicker2" name="date_of_death" placeholder="Date of Death*" class="dateReadonly form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Funeral Date: <input type="text" name="funeral_date" id="datepicker3" placeholder="Funeral Date*" class="dateReadonly form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Funeral Time: <input type="text" name="funeral_time" id="timepicker" placeholder="Funeral Time*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Surviving Family: <input type="text" maxlength="100" name="family_info" placeholder="spouse Mary Louise, and sons Joe, Ed, and Tim, etc. (Max Limit: 100 Characters)" class="form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Ways To Contribute: <input type="text" maxlength="40" name="memorial_donation_info" placeholder="e.g. Donation url or other Information* (Max Limit: 40 Characters)" class="form-control input-field" >
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Viewing Date: <input type="text" name="viewing_date" id="datepicker4" placeholder="Viewing Date*" class="dateReadonly form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Viewing Time: <input type="text" name="viewing_time" id="timepicker2" placeholder="Viewing Time*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Viewing Address: <input type="text" maxlength="50" name="viewing_address" placeholder="Viewing Address*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
Message: <textarea maxlength="500" name="message" id="" cols="30" rows="10" class="form-control input-field" placeholder="Message* (Max Limit: 500 Characters)" required></textarea>
</div>
</div>
</div>
<input type="hidden" name="obituary_sample" value="{{ obituary_form.obituary_sample.value }}" />
</div>
<div class="col-sm-12">
<h3>Upload Obituary Photo</h3>
<div class = "form-group">
Maximum image size is 8 MB. You can rotate and crop the uploaded image by using the control buttons at the bottom of the image.
<!-- original <input type="file" name="profile_image" placeholder="Obituary Image*" class="form-control input-field" required> -->
<input type="file" name="profile_image" placeholder="Obituary Image*" class="slim" required>
</div>
</div>
<div class="col-xs-12">
<h3>Upload Gallery Photos</h3>
<div class="dropzone" id="my-awesome-dropzone">
<div class="fallback">
(Maximum image size should be 8 MB)
<input type="file" name="gallery" multiple class="form-control input-field"/>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<input type="checkbox" onchange="document.getElementById('create').disabled = !this.checked;" /> I understand, that the obituary cannot be edited once paid for!
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<button type="submit" id="create" class="btn send-btn" disabled>Create</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
I'm trying to user the pattern attribute for email in Angular 4.3.0 but the field.errors.pattern returns true even when the email is correct.
I'm working on an existing code and this pattern was used in this.I'm also not able to understand the RegEx.
Below is the HTML form
<form #loginform="ngForm" class="form-horizontal b bg-white padding_default r-2x box-shadow" novalidate role="form">
<div class="text-danger wrapper text-center" *ngIf="authError">
</div>
<div class="animated fadeIn">
<div class=" m-b-md no-border ">
<input id="username" type="email" class="form-control input-lg b text-md" name="username" placeholder="Email" [(ngModel)]="loginData.email"
autofocus required #username="ngModel" pattern="emailPattern">
<div *ngIf="username.invalid && (username.dirty || username.touched)" class="alert alert-danger">
<div *ngIf="username.errors.required">
Name is required.
</div>
<div *ngIf="username.errors.pattern">
Name is invalid
</div>
</div>
<!--<div class="sxo_validate_msg text-danger text-sm" *ngIf="username.touched && isValidEmail">
<span>Invalid email address.</span>
</div>-->
</div>
<div class=" m-b-md no-border">
<input id="password" type="password" class="form-control input-lg b b-light text-md" name="password" [(ngModel)]="loginData.password"
placeholder="Password" required #password="ngModel">
<div class="text-danger sxo_validate_msg text-sm" *ngIf="password.dirty && password.invalid">
<span *ngIf="password.required">Password is required.</span>
</div>
</div>
<div class="m-b-md m-t-md">
<label class="i-checks text-sm">
<input name="rememberme" id="login-remember" type="checkbox" [(ngModel)]="loginData.rememberMe"><i></i> Remember me
</label>
</div>
<div class="controls m-t-md">
<div class="m-b-lg" *ngIf="showCaptche">
<re-captcha [site_key]="model.key" (captchaResponse)="setResponse($event)"></re-captcha>
<!--<div vc-recaptcha
theme="'light'"
key="model.key"
on-create="setWidgetId(widgetId)"
on-success="setResponse(response)"
on-expire="cbExpiration()"></div>-->
</div>
<input class="btn btn-lg btn-dark btn-block" value="Login" (click)="login()" [disabled]="!loginform.form.valid" />
<div [hidden]="!message" class="alert alert-danger sxo_validate_msg p-t-xs p-b-xs">
{{message}}
</div>
</div>
</div>
</form>
Below is the pattern
emailPattern:any = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
I have encounter the same problem too and I don't know why regex seems not working in my Angular 4 project. I start using Validators in Angular's FormGroup and the email validation works like a charm in my project.
Here's my snippet of code for my Edit Profile Page (edit-profile.component.html):
<form [formGroup]="editProfileForm" class="form-horizontal" (ngSubmit)="EditProfile()" >
<div class="form-group">
<label for="email" class="col-md-4 control-label">E-Mail Address </label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" formControlName="email" [(ngModel)]="user.email" required autofocus >
</div>
</div>
<span class="help-block">
<strong>{{ errors.email }}</strong>
</span>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary" [disabled]="editProfileForm.pristine">
Update
</button>
</div>
</div>
</form>
and in the edit-profile.component.ts file:
import { NgForm, FormGroup, FormBuilder, FormArray, FormControl, Validators } from '#angular/forms';
private errors = {
email: '',
};
public editProfileForm: FormGroup;
constructor(
private fb: FormBuilder,
) {
this.createForm();
}
createForm() {
// constructor + form Validator
this.editProfileForm = this.fb.group({
email: ['', Validators.compose([Validators.required, Validators.email])],
});
}
EditProfile() {
if (this.editProfileForm.invalid) {
if (this.editProfileForm.controls['email'].hasError('required')) {
this.errors.email = 'E-mail name cannot be empty';
} else if (this.editProfileForm.controls['email'].hasError('email')) {
this.errors.email = 'E-mail is not valid';
}
} else {
// submit the form
}
}
Hope this helps!
Angular 4 has a built-in email validation tag that can be added within the input. E.g.:
<input type="email" id="contactemail" email>
This will be valid for a series of numbers and letters then an # then
another series of letters. It will not account for the dot after the #
-- for that you can use the "pattern" tag within the input and your standard regex.
Or if you want to go with pattern try this
<input type="text" name="email" pattern="^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$" required email/>
To understand/learn RegExp : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp
The following should work:
emailPattern:any = new RegExp(/^(([^<>()\[\]\\.,;:\s#']+(\.[^<>()\[\]\\.,;:\s#']+)*)|('.+'))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
I have a simple app that takes entries/tasks and distibutes them to appropriate inbox's.
The model, template and view follows. What I want to do is modify the view so that I can
have a functional "delete" button in my form (alongside the "add/submit" button, like in an admin form.):
models.py
class InboxEntry(models.Model):
job_number = models.CharField(validators=[RegexValidator(regex='^\w{8}$', message='Please enter a valid job number', code='nomatch')], max_length=8, unique=False, blank=False, null=False)
cell_number = models.CharField(max_length=4, unique=False, blank=True, null=True)
job_name = models.CharField(max_length=64, unique=False, blank=False, null=False)
request = models.CharField(max_length=64, choices=PRINT_CHOICES)
date_in = models.DateField(("Date"), auto_now=True, auto_now_add=True)
date_due = models.DateTimeField(("Due"),auto_now=False, auto_now_add=False)
basecamp_link = models.URLField(validators=[RegexValidator(regex='^(http|https)://', message='url must begin with http or https', code='nomatch')], blank=True, null=False, max_length=300)
note = models.TextField(max_length=1000, unique=False, blank=True, null=True)
assigned_by = models.ForeignKey(UserProfile, blank=False, null=False)
box = models.CharField(max_length=64, choices=INBOX_CHOICES)
assigned_to = models.ForeignKey(UserProfile, related_name='+', blank=True, null=True)
assigned_team = models.ManyToManyField(ProjectTeam, blank=True, null=True)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default="Awaiting Action")
accepted_by = models.ForeignKey(UserProfile, related_name='+', blank=True, null=True)
completed_on = models.DateTimeField(("Completed"),auto_now=False, auto_now_add=False, blank=True, null=True)
def __unicode__ (self):
return u'%s %s' % (self.job_number, self.job_name)
class Admin:
pass
views.py
def edit_prdInboxEntry(request, id, userid):
if request.method == 'POST':
a=InboxEntry.objects.get(pk=id)
form = PrdInboxForm(request.POST, instance=a)
if form.is_valid():
form.save()
return HttpResponseRedirect('/production-display/'+ userid +'/')
else:
a=InboxEntry.objects.get(pk=id)
form = PrdInboxForm(instance=a)
user = request.user
u = UserProfile.objects.get(pk=userid)
creativerecords = InboxEntry.objects.filter(box="Creative")
studiorecords = InboxEntry.objects.filter(box="Studio")
records = InboxEntry.objects.filter(assigned_to=u)
return render_to_response('production_InboxEntry.html', {'form': form, 'records': records, 'studiorecords': studiorecords, 'creativerecords': creativerecords, 'user': user}, context_instance=RequestContext(request))
template
<form action="." method="POST">{% csrf_token %}
<div style="display:table;">
<div style="display:table-row;">
<div style="display:table-cell;">
<div class="group_input">
{{ form.assigned_by.errors }}
<label for="id_jassigned_by">Assigned by:</label>
{{ form.assigned_by }}
</div>
</div>
<div style="display:table-cell;"> <div>
<div style="display:table-cell;"> <div>
<div style="display:table-cell;"> <div>
<div style="display:table-cell;"> <div>
<div style="display:table-cell;"> </div>
</div>
<div style="display:table-row;">
<div style="display:table-cell;">
<div class="group_input">
{{ form.job_number.errors }}
<label for="id_job_number">job no:</label>
{{ form.job_number }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.cell_number.errors }}
<label for="id_cell_number">cell:</label>
{{ form.cell_number }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.job_name.errors }}
<label for="job_name">job name:</label>
{{ form.job_name }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.request.errors }}
<label for="request">request:</label>
{{ form.request }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.note.errors }}
<label for="id_note">note:</label>
{{ form.note }}
</div>
</div>
<div style="display:table-cell;">
<div class="container">
<!-- <div class='well'> -->
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<label for="id_date_due">date_due:</label>
{{ form.date_due}}
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<!-- </div> -->
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker();
});
</script>
</div>
</div>
</div> <!-- end css table-row -->
<div style="display:table-row;">
<div style="display:table-cell;">
<div class="group_input">
{{ form.box.errors }}
<label for="id_box">inbox:</label>
{{ form.box }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.assigned_to.errors }}
<label for="assigned_to">assigned_to:</label>
{{ form.assigned_to }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.basecamp_link.errors }}
<label for="id_basecamp_link">basecamp:</label>
{{ form.basecamp_link }}
</div>
</div>
<div style="display:table-cell;">
<div class="accepted_by">
{{ form.accepted_by.errors }}
<label for="accepted_by">accepted_by:</label>
{{ form.accepted_by }}
</div>
</div>
<div style="display:table-cell;">
<div class="group_input">
{{ form.status.errors }}
<label for="id_status">status:</label>
{{ form.status }}
</div>
</div>
<div style="display:table-cell;">
<div class="container">
<!-- <div class='well'> -->
<div class="form-group">
<div class='input-group date' id='datetimepicker2'>
<label for="id_completed_on">completed:</label>
{{ form.completed_on}}
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<!-- </div> -->
<script type="text/javascript">
$(function () {
$('#datetimepicker2').datetimepicker();
});
</script>
</div>
</div>
</div> <!-- end css table-row -->
<div style="display:table-row;">
<div style="display:table-cell;"> </div>
<div style="display:table-cell;">
<p><input id="inbox_submit_btn" type="submit" value="add" /></p>
</div>
<div style="display:table-cell;">
<p><input id="inbox_delete_btn" type="submit" value="delete" /></p>
</div>
</div>
</div> <!-- end css table -->
</form>
Can anyone help point me in the right direction. The docs seem to suggest that I need separate views and urls but I'm pretty sure this can be accomplished in a single view?
The docs seem to suggest that I need separate views and urls but I'm pretty sure this can be accomplished in a single view?
You could do this by passing in different POST parameters depending on which button was pressed, I guess. This is still quite a weird thing to want to do though. It's far neater and more maintainable to split them into different views.
You may be under a misapprehension when it comes to the views linking to templates. having two separate views (one for submissions, one for deletions) in no way affects your ability to display the two buttons that link to those view urls in your template.
If you're worried about code reuse (function-based views often share a lot of code, so this is a reasonable complaint) then I suggest looking into class based views
Edit:
It's just a case of linking to your second "delete" view with the button:
<div class="your-button-class" href="{% url "your-delete-view" pk=object.pk %}></div>