Json response not displaying a success message in the view (Laravel) - javascript

I'm trying to return the following message via Json as shown below. The $message is showing in the Response, but not sure how to display it in the view. I tried the below attempt, but failed.
Also If I don't use location.reload(); , the edit done will not show without reloading the page. So how can I do this properly?
Controller :
$message = "Successfully edited!";
return response()->json(['new_body' => $greq->title, 'message' => $message], 200);
JS :
.done(function () {
// location.reload();
$('#message').text(msg['message']);
$('#edit-greq').modal('hide');
});
View :
#if(Session::has('message'))
<div class="alert alert-success" align="center" id="message">
<strong>{{Session::get('message')}}</strong>
</div>
#endif

JS
.done(function (msg) { // You need to add return variable
$('#message').text(msg['message']); // In order to make it show you need to have this HTML element
$('#edit-greq').modal('hide');
});
View
<div class="alert alert-success" align="center" id="message">
#if(Session::has('message'))
<strong>{{Session::get('message')}}</strong>
#endif
</div>

Related

Trigger ReCaptcha v3 strange behaviour

I'm trying to implement ReCaptcha V3 in my website. But I've been pulling the few hairs that I had left out, as Google doesn't seem to care about docs at all...
And all examples I see are all the simple examples, not really what you would use in prod.
My challenges:
The 1st time I press Submit, the token isn't passed to my PHP for some reason, why not?
The 2nd and further times I always get the same "challenge_ts" back, why? The token is different each time...
Lastly, just wanted to check if my assumption is correct that after a success/fail with score you don't execute JavaScript (as that can be modified), but only PHP code?
Here's my index.html code:
<head>
<script src="https://www.google.com/recaptcha/api.js?render=xxx"></script>
</head>
<body data-spy="scroll" data-target=".fixed-top">
<!-- contact form demo container -->
<div style="max-width: 768px; margin: auto;">
<!-- contact form -->
<div class="card">
<h2 class="card-header">Contact Form</h2>
<div class="card-body">
<form id="myform" class="contact_form" method="post" action="mail.php">
<!-- form fields -->
<div class="row">
<div class="col-md-6 form-group">
<input id="name" name="name" type="text" class="form-control" placeholder="Name">
</div>
<!-- form message prompt -->
<div class="row">
<div class="col-12">
<div class="contact_msg" style="display: none">
<p>Your message was sent.</p>
</div>
</div>
</div>
<div class="col-12">
<input type="submit" value="Submit Form" class="btn btn-success" name="post">
</div>
<!-- hidden reCaptcha token input -->
<input type="hidden" id="token" name="token">
</div>
</form>
</div>
</div>
</div>
<!-- References for the opitional jQuery function to enhance end-user prompts -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$('#myform').submit(function() {
grecaptcha.ready(function() {
grecaptcha.execute('xxx', {action: 'homepage'}).then(function(token) {
// console.log(token);
document.getElementById("token").value = token;
console.log(token);
});
});
});
</script>
<script src="form.js"></script>
</body>
</html>
And here's my form.js code:
(function ($) {
'use strict';
var message = $('.contact_msg');
$('.contact_form').submit(function (e) {
e.preventDefault();
// FIRST TIME NOT GRABBING DATA
var token = $('#token').val();
console.log(token);
$.ajax({
type: 'POST',
url: 'form.php',
data: { token:token}
})
.done(done_func)
.fail(fail_func);
});
// Success function
function done_func(response) {
message.fadeIn()
message.html(response);
setTimeout(function () {
message.fadeOut();
}, 50000);
// form.find('input:not([type="submit"]), textarea').val('');
}
// fail function
function fail_func(data) {
message.fadeIn()
message.html(data.responseText);
setTimeout(function () {
message.fadeOut();
}, 20000);
}
})(jQuery);
And here's my form.php code:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// print_r("code:".$_POST['token']);
# BEGIN Setting reCaptcha v3 validation data
$url = "https://www.google.com/recaptcha/api/siteverify";
$data = [
'secret' => "xxx",
'response' => $_POST['token'],
'remoteip' => $_SERVER['REMOTE_ADDR']
];
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
# Creates and returns stream context with options supplied in options preset
$context = stream_context_create($options);
# file_get_contents() is the preferred way to read the contents of a file into a string
$response = file_get_contents($url, false, $context);
# Takes a JSON encoded string and converts it into a PHP variable
$res = json_decode($response, true);
# END setting reCaptcha v3 validation data
print_r($response);
# Post form OR output alert and bypass post if false. NOTE: score conditional is optional, since the successful score default is set at >= 0.5 by Google. Some developers want to be able to control score result conditions, so I included that in this example.
if ($res['success'] == true && $res['score'] >= 0.5) {
// ONLY EXECUTE PHP CODE? NOT LET JAVASCRIPT DECIDE NEXT STEPS?
http_response_code(200);
echo '<p class="alert alert-success">Success!</p>';
} else {
echo '<div class="alert alert-danger">
Error! The security token has expired or you are a bot.
</div>';
}}
Test site:
https://www.citydiscovery.com.au/login/index.html
P.s. what does "action" do in the execute function of grecaptcha? Does it have any purpose?
Ok, not sure what the issue was, but I'm now able to get a new timestamp each time by using a different code example from a YouTube video.
It's very tricky though, and so far have not seen any proper implementation at all.
Still coding, but some advice:
It takes around a second for the execute function to fetch a new token, so I built in a 1 sec delay before the button is enabled again
As mentioned in a comment, use the example ready function, but also call the function when submitting a form
Tokens are supposedly only valid for 2 mins, so there could still be an issue by calling the ready function on page load after 2 mins. Not yet sure how to solve that as calling the function when submitting the form doesn't work the first time

