Styling errors in the form - django

There is the following form.
<form id="contact_form" class="get-in-touch-form" method="post" enctype="multipart/form-data">
{% csrf_token %}
<h1 class="title {% if component.css_title_style %}{{ component.css_title_style }}{% endif %}">
{{ component.title }}
</h1>
<p class="subtitle {% if component.css_subtitle_style %}{{ component.css_subtitle_style }}{% endif %}">
{{ component.description }}
</p>
<div class="row">
<div class="col-sm-6">
<div class="input-wrapper">
{{ contact_form.name }}
</div>
<div class="input-wrapper">
{{ contact_form.email }}
</div>
<div class="input-wrapper">
{{ contact_form.phone }}
</div>
<div class="input-wrapper" style="position: relative;">
{{ contact_form.text }}
<img id="clip" src="{% static 'images/clip.png' %}" style="position: absolute; left: 95%; top: 5%;" onclick="document.querySelector('#id_file').click()">
</div>
<div class="input-wrapper" style="display: none">
{{ contact_form.file }}
</div>
<div class="input-wrapper">
<div class="col-md-5">
<div class="custom-checkbox">
{{ contact_form.nda }}
<label for="checkbox1">Send me an NDA</label>
</div>
</div>
<img src="/static/images/loader.svg" height="65" alt="Loading..." style="display: none;">
<input type="submit" value="Send" class="green-button">
</div>
</div>
<div class="col-sm-6">
<img src="{% static 'images/map_all.png' %}">
</div>
</div>
</form>
When I submit it and errors occur, text is displayed near the field that generates the error in its usual form. How can I style this text? For example, to highlight this field somehow?
I tried to do this through ajax, but it didn’t work. When I try to send a form containing errors to the server, I immediately get an error (for example, this field is required) and accordingly it does not reach any styling.
Now the error output looks like this.
How can you style it this way?

Add novalidate to form tag.
Add following block after your input fields.
<div class="contact_form_name" style="font-size:15pt; position: absolute; right: 30px; top: 20px; color: #FD7900; display: none"></div>
Add jquery + ajax code.
var frm = $('#contact_form');
frm.submit(function (e) {
e.preventDefault();
$.each($("div[class^='contact_form_']"), function(ind, value){
$(value).hide();
$(value).prev().css('border', 'none')
})
$.ajax({
type: frm.attr('method'),
url: '',
data: frm.serialize(),
success: function(data) {
console.log(data)
if (data.result == 'error'){
$.each(data.response, function(key, value) {
$('.contact_form_' + key).css('display', 'block')
$('.contact_form_' + key).prev().css("border", 'solid #FD7900')
$('.contact_form_' + key).text(value)
})
} else {
location.reload();
}
}
});
return false;
});
Add view function.
def post(self, request, *args, **kwargs):
contact_form = ContactFormForm(request.POST, request.FILES)
if contact_form.is_valid():
contact_form.save()
return JsonResponse({})
else:
response = {}
for k in contact_form.errors:
response[k] = contact_form.errors[k][0]
return JsonResponse({'response': response, 'result': 'error'})

Related

django returns MultiValueDictKeyError at / 'q'

django returns MultiValueDictKeyError at /
'q' in my dashboard template when I'm trying to add search functionality into my app. I want when a user type something on the search input to return the value that user searched for. but i endup getting an error when i try to do it myself.
MultiValueDictKeyError at /
'q'
def dashboard(request):
photos = Photo.objects.all()
query = request.GET['q']
card_list = Photo.objects.filter(category__contains=query)
context = {'photos': photos, 'card_list':card_list}
return render(request, 'dashboard.html', context)
<div class="container">
<div class="row justify-content-center">
<form action="" method="GET">
<input type="text" name="q" class="form-control">
<br>
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
<br>
<div class="container">
<div class="row justify-content-center">
{% for photo in photos reversed %}
<div class="col-md-4">
<div class="card my-2">
<img class="image-thumbail" src="{{photo.image.url}}" alt="Card
image cap">
<div class="card-body">
<h2 style="color: yellowgreen; font-family: Arial, Helvetica,
sans-serif;">
{{photo.user.username.upper}}
</h2>
<br>
<h3>{{photo.category}}</h3>
<h4>{{photo.price}}</h4>
</div>
<a href="{% url 'Photo-view' photo.id %}" class="btn btn-warning btn-
sm m-1">Buy Now</a>
</div>
</div>
{% empty %}
<h3>No Files...</h3>
{% endfor %}
</div>
</div>
try this
query = request.GET['q']
query = request.GET.get('q', '') # use get to access the q
The get() method returns the value of the item with the specified key.

