I am trying to upload multiple files for a blog post object, however, it seems that my Ajax form is not working properly and I cannot see the files uploading.
Since there is no post object at the time of creating the images, I am trying to upload the files then get them in my view and after saving the post I am trying to save those files by assigning the id of that post to them. Currently, my issue is it seems my files are not uploading and I cannot get them at all.
I am not getting any error and therefore, I cannot find an issue.
Below is my file upload and post create view:
#login_required
def post_create(request):
data = dict()
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save(False)
post.author = request.user
#post.likes = None
post.save()
for image in request.FILES.getlist('file'):
instance = Images(post=Post.objects.get(post.id),image=image)
instance.save()
data['form_is_valid'] = True
posts = Post.objects.all()
posts = Post.objects.order_by('-last_edited')
data['posts'] = render_to_string('home/posts/home_post.html',{'posts':posts},request=request)
else:
data['form_is_valid'] = False
else:
form = PostForm
context = {
'form':form
}
data['html_form'] = render_to_string('home/posts/post_create.html',context,request=request)
return JsonResponse(data)
class PostImageUpload(LoginRequiredMixin, View):
def get(self, request):
images = Images.objects.all()
return render(self.request, 'home/posts/post_create.html', {'images':images} )
def post(self, request):
data = dict()
form = ImageForm(self.request.POST, self.request.FILES)
if form.is_valid():
image = form.save(False)
image.save()
data = {'is_valid': True, 'name': image.file.name, 'url': image.file.url}
else:
data['is_valid'] = False
return JsonResponse(data)
This my javascript code:
$(document).ready(function(){
$(".js-upload-images").click(function () {
$("#fileupload").click();
});
$("#fileupload").fileupload({
change : function (e, data) {
if(data.files.length >= 4){
alert("Sorry, you can only upload up to 4 images")
return false;
}
},
dataType: 'json',
sequentialUploads: true,
start: function (e) {
$("#modal-progress").show();
},
stop: function (e) {
$("#modal-progress").hide();
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
var strProgress = progress + "%";
$(".progress-bar").css({"width": strProgress});
$(".progress-bar").text(strProgress);
},
done: function (e, data) {
if (data.result.is_valid) {
$("#image_list tbody").prepend(
"<tr><td><a href='" + data.result.url + "'>" + data.result.name + "</a></td></tr>"
)
}
}
});
});
HTML Code
{% load crispy_forms_tags %}
{% load static %}
<script src="{% static 'js/image_upload.js' %}"></script>
<script src="{% static 'js/jquery-file-upload/js/vendor/jquery.ui.widget.js' %}"></script>
<script src="{% static 'js/jquery-file-upload/js/jquery.iframe-transport.js' %}"></script>
<script src="{% static 'js/jquery-file-upload/js/jquery.fileupload.js' %}"></script>
<form method="POST" data-url="{% url 'home:post-create' %}" class="post-create-form">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title" >Create a Post</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{{ form|crispy }}
<div class="my-3 mx-3">
<button type="button" class="btn btn-sm mr-auto btn-primary js-upload-images">
<span><i class="fas fa-camera"></i></span>
</button>
<input id="fileupload" type="file" name="file" multiple
style="display: none;"
data-url="{% url 'home:post-image-upload' %}"
data-form-data='{"csrfmiddlewaretoken": "{{ csrf_token }}"}'>
<table id="image_list" class="table table-bordered my-2">
<tbody>
{% for image in images %}
<tr>
<td>{{ image.file.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="modal fade" id="modal-progress" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Uploading...</h4>
</div>
<div class="modal-body">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%;">0%</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>
The fileupload framework that I am using is working as well as I can see in the terminal Django is successfully completing the get request.
I appreciate all the help in advance!
Related
Iam building my portfolio website and i build a simple stocktracker. I added some charts from Chart.js, but somehow only one gets rendered when I excecute the code.
I managed to assign all the divs and data dynamically by making the variables dynamic. I did this by adding the portfolio id in the for loop. I can't figure out why its not working. Appreciate any help.
{% extends 'base.html' %}
{% block page_content %}
{% if user.is_authenticated %}
<body>
<div class="container">
<div class="row">
<div class="col-12">
<h2>
Welcome to the stocktracker
</h2>
<p>I build this stocktracker app to learn database operations. To get current stock data, I linked this to
the free API from Polygon.io. It's only possible to do 5 API calls per minute. You will see an error
message whenever the api calls are exceeded.
<br><br>Current features are:
<ol>
<li>Basic CRUD database operation</li>
<li>Adding portfolio's linked to user</li>
<li>Only show portfolio's linked to user</li>
<li>Show general KPI's in portfolio overview</li>
<li>KPI's calculated based on positions in portfolio</li>
<li>Adding position to portfolio</li>
<li>API connection with Polygon.io to get live stock data</li>
<li>Chart.js integration for visual representation of portfolio metrics</li>
</ol>
</p>
</div>
</div>
<div class="row">
<div class="col-8">
<h2>Select your portfolio</h2>
</div>
<div class="col-4 text-end">
<!-- Button trigger modal -->
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#addPortfolioModal">
Add new portfolio
</button>
<!-- Modal -->
<div class="modal fade" id="addPortfolioModal" tabindex="-1" role="dialog"
aria-labelledby="addPortfolioModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addPortfolioLabel">Modal title</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form name="portfolio_form" method="post">
{% csrf_token %}
<p>
{{ portfolio_form }}
</p>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
</button>
<input type="submit" value="Submit"/>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div>
{% for portfolio in portfolios %}
<div class="row pt-4">
<div class="col-6">
<a class="btn btn-primary" href="{% url 'portfolio_detail' portfolio.pk%}">Go to {{ portfolio }}</a>
</div>
</div>
{% if portfolio.total_positions > 0 %}
<div>
{% load static %}
<div class="col-4 text-start" style="width: 50%;">
<canvas id="pie-chart{{ portfolio.pk }}"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<script>
var randomNum_{{ portfolio.pk }} = () => Math.floor(Math.random() * (235 - 52 + 1) + 52);
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
countPositions = {{ portfolio.total_positions|safe }};
var barColors_{{ portfolio.pk }} = [];
for (let i = 0; i < countPositions; i++) {
randomGeneratedColor = rgbToHex(randomNum_{{ portfolio.pk }}(), randomNum_{{ portfolio.pk }}(), randomNum_{{ portfolio.pk }}());
while (barColors_{{ portfolio.pk }}.includes(randomGeneratedColor)) {
randomGeneratedColor = rgbToHex(randomNum(), randomNum(), randomNum());
}
barColors_{{ portfolio.pk }}.push(randomGeneratedColor);
}
var config_{{ portfolio.pk }} = {
type: 'pie',
data: {
datasets: [{
data: {{ portfolio.data_for_chart_array|safe }},
backgroundColor: barColors_{{ portfolio.pk }},
label: 'Stock ticker'
}],
labels: {{ portfolio.labels_array|safe }}
},
options: {
responsive: true
}
};
window.onload = function() {
var ctx = document.getElementById('pie-chart{{ portfolio.pk }}').getContext('2d');
window.myPie = new Chart(ctx_{{ portfolio.pk }}, config_{{ portfolio.pk }});
};
</script>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-4 pt-2">
<b>Total amount invested:</b> {{ portfolio.total_amount_invested }}
<br><b>Positions:</b> {{ portfolio.total_positions }}
<br><b>Profit:</b> {{ portfolio.total_profit }}
<br><b>Profit in %:</b> {{ portfolio.total_profit_percentage }} %
</div>
</div>
</div>
{% endfor %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
</div>
</body>
{% endif %}
{% endblock %}
Somehow only the last chart gets rendered instead of all three.
You have a loop there, and in each iteration of the loop, you're using window.onload = function() {…};
Basically, you're overwriting the onload function at each iteration of the loop, so only the last overwrite survives.
What you want is to add load event listeners on the window instead of continually overwriting one single listener.
To achieve this, I would recommend replacing this:
window.onload = function () {…}
with this:
window.addEventListener('load', function() {…})`
See addEventListener
Another way of seeing that window.onload = function () {…} is problematic is the following snippet:
window.onload = function () { alert('one') };
window.onload = function () { alert('two') };
Q: What do you expect to happen on page load here?
A: Similarly to your case, only the second function (alerting "two") will be called.
I'm trying to implement infinite scroll with django and jquery(Waypoint).
I have a ListView with a pagination of 5, but when waypoint loads second page, AJAX requests are no longer performed so I added the AJAX function on the onAfterPageLoad which helps bring back AJAX function to the newly loaded page.
That's fine, but then it introduces a bug to my code making the page loaded initially (First Page) no longer perform AJAX functions very well. It makes AJAX on the first page run 3 times if I just loaded a third page and makes AJAX on the second page run twice and so on depending on the number of pages loaded already.
I don't know if there are any cool ways to achieve this because I tried using just jquery without waypoint, but still get same errors as I get when using just waypoint making it an error. This is kinda tricky so far.
{% extends "base.html" %}
{% block content %}
{% load static %}
<div class="container" style="max-width:700px">
<div class="px-3 pt-md-5 pb-md-4 mx-auto text-center">
<h1 class="display-4">All Groups</h1>
<p class="lead">List of groups</p>
</div>
<div class="">
<div class="row infinite-container">
{% for group in groups %}
<div class="col-md-12 infinite-item">
<!-- <img class="img-fluid" src="https://picsum.photos/700"> -->
<a class="text-dark" href="{{ group.get_absolute_url }}">
<div class="card mb-4 box-shadow">
<div class="card-body">
<h2 style="font-size:18px;font-weight:bold;min-height:42px;">
{{group.name|truncatechars:50}}</h2>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">{{group.owner}}</small>
<small class="text-muted">{{group.date_created}}</small>
</div>
<p><a class='follow-btn' data-href='{{ group.get_group_follow_api_url }}'
data-likes='{{ page.likes.count }}'
href='{{ group.get_group_follow_url }}'>{{ group.follows.count }}
{% if request.user.profile in group.follows.all %}
Unfollow
{% else %}
Follow
{% endif %}
</a></p>
</div>
</div>
</a>
</div>
{% endfor %}
</div>
<!-- Comment for loading spinner -->
{% comment %}
<div class="d-flex d-none position-fixed" style="top:35vh;left:46vw">
<button class="btn btn-primary loading">
<span class="spinner-border spinner-border-sm"></span>
Loading...
</button>
</div>
{% endcomment %}
<!-- End of comment for loading spinner -->
<div class="row">
<div class="col-12">
{% if page_obj.has_next %}
<a class="infinite-more-link" href="?page={{ page_obj.next_page_number }}"></a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
<script src="{% static "js/jquery.waypoints.min.js" %}"></script>
<script src="/static/js/infinite.min.js"></script>
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
offset: 'bottom-in-view',
onBeforePageLoad: function () {
$('.loading').show();
},
onAfterPageLoad: function () {
$('.loading').hide();
$(document).ready(function(){
function updateText(btn, newCount, verb){
btn.text(newCount + " " + verb)
}
$(".follow-btn").click(function(e){
e.preventDefault()
var this_ = $(this)
var badge = this_.find('.unlike-update')
var followUrl = this_.attr("data-href")
var followCount = parseInt(this_.attr("data-follows")) | 0
var addFollow = followCount + 1
var removeFollow = followCount - 1
if (followUrl){
$.ajax({
url: followUrl,
method: "GET",
data: {},
success: function(data){
console.log(data)
var newFollows;
if (data.followed){
// updateText(this_, addLike, "Unlike")
// updateText(this_, data.likescount, badge)
updateText(this_, data.followscount, "Unfollow")
} else {
// updateText(this_, removeLike, "Like")
updateText(this_, data.followscount, "Follow")
// remove one like
}
}, error: function(error){
console.log(error)
console.log("error")
}
})
}
})
})
}})
</script>
{% include 'group/snippets/group_follow.html' %}
{% endblock %}
class GroupListView(LoginRequiredMixin, ListView):
model = Group
paginate_by = 5
context_object_name = 'groups'
template_name = 'group/group_list.html'
ordering = ['-date_created']
The program open Bootstrap Modal and load Django Form to create new permission, this is works. But when i want in the form add new Ajax call to load dynamically elements in Django ChoiceField appears the error and browser not finish the call never.
I open browser inspect console and appears XMLHttpRequest error
url.py:
path('permisos/', general_views.permission_list,name='permission_list'),
path('permisos/crear', general_views.permission_create, name='permission_create'),
path('permisos/<int:id>/editar', general_views.permission_update, name='permission_update'),
path('permisos/<int:id>/detalle', general_views.permission_detail, name='permission_detail'),
path('permisos/<int:id>/borrar', general_views.permission_delete, name='permission_delete'),
path('permisos/crear/cargar_elementos/', general_views.permission_load, name='ajax_load_permissions'),
never get to call this function from ajax
views.py:
def permission_load(request):
type = request.GET.get('type')
if type == 2: # object
list = ['general', 'billing', 'accounting']
elements = ContentType.objects.filter(app_label__in=list)
elif type == 3: # instance
list = ['general', 'billing', 'accounting']
content_type = ContentType.objects.filter(app_label__in=list)
elements = general_models.content_type.model.objects.all()
elif type == 4: # attribute
list = ['general', 'billing', 'accounting']
content_type = ContentType.objects.filter(app_label__in=list)
elements = general_models.content_type.model.objects.all()
# get instance atributtes
else: # module
elements = general_models.Modules.objects.all()
# other aspect is that i dont know how to load view result in the html choicefield
response = { 'element': elements }
json = simplejson.dumps(response)
return HttpResponse(json, mimetype="text/json")
forms.py:
class CustomPermisisonForm(forms.Form):
name = forms.CharField()
ACTION_TYPE = ((1, ('Ver')),(2, ('Añadir')),(3, ('Modificar')),(4, ('Borrar')))
action = forms.MultipleChoiceField(choices=ACTION_TYPE, label='Acciones', initial=1, widget=forms.SelectMultiple())
PERMISSION_TYPE = ((1, ('Módulo')),(2, ('Objecto')),(3, ('Instancia')),(4, ('Atributo')))
type = forms.ChoiceField(choices=PERMISSION_TYPE, label='Tipo', initial=1, widget=forms.Select(attrs={"data-objects-url":"{% url 'ajax_load_permissions' %}"}))
element = forms.ModelChoiceField(queryset=general_models.Module.objects.all())
permissions.html:
{% block javascript %}
<script src="{% static 'js/permissions.js' %}"></script>
{% endblock %}
# this is the line to open modal
<button type="button" onclick="return openModalPermission('{% url 'general:permission_create' %}')" class="btn btn-outline-primary float-right btn-sm">
<span class="fas fa-plus"></span>
</button>
permission_create.html:
{% load static %}
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form method="POST" action="{% url 'general:permission_create' %}">
{% csrf_token %}
<div class="modal-header">
<h4 class="modal-title">Nuevo Permiso</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% include 'permission_form.html' %}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Crear</button>
</div>
</form>
</div>
</div>
# when comment this line the error disappear but don't work js call
<script src="{% static 'js/permissions.js' %}"></script>
permission_form.html:
{% load widget_tweaks %}
{% load static %}
{% for field in form %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" %}
{% for error in field.errors %}
<p class="help-block">{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
permissions.js:
function openModalPermission(url) {
$('#modal-permission').load(url, function() {
$(this).modal('show');
});
return false;
}
$("#id_type").change(function () {
console.log("js function");
var url = $("id_type").attr("data-objects-url");
var type = $(this).val();
console.log(type);
console.log(url);
$.ajax({
url: url,
data: {
'type': type
},
success: function (data) {
$("#id_element").html(data);
},
error: function (qXHR, textStatus, errorThrown) {
console.log(qXHR)
console.log(textStatus)
console.log(errorThrown)
}
});
return false;
});
Anybody know how to solve this problem ?
Thanks in advance.
SOLVED
permissions.html:
<!-- pass this block to the end of the file -->
{% block javascript %}
<script src="{% static 'js/permissions.js' %}"></script>
{% endblock %}
I need to create a button that will automatically search in my database all user with a "secouriste" Attribute set and print their firstname, lastname and phone number in a popup.
Here is what I found from my research:
In my HTML, I have to set a button which will enable a popup modal with id of the user I want to get and under this button, there is the code of my popup modal with a listener.
In my JS, I get the data (which is an object).
In Ajax, I need to pass the ID to my controller.
In PHP, I get the ID with a symfony request and FindOneBy.
But there are different problems with this technique: I dont need to get only one person but a list of person with the good attribute so maybe I should use "FindBy" instead of "FindOneBy", but someone said to me that I should use a custom FindAll(). I'm completely lost right now. Here is what I could gather from posts, I know that's far from right, but this is what I have.
//=============================================
// Recherche PopUp Secouriste
//=============================================
$(document).on('show.bs.modal', '#secouristeModal', function (e) {
var id = $('#secouristeModal').data('id');
$.ajax({
url: 'UserBundle/utilisateur',
method: 'POST',
data: {
id: id
}
}).done(function (data) {
// Si status est égal à true
if(data.status) {
console.log(data);
$('#userTitle').replaceWith(data.user.firstName);
}
}).fail(function (data) {
// Code if error
});
})
PHP
$user = $this->findBy($request->request->get('secouristeAttribute' -> $secouristeAttribute));
if($user) {
return new JSONResponse(array(
'user' => $user
));
} else {
// Faire code de retour avec une erreur (status = false)
}
}
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#secouristeModal">
Liste des secouristes
</button>
<!-- Modal des secouristes-->
<div class="modal fade" id="secouristeModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Liste des Secouristes</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- prints a list but doesnt load it from db on request only -->
{% for user in workFlow.listeSecouriste|default('')%}
{% if user.tel is not null %}
<br />{{ user.username }} - {{ user.nom }} {{ user.prenom }} - {{ user.tel }}
{% else %}
<br />{{ user.username }} - {{ user.nom }} {{ user.prenom }}
{% endif %}
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Thank you very much for your help.
Exx
I don't think you can filter your query with a findAll so findBy is good.
But you need to pass an array, something like that:
$users = $this->findBy(['attribute' => $request->request->get('secouristeAttribute')]);
Also, I'm not really sure about that, but before you return your list of Users you could have to implement JsonSerializable Interface with the method jsonSerialize() (or at least the toArray() magic method).
I finally solved my problem, here is how I did it if it can help someone later:
//For my popup
function myAlert(message,titre='Information',btn='',class_msg='',fonction,args) {
//=======================================================
if (btn==''){
btn='<a name="btnOk" class="btn btn-success">Ok</a>';
}
if (class_msg!='') {
message='<div class="'+class_msg+'">'+message+'</div>';
}
myConfirm(message,titre,btn,fonction,args); // Message d'alerte
}
//listeSecouriste.html.twig
<ul>{% for secouriste in listeSecouriste |sort secouriste.nom %}
<li>{{ secouriste.fullName }} {{ secouriste.tel }}</li>
{% endfor %}
</ul>
//php: my controller
public function getSecours($agence=null){
$listeSecouriste = $this->getDoctrine()->getManager()->getRepository('SIGUserBundle:Utilisateur')->ListeSecouriste($agence);
$retour=array('ok'=>false);
if ($listeSecouriste!== null){
$retour['ok']=true;
$retour['html']=$this->renderView('SIGUserBundle:Utilisateur:listeSecouriste.html.twig',
array(
'listeSecouriste'=>$listeSecouriste
)
);
}
return new JsonResponse($retour);
}
I'm a newbie to Laravel 4, and I'm trying to get a form validation in bootstrap modal.
My modal have a form with a text input and a submit button, and I want that when the validation fails, the modal show me the error.
But the modal, after the validation and the page refresh, is closed.
Here is the code from the controller and the view:
Controller code:
public function postAvatar()
{
$avatar_rules = array(
'avatar_src' => 'url',
);
$validator = Validator::make(Input::all(), $avatar_rules);
$validator->setAttributeNames(User::$names_attr);
if ($validator->passes())
{
$avatar_src = (Input::get('avatar_src'))? Input::get('avatar_src') : URL::asset('assets/images/user/default-user-avatar.png');
$user = User::find(Auth::id());
$user->avatar_src = $avatar_src;
if ($user){
return Redirect::to('dashboard')->withSuccess("Success: avatar updated.");
}
return Redirect::to('dashboard')->withError("Error: an error has occurred.");
}
return Redirect::back()->withErrors($validator);
}
View code:
<!-- Modal -->
<div class="modal fade" id="avatarModal" tabindex="-1" role="dialog" aria-labelledby="avatarModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="avatarModalLabel">Update avatar</h4>
</div>
<div class="modal-body">
<h4><span class="label label-info">Current avatar</span></h4>
<img class="img-circle img-responsive dashboard-avatar" src="{{ $user->avatar_src }}" alt="{{ $user->username }} avatar">
<div class="divider"></div>
<h4><span class="label label-info">New avatar</span></h4>
{{ Form::open(array('url' => 'dashboard/avatar', 'method'=>'post', 'role'=>'form')) }}
<ul>
#foreach($errors->all() as $error)
<div class="alert alert-danger" role="alert">{{ $error }}</div>
#endforeach
</ul>
<div class="form-group">
<label for="avatar_src" class="control-label">Link avatar</label>
<input type="text" name="avatar_src" class="form-control" id="avatar_src" placeholder="Link of avatar image url">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update</button>
</div>
{{ Form::close() }}
</div>
</div>
</div>
How can I resolve ?
Thanks.
SOLVED:
Controller code:
public function postAvatar()
{
$avatar_rules = array(
'avatar_src' => 'url',
);
$validator = Validator::make(Input::all(), $avatar_rules);
$validator->setAttributeNames(User::$names_attr);
if ($validator->passes())
{
$avatar_src = (Input::has('avatar_src'))? Input::get('avatar_src') : URL::asset('assets/images/user/default-user-avatar.png');
$user = User::find(Auth::id());
$user->avatar_src = $avatar_src;
if ($user->save()){
if(Request::ajax()){
return Response::json(array('success' => true));
}
}
return Redirect::to('dashboard')->withError("Error: an error has occurred.");
}
return Response::json(array('errors' => $validator->errors()->toArray()));
}
View code:
<!-- Modal -->
<div class="modal fade" id="avatarModal" tabindex="-1" role="dialog" aria-labelledby="avatarModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="avatarModalLabel">Update avatar</h4>
</div>
<div class="modal-body">
<h4><span class="label label-info">Current avatar</span></h4>
<img class="img-circle img-responsive dashboard-avatar" src="{{ $user->avatar_src }}" alt="{{ $user->username }} avatar">
<div class="divider"></div>
<h4><span class="label label-info">New avatar</span></h4>
{{ Form::open(array('url' => 'dashboard/avatar', 'id'=>'avatar_form', 'method'=>'post', 'role'=>'form')) }}
<div class="alert alert-danger avatar_alert" role="alert" style="display: none">
<ul></ul>
</div>
<ul>
</ul>
<div class="form-group">
<label for="avatar_src" class="control-label">Link avatar</label>
<input type="text" name="avatar_src" class="form-control s_tooltip" id="avatar_src" placeholder="Avatar image links">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update</button>
</div>
{{ Form::close() }}
</div>
</div>
</div>
Ajax:
<script>
$(document).on('submit', '#avatar_form', function(event){
var info = $('.avatar_alert');
event.preventDefault();
var data = { avatar_src: $("#avatar_src").val() }
$.ajax({
url: "/dashboard/avatar",
type: "POST",
data: data,
}).done(function(response) {
info.hide().find('ul').empty();
if(response.errors)
{
$.each(response.errors, function(index, error){
info.find('ul').append(error);
});
info.slideDown();
}
else if(response.success){
window.location.href = "/dashboard";
}
});
});
</script>
Your best bet would be to validate the form via AJAX to avoid the page reloading entirely. You would then check the response of your AJAX request for the presence of errors and show them inside the modal if they exist.
You could also add in client side validation to prevent the request being made until the rules are satisfied. I wouldn't recommend using this INSTEAD of server side validation but using it ASWELL as is normally quite desirable.
To accomplish this, you'd need to do something along these lines:
Javascript:
Catch submit event of your form and make an AJAX request.
$(document).on('submit', 'form', function(event){
event.preventDefault();
var data = { avatar_src: $("#avatar_src").val(); };
$.ajax({
url: "/dashboard/avatar",
data: data
type: "POST",
}).done(function(response) {
if(response.errors)
{
// Add error to Modal Body
}
else
{
// Show success message, close modal?
}
});
});
Backend:
Modify your controller method to detect if the current request is an AJAX request and if so, return the response in JSON instead of Redirecting. For example:
if(Request::ajax())
{
return Response::json(array('errors' => $validator->messages()));
}
else
{
return Redirect::back()->withErrors($validator);
}
I've not tested any of that code so might contain some typos/errors but hopefully this helps you!
I was facing same issue. After research on internet,I found that Laravel don't support withSuccess('success_msg') method.
return Redirect::to('dashboard')->withSuccess("Success: avatar updated.");
Here is complete discussion on this topic:
https://github.com/laravel/framework/issues/906.
But you can handle this issue with this approach:-
- For Error message:-
[code has to be added in controller]
return Redirect::to('view')->withErrors('your error message.');
[code has to be added in view]
#if(isset($errors) && count($errors->all())>0)
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
- for succcess message:-
[code has to be added in controller]
$success_msg='your success message.';
Session::flash('successMsg', $success_msg);
return Redirect::to('view');
[code has to be added in view]
#if (Session::has('successMsg'))
{{ Session::get('successMsg') }}
#endif
This approach is working fine for me.
For better display of your errors you can use bootstrap css.