I'm trying to write a feature for my Fantasy Football league that allows players to trade with each other. Functionally it all works fine, but as I've coded it all in PHP I have an annoying problem where any time a button is pressed the page is effectively refreshed twice. I've read that I can get around this with jQuery and Ajax but sadly I don't really have any experience with either.
Here's a small section of the code that allows logged in users to withdraw a trade offer they have made:
echo "<input type='submit' id='btn-danger' name='withdraw".$trade_id."' value='Withdraw'>";
if($_POST && isset($_POST['withdraw'.$trade_id])) {
$withdraw = $link->prepare("DELETE FROM trade_id_offers_out WHERE trade_id_offer_id = ".$trade_id);
$withdraw->execute();
}
This creates a "Withdraw" button for each trade offer they have sent out and has a unique name of "withdraw" plus whatever number the offer is in the SQL table.
As I say functionally it works perfectly fine. But it refreshes the page twice and I'm wondering how I can take this code and turn it into something a little more practical?
Many thanks for your time.
First you should make sure you have included jQuery into your page html before any other jQuery (there are plenty of tutorials out there).
Second you need to give the submit button a class so you can select it using a jQuery selector. Change the php code of the button to this:
echo "<input type='submit' id='btn-danger' class='withdrawTradeBtn' name='withdraw".$trade_id."' value='Withdraw'>";
Finally you would make a ajax post request to your url (same url as your page in this case). The js would look something like this and would need to be placed before the end of the html body tag or after all your buttons are rendered:
(Note: I have not tested this but it should be pretty close to what you are after)
<script>
//we need to wait for the page to be loaded in the users browser
$(document).ready(function(){
//we are selecting all the buttons with the class withdrawTradeBtn
//we are binding to the click event so whenever any of the buttons are pressed the code will be ran.
$('.withdrawTradeBtn').on('click', function(e){
//we need to prevent the button from actually reloading the page
e.preventDefault();
//now we need to make a ajax post request to the url
$.post(
'/your/url', //the url to make the post
{$(this).attr('name'):'Withdraw'}, //the submitted data
function(data, status, jqXHR) {// success callback
//here is were you would delete the button or whatever
}
);
});
});
</script>
Most likely you would want to delete the trade entry from the html. You would do that in the success callback of the ajax post. I cant really add anything here because I don't know what your html structure looks like.
Hope this helps, let me know if you need any more help!
Related
It's my first time posting here.
I have a fairly simple script that I'm trying to get working on my word press website. I'm essentially trying to make a loop that goes through all the posts on a page and changes that URL to another URL
I am going to be pasting the new URL in the post excerpt field. What I want to happen is that once a user clicks on the image of a post on the homepage, they are taken to the URL that I specified on the post excerpt field of that respective post.
here is the code I came up with.
<script type="text/javascript">
jQuery( document ).ready(function( $ ) {
$('ul.g1-collection-items li.g1-collection-item').each(function(){
var that = $(this);
var excerpt_link = $(<?php echo get_the_excerpt ?>);
that.find('.entry-featured-media a').attr('href', excerpt_link);
});
});
</script>
But as expected, this doesn't work. Also, using this code seems to only work on the URL slug, not the entire URL
Any thoughts? Thank you so much for all your help!
The code dosen't work because you're mixing jQuery foreach loop without a Wordpress foreach loop. I get what you're trying to do, but you're doing it wrong.
In the part where you have the loop for posts just add the
<?php echo get_the_excerpt();?>
And put it on the anchor tag of the image, and you're done, no need for jQuery.
P.S. you also wrote the get_the_excerpt wrong, it wouldn't work. It's a function so it needs a ()
I have an HTML form which submits to another page via POST. Nothing special about it, except that after the form validates I try to hide and/or disable the submit button so that it cannot be double-submit, while also telling the user the next page might take a while to load.
The relevant code is:
jQuery(document).ready(function () {
jQuery("form#form").submit(function() {
var result = validate();
jQuery(this).find('input[type=submit]').prop('disabled', true);
jQuery("#submit-button-wrapper").html(jQuery("#submit-button-wrapper").html()+
"<br/><br/><span style='margin: 25px; padding: 5px; background: yellow; "+
"width: 100%; font-weight: bold;'>Loading... this may take a few minutes! "+
"<i class='fa fa-spinner fa-spin' style='color: blue;'></i></span>");
return result;
});
});
function validate() {
return true; // Does stuff, then returns a simple true or false
}
By request, here is the (very simple) button wrapper HTML:
<div class="col-sm-12" id="submit-button-wrapper">
<input type="submit" value="One More Step" />
</div>
When the I remove the which changes the button wrapper's HTML, the form submits just as you'd expect. When I have that line in, however, it still calls the next page and executes that code, without the displayed page ever changing.
I have tested in both Chrome and Firefox, so I know it's not a browser issue, but this is really weird behavior. What am I doing wrong?
My goal: (1) validate the user's input, (2) give the user a clue that the page is going to take a while to load and (3) display the output from the action="complete.php" page once the PHP on it has run.
Maybe you can achieve this with $ajax and show results on the same page.
Send POST data to /some.php
After sending data, give feedback to user changing button behavior
When the task is complete, receive data and verify success or error and act accordingly. If OK, change button text to "complete!" or something else, and append response data to some div. If NOT OK, give feedback as well.
In code:
$("form#form").submit(function(e) {
e.preventDefault();
$.ajax({
method: "POST",
url: "some.php",
data: $(this).serialize(),
dataType : 'json',
timeout: 2000,
cache: false,
afterSend: function() {
/*change button behavior here*/
},
success: function(result) {
if (result === "ok"){
/*maybe append data to div and update button text to complete*/
} else {
/*if result not ok, send feedback*/
}
}
});
});
BTW: ajax documentation http://api.jquery.com/jquery.ajax/
When you return true (if validated) then the form is submitted. However, you're changing the DOM / submit button wrapper and essentially removing the submit button, right? Likely that is what is causing your problem. Leave the submit button wrapper alone. If you want to display a message display it as an overlay or hide the submit button wrapper and show the message wrapper in its place, don't remove the submit button altogether.
I know that you're just showing a slight jQuery and HTML portion of the script, but that isn't quite enough to figure out your problem. Since not all of it seems to be there because you mention action="complete.php" but I don't see that within your jQuery or HTML sample of code. So I have a few questions of my own.
Is the form small or large. If it's a small form then why aren't you displaying the output on the submit page? You could do that with what you currently have but a single PHP or ASP page could save you on amount of pages to make and what not. As a side note, depending on size of the form, you can do the validation on same page or continue to use action="" for it if large.
Do you have need for a database file or are you saving to one? If you do/are, you could write to the DB file, have the submit open the next page and view what was saved in the database on that new page. Again, you can probably use a single PHP or ASP page.
This last part sounds more valid for your purpose. You could use location.href="http://www.domain.com/home.html";
or use window.location("http://www.domain.com/home.html"); to redirect to the new page.
On another matter about some of the comments others made.
You don't exactly need the + unless you're dividing each of those out into their own separate lines when you could just use one line to do that. That's probably what confused Rajesh about the '. In fact I'm not sure why you yourself mentioned the + when referring to Rajesh comment about "concat string" and "append" ,because those two have nothing to do with the +. In fact to take a guess, he might have been referring to your jQuery("#submit-button-wrapper").html(jQuery("#submit-button-wrapper").html() which kinda looks like a concat string.
Speaking about append, not really needed unless for example you're doing something like giving the user the option to add rows to a form question.
I am trying to do a simple query for info from a database through an html page. I've got all the backend stuff working fine, but I'm having trouble on the client side. I currently have a form where the user submits their ID# to get some info on their case.
But with my current setup, it returns an entirely new page and I just want to read in a text string, process it and update the content on the current html page without opening up a new one and replacing the old one. How can this be done?
Here's my code so far:
function showInfo() { } // I want to make the request here instead
<form name="register" action="http://localhost:8080/testapp/authenticate" method="get">
<p><label for="badge">ID #:</label>
<input id="badge" name="ID" type="text" pattern="[0-9]{6}"
placeholder="xxxxxx">
<button id="checkButton" type="submit" onClick="showInfo()">Enter</button>
</p>
</form>
My guess is that you're actually submitting the form, which is posting back to the server. What you will want to do is cancel the form from submitting and submit it using AJAX (which is what I believe you want?).
To do so, your showInfo() function should do one of these three things (I can never remember which one)
return false;
cancel the event, something like e.preventDefault()
stop the propagation, something like e.stopPropagation()
Once you've successfully prevented the form from hard-submitting, you can then do what you'd like by submitting your data via AJAX and manipulating your response however you'd like.
1st - Jason is absolutely right that what you want for this situation is AJAX, below is an example in motion.
2nd - You should be using a Javascript library such as jQuery, which might look intimidating (as it did for me at first), but it is really easy and completely worth the small effort to get it going.
3rd - With jQuery, your application tidbits should look something like this, using the example you provided:
HTML -
<p>
<label for="badge">ID #:</label>
<input id="badge" name="ID" type="text" pattern="[0-9]{6}"
placeholder="xxxxxx">
// Please note that I removed the onClick section from the line below.
<button id="checkButton" type="button">Enter</button>
</p>
JQUERY -
// The default function you described to take information and display it.
function showInfo(data) {
// Insert your function here, probably using JSON as the Content Type
}
// This is the key AJAX function, using jQuery, that takes your info and gets a
// response from the server side, the sends it to the function above in order for it
// to be displayed on the page.
function processIdInfoCheck() {
$.ajax({
type: 'post',
url: '/http://localhost:8080/testapp/authenticate',
data: {
'id': $('#badge').val();
},
dataType: 'json',
success: displayIdInfoReturn,
error: function () {
alert("There was an error processing your request, please try again");
}
});
}
// When the page loads, the code below will trigger, and bind your button click
// with the action you want, namely triggering the AJAX function above
(function ($) {
$('#checkButton').bind('click', processIdInfoCheck);
})(jQuery);
Just remember, AJAX takes some effort to get the desired effect, but when you look at page load times, request numbers, etc... It is totally worth it. Please let me know if this was helpful and if you need any specifics.
The basics:
I have a webpage where a user can 'add an article'; when they click to 'add an article' it opens an iframe (a pop-up modal box).
In the Iframe there is a form with 'save' and 'cancel' buttons - what I'm trying to do is make it so when the user hits 'save', it will close the modal box, and then refresh the page.
I have it set so the iframe closes and the data is saved to the database, but I can't get the page to refresh (which would then display the new article)
I've been unable to do this as of yet, despite googling for days. I'm not a javascript pro, but I've learned enough in the past couple days to do a thing or two.
Here is the code for the button:
<a class="toolbar" href="#" onclick="javascript: submitbutton('save'); return false;">
Here is the end of the javascript function that handles the saving of the data:
function submitbutton(pressbutton) {
...
<?php endif; ?>
submitform( pressbutton );
parent.$('sbox-window').close();
}
}
http://community.getk2.org/forum/topics/solved-adding-articles-on-the?xg_source=activity
That link is the fix that I was looking for - this question was originally aimed at the K2 Component for Joomla.
Myself and another person were able to resolve the issue by writing some code of our own. In that thread as well as the one linked in the replies, a solution is arrived upon.
EDIT: A request was made to post the solution here, so here's a short summary
If you have users creating articles from the front end and you want the 'save' button to close the model box window that pops up when they add or edit an article - just follow the steps below to achieve this:
*Note: there are a few other fixes that work to close the box, but not refresh the page - this does both.
The key is passing an extra parameter through the URL that gets created when the user clicks "Save", then we just check to see if that parameter (which I will call 'step') exists - if it does, we refresh the page.
Lets follow along, first we must add this parameter to the URL created -
Open the item.php file located at:
Yoursite->administrator->components->com_k2->models->item.php
On or around line 646 - you will see some text that resembles:
case 'save':
default:
$msg = JText::_('Item Saved');
if ($front)
$link = 'index.php?option=com_k2&view=item&task=edit&cid='.$row->id.'&tmpl=component';
else
$link = 'index.php?option=com_k2&view=items';
break;
So what we need to do is add our parameter to that URL so it will look like this (remember I called the parameter 'step', and will be setting it =1) - the code will now look like this:
if ($front)
$link = 'index.php?option=com_k2&view=item&task=edit&cid='.$row->id.'&step=1&tmpl=component';
Now when the user clicks 'save' the parameter 'step' is getting passed along, and when the form reloads to show the user their information they had entered, step=1!
So then we have to add the php to check for that - that's simple enough:
Open the form.php file located at:
Yoursite->components->com_k2->views->item->tmpl->form.php
In there you can see where the form actually begins (on or around line 249), what we want to do is just add a little bit of php that checks to see if our 'step' parameter is equal to 1. If it is - we'll refresh the parent page using some javascript, that will automatically close the model box and cause the 'item saved' text to display to the user letting them know what happened.
The existing code looks like :
<form action="index.php" enctype="multipart/form-data" method="post" name="adminForm" id="adminForm">
<div class="k2Frontend">
<table class="toolbar" cellpadding="2" cellspacing="4">
When finished it will look like this:
<form action="index.php" enctype="multipart/form-data" method="post" name="adminForm" id="adminForm">
<div class="k2Frontend">
<?php if (JRequest::getInt('step')=='1') { ?>
<script language="javascript">
var XHRCheckin = new Ajax('index.php?option=com_k2&view=item&task=checkin&cid=<?php echo $this->row->id; ?>', {
method: 'get'
});
dummy = $time() + $random(0, 100);
XHRCheckin.request("t"+dummy);
parent.$('sbox-window').close();
window.parent.location.reload();
</script>
<?php } ?>
<table class="toolbar" cellpadding="2" cellspacing="4">
That checks to see if 'step' is =1. If it is - it runs javascript to refresh the parent window - closing the box and refreshing the page automatically. It also checks in the article on the backend.
This ensures the easiest possible thing for the user (i.e. they don't have to click 'back' and 'refresh' which is extremely counter-intuitive) and gives the front end user a back-end experience.
I hope this helps people - it took me a LOT of chasing things in the wrong direction before I thought of this solution.
I'm pretty saddened the developers never helped with something that's affected so many people, but oh well - problem was solved!
Try window.location.reload
You'll also want to get rid of the "return false;" from your onclick handler. That may prevent the page from refreshing. Also in general, put any "return" statements from within the event handler function.
I think you're looking for
parent.location.reload();
Incidentally, you don't actually need to close the iframe - once you reload the parent page, it'll be gone anyway.
Check out jQuery fancyBox.
fancyBox is a tool that offers a nice and elegant way to add zooming functionality for images, html content and multi-media on your webpages. It is built at the top of the popular JavaScript framework jQuery and is both easy to implement and a snap to customize.
It' has a "Reload page after closing", function.
$(".fancybox").fancybox({
afterClose : function() {
location.reload();
return;
}
});
I have a piece of code in jQuery that I use to get the contents of an iFrame after you click a link and once the content is completed loading. It works, but I have a problem with it repeating - at least I think that is what it is doing, but I can't figure out why or how.
jQuery JS:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
$("#fileuploadframe").load(function(){
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{action:"savePage",html:response, id: theID},
function(data){
alert(data);
});
});
});
HTML Links ( one of many ):
<a href="templates/1000/files/index.php?pg=0&preview=false"
target="fileuploadframe" class="pageSaveButton" rel="0">Home</a>
So when you click the link, the page that is linked to is opened into the iframe, then the JS fires and waits for the content to finish loading and then grabs the iframe's content and sends it to a PHP script to save to a file. I have a problem where when you click multiple links in a row to save multiple files, the content of all the previous files are overwritten with the current file you have clicked on. I have checked my PHP and am pretty positive the fault is with the JS.
I have noticed that - since I have the PHP's return value alerted - that I get multiple alert boxes. If it is the first link you have clicked on since the main page loaded - then it is fine, but when you click on a second link you get the alert for each of the previous pages you clicked on in addition to the expected alert for the current page.
I hope I have explained well, please let me know if I need to explain better - I really need help resolving this. :) (and if you think the php script is relevant, I can post it - but it only prints out the $_POST variables to let me know what page info is being sent for debugging purposes.)
Thanks ahead of time,
Key
From jQuery .load() documentation I think you need to change your script to:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
var lnk = $(this).attr("href");//LINK TO LOAD
$("#fileuploadframe").load(lnk,
function(){
//EXECUTE AFTER LOAD IS COMPLETE
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{
action:"savePage",
html:response,
id: theID
},
function(data){alert(data);}
);
});
});
As for the multiple responses, you can use something like blockui to disable any further clicks till the .post call returns.
This is because the line
$("#fileuploadframe").load(function(){
Gets executed every time you press a link. Only add the loadhandler to the iframe on document.ready.
If a user has the ability via your UI to click multiple links that trigger this function, then you are going to run into this problem no matter what since you use the single iframe. I would suggest creating an iframe per save process, that why the rendering of one will not affect the other.