Open href in link only after certain events have executed - javascript

I have a link to the Tumblr share widget, and need to append some query string params to it before it opens (triggered by clicking on the link). However, the link opens before these params are appended, I think because it takes a few seconds-- I'm sending an image on the page to be hosted on imgur and returning that URL.
Is there any way to delay the new link from being opened until AFTER my new image url is returned??? I've tried using e.preventDefault(); and return false; but haven't had any luck.
My HTML is:
<button id='tumblrshare'>tumblr</button
$('body').on('click','#tumblrshare',function(e){
var svg = $("#svg")[0];
svg.toDataURL("image/png", {
callback: function(img) {
var img = img.replace("data:image/png;base64,", "");
var imgurTitle = $("meta[property='og:title']").attr("content");
$.ajax({
url: 'https://api.imgur.com/3/image',
headers: {'Authorization': 'Client-ID **********'},
type: 'POST',
data: {'image': img, 'type': 'base64', 'title': imgurTitle},
success: function(result) {
imageURL = result.data.link;
window.location = 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=http://www.example.com&caption=mycaption&posttype=photo&content=' + imageURL;
},
error: function(){
console.log('error');
}
}); //ajax
}//callback
});//svg
}); //tumblrshare
Please help!!

Altering the 'href' attribute of a link won't change it's destination once it's already been clicked. Consider using window.location to redirect the user when your ajax call is complete.
$('body').on('click','#tumblrshare',function(e){
e.preventDefault(); // Stop the default behaviour
...
$.ajax({
success: function(result){
window.location = result.data.link;
},
...
});
...
});

function loadTumblr(){
var svg = $("#svg")[0];
svg.toDataURL("image/png", {
callback: function(img) {
var img = img.replace("data:image/png;base64,", "");
var imgurTitle = $("meta[property='og:title']").attr("content");
$.ajax({
url: 'https://api.imgur.com/3/image',
headers: {'Authorization': 'Client-ID **********'},
type: 'POST',
data: {'image': img, 'type': 'base64', 'title': imgurTitle},
success: function(result) {
imageURL = result.data.link;
window.location.href = 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=http://www.example.com&caption=mycaption&posttype=photo&content=' + imageURL;
},
error: function(){
console.log('error');
}
}); //ajax
}//callback
});//svg
}

