Binding Images to Image placeholder in repeater - nativescript

I have a repeater that loads info from SQLite and works well. The user has options to take photos which are stored both in their photo library and in a temp folder. On reloading the page I need to reload the images to for a sliding gallery of thumbnails under the relevant section in the repeater.
The Image repeater is defined as
<Repeater items="{{ images }}" id="{{ repeaterphotoid }}">
<Repeater.itemTemplate>
<Image src="{{localurl}}" width="75" height="75" visibility="{{photoevidence === 'y' ? 'visible' : 'collapse'}}" />
</Repeater.itemTemplate>
</Repeater>
And my code is
exports.takePic = function(args){
var page = args.object;
camera.requestPermissions().then(
function success(){
var livesite = appSettings.getString("livesite");
var images=[];
var whichcamera = args.object;
var options = {saveToGallery: true, keepAspectRation: true, height: 1024 };
var gallery = args.object.page.getViewById("images-"+whichcamera.id);
var source = new imageSourceModule.ImageSource();
camera.takePicture(options).then(function(imageAsset){
var img = new imageModule.Image();
source.fromAsset(imageAsset).then((imageSource) => {
var auditDB = new sqlite("my.db", function(err, db){
if (err){
alert("Failed to open the database", err);
} else {
var tempfilename = livesite+"-"+whichcamera.qid+"-";
db.all("SELECT filename FROM images WHERE filename LIKE '"+tempfilename+"%'").then(rows =>{
//console.log("Images rows="+rows.length+1);
if (rows.length == 0){
imageCount = 1;
}
else
{
imageCount = rows.length+1;
}
var livesite = appSettings.getString("livesite");
// var path = filesystem.path.join(filesystem.knownFolders.documants().path,"photos")
var folder = filesystem.knownFolders.documents();
var filename = livesite+"-"+whichcamera.qid+"-"+imageCount+".jpg";
var imgPath = filesystem.path.join(folder.path,filename);
var saved = imageSource.saveToFile(imgPath,"jpg");
if (saved){
var livesite = appSettings.getString("livesite");
var liveaudit = appSettings.getString("liveaudit");
db.execSQL("INSERT INTO images (localurl,remoteurl,syncd,siteid,filename,question) VALUES(?,?,?,?,?,?)",[imgPath,'-','n',livesite,filename,whichcamera.qid])
var imageList = [];
var tempfilename = livesite+"-"+whichcamera.qid+"-";
var imageSQL = "SELECT localurl,remoteurl,filename FROM images WHERE filename LIKE '"+tempfilename+"%'";
db.all(imageSQL).then(rows =>{
for (var row in rows) {
imageList.push({
localurl: rows[row][0],
filename: rows[row][2]
});
}
const imagesource = fromObject({
images: imageList
});
imagesource.set = ("images", imageList);
var imageholder = args.object.page.getViewById("repeat_"+whichcamera.id);
imageholder.bindingContext = imagesource;
});
};
});
};
});
});
}).catch(function (err) {
alert("Camera Error "+err.message);
})
//alert("Taking Pic with camera "+whichcamera.id);
},
function failure(){
alert("You must allow this app access to the camera and your photos library.")
});
}
Binding to the questions works as expected but I cannot bind the images to the image repeater, nothing happens. Obviously missing something but going code blind.

Related

How can I get the signature from Vue Signature Pad + Laravel

