I'm using summernote html text editor on my site. I want to download images to my server when user put an image url to Image URL area then press to Insert Image button.
Currently summernote only get image's source for src attribute. I want to store images on my own Amazon S3 Bucket or VPS.
There are many docs about summernote image upload but all of them for upload from pc not from URL.
How can I overwrite this feature?
Image dialog
So since you are not able to read dataUrl of cross-origin images in your client-side script the decision is to get url from Image URL area and send it to your backend. There you may use a simple php script to download the image.
The example includes both client and backend codes. Both tested. All you need is to put these two scripts to one of your web server's directories and give it a try.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Summernote</title>
<!-- include libraries(jQuery, bootstrap) -->
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script>
<!-- include summernote css/js-->
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.2/summernote.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.2/summernote.js"></script>
</head>
<body>
<div id="summernote">Hello Summernote</div>
<script type="text/javascript">
$(document).ready(function() {
$('#summernote').summernote();
$('button[data-original-title="Picture"]').click(function(){
// Set handler on Inset Image button when dialog window is opened
$('.modal-dialog .note-image-btn').one('click', function(e) {
// Get Image URL area
var imageUrl = $('.modal-dialog .note-image-url').val();
// Send it to your backend
$.ajax({
url: "image_loader.php",
data: "url="+imageUrl,
type: "POST",
dataType: 'json'
}).success(function(data) {
if (typeof data[0] === 'string') {
$('img[src="'+imageUrl+'"]').attr('src', data);
} else {
// What to do if image downloading failed
window.alert('oops');
}
}).error(function() {
// What to do if ajax request failed
window.alert('oops');
});
});
});
});
</script>
</body>
</html>
image_loader.php
<?php
if ($_POST['url']) {
// Here you'd better put some logic to check that $_POST['url'] is a correct url before use it
$image = file_get_contents($_POST['url']);
if ($image) {
// Put downloaded image on your server
$file = fopen('imagename.jpeg', 'w');
fwrite($file, $image);
fclose($file);
}
/**
* Now your code needs to echo one of the following:
* string Url of an uploaded image on your server
* bool False if it failed
*
* To avoid bool to string conversion during output response needs to be sent as JSON
*/
$response = ($image) ? array('/PATH_TO_IMAGE_DIRECTORY_IF_NEEDED/imagename.jpeg') : array(false);
echo json_encode($response);
}
For example with this image https://imgsnap.com/images/2015/02/23/abstract_0005.jpg
UPDATE (to your comment about img styling)
Put the following line in summernote.js to trigger a special event when image url has been handled by the editor.
$(document).trigger('imageUrlInserted', src);
Put it on line 4095 (according to my version of file) inside of insertImage() method before
$image.css('width', Math.min($editable.width(), $image.width()));
Now in index.php inside of
$('.modal-dialog .note-image-btn').one('click', function(e) {
...
...
});
replace all the code with this
// Get Image URL area
var imageUrl = $('.modal-dialog .note-image-url').val();
// Send it to your backend after the image been handled by the editor
$(document).on('imageUrlInserted', function(e, sourceUrl) {
if (sourceUrl === imageUrl) {
$.ajax({
url: "image_loader.php",
data: "url="+imageUrl,
type: "POST",
dataType: 'json'
}).success(function(data) {
if (typeof data[0] === 'string') {
$('img[src="'+imageUrl+'"]').attr('src', data).removeAttr('style');
} else {
// What to do if image downloading failed
window.alert('oops');
}
}).error(function() {
// What to do if ajax request failed
window.alert('oops');
});
}
});
Related
I needed a code to upload images to the web application and I did it using the following example:
source
the code works fine on localhost on apache. Now I want to convert the image file to the same base64 while uploading it to the server. I couldn't find how to modify the code for this. Can anyone help? Thanks.
This is upload.php:
<?php
/* get the name of the uploaded file */
$filename = $_FILES['file']['name'];
/* choose where to save the uploaded file */
$location = "upload/".$filename;
/* save the upploaded file to the local filesystem */
if ( move_uploaded_file($_FILES['file']['tmp_name'], $location) ) {
echo 'Success';
} else {
echo'Failure';
}
?>
and this is uploader.html
<!DOCTYPE html>
<html>
<head>
<title> Ajax JS F Up Example </title>
</head>
<body>
<!-- HTML5 Input Form Elements -->
<input id="fileupload" type="file" name="fileupload" />
<button id="upload-button" onclick="uploadFile()"> Upload </button>
<!-- Ajax JS File Up Logic-->
<script>
async function uploadFile() {
let formData = new FormData();
formData.append("file", fileupload.files[0]);
await fetch('/upload.php', {
method: "POST",
body: formData
});
alert('File uploaded.');
}
</script>
</body>
I have a header.html and header.js files because I want to use the same header through my webpages.
In header.js file, on window load I want it to console.log("header file loaded").
I also have index.html and index.js file for my homepage. In index.js, on window load I want it to console.log("index file loaded")
I called header.html in index.html file, in order to import the header for the homepage. This works fine.
based on js files the console output should
header file loaded
index file loaded
The problem I am having is that
it seems like header.js and index.js cannot work simultaneously
only the last referenced file gets outputed in the console
for example this format
<script src="js/header.js"></script>
<script src="js/index.js"></script>
will output
index file loaded
and this
<script src="js/index.js"></script>
<script src="js/header.js"></script>
will output
header file loaded
I use the code to import header.html in index.html
<head>
<div data-include="header"></div>
</head>
<body>
<script>
$(function(){
var includes = $('[data-include]');
jQuery.each(includes, function(){
var file = $(this).data('include') + '.html';
$(this).load(file);
});
});
</script>
</body>
this is the content of both js file
function retrieveInfo(data) {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/Sellers/' + userId).once('value').then(function(snapshot) {
console.log(userId)
console.log("index file loaded")
});
}
})
}
what am I doing wrong and how can I fix it to have both js file called?
You are doing it in a wrong way, .load() is used for loading HTML contents. You should be using .getScript(), to load the js and execute it.
According to docs:
.load()
Load data from the server and place the returned HTML into the matched element.
.getScript()
Load a JavaScript file from the server using a GET HTTP request, then execute it.
Here is an example for using getScript:
$.ajax({
url: url,
dataType: "script",
success: function() {
alert("script loaded");
}
});
In your case it would be:
$(function(){
var includes = $('[data-include]');
jQuery.each(includes, function(){
var JS = $(this).data('include') + '.js';
var file = $(this).data('include') + '.html';
$(this).load(file);
$.ajax({
url: JS,
dataType: "script",
success: function() {
alert(file + " loaded");
}
});
});
});
I have:
test.json - contains the content to be uploaded into the HTML page
test.js - contains the function that sends an Ajax request to the JSON file, parses, compiles with Handelbars Temlate and puts the content into the HTML page (using innerHTTML).
addcontent.js - javascript file which calls the function from the test.js file
index.html - contains the Handlebars Template, Div
where the content will be placed after processing, and a link to the
addcontent.js.
Everything works, if inside index.html there is a link directly to test.js.
Everything works if I wrap the code inside test.js in a function with variables and call this function in the same file.
But if I call this function from addcontent.js and connecting addcontent.js and test.js using commonJS module approach, it does not work.
Probably I made a syntax mistake somewhere, but I don't see it.
P.S. I use NodeJS, NPM, HTTP-server and I'm going to merge all javascript files using browserify after all
//test.js
module.exports = function addContent (jsonDir, templId, finId){
function sendGet(callback) {
/* create an AJAX request using XMLHttpRequest*/
var xhr = new XMLHttpRequest();
/*reference json url taken from: http://www.jsontest.com/*/
/* Specify the type of request by using XMLHttpRequest "open",
here 'GET'(argument one) refers to request type
"http://date.jsontest.com/" (argument two) refers to JSON file location*/
xhr.open('GET', jsonDir);
/*Using onload event handler you can check status of your request*/
xhr.onload = function () {
if (xhr.status === 200) {
callback(JSON.parse(xhr.responseText));
} else {
alert(xhr.statusText);
}
};
/*Using onerror event handler you can check error state, if your request failed to get the data*/
xhr.onerror = function () {
alert("Network Error");
};
/*send the request to server*/
xhr.send();
}
//For template-1
var dateTemplate = document.getElementById(templId).innerHTML;
var template = Handlebars.compile(dateTemplate);
sendGet(function (response) {
document.getElementById(finId).innerHTML += template(response);
})
}
/* test.json */
{
"time": "03:47:36 PM",
"milliseconds_since_epoch": 1471794456318,
"date": "08-21-2016-123",
"test": "lalala 123"
}
/* addcontent.js */
var addContent = require('./test');
addContent("json/test.json", "date-template", 'testData');
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="handlebars-v4.0.5(2).js"></script>
</head>
<body>
<!-- template-1 -->
<div id="testData"></div>
<script id="date-template" type="text/x-handlebars-template">
Date:<span> <b>{{date}}</b> </span> <br/> Time: <span><b>{{time}}</b>
</span>
</script>
<script type="text/javascript" src="addcontext.js"></script>
</body>
</html>
I have successfully sent a csrf token using dropzone but using jquery style, now I don't want to use any jquery in my code I want to use javascript style to get the csrf token. I tried using below code but it keeps on giving me the tokenmismatch error,
myDropzone.on("sending", function(file,xhr,formData) {
// Show the total progress bar when upload starts
var folname = document.getElementById('folname').value;
var token = document.getElementsByName("_token")[0].value;
formData.append('folname',folname);
formData.append('_token', token );
});
this is the code that is working using jquery.
myDropzone.on("sending", function(file,xhr,formData) {
// Show the total progress bar when upload starts
var folname = document.getElementById('folname').value;
formData.append('folname',folname);
formData.append('_token', $('input[name="_token"]').val() );
});
any advice is appreciated. thanks guys.
Plain old inline javascript variable perhaps? Placed before all scripts possibly at the head
var csrf_token = "{{ csrf_token() }}";
...
// js file where dz related code is residing
...
myDropzone.on("sending", function(file,xhr,formData) {
// Show the total progress bar when upload
var folname = document.getElementById('folname').value;
formData.append('folname',folname);
formData.append('_token', csrf_token);
});
Guys thank you for leading me to the right path. I found the problem, I have two elements with "_token" name. so when debugging it returns 'undefined' error.
this code now works.
var token = document.getElementsByName("_token")[0].value;
my csrf token declaration is like this
<form name="post_form" id="post_form" class="form-horizontal" role="form" method="POST" action="/post">
{!! csrf_field() !!}
<!-- other code input boxes -->
</form>
<!--my dropzone code is below the form-->
<script>
// dropzone code here
</script>
the solution is either I use the token in my meta tag to my dropzone submission or change the name of the meta tag name from "_token" to something else.
so for this, I choose to use the meta tag to my dropzone code and it's now working. please see below for the solution.
I added a meta tag in my header with "_token" name.
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="_token" content="{!! csrf_token() !!}"/>
</head>
and in my footer
<script type="text/javascript">
$.ajaxSetup({
headers: { 'X-CSRF-Token' : $('meta[name=_token]').attr('content') }
});
</script>
</body>
</html>
I have use the meta tag token value instead. here's what I did.
myDropzone.on("sending", function(file,xhr,formData) {
// Show the total progress bar when upload starts
var folname = document.getElementById('folname').value;
var token1 = document.getElementsByTagName('meta')['_token_'].getAttribute('content');
formData.append('folname',folname);
formData.append('_token', token1 );
});
let me know if I should add anything else to make the post more useful.
There are two ways to solve it.
--- FIRST (easiest) ---
<form method="POST" action="/your/url/here" class="dropzone" id="upload-files" enctype="multipart/form-data">
{{ csrf_field() }}
{{ method_field('POST') }}
</form>
<script>
$(function() {
Dropzone.options.uploadFiles = {
paramName: 'document_files',
maxFilesize: 3,
init : function() {
this.on("success", function(file, response) {
// file uploaded successfully
});
}
};
});
</script>
--- SECOND ---
Using dropzone in this way, you can place your dropzone inside another form.
<div class="dropzone dropzone-previews" id="dropzone-upload-documents"></div>
<script>
$(function() {
// in this case is important that autoDiscover = false
Dropzone.autoDiscover = false;
$("#dropzone-upload-documents").dropzone({
paramName: 'document_files',
maxFilesize: 3,
url: "/your/url/here",
init: function() {
this.on("success", function(file, response) {
// file uploaded successfully
});
},
sending: function(file, xhr, formData) {
formData.append("_token", "{{ csrf_token() }}");
formData.append("_method", "POST");
}
});
});
</script>
I have attempted to go about the use of Paypal Lightbox a bit differently.
I have used a button to trigger an ajax call which then generates the PayKey and if all goes well then triggers the form (from the documentation) to be created and submitted.
When i click the button the lightbox html is created but the content is not loaded into it. Instead i get the error:
Load denied by X-Frame-Options: https://www.sandbox.paypal.com/us/cgi-bin/webscr?cmd=_dispatch-failed does not permit cross-origin framing.
My Code:
<head>
<script src="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>
</head>
External Script:
$("#checkout").click(function() {
var id = $(this).data("id");
if(id) { pay(id); }
});
function pay(id) {
$.ajax({
url : 'paypal/Pay-Chained.php',
type : 'POST',
data : "id="+id,
success : function (data) {
var info = (JSON.parse(data));
if (info['Type'] == 'Success') {
var output = info['URL'].substr(0, 64) + "expType=light&" + info['URL'].substr(64);
$("body").append('<form action="'+output+'" target="PPDGFrame" class="standard"><input type="submit" id="submitBtn"></form>');
$("#submitBtn").click();
} else {
alert("Error: Please try again or contact support.");
}
},
error : function () {
alert("Error: Please try again.");
}
});
}
At the bottom of the buttons page:
<script type="text/javascript" charset="utf-8">
var embeddedPPFlow = new PAYPAL.apps.DGFlow({trigger: 'checkout'});
</script>
I am thinking maybe it has to do with the order things are executed but can't seem to figure it out. Any help would be great!
EDIT: I just created a blank page and copied the script from the documentation exactly. I still get the same error. Might it have something to do with server settings? I am running a WampServer with an address like 192.168.1.1/mysite/index.html.