I'm building an ajax upload with an editing function (rotate, zoom and crop), and I'm using guillotine by matiasgagliano (https://github.com/matiasgagliano/guillotine) for this. My problem is that after upload the user get redirected to the editing page through ajax, but when landing on that page I always have to refresh the page in browser for the image to load.
I've tried auto-reloading, both through js and php, but that doesn't help, neither does adding a button to load the same url again. Only refresh from browser button (tested in several browsers) works. I've tried implementing jquery.turbolinks, but that stopped guillotine functions from working.
I'm loading the guillotine.js in head section after jQuery, and have the function in bottom before body tag.
Any tip or help would be appreciated. Thx
Here is some of the code:
HTML:
<div class='frame'>
<img id="id_picture" src="identifications/<?php echo $id_url; ?>" alt="id" />
</div>
<div id='controls'>
<a href='javascript:void(0)' id='rotate_left' title='<?php echo $word_row[434]; ?>'><i class='fa fa-rotate-left'></i></a>
<a href='javascript:void(0)' id='zoom_out' title='<?php echo $word_row[436]; ?>'><i class='fa fa-search-minus'></i></a>
<a href='javascript:void(0)' id='fit' title='<?php echo $word_row[438]; ?>'><i class='fa fa-arrows-alt'></i></a>
<a href='javascript:void(0)' id='zoom_in' title='<?php echo $word_row[437]; ?>'><i class='fa fa-search-plus'></i></a>
<a href='javascript:void(0)' id='rotate_right' title='<?php echo $word_row[435]; ?>'><i class='fa fa-rotate-right'></i></a>
</div>
Js:
<script type='text/javascript'>
jQuery(function() {
var picture = $('#id_picture');
picture.guillotine({
width: 240,
height: 180
});
picture.on('load', function(){
// Initialize plugin (with custom event)
picture.guillotine({eventOnChange: 'guillotinechange'});
// Display inital data
var data = picture.guillotine('getData');
for(var key in data) { $('#'+key).html(data[key]); }
// Bind button actions
$('#rotate_left').click(function(){ picture.guillotine('rotateLeft'); });
$('#rotate_right').click(function(){ picture.guillotine('rotateRight'); });
$('#fit').click(function(){ picture.guillotine('fit'); });
$('#zoom_in').click(function(){ picture.guillotine('zoomIn'); });
$('#zoom_out').click(function(){ picture.guillotine('zoomOut'); });
$('#process').click(function(){
$.ajax({
type: "POST",
url: "scripts/process_id.php?id=<?php echo $emp_id; ?>&user=<?php echo $user; ?>",
data: data,
cache: false,
success: function(html)
{
window.location = "<?php echo $finish_url; ?>";
}
});
});
// Update data on change
picture.on('guillotinechange', function(ev, data, action) {
data.scale = parseFloat(data.scale.toFixed(4));
for(var k in data) { $('#'+k).html(data[k]); }
});
});
});
</script>
Make sure both the DOM-tree and the script is loaded.
var script = document.createElement('script');
script.src = "guillotine-master/js/jquery.guillotine.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = function () {
jQuery(function() {
var picture = $('#sample_picture');
picture.guillotine({
width: 240,
height: 300
});
picture.on('load', function(){
// Initialize plugin (with custom event)
picture.guillotine({eventOnChange: 'guillotinechange'});
// Display inital data
var data = picture.guillotine('getData');
for(var key in data) { $('#'+key).html(data[key]); }
// Bind button actions
$('#rotate_left').click(function(){ picture.guillotine('rotateLeft'); });
$('#rotate_right').click(function(){ picture.guillotine('rotateRight'); });
$('#fit').click(function(){ picture.guillotine('fit'); });
$('#zoom_in').click(function(){ picture.guillotine('zoomIn'); });
$('#zoom_out').click(function(){ picture.guillotine('zoomOut'); });
$('#process').click(function(){
$.ajax({
type: "POST",
url: "scripts/process_img.php?id=<?php echo $emp_id;?>&user=<?php echo $user; ?>",
data: data,
cache: false,
success: function(html)
{
window.location = "<?php echo $finish_url; ?>";
}
});
});
// Update data on change
picture.on('guillotinechange', function(ev, data, action) {
data.scale = parseFloat(data.scale.toFixed(4));
for(var k in data) { $('#'+k).html(data[k]); }
});
});
});
};
You're incorrectly loading Guillotine twice, before and inside the onload handler.
You should initialize Guillotine after the image is loaded and just once:
var picture = $('#sample_picture');
picture.on('load', function(){
picture.guillotine({
width: 400,
height: 300,
eventOnChange: 'guillotinechange'
});
...
});
If after fixing this you still get any troubles, be aware that if an image is already loaded the onload event never gets triggered, even if the image is not present but cached it might load before you set the handler for onload.
It's not that jQuery doesn't execute on page load but possibly that the onload event never gets triggered.
To prevent this you can force the image to be loaded, place this after setting the onload handler:
// Force reloading if completed or if undetermined.
if (picture[0].complete !== false) {
// 1x1 gif
gif = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='
// Save original src, replace with the gif and reload the original src
src = pic.src; pic.src = gif; pic.src = src
}
I hope this solves your problem, don't lose your faith in Guillotine ;)
Thanks for the respond guys, but i was unable to solve it.
As soon as I wrapped any function around the jQuery function, the functions within it stopped working.
I ended up using Jcrop instead of Guillotine, and built a rotating function that can be used before cropping. Now everything is working well.
Link to Jcrop: http://deepliquid.com/content/Jcrop.html
Related
<div id="success_hold">
<?php
if($row['mandate_end']!=date('Y-m-d') && $row['job_position']=='unhold')
{
echo '<span class="badge badge-success">Open</span>';
}
else
{
echo '<span class="badge badge-warning">Hold</span>';
}
?>
</div>
<script>
$(document).ready(function(){
var flag = 1;
$(".hold").click(function(){
job_id = this.id;
if(flag == 1)
{
$.ajax({
type:"POST",
data:{"job_id":job_id},
url:"<?php echo base_url(); ?>pausehold",
success:function(data){
$("#success_hold").load("#success_hold");
}
});
flag = 0;
}
else
{
$.ajax({
type:"POST",
data:{"job_id":job_id},
url:"<?php echo base_url(); ?>resumehold",
success:function(data){
$("#success_hold").load("#success_hold");
}
});
flag = 1;
}
});
});
</script>
I have div where id="success_hold". Now, what happens when I click on class="hold" I am updating my data. Now, I want to refresh my <div id="success_hold"> without reload whole page where I am using .load() function But the problem is that when I use .load() the function shows the whole page in success_hold. So, How can I fix this issue? I want to refresh only success_hold.
Thank You
The problem is because load() is used to make another AJAX request and place the a portion of the HTML retrieved from that request in the target element.
As you're already making an AJAX request to get the data, which is presumably HTML, you simply need to append() data to the container.
Also note that the only difference between the two sides of your condition is the URL the request is sent to, so you can easily DRY this code up:
$(document).ready(function() {
var flag = true;
$(".hold").click(function() {
var url = '<?php echo base_url(); ?>' + (flag ? 'pausehold' : 'resumehold');
flag = !flag;
$.ajax({
type: "POST",
data: { job_id: this.id },
url: url,
success: function(data) {
$("#success_hold").append(data);
}
});
});
});
If data contains the entire page, then you should change that PHP file to return only the relevant HTML as it will help to speed up the request. If, for whatever reason, you can't do that then you can extract the required element from the response like this:
$("#success_hold").append($(data).find('#success_hold'));
success:function(data){
$("#success_hold").load("#success_hold");
}
This is your success method in ajax. You want to pur the content of data into your div #success_hold ?
If you want that, just do this :
success:function(data){
$("#success_hold").html(data);
}
let's say I have a wordpress shortcode, in a page (not post), like [display id="144,145,146"] and I want to add a link in the page like "click here to sort by views", so I can click the link and a javascript function can change the shortcode, putting different ids. Is it possible?
This is not possible without using AJAX unless you load you load all of the different short code options beforehand.
Preloading Shortcodes:
$('#change-shortcode').on('click', function() {
$('.shortcode-container').toggleClass('hidden');
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="shortcode-container">[display id="144,145,146"]</div>
<div class="shortcode-container hidden">[display id="147,148,149"]</div>
<br/><br/>
<a id="change-shortcode">Click Here</a>
Fetching Shortcodes with AJAX:
// Add the "fetch_shortcode" AJAX action.
add_action('wp_ajax_nopriv_fetch_shortcode', 'fetch_shortcode');
add_action('wp_ajax_fetch_shortcode', 'fetch_shortcode');
function fetch_shortcode() {
if (isset($_POST['ids'])) {
$ids = implode(',', $_POST['ids']);
// ob_start and ob_get_clean will prevent the shortcode from displaying and instead will return the value to the $html variable.
ob_start();
do_shortcode('[display id="' . $ids . '"]');
$html = ob_get_clean();
wp_send_json_success($html);
}
}
On the front end, you would have this:
<div id="shortcode-container">[display id="144,145,146"]</div>
<br/><br/>
<a id="change-shortcode">Click Here</a>
<script>
$('#change-shortcode').on('click', function() {
// This is where you get to use the 'fetch_shortcode' action name that you created above.
data = {
ids: [147, 148, 149],
action: 'fetch_shortcode'
};
$.ajax({
url: "<?php echo admin_url('admin-ajax.php') ?>",
method: "POST",
data: data
}).done(function(response) {
$('#shortcode-container').html(response.data);
});
});
</script>
I am trying to submit an ajax function via a link click, I am using onclick like so:
<a href="<?php echo SITE_URL; ?>watchlist/remove/<?php echo System::escape($this->item->item_id); ?>" onclick="manage_watchlist(); return false;" id="watchlist">
Remove From Watchlist
</a>
and my function:
var manage_watchlist = function(e)
{
alert("ff");
e.preventDefault();
$.ajax({
url: $(this).attr('href'),
type: 'post',
dataType: 'json',
success: function(data)
{
if(data.success)
{
if($(this).hasClass("remove"))
{
$(this).text("Add to Watchlist");
$(this).removeClass("remove").addClass("add");
$(this).attr('href', '<?php echo SITE_URL; ?>watchlist/add/<?php echo System::escape($this->item->item_id); ?>');
}
else
{
$(this).text("Remove from Watchlist");
$(this).removeClass("add").addClass("remove");
$(this).attr('href', '<?php echo SITE_URL; ?>watchlist/remove/<?php echo System::escape($this->item->item_id); ?>');
}
$('#watch_success_message').html(data.success + alert_close).show();
}
else
{
$('#watch_error_message').html(data.error + alert_close).show();
}
<!-- hide loading icon -->
$('.ajloading').hide();
},
error: function()
{
<!-- hide loading icon -->
$('.ajloading').hide();
}
});
return false;
}
I have put an alert in the function which works so my function is working, but it is still visiting the link for some reason?
You need to pass in event with the inline event handler.
onclick="manage_watchlist(event);"
or better yet, dump the inline event and use jQuery to attach the event.
For an inline event e.preventDefault(); "prevents" return false.
Use only return false;.
Do something like this:
<a href="<?php echo SITE_URL; ?>watchlist/remove/<?php
echo System::escape($this->item->item_id); ?>" id="watchlist">
Remove From Watchlist
</a>
//JS
$(document).ready(function(){
$('#watchlist').click(function(e){
var $this = $(this); //**this** is the anchor
e.preventDefault(); //e is click event.
$.ajax({//use $this when you mean the anchor
//**this** here is $.ajax
//...
//your code here
});//$.ajax
});//$('#watchlist').click
});//$(document).ready
When you put code into the string for onclick it does not act as you may think it does. It behaves similar to this:
function(event) {
manage_watchlist();
}
which is why you must pass the event object to your function in the html onclick.
onclick="manage_watchlist(event);"
will look like
function(event) {
manage_watchlist(event);
}
So I have a index.php file which uses ajax for loading contents from another .php file within the same directory. But for some reason when you click a link from the menu and it is loaded in the ajax, the php script from the news panel isn't executing, or it isn't visible.
Demo Link: http://www.michaeldylanedwards.co.uk/#archives
Direct Link: http://www.michaeldylanedwards.co.uk/archives.php
php script
<?PHP
$category = "8";
$template = "Archives";
include("admin/show_news.php");
?>
Here is the codes for the ajax loaded content;
load_page.php
<?php
if(!$_POST['page']) die("0");
$page = $_POST['page'];
if(file_exists($page.'.php'))
echo file_get_contents($page.'.php');
else echo 'There is no such page!';
?>
script.js
var default_content="";
$(document).ready(function(){
checkURL();
$('ul li a').click(function (e){
checkURL(this.hash);
});
//filling in the default content
default_content = $('#pageContent').html();
setInterval("checkURL()",250);
});
var lasturl="";
function checkURL(hash)
{
if(!hash) hash=window.location.hash;
if(hash != lasturl)
{
lasturl=hash;
// FIX - if we've used the history buttons to return to the homepage,
// fill the pageContent with the default_content
if(hash=="")
$('#pageContent').html(default_content);
else
loadPage(hash);
}
}
function loadPage(url)
{
url=url.replace('#','');
$('#loading').css('visibility','visible');
$.ajax({
type: "POST",
url: "load_page.php",
data: {page: url},
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0)
{
$('#pageContent').html(msg);
$('#loading').css('visibility','hidden');
}
}
});
}
Any help would be appreciated!
So, when on the #archives page its blank, clicking around on the top links #home, #blog etc work, which im assuming is expected behaviour.
However, when clicking on #contact and #social, it breaks the site.. This is because whatever ajaxpage() function is doing (you haven't included it in the above JS) is removing the #pageContent that the loadPage() function requires to insert your content.
(I believe the ajaxpage() is just whacking it's response output into the content, which is removing the inner #pageContent)
EDIT: for clarity purposes, I've edited this question.
EDIT 2: I was able to solve half of my issue.
Below is a simple script for users to delete the pictures they uploaded.
Depending on whether or not there is an image saved in the database. A toggle OR an upload icon should show.
The issue is that when the delete button is clicked, the picture and the toggle buttons get removed BUT the upload icon won't show (unless page is refreshed).
if (image exists in database) {
<div class="toggle" id="toggle<?php echo $image_id ?>"></div>
}
else {
<div class="upload_icon" id="upload<?php echo $image_id ?>"></div>
}
`SQL query to select image in database`
//this DIV expands when the toggle button is clicked
<div class="content" id="image<?php echo $image_id ?>"><img src="<?php echo
$path ?>" />
<div class="remove content"><a href="#" id="<?php echo $image_id ?>"
class="delete_icon">Remove!</a></div>
</div>
Javascript part:
$(function(){
$('.delete_icon').on("click",function()
{
var ID = $(this).attr("id");
var dataString = 'image_id='+ ID;
$this = $(this);
if(confirm("Are you sure you want to delete this image ?"))
{
$.ajax({
type: "POST",
url: "delete.php",
data: dataString,
cache: false,
success: function(html){
$('#image'+ID).remove()
$('#toggle'+ID).remove()
$('#upload'+ID).show();
});
}
return false;
});
});
What am I missing here ?
this is no longer the link once you're inside the context of the success function. I saved off this and used it inside, that should do the trick.
Also I'm not sure that the find is actually going to work. Based on your example I'm not sure that #toggle elements are actualy nested within .delete_icon.
If they aren't you might want to do $('#toggle'+ID) rather than using find. It's an ID selector anyway so it wouldn't be affecting performance.
$(function(){
$('.delete_icon').on("click",function() {
var ID = $(this).attr("id"),
dataString = 'image_id='+ ID,
$this = $(this);
if( confirm("Are you sure you want to remove this image ?") ) {
$.ajax({
type: "POST",
url: "delete.php",
data: dataString,
cache: false,
success: function(html) {
$this.closest(".content").hide();
$('#toggle'+ID).hide()
$('#upload'+ID).show();
}
});
}
return false;
});
});