Passing dictionary index as variable to url in Django template

I am trying to pass a string stored in a dictionary to url to be used as a variable. I want it to be passed to the function the url is pointing to. I tried putting it in {{ post.username }} but it won't accept it. Currently, I have it in quotes as "post.username" but it accepts is as the literal string and not the string stored in the dictionary. Any help would be appreciated.
Template
{% for post in posts %}
<div class="row">
<div class="col-sm-3">
</div>
<div class="col-sm-6">
<div class="card" style="width: 40rem;">
<div class="card-header bg-white">
{{ post.user_name }}
<div class="text-black-50 mt-2">{{ post.created_date }} ago</div>
</div>
<img class="card-img-top" src="{{ post.picture }}" alt="Post Image" style="width: 100%; height: 30vw; object-fit: cover">
<div class="card-body">
<p class="card-text">{{ post.description }}</p>
Comments | {{ post.comments }}
</div>
</div>
</div>
<div class="col-sm-3">
</div>
</div>
URL
path('user_view/<account_id>', views.user_view, name='user_view')
I tried path('user_view/<str:account_id>' but no luck
View
def user_view(request, account_id):
user = User.objects.get(username=account_id)
user_prop = UserProperty.objects.get(user_id=user)
account_info = [user_prop.profile_photo, account_id, user_prop.bio]
print(account_info)
return render(request, 'users/user_view.html', {'account_info': account_info})
When I click on the anchor on the website, it gives me this address : http://localhost:8000/user_view/post.username
try:
<img class="rounded-circle" src="{{ post.user_image }}" style="width:30px; height: 30px;"> {{ post.user_name }}
In your urls:
path('user_view/<str:account_id>/'

I'm using ajax to set up a view of uploaded data, but it works in first item only

I have to set up the user should be able to view the contact info of customer, For that I'm using ajax. the code is working but the problem is the ajax is only working in the first item, other buttons are not working what is the reason
another issue is when i hit the button again it showing data agin and agin how to control it
how to solve these two issues
views.py
def contact_details(request):
property_details = Property.objects.all()
seraializer = PropertySerializer(property_details, many=True)
data = seraializer.data
return JsonResponse(data, safe=False )
HTML page(including ajax)
{% if accomodations %}
{% for accomodation in accomodations %}
<div class="row">
<div class="col-sm-2 col-md-2"></div>
<div class="col-sm-4 col-md-4">
<img src="{{accomodation.images.url}}" class="img-responsive" style="width:100%">
</div>
<div class="col-sm-5 col-md-5">
<div class="caption">
<h3>{{ accomodation.headline }}</h3>
<div>
{{ accomodation.city }}
</div>
<div>
{{ accomodation.location }}
</div>
<div>
{{ accomodation.facilites }}
</div>
<div>
{{ accomodation.rent }}
</div>
<div>
{{ accomodation.owner }}
</div>
<div>
{{ accomodation.id }}
</div>
<button id="request-btn" name="property_id" class="btn btn-primary">Contact info:</button>
</form>
<div id=response></div>
</div>
</div>
</div>
<hr>
{% endfor %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#request-btn").click(function(){
$.ajax({
url: "{% URL 'contact_details' %}" ,
type: "GET",
dataType:"json",
success:
function(result){
$.each(result, function() {
html = "Email:" +this.email + "<br>" +"Mobile:" + this.mobile +"<hr>"
$("#response").append(html)
});
}
});
});
});
</script>
{% else %}
<h1>Not Found</h1>
{% endif %}
The problem is that you are using an id instead of a class, that's why only the first button works. Change it to class instead, then it should work. Try this:
<script type="text/javascript">
$(document).ready(function(){
$(".request-btn").click(function(){
var reference = this;
$.ajax({
url: "{% URL 'contact_details' %}" ,
type: "GET",
dataType:"json",
success:
function(result){
$.each(result, function() {
html = "Email:" +this.email + "<br>" +"Mobile:" + this.mobile +"<hr>"
$("#response").append(html)
});
}
});
});
});
</script>
I'm not sure what your second question is - could you please rephrase it or add details?

Iframe in jQuery dialog doesn't have any style