$("a.alate").on("click",function(event){
_thislink = $(this).attr("href");
event.preventDefault();
console.log(_thislink);
$.ajax({
type: 'get',
url : 'https://restcountries.eu/rest/v1/all',
fail:function(data) {
console.log("fail");
}
}).done(function(data) {
// when request finish
console.log(data);
// window.location = _thislink;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="alate" href="http://stackoverflow.com">Update Data then go</a>
the most important on you code to use
e.preventDefault();
to stop default behavior of href

Related

Refresh data without reloading the page

I have a function for adding likes on the page
blade.php
<a href="/article/{{ $article->id }}?type=heart" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_heart }}
</div>
<a href="/article/{{ $article->id }}?type=finger" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_finger }}
</div>
js
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
});
$('.like-button').on('click', function(event) {
event.preventDefault();
let href = $(this).attr('href');
$.ajax({
url: href,
type: 'POST',
success: function() {
window.location.reload();
},
});
});
});
But when I click on the like to update the data, I reload the page using window.location.reload();
Can this somehow be done without reloading the page?
This is how adding likes is implemented, they are added to cookies and stored for 24 hours
web routes
Route::post('article/{id}', 'App\Http\Controllers\ArticleController#postLike');
Article controller
public function postLike($id, Request $request) {
$article = Article::find($id);
if(!$article){
return abort(404);
}
$type = $request->input('type');
if ($article->hasLikedToday($type)) {
return response()
->json([
'message' => 'You have already liked the Article '.$article->id.' with '.$type.'.',
]);
}
$cookie = $article->setLikeCookie($type);
$article->increment("like_{$type}");
return response()
->json([
'message' => 'Liked the Article '.$article->id.' with '.$type.'.',
'cookie_json' => $cookie->getValue(),
])
->withCookie($cookie);
}
Article model
public function hasLikedToday(string $type)
{
$articleLikesJson = Cookie::get('article_likes', '{}');
$articleLikes = json_decode($articleLikesJson, true);
if (!array_key_exists($this->id, $articleLikes)) {
return false;
}
if (!array_key_exists($type, $articleLikes[$this->id])) {
return false;
}
$likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$this->id][$type]);
return ! $likeDatetime->addDay()->lt(now());
}
public function setLikeCookie(string $type)
{
$articleLikesJson = Cookie::get('article_likes', '[]');
$articleLikes = json_decode($articleLikesJson, true);
$articleLikes[$this->id][$type] = now()->format('Y-m-d H:i:s');
$articleLikesJson = json_encode($articleLikes);
return cookie()->forever('article_likes', $articleLikesJson);
}
Assuming those DIVs hold the number of hearts, if the response of the target page is the new number of hearts then:
success: function(data) {
targetElement.find(".comments-sub-header__item-icon-count").html(data)
}
elsewhere if you want to add +1 to current number regardless of server response:
success: function() {
var current= parseInt(targetElement.find(".comments-sub-header__item-icon-count").html());
targetElement.find(".comments-sub-header__item-icon-count").html(current+1)
}
Footnote: as the ajax request is nested inside the click function, the targetElement in my codes is the clicked element. You may get it in defferent ways e.g.
$('.like-button').on('click', function(event) {
var targetElement=$(this);
....
}
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
});
$('.like-button').on('click', function(event) {
event.preventDefault();
let href = $(this).attr('href');
$.ajax({
url: href,
type: 'POST',
success: function(response) {
$(this).parent(".comments-sub-header__item-icon-count").html(
parseInt($(this).parent(".comments-sub-header__item-icon-count").html()) + 1
)
// or return like or heart count from server
$(this).parent(".comments-sub-header__item-icon-count").html(response)
},
});
});
});
This should work for you
$(function () {
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
},
});
$(".like-button").on("click", function (event) {
event.preventDefault();
const likeBtn = $(this);
$.ajax({
url: likeBtn.attr("href"),
type: "POST",
success: function () {
let currentCount = likeBtn.next().text();
likeBtn.next().text(parseInt(currentCount) + 1);
},
});
});
});
You can simply add the new count to the response from your controller.
return response()
->json([
'message' => 'Liked the Article '.$article->id.' with '.$type.'.',
'cookie_json' => $cookie->getValue(),
'new_count' => $article->{"like_{$type}"},
])
->withCookie($cookie);
Now you can use the updated count as new_count from the database.
$.ajax({
url: href,
type: 'POST',
success: function (response) {
$(this).next().text(response.new_count)
},
});

Why do the ajax requests fire multiple times

