Beginning developer here, making a website using wordpress as a platform. I would like the user to be able to click an upvote button and upvote a post without refreshing the page. I figure I should probably use javascript to highlight the button once clicked as well as change the vote number. However, I am having trouble figuring out how to run a php script (to update the database) without refreshing the page.
Thanks in advance,
sample upvote php for posts add this to your functions file....
add_action('wp_ajax_upvote', 'upvote');
add_action('wp_ajax_nopriv_upvote', 'upvote');
function upvote() {
$postid= $_POST['id'];
$direction = $_POST['direction'];
$votes= get_post_meta($postid, '_votes', true);
if($direction='down') {
$votes--;
} else {
$votes++;
}
update_post_meta($postid, '_votes', $votes);
echo $votes;
exit();
}
The above needs security like any form submit of $_POST variables. Dont leave these out in your code!!
jQuery Code
jQuery(document).ready(function($){
$('.arrow').click(function(){ //if your upvote has class arrow?
//you need someway of passing postid to here!
//if you want up / downvote -- logic needed here, if not remove direction from below!
$.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
data: {
action: 'upvote',
id: id,
direction: direction //remove if not needed
},
success: function (output) { //do something with returned data
console.log(output);
jQuery('#postupvote').text(output); //write to correct id - maybe use postid in the id of the vote count on the page e.g. id="vote23" jQuery('#vote'+postid)
}
});
});
})
google wordpress ajax for more information
Related
how is it possible to achieve this:
http://jennamolby.com/how-to-display-dynamic-content-on-a-page-using-url-parameters/
using php?
let's say that I have the following a url:
http://localhost:8888/index.php?page=pages-folder/works-folder/content-manager?article=my-article
to get there I have a link in pages-folder/works.php :
link
which should open content-manager.php in which inside a div I should load my-article.php
EDITED:
I have an index file in which a load into the div.container all the pages I need, so in this case my works.php file is loaded int the div.container using using:
<?php
$page = $_GET['page'];
if(!empty($page)){
$page .= '.php';
include($page);
}
else {
include('pages/home.php');
}
since I also needed to update the url without reloading the page I use this script:
function ChangeUrl(page, url) {
if (typeof (history.pushState) != "undefined") {
var obj = { Page: page, Url: url };
history.pushState(obj, obj.Page, obj.Url);
}
}
$('ul.menu li a').on('click', function(){
var page = $(this).attr('href');
var pageUrl = page.split("/");
pageUrl = pageUrl[1];
$('.container').load(page + '.php', function(){
//fadeout old content
//fadein new content
});
ChangeUrl('Page1', '?page=' + page);
return false;
})
once I have my works.php loaded into the div.container I have the above mentioned link which should lead me to: pages-folder/works-folder/content-manager.php
it is in this page where I'd like to load my-article.php inside the main div of content-manager.php
I thought that adding the ?article= variable would have worked using the same system as above:
$article = $_GET['article'];
if(!empty($article)){
$article .= '.php';
include($article);
}
else {
...
}
but it doesn't...
how can I achieve this?
Why you don't just add you article as a query param ?
http://localhost:8888/index.php?page=pages-folder/works-folder/content-manager&article=my-article
and make a link like this
link
This is just an exemple to understand what you want to do, don't use this kind of code in production, he is vulnerably to CSRF attack
EDIT: with echo it's better sorry
I haven't answered your question per se but this is the sort of code you are looking for:
<?php if (isset($_GET["page"]) && strtolower($_GET["page"]) == "1") { ?>
<p>You are on page one</p>
Back
<?php } elseif (isset($_GET["page"]) && strtolower($_GET["page"]) == "2") { ?>
<p>You are on page two</p>
Back
<?php } else { ?>
<p>You have not selected a page. Click one of the links:</p>
Page one
Page two
<?php } ?>
Explanation
How does $_GET work?
$_GET is a super global variable - meaning it can be accessed from anywhere.
It is a an associative array of variables passed to the current script via the URL parameters.
These are specified following a question mark (?) in the URL. To specify multiple parameters you must use the ampersand (&) character between each one.
$_GET must be specified at the end of the URL after everything else.
http://www.example.com/thisPage.php?page=a
http://www.example.com/thisPage.php?page=a&theme=light
The first URL will produce a $_GET with one element which can be accessed as: $_GET["page"] and would return a string of one character a.
The second will produce:
$_GET["page"]; // returns "a"
$_GET["theme"]; // returns "light"
Notice that for each parameter a new key-value pair is created.
I wrote a comprehensive explanation of superglobals on SO Documentation, but that has since been deprecated. RIP my hard work :P
Showing differing content
As you can see from my answer above. You can use simple if statements to check what the value is.
Firstly, ensure that $_GET isset and then check the value.
I have converted the value of the array to lowercase since "A" is not the same as "a".
The example you linked to really over-complicates things. There is honestly no need for all that regular expressions, and it also relies on JavaScript which is not necessarily a good idea.
With my example at the top, there is no difference between user experience as PHP is server sided thus all the content is worked out and then served to the user.
One step further
Using this you can go that extra step and have an event listener and combine it with AJAX.
Altering my initial example you can have the following.
I have used the jQuery library as it is a lot easier to implement.
<div id="test">
<?php if (isset($_GET["page"]) && strtolower($_GET["page"]) == "1") { ?>
<p>You are on page one</p>
Back
<?php } elseif (isset($_GET["page"]) && strtolower($_GET["page"]) == "2") { ?>
<p>You are on page two</p>
Back
<?php } else { ?>
<p>You have not selected a page. Click one of the links:</p>
Page one
Page two
<?php } ?>
</div>
function myAJAX() {
$("a").on("click", function(e) {
e.preventDefault();
// get the clicked page number
if (this.href.indexOf("&") > -1) {
var d = this.href.substring(this.href.indexOf("page=") + "page=".length, this.href.indexOf("&"))
} else {
var d = this.href.substr(this.href.indexOf("page=") + "page=".length)
}
$.ajax({
method: "GET",
url: "t.php",
data: "page=" + d,
success: function(data, textStatus, jqXHR) {
// change the content of the #test div
$("#test").html($($.parseHTML(data)).filter("#test")[0]);
myAJAX();
}
});
});
}
myAJAX();
Notice that the HTML is not being wrapped in <div id="test"> which is so that the JavaScript can find that element and change it in the function.
$("#test").html($($.parseHTML(data)).filter("#test")[0]); is the line that is fetching the HTML and changing it with the data from the page you tried to click on.
I also call the function inside itself so that it will reattach on the anchor links. If you remove this line then the page will redirect as normal.
The good thing about this implementation is that if your user does not have JavaScript then the page will act as normal and there will be a normal reload of the site.
No need for any extra work on your part.
Is there a way to call a (jquery action/write an html text) to a div of a new page after calling the window.location command?
Im trying to make an ajax form submit where the user will be redirected to a new page upon submit,
and in that new page a hidden div will appear with text inside of it
currently this is my code
script.js
$.ajax({
url:url,
type:'POST',
data:datastr,
success:function(result){
if(result=="duplicate"){
$("#status").attr('class', 'span12 alert alert-error');
$("#status").show();
$("#status").html("<h4><center>Duplicate Username</center></h4>");
$("#dept_name").closest(".control-group").attr('class', 'control-group');
$("#username").closest(".control-group").attr('class', 'control-group error');
$("#password").closest(".control-group").attr('class', 'control-group');
$("#username").focus();
}
else{
$("#dept_name").closest(".control-group").attr('class', 'control-group');
$("#username").closest(".control-group").attr('class', 'control-group');
$("#password").closest(".control-group").attr('class', 'control-group');
window.location = base + 'admin/departments/edit_dept/' + result;
}
}
});
i want to make this block of code below work on the page where window.location is going
$("#status").attr('class', 'span12 alert alert-error');
$("#status").show();
$("#status").html("<h4><center>Successfully added Department</center></h4>");
is it possible?
thanks
You can use CI session flash data.
http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Before triggering window.location, set the message in flashdata. On the landing/redirected-to page, check to see if flashdata has a value (success/failure). If so, display (or trigger a js method to show) the message.
You could add a parameter with your window.location, like:
window.location = base + 'admin/departments/edit_dept/' + result + '?showMessage=12'
Then on the next page, have a jquery script that looks for that parameter and shows the message. See this question.
Or you can do it in on the server. But with jquery it works with static html too.
This is a patchup, May require some tuning though.
window.location = base + 'admin/departments/edit_dept/' + result+'/err'; //changed to catchup with the view part
In the Controller:
<?php
if($this->uri->segment(4) == "err"){
$data['err'] = true; #will reflect that we need to show the js in the view
$this->load->view('view', $data);
}
?>
In the view part:
<?php if(isset($err)){ ?>
<script type="text/javascript">
$("#status").attr('class', 'span12 alert alert-error');
$("#status").show();
$("#status").html("<h4><center>Successfully added Department</center></h4>");
</script>
<?php } ?>
I am working on a comments system and I have made it nice with jQuery, I have a problem. I made it fetch the DB stuff every 2000 miliseconds (2 seconds). And here is the problem, when a user clicks "report comment" another div with a message will show, but after the 2 seconds it disappears, and I'm assuming it's because the setInterval is refreshing the content.
But here is what I've done.
NOTE: I put this part of the code within the while() function in PHP so it loops with all the other comments, and I've assigned them with a uniqueID.
<script type="test/javascript">
$("#<?= $lc['uniqueid']; ?>").click(function() {
$("#report<?= $lc['uniqueid']; ?>").fadeIn();
});
</script>
And here is the script where it refreshes the content ext, (it's on the bottom of my webpage by the way)
setInterval(function() {
$.get('serverinfo.php?showcomments=<?= $id; ?>', function(data) {
$('#showcomments').html(data);
});
}, 2000);
So if anyone would know how to ignore the div that shows up when a user clicks report to be removed, I'd appreciate it! thank you.
A possible solution is conditional update of your content. ie, when user clicks "report comment" add a line
$('#showcomments').addClass("comment-active");
Then make your update conditional:
setInterval(function () {
$.get('serverinfo.php?showcomments=<?= $id; ?>', function (data) {
if (!$('#showcomments').hasClass("comment-active")) {
$('#showcomments').html(data);
}
});
}, 2000);
And to add, of course, delete the class when the report comment is closed.
$('#showcomments').removeClass("comment-active");
I've created a bookmark page that retrieves links from a database and displays it. I'm able to log in, add new links & delete them. However, when I delete an entry it displays delete.php instead of loading the page onto itself (the query does work).
I've most likely over-complicated my code at this point and am probably overlooking something simple, as I've used a lot of JavaScript for other elements of the page.
The entries are added dynamically so this part of the HTML is being appended:
<h2>
[x]
</h2>
<a href="'+url+'" target="iFrame" class="linkURL">
<div class="bookmark">
<h3 style="float: left;">'+title+'</h3>
<br />
<p>'+desc+'</p>
</div>
</a>
JavaScript:
// DELETE FUNCTION
$("h2 a").click(function() {
return false;
var action = $(this).attr('href');
var form_data = {
URL: $("#linkURL").attr('href'),
is_ajax: 1
}; // form_data
$.ajax({
type: "POST",
url: action,
data: form_data,
success: function(response){
if(response == 'success') {
alert('Successful delete!');
} else { // if
alert('Delete failed.');
} // else
} // function(response)
}); // ajax
return false;
}); // h2
The page is located here: http://samaradionne.com/links6/ if it is easier to view the whole thing.
You are using both an anchor tag a and a click event. You are getting the actual delete.php page because when you click on the anchor tag it works just like any regular link. You have no where in your code something that says "hey, don't actually follow this link like normal".
To not follow the link, you need
[x]
Furthermore, you attached your jQuery click event to the h2, which is not bad in of itself, just confusing as the intent is to actually click the link. In that case, you need:
$("h2 a").click(function(){});
Lastly, to bring this all together, you could do the following:
$("h2 a").click(function(){
// your normal logic
return false; // don't follow link
});
And then you don't have to have the onclick inside the anchor tag.
Since my links were dynamically generated, my .h2 a click was attaching itself to something that wasn't there yet. I added an event trigger to my append function that calls to my delete function.
Problem solved.
I wonder whether someone can help me please.
The extract of script below enables a user to delete records from a table, linked to a mySQL database.
<script type="text/javascript">
$(document).ready(function(){
$('form.delete').submit(function(e){
e.preventDefault();
var elem = $(this).closest('.delete');
var lid = $(this).serialize();
$.confirm({
'title' : 'Delete Confirmation',
'message' : 'If you delete this Location, all associated Find records will also be deleted. <br /><br />They cannot be restored at a later time! Do you wish to continue?',
'buttons' : {
'Yes' : {
'class' : 'blue',
'action': function(){
//elem.slideUp();
$.ajax({
url: 'deletelocation.php',
type: 'POST',
data: lid,
success: function(response) {
console.log('success', response);
setTimeout(function() {
$('body').fadeOut(400, function(){
location.reload();
setTimeout(function(){
$('body').fadeIn(400);
}, 500);
window.scrollTo(x-coord, y-coord);
});
}, 2000);
},
error: function() {
console.log('error')
}
});
}
},
'No' : {
'class' : 'gray',
'action': function(){} // Nothing to do in this case. You can as well omit the action property.
}
}
});
});
})
</script>
I can manage to get the 'Delete Confirmation' message working and the actual deletion of the record, but I'm having a little difficulty in adding a 'Fade out' as the deletion takes place and then a 'Fade in' upon page reload.
I've read a number of posts and from these I came up with the following which I've integrated into the above :
setTimeout(function() {
$('body').fadeOut(400, function(){
location.reload();
setTimeout(function(){
$('body').fadeIn(400);
}, 500);
window.scrollTo(x-coord, y-coord);
});
}, 2000);
However this doesn't work, and I'm not sure why. I just wondered where someone may be able to take a look at this please and let me know where I'm going wrong.
Many thanks and kind regards
The script after location.reload() does not executed because the page is reload.
You can add a flag in your url (#reload) and at start of page's load, you can do
$('body').hide().fadeIn() if you find the flag.
You can't have a javascript action set to occur after the location.reload().
location.reload() will reload the page, and anything left in the JS stack at the time the page reloaded will be lost.
You would need to add the body fadeIn as a function to the page itself, perhaps if there is a particular url param? So rather than reloading the page, you would be navigating to the same page, plus a specified querystring, such as ?reload=true, or to a specific anchor, such as #myAnchor
firstly thank you very much for your help. I have however realised where my problem lay. I had the JavaScript after the body section of my page. I've now moved this to the beginning of my script before the form, and it works fine. Kind regards