Hi I have read but I have not found the answer so I ask:
How can I get the signature picture?
My Vuejs code is this one:
<VueSignaturePad width="100%" height="500px" ref="signaturePad" />
<div>
<button #click="save">Guardar</button>
<button #click="undo">Borrar</button>
</div>
My methods are:
undo() {
this.$refs.signaturePad.undoSignature();
},
save() {
this.loading = true;
e.preventDefault();
let currentObj = this;
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
let formData = new FormData();
formData.append('signature', this.$refs.signaturePad.saveSignature());
axios.post('/api/signature/store?api_token='+App.apiToken, formData, config)
.then(function (response) {
currentObj.success = response.data.success;
})
}
My Laravel code has this:
$fileName = time().'_'.'signature'.'_'.$this->user->rut.'_'.date('d_m_Y').'.'.$request->file->getClientOriginalExtension();
$signature = new Signature;
$signature->rut = $this->user->rut;
$signature->signature = $fileName;
$signature->save();
Storage::disk('dropbox')->putFileAs(
'signatures/',
$request->file,
$fileName
);
The problem is that it displays me an error:
Call to a member function getClientOriginalExtension() on null
So I wonder how can I get the image?
this option worked for me to convert the base64 file to image before sending it
Vue code
<div id="app">
<vueSignature ref="signature" :sigOption="option" :w="'800px'" :h="'400px'" :disabled="disabled"></vueSignature>
<vueSignature ref="signature1" :sigOption="option"></vueSignature>
<button #click="save">Save</button>
<button #click="clear">Clear</button>
<button #click="handleDisabled">disabled</button>
</div>
functions
save(){
var _this = this;
var png = _this.$refs.signature.save()
var block = png.split(";");
// Get the content type of the image
var contentType = block[0].split(":")[1];// In this case "image/gif"
// get the real base64 content of the file
var realData = block[1].split(",")[1];// In this case "R0lGODlhPQBEAPeoAJosM...."
// Convert it to a blob to upload
var blob = this.b64toBlob(realData, contentType);
let data = new FormData()
data.append('img', blob)
axios.post(this.url, data).then(res=>{
console.log(res.data)
}).catch(function (error) {
console.log(error.response)
})
},
b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
},
I hope I've helped

How to save video to Laravel storage folder on Tinymce

