Ajax request 'onError' handler - javascript

There is one feature on my site: delete without page refresh. The user just presses 'delete' and the browser will send Ajax-request. It will load 'delete' script with id parameter.
All work well. But it is not very good because of referential integrity of the database. For example, It is possible to delete street, where some people are living.
I want to upgrade my script. I want to add a check to delete script and don't let delete data if some 'people' are connected to 'street' table.
jQuery handler of button click:
$('body').on('click', '.deleteStreet', function()
{
var id = $(this).attr('id');
var hideMe = $(this).parent().parent();
var dataString = 'id=' + id;
if(confirm("Are you sure you want to delete street? It is possible some people living there!"))
{
$.ajax({
type: "GET",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
hideMe.hide();
}
});
return false;
}
});
It will call script anyway and now will delete data anyway. I can add some checks to delete script now and it wouldn't delete, but jquery script would work anyway and will hide table row anyway (because request was send ok, without 404, etc)
1) Is it possible to see delete script result and hide or not hide row depending on it? For example, it will return true or false, js script will catch it and show message about deleting or not deleting of data depending on it.
2) This problem caused by structure of my site. There are some switches on index.pl and load appropriate scripts loading depending on query (mode=street then load street.pl, mode=user then load users.pl etc). So it will show all data loaded before delete.pl script and it will be impossible to check script returned true or false.
Any help? :) Thank you!
P.S.: I am very sorry for my awful english.

You can have the result of your ajax call in the first parameter of the success callback. ex:
$.ajax({
type: "POST",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
if(e === '1'){
hideMe.hide();
}
}
});
try to log your result in the console for tests: console.log(e).
For deleting data you should use a POST request ( or DELETE but not supported by all browsers).
I dont know how your datas (streets) looks like but an other way could it be to return all your existing streets in a json object on the delete request result. And refresh all lines.

Related

Hide div after click of button with mysql