I have a Django admin application that displays a jQuery dialog showing a page in an iframe inside the dialog that I show using:
function opendialog(page, dialog_title) {
var $dialog = $('#applied-assay')
.html('<iframe style="border: 0px; " src="' + page + '" width="100%" height="100%"></iframe>')
.dialog({
title: dialog_title,
autoOpen: false,
dialogClass: 'dialog_fixed,ui-widget-header',
modal: true,
draggable:true
});
$dialog.dialog('open');
}
function open_modal(url, title)
{
opendialog(url, title);
return false;
}
So far, so good. However the content of the iframe doesn't have any style:
The html template rendered inside the iframe looks like:
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_list %}
{% block extrahead %}
{{ block.super }}
{{ media.js }}
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/start/jquery-ui.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
{% endblock %}
<div class="modal-dialog">
<div class="modal-content">
<form role="form" action="{% url 'myapp:applied_assay' 1 %}" method="post">
<div class="modal-header">
<h3>Select applied assay type 1</h3>
</div>
<div class="modal-content">
{% csrf_token %}
<div class="panel panel-default">
<div class="panel-body">
{{ form.as_p }}
</div>
</div>
</div>
<div class="modal-footer">
<div class="col-lg-12 text-right">
<input type="submit" class="btn btn-primary" name="submit" value="Accept">
<button type="button" class="btn btn-default" onclick="return close_modal()">
Cancel
</button>
</div>
</div>
</form>
</div>
</div>
Any ideas?
You need to also include stylesheets in the header of your iframe and the respective classes in the html tags. You've only included a jquery-ui css file, but haven't used any of its classes in the iframe elements.

Saving edited data back to database using django and knockout

