I have a file that's called camera.php, here is the source bellow :
camera.php
<div id="video" style="margin: auto;text-align:center;">
<video autoplay id="vid"></video>
</div>
<button id="start" class="btn" onclick="Start()">Start</button>
<button id="stop" class="btn" onclick="Stop()">Stop</button>
<button id="takeshot" class="btn" onclick="TakeShot()">TakeShot</button>
<canvas id="canvas" width="640" height="480"></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
video = document.getElementById('vid');
function Start() {
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({video : true}).then((stream) => {
video.srcObject = stream;
});
}
else
console.log('ur navigator does not support getUserMedia !!');
}
function Stop() {
if (video.srcObject)
video.srcObject = undefined;
}
function TakeShot() {
if (video.srcObject) {
canvas = document.getElementById('canvas');
gtc = canvas.getContext('2d');
gtc.drawImage(video, 0, 0);
imgData = canvas.toDataURL('image/png');
//gtc.clearRect(0, 0, canvas.width, canvas.height);
pb = document.getElementById('pb').value;
pub(imgData, pb);
}
else
console.log('you need to use Webcam to take a shot');
}
function pub(img, pb) {
// using jquery.post() to send request
$.post('https://xxxxxx.com/camera/save', {'img' : img, 'pub' : pb, 'stick' : stickSelectd}, (result) => {
obj = JSON.parse(result);
if (obj.error == true) {
document.getElementById('msg').innerHTML = obj.msg;
}
else
document.getElementById('msg').innerHTML = 'Publication has been added';
}).done(() => {
alert('request is done');
}).fail(() => {
alert('request is fail');
});
// using jquery.ajax() to send post request
$.ajax({
url : 'https://xxxxxx.com/camera/save',
method : 'POST',
data : {
'img' : img, 'pub' : pb, 'stick' : stickSelectd
},
headers : "Content-type : image/png",
Success : (result) => {
alert(result);
},
err : () => {
alert('error');
}
});
}
</script>
.htaccess
I know too many risks for allow-origin "*" but i use it just for testing.
Header Set Access-Control-Allow-Origin "*"
always request sending by $.post() alert 'request is fail' and sometimes the request is received from the server and save the image but the meme respond is getting ('request is fail').
there is all fine in my code or i miss something like headers, .. ??
and thanks for helping
it works now with ajax(), i change the function pub to :
function pub(img, pb) {
$.ajax({
url : 'https://xxxxxxxx.com/camera/save',
method : 'POST',
data : {
'img' : img, 'pub' : pb, 'stick' : stickSelectd
},
headers : "Content-type : image/png"
}).done((result) => {
obj = JSON.parse(result);
if (obj.error == true) {
document.getElementById('msg').innerHTML = obj.msg;
}
else
document.getElementById('msg').innerHTML = 'Publication has been added';
}).fail(() => {
document.getElementById('msg').innerHTML = 'something wrong !! try again';
})
}
i don't know why the old syntax doesn't work, I think it fine ?!
Related
I am using stripo HTML editor and i have completed my installation process, but now i just want to save the whole form in form of html in my react code not in any external file. I could not find any solutuon online or anything in their documentation regarding this. I also want to add preview and export option in the header as well as the whole header in their demo.
Here's my code till now.
This is my result of my existing code
What i want is given below
This is the result i want. I want to access all the possible header options given. Also a button by which i can get the html of the above image that i have posted
Below is my code
import "./App.css";
var notifications = {
autoCloseTimeout: 4000,
container: ".notification-zone",
error: function (text, id, params) {
this.showNotification(
this.getErrorNotification.bind(this),
text,
id,
params
);
},
warn: function (text, id, params) {
this.showNotification(
this.getWarningNotification.bind(this),
text,
id,
params
);
},
info: function (text, id, params) {
this.showNotification(
this.getInfoNotification.bind(this),
text,
id,
params
);
},
success: function (text, id, params) {
this.showNotification(
this.getSuccessNotification.bind(this),
text,
id,
params
);
},
loader: function (text, id, params) {
this.showNotification(
this.getLoaderNotification.bind(this),
text,
id,
params
);
},
hide: function (id) {
// var toast = `$('#' + id, this.container);
// toast.effect('fade', 600, function () {
// toast.remove()
// })`;
},
showNotification: function (notificationGetter, text, id, params) {
params = Object.assign({ autoClose: true, closeable: true }, params || {});
if (!id || !`$('#' + id).length`) {
var toast = notificationGetter(text, id, !params.closeable);
this.container.append(toast);
toast.effect("slide", { direction: "down" }, 300);
if (params.autoClose) {
setTimeout(function () {
toast.effect("fade", 600, function () {
toast.remove();
});
}, this.autoCloseTimeout);
}
}
},
getErrorNotification: function (text, id, nonclosable) {
return this.getNotificationTemplate("alert-danger", text, id, nonclosable);
},
getWarningNotification: function (text, id, nonclosable) {
return this.getNotificationTemplate("alert-warning", text, id, nonclosable);
},
getInfoNotification: function (text, id, nonclosable) {
return this.getNotificationTemplate("alert-info", text, id, nonclosable);
},
getSuccessNotification: function (text, id, nonclosable) {
return this.getNotificationTemplate("alert-success", text, id, nonclosable);
},
getLoaderNotification: function (text, id) {
var notification = `$('\
<div class="alert alert-info" role="alert">\
<div style="width:auto; margin-right: 15px; float: left !important;">\
<div style="width:20px;height:20px;border-radius:50%;box-shadow:1px 1px 0px #31708f;\
animation:cssload-spin 690ms infinite linear"></div>\
</div>' + text + '\
</div>')`;
id && notification.attr("id", id);
return notification;
},
getNotificationTemplate: function (classes, text, id, nonclosable) {
var notification = `$('\
<div class="alert alert-dismissible ' + classes + (nonclosable ? ' nonclosable' : '') + '" role="alert">\
' + (nonclosable ? '' :
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">\
<span aria-hidden="true">×</span>\
</button>') +
text +
'</div>')`;
id && notification.attr("id", id);
return notification;
},
};
export default function App() {
function request(method, url, data, callback) {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState === 4 && req.status === 200) {
callback(req.responseText);
} else if (req.readyState === 4 && req.status !== 200) {
console.error(
"Can not complete request. Please check you entered a valid PLUGIN_ID and SECRET_KEY values"
);
}
};
req.open(method, url, true);
if (method !== "GET") {
req.setRequestHeader("content-type", "application/json");
}
req.send(data);
}
function loadDemoTemplate(callback) {
request(
"GET",
"https://raw.githubusercontent.com/ardas/stripo-plugin/master/Public-Templates/Basic-Templates/Trigger%20newsletter%20mockup/Trigger%20newsletter%20mockup.html",
null,
function (html) {
request(
"GET",
"https://raw.githubusercontent.com/ardas/stripo-plugin/master/Public-Templates/Basic-Templates/Trigger%20newsletter%20mockup/Trigger%20newsletter%20mockup.css",
null,
function (css) {
callback({ html: html, css: css });
}
);
}
);
}
useEffect(() => {
function initPlugin(template) {
const apiRequestData = {
emailId: "rhuzaifa2468#gmail.com",
};
const script = document.createElement("script");
script.id = "stripoScript";
script.type = "text/javascript";
script.src = "https://plugins.stripo.email/static/latest/stripo.js";
script.onload = function () {
window.Stripo.init({
settingsId: "stripoSettingsContainer",
previewId: "stripoPreviewContainer",
codeEditorButtonId: "codeEditor",
undoButtonId: "undoButton",
redoButtonId: "redoButton",
locale: "en",
html: template.html,
css: template.css,
notifications: {
info: notifications.info.bind(notifications),
error: notifications.error.bind(notifications),
warn: notifications.warn.bind(notifications),
loader: notifications.loader.bind(notifications),
hide: notifications.hide.bind(notifications),
success: notifications.success.bind(notifications),
},
apiRequestData: apiRequestData,
userFullName: "Plugin Demo User",
versionHistory: {
changeHistoryLinkId: "changeHistoryLink",
onInitialized: function (lastChangeIndoText) {
"#changeHistoryContainer".show();
},
},
getAuthToken: function (callback) {
request(
"POST",
"https://plugins.stripo.email/api/v1/auth",
JSON.stringify({
pluginId: "53c40f7b8d8c4b249b55b39ea9cda545",
secretKey: "e37d5bedd3c64055b3d18b3ff40c4e84",
}),
function (data) {
callback(JSON.parse(data).token);
}
);
},
});
};
document.body.appendChild(script);
}
loadDemoTemplate(initPlugin);
}, []);
return (
<div className="App">
<span id="changeHistoryContainer" style={{ display: "none" }}>
Last change: <a id="changeHistoryLink"></a>
</span>
<button id="undoButton" className="control-button">
Undo
</button>
<button id="redoButton" className="control-button">
Redo
</button>
<button id="codeEditor" className="control-button">
Code editor
</button>
<div id="stripoSettingsContainer"></div>
<div id="stripoPreviewContainer"></div>
</div>
);
}``
`
I want to do this after the user registers, shows a successful message and the text boxes are empty again and ready for the next registration, but the registration success message is only displayed for the first registration, but I want to Display each registration
public IActionResult submitSingelControlItem(int Projectid,String calender, String ProjectName,String ProjectManagementName, String ajaxControlItem,String ajaxFraindName,int SingelControlState)
{
Hesabrsee hesabrsee = new Hesabrsee();
hesabrsee.ControlDate = ConvertDateTime.ConvertShamsiToMiladi(calender);
hesabrsee.SabtDate = DateTime.Now;
hesabrsee.Projectid = Projectid;
hesabrsee.ProjectName = ProjectName;
hesabrsee.ProjectManagementName = ProjectManagementName;
hesabrsee.FaraindName = ajaxFraindName;
hesabrsee.Deiscreption = ajaxControlItem;
hesabrsee.ControlState = SingelControlState;
_context.Add(hesabrsee);
_context.SaveChanges();
return Json(new { status = "ok" });
}
<script>
$("#btn").on('click', function () {
var ajaxFraindName = $("#ajaxFraindName").val();
var ajaxControlItem = $("#ajaxControlItem").val();
var calender = $("#calender").val();
var SingelControlState = $("#SingelControlState").val();
if (ajaxFraindName == '' || ajaxControlItem == '' || calender == '' || SingelControlState == '') {
alert("لطفا ورودی ها را پر کنید");
}
else {
$.ajax({
type: "Post",
url: '#Url.Action("submitSingelControlItem", "Hasabrsee")',
data: {
'ajaxControlItem': $("#ajaxControlItem").val(),
'ajaxFraindName': $("#ajaxFraindName").val(),
'Projectid': $("#Projectid").val(),
'ProjectName': $("#ProjectName").val(),
'ProjectManagementName': $("#ProjectManagementName").val(),
'calender': $("#calender").val(),
'SingelControlState': $("#SingelControlState").val(),
}
}).done(function (res) {
if (res.status == 'ok') {
$("#ohsnap").removeClass('d-none').removeClass('alert-danger').addClass('alert-success').html('مورد کنترلی با موفقیت ثبت شد');
$("#ajaxControlItem").val("");
$("#ajaxFraindName").val("");
}
setTimeout(function () {
$('#ohsnap').fadeOut('fast');
}, 2000)
});
}
});
</script>
<div id="ohsnap" class="col-md-4 col-xs-12 alert d-none" style="text-align:center;"></div>
Of course, it displays the message only once because you are removing the class from the $("#ohsnap") div and then you are not restoring it.
Try using Toastr to display the popup alert. It is easier to do.
From the Toastr documentation:
Download the CSS and JS files and add them to your project.
Reference the css <link href="toastr.css" rel="stylesheet"/>
Reference the script <script src="toastr.js"></script>
in your .done() function call toastr;
.done(function (res) {
if (res.status == 'ok') {
toastr.success('title-here', 'مورد کنترلی با موفقیت ثبت شد', {
timeOut: 2000,
closeButton: true,
});
$("#ajaxControlItem").val("");
$("#ajaxFraindName").val("");
});
I try to set up plugin ckeditor/ckeditor5-export-pdf on my Laravel App But I cant do this. I still get issues like: Uncaught TypeError: Failed to resolve module specifier "#ckeditor/ckeditor5-export-pdf/src/exportpdf". Relative references must start with either "/", "./", or "../".
I did all steps as in docs: https://ckeditor.com/docs/ckeditor5/latest/features/export-pdf.html#configuration But when I try use import ExportPdf from '#ckeditor/ckeditor5-export-pdf/src/exportpdf'; I get the error like above. Please help. Maybe some have stuck on this issue before
import ExportPdf from '#ckeditor/ckeditor5-export-pdf/src/exportpdf';
console.log(ExportPdf);
$(document).ready(function () {
/*function ExportPdf(editor) {
editor.execute('exportPdf');
}*/
function SimpleUploadAdapter(editor) {
editor.plugins.get('FileRepository').createUploadAdapter = function(loader) {
return {
upload: function() {
return loader.file
.then(function (file) {
return new Promise(function(resolve, reject) {
// Init request
var xhr = new XMLHttpRequest();
xhr.open('POST', '/admin/instructions/ckmedia', true);
xhr.setRequestHeader('x-csrf-token', window._token);
xhr.setRequestHeader('Accept', 'application/json');
xhr.responseType = 'json';
// Init listeners
var genericErrorText = `Couldn't upload file: ${ file.name }.`;
xhr.addEventListener('error', function() { reject(genericErrorText) });
xhr.addEventListener('abort', function() { reject() });
xhr.addEventListener('load', function() {
var response = xhr.response;
if (!response || xhr.status !== 201) {
return reject(response && response.message ? `${genericErrorText}\n${xhr.status} ${response.message}` : `${genericErrorText}\n ${xhr.status} ${xhr.statusText}`);
}
$('form').append('<input type="hidden" name="ck-media[]" value="' + response.id + '">');
resolve({ default: response.url });
});
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
loader.uploadTotal = e.total;
loader.uploaded = e.loaded;
}
});
}
// Send request
var data = new FormData();
data.append('upload', file);
data.append('crud_id', {{ $instruction->id ?? 0 }});
xhr.send(data);
});
})
}
};
}
}
var allEditors = document.querySelectorAll('.ckeditor');
for (var i = 0; i < allEditors.length; ++i) {
ClassicEditor.create(
allEditors[i], {
extraPlugins: [SimpleUploadAdapter, /*ExportPdf*/],
/*toolbar: [
'exportPdf', '|',
],
exportPdf: {
stylesheets: [
'./path/to/fonts.css',
'EDITOR_STYLES',
'./path/to/style.css'
],
fileName: 'my-file.pdf',
converterOptions: {
format: 'A4',
margin_top: '20mm',
margin_bottom: '20mm',
margin_right: '12mm',
margin_left: '12mm',
page_orientation: 'portrait'
}
}*/
}
);
}
});
</script>```
I solved my problem with https://ckeditor.com/ckeditor-5/online-builder/ Builded what I want and setup it on my App
I try to do a single post request to upload multiple files. Now I have a functionally method that works for multiple files. But I want a single request.
submitFile(){
this.contract_file.forEach((file) =>{
let formData = new FormData();
formData.append('file', file.file);
axios.post('contracts/uploadfile/' + this.id_contract,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
}
}
).then(function(){
//
})
.catch(function(){
//
});
})
},
public function uploadFile(Request $request, Contract $contract)
{
$filename = $request->file('file')->getClientOriginalName();
$path = $request->file('file')->store($contract->id,'uploads');
$contractFile = new ContractFile();
$contractFile->fill([
'contract_id' => $contract->id,
'name' => $filename,
'path' => $path,
])->save();
}
Update:
This is what I changed,but..
let formData = []
this.contract_file.forEach((file,index) =>{
formData[index] = new FormData();
formData[index].append('file', file.file);
})
foreach($request->file('file') as $file){
//same code but I use $fille
}
Message:
Missing boundary in multipart/form-data POST data in Unknown
Update2:
<file-upload
class="btn btn-primary"
:multiple="true"
:drop="true"
:drop-directory="true"
v-model="files"
#input-filter="inputFilter"
#input-file="inputFile"
ref="upload">
<i class="fa fa-plus"></i>
Select files
</file-upload>
My answer is not properly tested since I had to adapt my code. Let me know if it doesn't work or if I'm missing something.
Basically, I built my own FormData to be more flexible and easier to reuse.
Form.vue
<template>
<div>
<input #change="upload($event)"
type="file"
name="picture"
id="new-file"
class="custom-file-input"
aria-label="picture"
multiple
>
<label class="custom-file-label" for="new-file">
<span>File...</span>
<span class="btn-primary">Browse</span>
</label>
<button #click="submit" type="button" >Submit</button>
</div>
<template>
<script>
import MyFormData from "./MyFormData";
export default {
data() {
return {
form: new MyFormData({contract_id: 5, files: []})
}
},
methods: {
upload(event) {
for (let file of event.target.files) {
try {
let reader = new FileReader();
reader.readAsDataURL(file); // Not sure if this will work in this context.
this.form.files.push(file);
} catch {}
}
},
submit(){
this.form.post('/my-url')
.catch(errors => {
throw errors;
})
.then((response) => location = response.data.redirect);
}
}
}
</script>
MyFormData.js
export default class MyFormData {
constructor(data, headers) {
// Assign the keys with the current object MyFormData so we can access directly to the data:
// (new FormData({myvalue: "hello"})).myvalue; // returns 'hello'
Object.assign(this, data);
// Preserve the originalData to know which keys we have and/or reset the form
this.originalData = JSON.parse(JSON.stringify(data));
this.form = null;
this.errors = {};
this.submitted = false;
this.headers = headers || {}
}
// https://stackoverflow.com/a/42483509/8068675
// It will build a multi-dimensional Formdata
buildFormData(data, parentKey) {
if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File) && !(data instanceof Blob)) {
Object.keys(data).forEach(key => {
this.buildFormData(data[key], parentKey ? `${parentKey}[${key}]` : key);
});
} else {
const value = data == null ? '' : data;
this.form.append(parentKey, value);
}
}
// Returns all the new / modified data from MyFormData
data() {
return Object.keys(this.originalData).reduce((data, attribute) => {
data[attribute] = this[attribute];
return data;
}, {});
}
post(endpoint) {
return this.submit(endpoint);
}
patch(endpoint) {
return this.submit(endpoint, 'patch');
}
delete(endpoint) {
return axios.delete(endpoint, {}, this.headers)
.catch(this.onFail.bind(this))
.then(this.onSuccess.bind(this));
}
submit(endpoint, requestType = 'post') {
this.form = new FormData();
this.form.append('_method', requestType);
this.buildFormData(this.data());
return axios.post(endpoint, this.form, {
headers: {
'Content-Type': `multipart/form-data; boundary=${this.form._boundary}`,
}
})
.catch(this.onFail.bind(this))
.then(this.onSuccess.bind(this));
}
onSuccess(response) {
this.submitted = true;
this.errors = {};
return response;
}
onFail(error) {
console.log(error);
this.errors = error.response.data.errors;
this.submitted = false;
throw error;
}
reset() {
Object.assign(this, this.originalData);
}
}
Edit Based on your note specifying you're using vue-upload-component
Your submit method should look like this
submitFile(){
let files = this.contract_file.map((obj) => obj.file));
let form = new MyFormData({files: files});
form.post('contracts/uploadfile/' + this.id_contract)
.then(function(){
//
})
.catch(function(){
//
});
},
In your controller
public function uploadFile(Request $request, Contract $contract) {
if($request->hasFile('files')){
$files = $request->file('files');
foreach ($files as $file) {
$filename = $file->getClientOriginalName();
$path = $file->store($contract->id,'uploads');
$contractFile = new ContractFile();
$contractFile->fill([
'contract_id' => $contract->id,
'name' => $filename,
'path' => $path,
])->save();
}
}
}
Adding the boundary to the Content-Type header fixed my problem. You can do it like below. Just change only submitFile() function.
submitFile(){
this.contract_file.forEach((file) =>{
let formData = new FormData();
formData.append('file', file.file);
axios.post('contracts/uploadfile/' + this.id_contract,
formData,
{
headers: {
'Content-Type': 'multipart/form-data;boundary=' + Math.random().toString().substr(2),
}
}
).then(function(){
//
})
.catch(function(){
//
});
})
},
I'm making litte app to get pages by URL and check their title.
I need check URLs line by line which is user pasted in textarea.
Process sequence :
Check URL > append response to page > then check next url......
Here is my code :
HTML :
<textarea id="textarea" name="urlLine"></textarea>
<button type="button" name="action" id="check">Check IT!</button>
Js :
function getResp(req) {
var uri = req.shift();
$.ajax({
type: 'POST',
url: 'r.php',
async: true,
data: {'uriLine': uri},
success: function (msg) {
$('.collection').append(msg);
$('body').animate({
scrollTop: height,
}, 500)
},
fail: function (msg) {
console.log(msg);
}
});
if (typeof uri !== 'undefined' && uri.length > 0) {
setTimeout(getResp, 5, req);
} else {
alert('Finish');
}
}
$(document).ready(function () {
$('#check').click(function () {
var uris= $('textarea').val().split('\n');
getResp(uris);
});
PHP :
sleep(5); // I don't know why i'm adding. Just wait for performance.
$title = 'title_i_searching';
$adress = $_POST['uriLine'];
if($check->chekURL('https://'.$adress) == $title){
echo ' OK';
}else{
echo 'NOT OK';
}
PHP CLASS :
class checkES
{
public $url;
public function chekURL($url){
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
"http"=>array(
"timeout"=> 5
)
);
$str=
file_get_contents($url,false,stream_context_create($arrContextOptions));
if(strlen($str)>0){
$str = trim(preg_replace('/\s+/', ' ', $str));
preg_match("/\<title\>(.*)\<\/title\>/i",$str,$title);
return $title[1];
}
}
public function parseByLine($content){
$lines = preg_split('/\r\n|[\r\n]/', $content);
return $lines;
}
}
But when i run this code for example; in 20 URL searching on 5th url page alert 'finish'. But append function still continue.
Sometimes, page crash down.
I could not find the healthy method.
I wish i was explain. Sorry for bad language.
Try moving the code to process next uri in success function like this:
function getResp(req) {
var uri = req.shift();
$.ajax({
type: 'POST',
url: 'r.php',
async: true,
data: {'uriLine': uri},
success: function (msg) {
$('.collection').append(msg);
$('body').animate({
scrollTop: height,
}, 500);
if (typeof uri !== 'undefined' && uri.length > 0) {
setTimeout(getResp, 5, req);
} else {
alert('Finish');
}
},
fail: function (msg) {
console.log(msg);
}
});
}