I want to hide a 'div' after a button is clicked. I don't want to use .remove() because when you refresh the app it comes back. I have the information about this div on the database and I wanna work with it.
I tried already creating an Ajax call to select the information that I'm looking at and then on the front-end I'm telling if it exist then delete it. But I feel like I'm missing something and I don't know why.
Frontend:
$('#deletePromo').on('click', function(res){
let success = function(res){
if (eventName && customerID){
$(`#promotion-container .promo${i}`).remove();
}
}
$.ajax({
type: 'POST',
url: '/api/promotions-done',
crossDomain: true,
//success: success,
dataType: 'json',
data: {
customerID : customerID,
eventName : eventName,
}
}).done(function(res){
console.log('res', res)
if (res != null){
$(`#promotion-container .promo${i}`).remove();
//$(`#promotion-container .promo${i}`).css('display', 'none')
}
})
})
})
Backend:
router.post('/promotions-done', function(req, res) {
let customerID = req.user.customer_id
let restaurantGroupId = req.user.restaurant_group_id
let eventName = req.body.eventName
db.task(t => {
return t.any(`SELECT * FROM promotions_redemption WHERE (customer_id = '${customerID}' AND event_name = '${eventName}' AND restaurant_group_id = ${restaurantGroupId})`).then(function(promotionsDone) {
return res.json({'promotionsDone': promotionsDone})
})
.catch((err) =>{
console.log(err)
})
})
})
What I'm trying to do here is saying if the customerID and eventName already exist on the table then remove div from the person. I don't have much experience working with backend so is there a way to tell the program to check the database for this information and if it exists then remove the div.
You probably have some HTML in a template file, or in the database that has the button there to start with. Since your AJAX code will only run when the button is clicked, you will need to either do 1 of 2 things:
Add an AJAX call on page load
Handle looking for the button and hide/show it in your templating language/platform (think asp.net, python django, php laravel etc) to avoid the AJAX request.
Since we don't know your platform, I will show you option 1
First, I would change the initial state of your HTML to NOT show the button by default. This would look something like this:
<div id="promotion-container">
<button class="promo" style="display: none" />
</div>
Otherwise you will have the button be shown for the amount of time the AJAX request takes.
Next, you will want to add this function call to the page. I have reversed the login in the done function to "show" the button or unhide it.
$(document).ready(function(){
let success = function(res){
if (eventName && customerID){
$(`#promotion-container .promo${i}`).remove();
}
}
$.ajax({
type: 'POST',
url: '/api/promotions-done',
crossDomain: true,
//success: success,
dataType: 'json',
data: {
customerID : customerID,
eventName : eventName,
}
}).done(function(res){
console.log('res', res)
if (res === null){
//$(`#promotion-container .promo${i}`).remove();
$(`#promotion-container .promo${i}`).css('display', 'block')
}
})
})
})
The easiest solution to your problem would be to use a client-side cookie. If you don't have a cookie package already, I'd recommend js-cookie.
On your html page:
<div id="promotion-container" hidden> //you want it hidden by default
//if it is shown by default there will be an annoying screen flicker when the pages loads
<script src="/path/to/js.cookie.js"></script>
On jQuery page:
$(document).ready( function() {
if (!Cookies.get('name1') || !Cookies.get('name2')) {
$('#promotion-container').show();
};
Cookies.set('name1', customerId, {expires:14} ); //must include expiration else the cookie will expire when the browser closes.
Cookies.set('name2', eventName, {expires:14} ); //you might need to make an eventId if eventName is too large
});
The second input for Cookies.set is the 'value' for the cookie. if 'value' = null, then Cookies.get('name') = null.
This is assuming you already have the means to set customerId and eventName for each user. Also you might need to modify where the Cookies are set based on when the customerId is created on the page.
EDIT:
There are 2 ways you can run a query the way you describe, both of which won't work they way you want unless you use a session cookie.
1) You have res.render inside of a query.
This would ensure the div is never shown to a user that has already clicked on it, but would significantly hurt your site's performance. The query would run every time the page is rendered, regardless of whether or not the client has a customerId. Your site would would be painfully slow with a large amount of traffic.
2) You run a POST request through client-side js with ajax and compare the customerId with your db; if a result is found, you remove the div.
This would function the way you want it to, and wouldn't hurt performance, but nothing is stopping a customer from using something like burp to intercept the POST request. They could change the data argument to whatever they want and make sure the div loads for them.
The only solution to these problems that I see would be to validate a user when they click on the div AND on the server with a session cookie. (for user validation I use passport and express-session).
I can show you how I set this up, but to make it specific to your needs I would need to know more about how your site is setup.
PS I misunderstood why you needed to hide the div, and using a client-side cookie would be a terrible idea in hindsight.

Laravel - Ability to filter database using AJAX

This is my first time attempting filtering and searching the mySQL database. From my research I have found out I need an AJAX call and some PHP query that will help my achieve the filtering I want to achieve.
This is what I want the AJAX search to do:
Have an Apply button. When I click the button I want a URL to get generated and the AJAX call to happen.
Only reload part of the page where the data queried is contented.
So far I have managed to create this:
$("#filteridname").change(function() {
$value=$(this).val();
$.ajax({
type: "get",
url: "{{$myurl}}",
data: {'search':$value},
success: function(data){
$('#data-holder').html(data);
}
});
});
This manages to create the URL one of the filters, but it does not take the other filters into consideration. I also did not manage to create the button. I am guessing you would need a where statement in the PHP to filter the database?
Would anyone be willing to assist me in creating the AJAX call and PHP query for the filters?
In total I have three filters, and when I click a button I want an AJAX call to filter my database with the three filters and return the results without having to reload the whole webpage.
EDIT: Here is my JS AJAX query:
$("#apply").click(function() {
$country=$('#filter-country').val();
$type=$('#filter-type').val();
$year=$('#filter-year').val();
$.ajax({
type: "GET",
url: "{{$launchsitename->site_code}}",
data: {'country':$country, 'type':$type, 'year':$year},
success: function(data) {
$('#data-holder').append(data);
}
});
});
Now I just need to create a PHP query.
you can use propriety called .Append() instead of .html() ,also here you are getting one element value on change , if you want to get the three of them at one button click , you can make it the same way that you got the val of the first one , and just adding it to the request and handle it back in PHP to divide and execute each one or just pass the three of them to your procedure , depends on what you have
$("#filteridname").change(function() {
$value=$(this).val();
$.ajax({
type: "get",
url: "{{$myurl}}",
data: {'search':$value},
success: function(response){
$('#data-holder').append(response);
}
});
});
Read about .append()