I'd like to save the video I uploaded in the Laravel storage folder, but for now I'm only able to save this away:
<p><video controls="controls" width="300" height="150">
<source src="data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGl</video></p>
I would like the url to be
`storage/video-name
.
My current code is this:
file_picker_types: 'media',
file_picker_callback: function(cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
var id = 'blobid' + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(',')[1];
var blobInfo = blobCache.create(id, file, base64);
blobCache.add(blobInfo);
cb(blobInfo.blobUri(), { title: file.name }); // here
};
reader.readAsDataURL(file);
};
input.click(); //here
},
How could I adapt my code so that I can save it in Laravel storage folder?
Laravel version: 8
Tinymce: 5

Ckeditor scrollbar marker / Text Position Indicator

I would like to implement scrollbar marker into ckeditor and i can't seem to find the right way to do it i have triyed this code
var win = new CKEDITOR.dom.window( window );
var pos = win.getScrollPosition();
console.log(pos);
but it only return the google chrome scrollbar x=0 & Y=0
var win = new CKEDITOR.dom.window( domWindow );
var pos = win.getScrollPosition();
console.log(pos);
and this give me an error domWindow is not defined
i found this example it may help: https://codepen.io/Rplus/pen/mEjWJm
(() => {
var containerQS = '.article';
var container = document.querySelector(containerQS);
var form = document.querySelector('.form');
var input = form.querySelector('input[type="text"]');
var markClass = 'mark';
var markerHeight = '2px';
var _color = 'currentColor';
var containerY = container.offsetTop;
var containerH = container.scrollHeight;
var customStyle = document.createElement('style');
container.appendChild(customStyle);
var renderScrollMarker = ($parent, posArr) => {
var _posArr = posArr.map(i => {
return `transparent ${i}, ${_color} ${i}, ${_color} calc(${i} +
${markerHeight}), transparent calc(${i} + ${markerHeight})`;
});
customStyle.innerHTML = `article::-webkit-scrollbar-track {
background-image: linear-gradient(${_posArr.join()});
}`;
};
var calcEleRelativePos = ($ele) => {
return ($ele.offsetTop - containerY) / containerH;
};
var markOpt = {
className: markClass,
done: function () {
var marks = document.querySelectorAll(`.${markClass}`);
var allY = [].map.call(marks, (mark) => {
return (calcEleRelativePos(mark) * 100).toFixed(2) + '%';
});
renderScrollMarker(container, allY);
console.log(allY);
}
};
var instance = new Mark(container);
form.addEventListener('submit', (e) => {
e.preventDefault();
var _text = input.value.trim();
console.log(_text, form.oldText);
if (_text === '') {
instance.unmark(markOpt);
return;
}
form.oldText = _text;
instance.unmark().mark(_text, markOpt);
});
// trigger
form.querySelector('input[type="submit"]').click();
})();
but as ckeditor secures a lot of element, i would love to know if any one has done this before with CKeditor
i just got the real editor scrollbar position, i only need to put a marker using style or any availble methode
var win=CKEDITOR.instances.editor1.document.getWindow();
var pos = win.getScrollPosition().y;
console.log(pos);
this worked for me :
var jqDocument = $(editor.document.$);
var documentHeight = jqDocument.height();
var scrollTo =jqDocument.scrollTop();
var docHeight = jqDocument.height();
var scrollPercent = (scroll)/(docHeight);
var scrollPercentRounded = Math.round(scrollPercent*100);
$(".ui-slider-handle").css("bottom", 100-scrollPercentRounded+"%");

Cant reading from file in nativescrypt

I trying write some strings in file and then read them, but having error message Cannot access a locked file. Tested on iphone and android.
page.xml
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded" actionBarHidden="true">
<StackLayout>
<Label text="Tap the button" id="label"/>
<Button text="TAP" id="btn" />
</StackLayout>
</Page>
page.js
var frameModule = require("ui/frame");
var view = require("ui/core/view");
var dialogs = require("ui/dialogs");
var fs = require("file-system");
function pageLoaded(args) {
var page = args.object;
var button = view.getViewById(page, "btn");
var label = view.getViewById(page, "label");
button.on("tap", function (){
var documents = fs.knownFolders.documents();
var myFile = documents.getFile("Test_Write.txt");
myFile.writeText("Something")
.then(function () {
myFile.readText()
.then(function (content) {
label.text = content;
}, function (error) {
label.text = error;
});
}, function (error) {
label.text = error;
});
});
}
exports.pageLoaded = pageLoaded;
The write methods lock but never unlock the file.
This has been addressed with the following pull request.

html2canvas is not highlighting the highlighted circles

http://4axiz.com/canadian_crime/
in this link, if i select any circle, and then save that state, in the exported image, the highlighted circle is not showing, this is showing the whole svg. Probably html2canvas can't use any css.
To save i used this way:
var xmlString = "";
var urlParam = "";
function save_state() {
var filters = [];
for (var i = 0; i < dc.chartRegistry.list().length; i++) {
var chart = dc.chartRegistry.list()[i];
for (var j = 0; j < chart.filters().length; j++) {
filters.push({ChartID: chart.chartID(), Filter: chart.filters()[j]});
}
}
urlParam = encodeURIComponent(JSON.stringify(filters));
var svgElements = $("#svgContainer").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function () {
var canvas, xml;
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
// this.className s(= "tempHide";
$(this).attr("class", "tempHide");
$(this).hide();
});
$.ajaxSetup({async: false});
html2canvas($('#svgContainer'), {
onrendered: function (canvas) {
var imgString = canvas.toDataURL("image/png");
allowTaint: true
var postdata = {'state': urlParam, 'image': imgString}
var url = '<?php echo site_url("crime/save_crime_state")?>';
$.post(url, postdata, function (data) {
if (data.status == "success") {
$("#svgContainer").find('.screenShotTempCanvas').remove();
$("#svgContainer").find('.tempHide').show().removeClass('tempHide');
var myImage = $('<img/>');
myImage.attr('class', "groupMediaPhoto");
myImage.attr('src', data.filepath);
myImage.bind('click', function(){
load_state(urlParam);
});
myImage.appendTo($('.sidecontainer'));
// $(".sidecontainer").append(str);
}
}, "json");
}
});
$.ajaxSetup({async: true});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Resources