I have a form inside a modal that either saves a memo when one button is clicked or deletes it when another is clicked. The items get saved/deleted but the request count multiplies with each click. I'm getting 4 of the same request etc. How do i stop this. do i have to unbind something?
$('#modal').on('show.bs.modal', function (e) {
var origin = $(e.relatedTarget);
var memoId = origin.attr('data-id');
$('#modal').click(function(event){
if($(event.target).hasClass('memo-save')) {
event.preventDefault();
var memoText = $(event.target).parent().parent().find('textarea').val();
var memo = {
memo: memoText,
id: memoId
}
$.ajax({
type: "POST",
url: '/memos/add-memo?memo=' +memo+'&id=' + memoId,
data: memo,
success: function (result) {
$(event.target).toggleClass('active').html('Memo Saved');
}
});
} else if($(event.target).hasClass('memo-delete')) {
event.preventDefault();
var memoText = "";
var memo = {
id: memoId
}
$.ajax({
type: "POST",
url: '/memos/remove-memo?id=' + itemId,
data: memo,
success: function (result) {
$(event.target).toggleClass('active').html('Memo Deleted');
}
});
}
});
});
you can move the $('#modal').click outside the $('#modal').on('show.bs.modal' that way it will not re-add the listener each time the modal is shown

scroll div down on specific event

I have a simple chat application using Ajax and HTML.
Whenever I load new messages, I want to scroll the div to show the most recent message, so I'm doing the following:
jQuery:
function SendMessage()
{
var clientmsg = $("#comment").val();
var email = $("#email").val();
event.preventDefault();
if (clientmsg != '')
{
$.ajax(
{
type: 'POST',
url: url,
data:
{
email: email,
message: clientmsg
},
success: function (data)
{
// Success means the message was saved
// Call the function that updates the div with the new messages
UpdateChat();
$("#conversation").scrollTop($("#conversation").outerHeight() * 1000);
}
});
}
}
I use this line to scroll the div down to the maximum:
$("#conversation").scrollTop($("#conversation").outerHeight()*1000);
My problem is, it scrolls down to the maximum WITHOUT showing the new messages. It scrolls down till the last message before the new one. Which is weird, because I'm calling it after updating the chat. Here's the function that updates the chat:
function UpdateChat(){
$.ajax({
// URL that gives a JSON of all new messages:
url: "url",
success: function(result)
{
var objects = JSON.parse(result);
$("#conversation").html("");
objects.forEach(function(key, index){
//append the messages to the div
$("#conversation").append("html here");
});
}
});
};
As mentioned in comments, you can use a setTimeout() to let the dom update add give some time before scrolling. See code below:
function SendMessage()
{
var clientmsg = $("#comment").val();
var email = $("#email").val();
event.preventDefault();
if (clientmsg != '')
{
$.ajax(
{
type: 'POST',
url: url,
data:
{
email: email,
message: clientmsg
},
success: function (data)
{
// Success means the message was saved
// Call the function that updates the div with the new messages
UpdateChat();
setTimeout(function() {
$("#conversation").scrollTop($("#conversation").outerHeight() * 1000);
}, 500);
}
});
}
}
Assuming you insert a new element at the bottom, you could use scrollIntoView to make sure the new element is visible:
$.ajax({
// ...
success: function(data) {
var lastElement = $('#conversation :last-child');
lastElement[0].scrollIntoView();
}
});
Try putting the scroll line inside a setTimeout() method to allow about 500ms for things to update before scrolling down.
jQuery:
function SendMessage(){
var clientmsg = $("#comment").val();
var email = $("#email").val();
event.preventDefault();
if (clientmsg != '') {
$.ajax({
type: 'POST',
url: url,
data: {
email: email,
message: clientmsg
},
success: function (data) {
// Success means the message was saved
// Call the function that updates the div with the new messages
UpdateChat();
setTimeout(performScroll, 500);
}
});
}
}
and the scroll function
function performScroll() {
$("#conversation").scrollTop($("#conversation").outerHeight()*1000);
}

How to redirect in ajax after successfully post of data

I am submitting form data using Ajax and they are successfully saved in the database and I am able to alert the response data. I now want to use the returned data as response to call another function using Ajax and pass them as parameters so that to the called function they can be used to fetch data and and display them on the web page.
The problem is that when the data have been alerted, the function I call using Ajax is not responding even when I use some functions like window.location.href, window.location.replace, window.location.reload they are not executed
Here is the sample code
submitHandler: function(form) {
/*errorHandler.hide(); */
var el = $(div);
el.block({
overlayCSS: {
backgroundColor: '#fff'
},
message: '<i class="fa fa-refresh fa-spin"></i>',
css: {
border: 'none',
color: '#333',
background: 'none'
}
});
/*Set off for database validation */
$('#name1').removeClass('has-error');
$('#name1 .help-block').empty();
$('#date1').removeClass('has-error');
$('#date1 .help-block').empty();
/*end database validation */
/*ajax options */
var options = {
/*target: '#output2', target element(s) to be updated with server response */
success: function(data, textStatus, XMLHttpRequest) {
el.unblock();
if (!data.success) {
/*append error message on the form for each control and database validation*/
console.log(data);
if (data.errors.name1) {
$('#name1').addClass('has-error');
$('#name1 .help-block').html(data.errors.name1);
}
} else {
var business_id = data.business_id;
var bnm_app_id = data.bnm_app_id;
var name = data.name;
var doc = data.doc;
alert(business_id);
alert(bnm_app_id);
alert(name);
alert(doc);
if (window.XMLHttpRequest) {
myObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
myObject = new ActiveXObject('Micrsoft.XMLHTTP');
myObject.overrideMimeType('text/xml');
}
myObject.onreadystatechange = function() {
data = myObject.responseText;
if (myObject.readyState == 4) {
//document.getElementById('step-2').innerHTML = data;
window.location.reload(true);
}
}; //specify name of function that will handle server response........
myObject.open('GET', '<?php echo base_url()."bn_application/register";?>?bnm_app_id=' + bnm_app_id + '&doc=' + doc + '&business_id=' + business_id + '&name=' + name, true);
myObject.send();
}
},
error: function(xhr, textStatus, errorThrown) {
el.unblock();
if (xhr.responseText === undefined) {
$.gritter.add({
/* (string | mandatory) the heading of the notification */
title: 'Connection timed out',
class_name: 'gritter-black'
});
} else {
var myWindow = window.open("Error", "MsgWindow", "width=900, height=400");
myWindow.document.write(xhr.responseText);
}
/*clear controls that do not need to keep its previous info */
},
url: home + 'bn_application/save_clearance_name',
/* override for form's 'action' attribute*/
data: {
name1_percent: name1_percent
},
type: 'post',
/* 'get' or 'post', override for form's 'method' attribute*/
dataType: 'json',
/* 'xml', 'script', or 'json' (expected server response type)*/
beforeSend: function() {
},
uploadProgress: function(event, position, total, percentComplete) {
},
complete: function() {
}
};
/*submit form via ajax */
$('#bn_clearance').ajaxSubmit(options);
}
If i understand you right , you need something like this ?
$.ajax({
type: "GET",
url: baseUrl + 'api/cars',
success: function (firstResponse) {
$.ajax({
type: "GET",
url: baseUrl + 'api/cars/' + firstResponse[0].Id,
success: function (secondResponse) {
window.location.href = secondResponse[0].Make;
}
});
}
});
You can use window.open function
$("button").click(function(){
$.ajax({url: "demo_test.txt", success: function(result){
$("#div1").html(result);
window.open("http://www.w3schools.com", "_self");
}});
});
You should put your redirecting url in success function of ajax. (if you are using jQuery). Because javascript runs codes asynchronously and probably your code tries to run before you get response from request.

AJAX reloads the page without inserting into database

I am new to Ajax and confused. The problem is the ajax reloads the page. The function mentioned in the url inserts the data into database. but the page reloads. I guess the URL is not working but i am not sure on this.
Here is my Controller Function
public function insert_student_fee_payment()
{
$std_code=$this->input->post('std_code');
$total_fee=$this->input->post('total_fee');
$payable_fee=$this->input->post('payable_fee');
$date=date('Y m d');
$class_detail=$this->db->select('class.class_year,class.class_semester')
->join('class','class_student.class_id=class.class_id','LEFT')
->where('class_student.student_id',$std_code)
->where('class_student.class_student_status',2)
->limit(1)
->get('class_student')
->result();
if(count($class_detail)>0)
{
foreach($class_detail as $cd)
{
$year=$cd->class_year;
$semester=$cd->class_semester;
}
}
$data=array(
'std_code'=>$std_code,
'year'=>$year,
'semester'=>$semester,
'total_fee'=>$total_fee,
'payable_fee'=>$payable_fee,
'date'=>$date,
'status'=>2
);
if($this->db->insert('student_fees',$data))
{
echo '1';
}
}
and here is my Ajax code in form
<script type="text/javascript">
$(document).ready(function(){
$('#insert_fee_payment').click(function(){
var std_code=$('#std_code').text();
var total_fee=$('#total_fee').text().split(' ');
var payable_fee=$('#payable_fee').text().split(' ');
total_fee=total_fee[0];
payable_fee=payable_fee[0];
var data='std_code='+std_code+'&total_fee='+total_fee+'&payable_fee='+payable_fee;
$.ajax({
url: '<?php echo base_url()."index.php/finance/insert_student_fee_payment;?>',
type: 'POST',
data: data,
success: function(response)
{
alert(response);
},
error: function(response,status,err)
{
alert(err.message);
}
});
});
});
any help guys
We don't see the HTML so it's hard to say what's wrong but my guess is that $('#insert_fee_payment') is a submit button so you have to cancel the action by default which is submitting the form.
$('#insert_fee_payment').click(function(e){
e.preventDefault();
};
or
$('#insert_fee_payment').click(function(){
var std_code=$('#std_code').text();
var total_fee=$('#total_fee').text().split(' ');
var payable_fee=$('#payable_fee').text().split(' ');
total_fee=total_fee[0];
payable_fee=payable_fee[0];
var data='std_code='+std_code+'&total_fee='+total_fee+'&payable_fee='+payable_fee;
$.ajax({
url: '/index.php/finance/insert_student_fee_payment',
type: 'POST',
data: data,
success: function(response)
{
alert(response);
},
error: function(response,status,err)
{
alert(err.message);
}
});
return false;
});
Add return false after the error function.
$(document).ready(function(){
$('#insert_fee_payment').click(function(){
var std_code=$('#std_code').text();
var total_fee=$('#total_fee').text().split(' ');
var payable_fee=$('#payable_fee').text().split(' ');
total_fee=total_fee[0];
payable_fee=payable_fee[0];
var data='std_code='+std_code+'&total_fee='+total_fee+'&payable_fee='+payable_fee;
$.ajax({
url: '/index.php/finance/insert_student_fee_payment',
type: 'POST',
data: data,
success: function(response)
{
alert(response);
},
error: function(response,status,err)
{
alert(err.message);
}
return false;
});
});
});

Categories

Resources