Retain javascript data while Forward and Backward browser button click

I have following dropdown which calls javascript showTable method.
<select name="any_name" id="any_id" onChange="showTable()">
I have following showTable method which calls a php method via post to populate data in my showData div.
function showTable()
{
$.ajax({
type: "POST",
url: "sample.php",
data: {"Id" : myId},
success: function (data)
{
document.getElementById("showData").innerHTML= data;
}
});
}
It works fine. Now the problem arises when I hit FORWARD and then BACKWARD browser button. On hitting BACKWARD button, I get my previous page but my showData div is empty. How can I retain data in this div which I got from my PHP script? I think I have made it clear what I want to ask.
Look for local storage w3schools.com/html/html5_webstorage.asp and manage to save and retreive values between your back/forward behavior.
;)

Only allow access to a php action through form submit, but when using an ajax call

i have a form that deletes the comment its in.
To only allow the page that carries out the php action to be viewed when the form is submitted i do a basic
if (isset($_POST['submit-delete'])) {
// carry out delete
}
this works fine, but i am using ajax to not reload the page.
The response is the same as i have used else where:
$(document).ready(function(){
$(".delrepcomment").submit(function(){
$.ajax({
type: "POST",
url: "process/deletecomment.php",
data: $(".delrepcomment").serialize(),
dataType: "json",
success: function(response){
if (response.commentDeleted === true) {
$('#successdisplay').fadeIn(1000),
$('#successdisplay').delay(2500).fadeOut(400);
}
else {
$('.delrepcomment').after('<div class="error">Something went wrong!</div>');
}
}
});
return false;
});
});
This however doesnt work, unless i remove the check to see if the form has been submitted.
Whats the best way around this? I want to keep the check for the form being submitted incase of js being turned off or any direct access attempts.
Thanks.
You should post the data you require for the script to work. In your case, you have to post a key-value-pair with "submit-delete" as the key and an arbitrary value (unless you check that value later in the code).
On the other hand, PHP stores the used HTTP method in $_SERVER['REQUEST_METHOD'], this would be "POST" in your case.

AJAX Load Content

Im completely lost on how to work AJAX. Looked up some tutorials and all seemed pretty confusing. I ran into the problem: [ Script only runs once ].
I would use it to reload pages like so: [ http://www.roblox.com/Poison-Horns-item?id=62152671 ] so I could get the latest item prices, without refreshing the page. if anyone could help/tell/point me in the right direction, it'd help TONS.
Im somewhat a beginner scripter, so be a little patient ;)
Thanks for any help,
Alex
AJAX requests are the same as page requests (GET and POST), except that they are handled asynchronously and without leaving the current page. The response data is the source of the page you wanted to fetch. That source is useless until you parse/use it.
A simple jQuery example:
//for example, we are on example.com
$.ajax({
type : 'get', //the METHOD of the request, like the method of the form
url : 'index.php' //the url to fetch
data : { //additional data which is synonymous to:
query1 : 'foo', // - url queries
query2 : 'bar', // - form inputs
query3 : 'baz',
},
success : function(resposeText){ //response text is the raw source of the fetched resource
$(element).html(responseText); //use response as HTML for element
}
});
//this is similar to requesting:
http://example.com/index.php?query1=foo&query2=bar&query3=baz
agree with joseph. You can use ajax by javascript manner or by jQuery, I personally suggest jQuery because it is simple to implement.
$.ajax({
type: 'GET',
url: "URL you want to call" ,
data: 'Data you want to pass to above URL',
cache: true, //to enable cache in browser
timeout: 3000, // sets timeout to 3 seconds
beforeSend: function() {
//when ur ajax call generate then u can set here loading spinner
},
error: function(){
// will fire when timeout is reached
},
success: function(response){
//in response you can get your response data from above called url.
}
});

Categories

Resources