Refresh a div after an AJAX request

I have a notifications panel and when the user clicks the cross to delete a notification I want just the DIV to refresh so it will throw away the old notification and refresh with the current ones, here i what I have now, it refreshes but all the data disappears and shows nothing but the box.
Screenshots
Before:
After:
HTML
<div id="messageboxcon">
#php
$usersid2 = Auth::id();
$usersalert2 = DB::table('notifications')->where('userid', $usersid2)->orderBy('created_at', 'desc')->get();
#endphp
<h3 style="color: gray;
font-weight: 100;
float: left;
margin-left: 15px;
margin-top -50px;">
Notifications : {{count($usersalert2)}}
</h3>
<div class="notificationcontainer">
#php
$usersid = Auth::id();
$usersalert = DB::table('notifications')->where('userid', $usersid)->orderBy('created_at', 'desc')->get();
#endphp
#if(count($usersalert) > 0)
#foreach ($usersalert as $item)
<div class="notification">
<h2 class="notiftitle">{{$item->type}}</h2>
<h3>{{$item->message}}</h3>
<a class="removenotif" data-id="{{$item->id}}" data-token="{{ csrf_token() }}"><i class="crossnotif fas fa-times fa-sm"></i></a>
</div>
#endforeach
#endif
</div>
</div>
JavaScript
$(".removenotif").click(function(ev){
var id = $(this).data("id");
var token = $(this).data("token");
$.ajax({
url: 'deletenotif/'+id,
type: 'DELETE',
dataType: 'JSON',
data: {
"id":id,
"_method": 'DELETE',
"_token": token,
},
success: function (data) {
console.log("it worked");
$('#messageboxcon').load(document.URL + ' #messageboxcon');
},
error: function (data) {
alert(data);
}
});
In the success callback, I would make use of the jQuery .parents() function.
In the context of the click event handler function, $(this) represents the "close notification element".
You need to remove the <div> with the notification class.
So I would do something like $(this).parents('.notification').remove().
I'm not sure what you're trying to achieve with this:
$('#messageboxcon').load(document.URL + ' #messageboxcon');
It will load the entire webpage in the messageboxcon <div> which is not what you want to achieve.
If you want to refresh the content, perform an AJAX call getting just the HTML for the notifications.
Just create a page (notifications.php) on server side that does just what you do initially:
#php
$usersid = Auth::id();
$usersalert = DB::table('notifications')->where('userid', $usersid)->orderBy('created_at', 'desc')->get();
#endphp
#if(count($usersalert) > 0)
#foreach ($usersalert as $item)
<div class="notification">
<h2 class="notiftitle">{{$item->type}}</h2>
<h3>{{$item->message}}</h3>
<a class="removenotif" data-id="{{$item->id}}" data-token="{{ csrf_token() }}"><i class="crossnotif fas fa-times fa-sm"></i></a>
</div>
#endforeach
#endif
Then in the success callback you remove the notification the user wants to delete for immediate feedback. And then make an AJAX call to refresh the notifications with something like that:
$('#notificationcontainer').load('notifications.php')
in success do something like $("#item-"+id).remove();
change this line
$('#messageboxcon').load(document.URL + ' #messageboxcon');
to this :
$('#messageboxcon').load(document.URL + '#messageboxcon');
in your success code.you have a extra space
You need to create a new javascript function, in which, you'll get the data from notification table. The function should look like this:
function updateContent(){
$.ajax({
url: 'n.php',
type: 'GET',
success: function (data) {
console.log("get recent data in HTML");
$('.notificationcontainer').html(data);
},
error: function (data) {
console.log(data);
}
});
}
And, code which is in n.php file
#php
$usersid = Auth::id();
$usersalert = DB::table('notifications')->where('userid', $usersid)->orderBy('created_at', 'desc')->get();
#endphp
#if(count($usersalert) > 0)
#foreach ($usersalert as $item)
<div class="notification">
<h2 class="notiftitle">{{$item->type}}</h2>
<h3>{{$item->message}}</h3>
<a class="removenotif" data-id="{{$item->id}}" data-token="{{ csrf_token() }}"><i class="crossnotif fas fa-times fa-sm"></i></a>
</div>
#endforeach
#endif
Now, just call that javascript function in removenotif click success method like this -
updateContent();
Create a duplicate of the notification container in a different file, let's say not.php
Then Create a new Ajax with the URL as not.php
Then use the id of the notification container to get the data of the jquery. So it will be like a refresh.
Then create a button that will execute the new jQuery you have created on a click event.
So what you'll do is that, after your previous jQuery has deleted the notification, you'll make it cause a click even on the fresh button so that you wouldn't have to click it manually.
This will replace the old notification container with the new one.
Remember to link the jQuery file add aslo may want to add the jQuery code to the new file, that is not.php otherwise it will work only once since it won't get any ajax to use if you don't put it there as well

How to show success message on top of my form after submissin [duplicate]

I have the below code for show/hide success div as per the service call's response plus i need to pass the Service Response's request to the Success Div. How do i pass the requestId and show the success div?
<div id="showResponseArea" class="alert alert-success hide">
<span>
<strong>Success !! </strong>Your request <<requestId>> has been successfuly created !!!
</span>
</div>
$.ajax({
url:
type:
data:
success: function(resObj){
$("#showResponseArea span").removeClass("hide");
var requestId = resObj.requestId;
}
error: funciton(resObj){
alert("Some Error Occured");
}
});
First of all you are removing the hide class from wrong TAG span which does not have that class. hide class should be removed from from the parent div with id="showResponseArea" which has the hide class, secondly You need to wrap the <<requestId>> in span with an id. like
<div id="showResponseArea" class="alert hide">
<span>
<strong>Success !! </strong>Your request <span id="requestId"> // Request id goes here</span> has been successfuly created !!!
</span>
Then in the ajax success function
success: function(resObj){
$("#showResponseArea").removeClass("hide");
$("#showResponseArea").removeClass("alert-danger");
$("#showResponseArea").addClass("alert-success");
//OR $("#showResponseArea").removeClass("hide").show();
var requestId = resObj.requestId;
$("#requestId").text(requestId );
},
error: function(err,xhr,status){
$("#showResponseArea").removeClass("hide");
$("#showResponseArea").removeClass("alert-success");
$("#showResponseArea").addClass("alert-danger");
//OR $("#showResponseArea").removeClass("hide").show();
$("#requestId").text(xhr.responseText);
}
When you are getting response msg you can use it as you want in your html. You can modify response message as you want, so use .html() in your javascript code to manipulate your response msg. Your response for example can be "<strong>Success, great, foo foo foo!<strong>" or "<strong>Error, foo foo foo!<strong>". Use ajax request as function to show response, generate response message in your req page.
jsFiddle
HTML:
<div id="showResponseArea" class="alert alert-success">
<span></span>
</div>
JS:
$.ajax({
url:
type:
data:
success: function(msg){
$("#showResponseArea span").html(msg); //you will paste your response msg to the span
}
error: funciton(msg){
alert("Some Error Occured");
}
});

Refresh a div after successful AJAX operation in Laravel

I want to refresh/update my div when a successful ajax operation occurs. But I've no exact idea how to do that.
Clearly, I can say that my div should show the inserted data after the successful insertion operation done by ajax. And it obviously should be done without loading page.
I'm attaching what I've tried so far.
Route(web.php)
Route::resource('posts', 'PostsController', ['only' => ['store']]);
Cotroller(PostsController)
public function store(Request $request)
{
$this->validate($request, array(
'post' => 'required|min:20',
));
$post=new Post();
$post->userId=Auth::user()->id;
$post->post=$request->post;
$post->save();
return redirect()->route('home');
}
Controller(PagesController)
public function getHome(){
$posts=Post::orderBy('id', 'DESC')->get();
return view('pages.home')->withPosts($posts);
}
JS
$.ajax({
url: form.action,
type: form.method,
data: $(form).serialize(),
success: function(response){
$('.all-posts-body').load(); //No idea how to do this
},
})
Views(home.blade)
<div class="all-posts-body">
#if($posts->isEmpty())
<div class="alert alert-warning">No post yet!</div>
#else
#foreach($posts as $post)
<div class="card">
<div class="card-body">
{!! nl2br($post->post) !!}
</div>
</div>
<br>
#endforeach
#endif
</div>
This .all-posts-body should be refreshed without reloading page whenever I insert a post by ajax.
I'm attaching a sample image for better explanation
You can send the HTML content that you want from the backend and replace the success with
success: function(response){
$('.all-posts-body').html(response);
},
you can make something like this (i prefer to use id not class)
$('#all-posts-body').load(location.href+(' #all-posts-body'));
and please add space before your id

Displaying PHP success and fail messages with Ajax

What went wrong in this code? I ready many post here on this issue but can't fix my error. I have the following.
HTML Code
<div id="successMessage" style="display:none;"> It worked </div>
<div id="failMessage" style="display:none;"> It failed </div>
<div container>
<div class="modal">
<form>
....
</form>
</div>
</div>
PHP Code
if(!$stmnt->execute()){
echo "Failed!";
}else{
echo "Inserted";
}
AJAX Code
success: function(data){
viewData();
if (data=="Failed!") {
console.log(data);
$("#failMessage").show();
} else if(data=="Inserted"){
console.log(data);
$("#successMessage").show();
}
}
Problem: I would like to display the error in the page not in console. I want to inform the user. Why is it not working with $("#successMessage").show();?
PS: I am using Bootstrap. Also how can I show my messages using one(1) div="msg" tag?
Found a mistake in your code
PHP Code
if(!$stmnt->execute()){
echo "Failed!"; // Check the exclamation mark
}else{
echo "Inserted";
}
AJAX Code
success: function(data){
viewData();
$('#addData').modal('hide');//close the modal.
if (data=="Failed!") { // Add an exclamation mark to correct code
$("#failMessage").show();
//console.log(data); is showing message from PHP
} else if (data=="Inserted") { // Change this else to else if
$("#successMessage").show();
//console.log(data); is showing message from PHP
}
Change "Failed" in ajax to "Failed!". Also, change the else to correct format of else if

Categories