I am trying to figure out how to save edited data back to the database using django forms and knockout. The edit.html file has been changed to use knockout to display and edit information on the edit page. I need to figure out how to change the views.py file to save the information. The page seems to be behaving how I want it to (I think...), but I don't know how to update the information back to the database once editing has occurred since I am not using django fields in the .html file.
I have read this thread: using knockout.js with django forms?, but that is using fields in the html file instead of the knockout code. I'm not opposed to going that route if that is a better method, but was struggling a little with the implementation of that idea when I tried it.
The relevant info from the views.py file:
#render_to('phones/edit.html')
def EditPhone(request, number):
p_number = PhoneTable.objects.get(number=number)
customer_list = list(Customer.objects.values('customer_id'))
JSON_customer_list = json.dumps(customer_list)
if not request.POST:
return dict(
form=PhoneForm(instance=p_number),
CallType=p_number.call_type,
number=number,
Customer=p_number.customer_id,
extension=p_number.profile.extension,
department=p_number.profile.department,
JSON_customer_list=JSON_customer_list
)
form = PhoneForm(request.POST, instance=p_number)
if not form.is_valid():
return dict(form=form)
form.save()
messages.success(request, 'Phone Number updated')
return redirect('phones:available_phones', number=p_number.number)
class PhoneForm(ModelForm):
class Meta:
model = PhoneTable
This is the html file:
{% block pagetitle %}Edit Phone Number: {{ number }}{% endblock %}
{% block content %}
<div class="row">
<div class="span2">
<div class="pull-right">Call Type:</div>
</div>
<div class="span6">
<select data-bind="options: callTypes, value: callType"></select>
</div>
</div>
<div class="row">
<!-- ko if: callType() === "Direct" -->
<div class="span2">
<div class="pull-right">Extension:</div>
</div>
<div class="span6">
<input type="text" data-bind="value: editExtension" />
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Sales" -->
<div class="span2">
<div class="pull-right">Customer:</div>
</div>
<div class="span6">
<select data-bind="options: customerDisplays, value: selectedCustomer"></select>
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Service" -->
<div class="span2">
<div class="pull-right">Service Profile:</div>
</div>
<div class="span6">
<select data-bind="options: servProfiles, value: servProfile"></select>
</div>
<!-- /ko -->
</div>
<div class="form-actions">
<input type="submit" class='btn btn-primary' value="Update" />
<a class="btn" href="{% url phones:available_phones %}">Cancel</a>
</div>
{% endblock %}
{% block javascript_compress %}
<script type='text/javascript' src="{% static 'js/knockout/knockout.js' %}"></script>
<script type="text/javascript">
$(function(){
customerListFromServer = {{ JSON_customer_list|safe }};
var PhoneViewModel = function() {
var self = this;
customerList = [];
for (var key in customerListFromServer) {
customerList.push(customerListFromServer[key].customer_id);
}
self.callTypes = ko.observableArray(['Free', 'Direct', 'Sales', 'Service']);
self.callType = ko.observable("{{ CallType }}");
self.editExtension = ko.observable("");
self.servProfiles = ko.observableArray(["{{ extension }}", "{{ department }}"]);
self.servProfile = ko.observable();
self.customerDisplays = ko.observableArray(customerList);
self.selectedCustomer = ko.observable();
}
ko.applyBindings(new PhoneViewModel());
});
</script>
{% endblock %}
Any suggestions? If I am missing something, please let me know. Thank you.
I figured this out, so I will post how if it can help anyone else.
I added a form id and post method along with a hidden field to the html file. As Kevin suggested, I used a data-bind on the submit button and added a submit function to the ko viewModel. Then I changed the views.py file to get the json data and to save the edited values.
#render_to('phones/edit.html')
def EditPhone(request, number):
p_number = PhoneTable.objects.get(number=number)
customer_list = list(Customer.objects.values('customer_id'))
JSON_customer_list = json.dumps(customer_list)
if not request.POST:
return dict(
form=PhoneForm(instance=p_number),
CallType=p_number.call_type,
number=number,
Customer=p_number.customer_id,
extension=p_number.profile.extension,
department=p_number.profile.department,
JSON_customer_list=JSON_customer_list
)
json_data = request.POST.get('json_blob')
obj = loads(json_data)
p_number.call_type = obj.get("callType")
p_number.customer_id = obj.get("selectedCustomer")
p_number.profile.extension = obj.get("editExtension")
p_number.profile.department = obj.get("servProfile")
p_number.save()
messages.success(request, 'Phone Number updated')
return redirect('phones:available_phones')
class PhoneForm(ModelForm):
class Meta:
model = PhoneTable
The html file:
{% block pagetitle %}Edit Phone Number: {{ number }}{% endblock %}
{% block content %}
<form id="phone_form" method="post">
{% csrf_token %}
<input type="hidden" id="json_blob" value="" />
<fieldset>
<div class="row">
<div class="span2">
<div class="pull-right">Call Type:</div>
</div>
<div class="span6">
<select data-bind="options: callTypes, value: callType"></select>
</div>
</div>
<div class="row">
<!-- ko if: callType() === "Direct" -->
<div class="span2">
<div class="pull-right">Extension:</div>
</div>
<div class="span6">
<input type="text" data-bind="value: editExtension" />
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Sales" -->
<div class="span2">
<div class="pull-right">Customer:</div>
</div>
<div class="span6">
<select data-bind="options: customerDisplays, value: selectedCustomer"></select>
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Service" -->
<div class="span2">
<div class="pull-right">Service Profile:</div>
</div>
<div class="span6">
<select data-bind="options: servProfiles, value: servProfile"></select>
</div>
<!-- /ko -->
</div>
<div class="form-actions">
<input type="submit" class='btn btn-primary' value="Update" data-bind="click: submitForm" />
<a class="btn" href="{% url phones:available_phones %}">Cancel</a>
</div>
{% endblock %}
{% block javascript_compress %}
<script type='text/javascript' src="{% static 'js/knockout/knockout.js' %}"></script>
<script type="text/javascript">
$(function(){
customerListFromServer = {{ JSON_customer_list|safe }};
var PhoneViewModel = function() {
var self = this;
customerList = [];
for (var key in customerListFromServer) {
customerList.push(customerListFromServer[key].customer_id);
}
self.callTypes = ko.observableArray(['Free', 'Direct', 'Sales', 'Service']);
self.callType = ko.observable("{{ CallType }}");
self.editExtension = ko.observable("");
self.servProfiles = ko.observableArray(["{{ extension }}", "{{ department }}"]);
self.servProfile = ko.observable();
self.customerDisplays = ko.observableArray(customerList);
self.selectedCustomer = ko.observable();
self.submitForm = function() {
$("#json_blob").val(ko.toJSON(self));
$("#phone_form").submit();
}
}
ko.applyBindings(new PhoneViewModel());
});
</script>
{% endblock %}
With knockout, i typically like to control as much as possible through the view model, including saving information back to the server. in your case, i would have the submit button execute a save function inside the view model like so:
html:
<input type="submit" class='btn btn-primary' value="Update" data-bind="click: submitForm" />
in your knockout view model, there are a couple of ways you can save the data:
self.submitForm = function () {
// save via postback
ko.utils.postJson('/EditPhone', ko.toJSON(self));
// save via ajax
$.ajax({
type: 'POST',
data: ko.toJSON(self),
url: '/EditPhone',
success: function () {
alert("saved");
},
error: function () {
alert("no worky");
}
})
}
unfortunately, i have no experience with django so im not sure exactly how you need to set that up in order to accept the json data coming back to the server