upload multi images from different inputs - image

I want user to be able to change his logo image + home profile image each with different input but when ever I change one of them both changed this is my upload function
handleFileUpload( e ) {
e.preventDefault();
if (!e.target.files.length > 0)//user canceled selecting a file
return
var reader = new FileReader();
var file = e.target.files[0];
reader.onloadend = ( ) => {
this.setState({
imgUrl: reader.result,
homeImgUrl: reader.result,
});
}
reader.readAsDataURL(file)
}

You are getting images from different inputs but setting the same file to both your state values. Instead of this set your state dynamically based on your input name. I'm not accustomed to FileReader but setting state would be like this:
handeFileChange = ( e ) => {
........
this.setState( { [ e.target.name ]: e.target.files[ 0 ] } );
.......
}
Input names must match with your state names. This handles file change, then you can use a file upload method. If you want to upload files directly with change, you can use one method for that of course.

Related

CKEditor5: How to create model element value from data attribute?

I have legacy html data that I'm trying to edit with CKEditor5. The data format is:
<my-data-element url="https://something.com/more/stuff"></my-data-element>
The desired model format is
<my-model-element>
https://something.com/more/stuff
</my-model-element>
where the url attribute in the data is now the text of the model element. my-model-element is an editable widget so the user can easily modify the existing URL, copy/paste/etc. When the model is convert to data, the text in my_model-element should be converted to the url value for my-data-element. Reading the value of the url attribute is relatively easy, but I can't figure out how to set the text of the my-model-element. While this looks similar to a link, it's not a link. I considered borrowing from the link editing code, but that's a lot of code and this should be a root level object.
For data down casting, extracting the value of the element to set as the url is easy. The code below leaves the text of my-model-element in my-data-element but I can deal with that for now. It also results in my-data-element having the attribute undefined="undefined", for some reason, but I can also live with that.
schema.register( 'my-model-element', {
isObject: true,
allowWhere: '$block',
allowAttributes: ['url'],
allowContentOf: '$block'
} );
conversion.for( 'dataDowncast' ).elementToElement( {
model: 'myElement',
view: ( modelItem, {writer: viewWriter } ) => {
const data = modelItem.getChild(0).data;
const elem = viewWriter.createContainerElement (
'my-data-element', { url: data }
);
return elem;
}
} );
conversion.for( 'dataDowncast' ).attributeToAttribute( {
model: 'url',
// view has to be a function or the url doesn't get updated
view: () => 'url',
});
For up casting I can get the url from my-data-element, but have not been successful setting the text of my-model-element. Instead, the text value of my-model-element remains empty.
conversion.for( 'upcast' ).elementToElement( {
model: ( viewElement, {writer: modelWriter }) => {
// Pulling the URL works
const url = viewElement.getAttribute('url');
// But creating the child of the new element doesn't
const text = modelWriter.createText(`${url} DOESNT WORK`);
const elem = modelWriter.createElement('my-model-element', {}, text);
return elem;
},
view: {
name: 'my-data-element',
}
} );
I've read the majority of the CKEditor5 documentation on up and down casting, and the tutorials on block, inline, and data driven widgets.

Storybook problem while migrating argument of type object from addon-knobs to addon-controls

I'm having some trouble migrating one thing from the old addon-knobs to the new controls. Let me explain, maybe it's not such difficult task but I'm blocked at the moment.
I'm using StencilJS to generate Web Components and I have a custom select component that accepts a options prop, this is an array of objects (the options of the select)
So, the story for this component in the previous version of Storybook looks something like this:
export const SelectWithArray = () => {
const selectElement = document.createElement('my-select');
selectElement.name = name;
selectElement.options = object('Options', options);
selectElement.disabled = boolean('Disabled', false);
selectElement.label = text('Label', 'Label');
return selectElement;
};
This works fine, the select component receives the options property correctly as an array of objects.
Now, migrating this to the new Storybook version without addon-knobs, the story is looking like this:
const TemplateWithArray: Story<ISelect> = (args) => {
return `
<my-select
label="${args.label}"
disabled="${args.disabled}"
options="${args.options}"
>
</my-select>
`;
};
export const SelectWithArray: Story<ISelect> = TemplateWithArray.bind({});
SelectWithArray.argTypes = {
options: {
name: 'Options',
control: { type: 'object' },
}
}
SelectWithArray.args = {
options: [
{ text: 'Option 1', value: 1 },
]
}
And with this new method, the component is not able to receive the property as expected.
I believe the problem is that now, the arguments is being set directly on the HTML (which would only be accepting strings) and before it was being set on the JS part, so you could set attributes other than strings.
Is there a way to achieve this? without having to send the arguments as a string.
Thanks a lot!!
One way I've discovered so far is to bind the object after the canvas has loaded via the .play function;
codeFullArgs.play = async () => {
const component = document.getElementsByTagName('your-components-tag')[0];
component.jobData = FullArgs.args.jobData;
}

Google script spreadsheet - I need to run one script from multiple buttons but with different parameters

I have two buttons (Button1 and Button2) and one function: MyFunction(number). And I either need to pass a parameter to the function or find out what button the function was started from. Is it possible?
function MakePDF(number) {
var ui = SpreadsheetApp.getUi();
//Get Active Spreadsheet
var spreadSheet=SpreadsheetApp.getActiveSpreadsheet();
spreadSheet.getRange('B2').setValue(number); //HERE I NEED TO GET THE SPECIFIC NUMBER FROM 1 TO 100
//Get Sheet to print of the spreadsheets
var sheets=spreadSheet.getSheets();
var Faktura = spreadSheet.getSheetByName("Invoice");
var sheetID = Faktura.getSheetId();
//Export URL with Parameters
var spreadSheetId = spreadSheet.getId();
var URL = "https://docs.google.com/spreadsheets/d/"+spreadSheetId+"/export"+
"?format=pdf&"+
"size=7&"+
"fzr=false&"+
"portrait=true&"+
"fitw=true&"+
"gridlines=false&"+
"printtitle=false&"+
"sheetnames=false&"+
"pagenum=UNDEFINED&"+
"attachment=true&"+
"gid="+sheetID;
//the HTTP method for the request: get and headers : authorization : Bearer tokens to access OAuth 2.0-protected resources
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
//Return the data inside this object as a blob.
var response=UrlFetchApp.fetch(URL,params).getBlob();
//To set name of file
var VS = listOvladani.getRange('B6').getValue();
var firma = listOvladani.getRange('B5').getValue();
firma = removeDiak(firma);
firma = firma.toString().replace(/ /g, '-');
firma = firma.toString().replace(/\./g,'');
firma = firma.toString().replace(/,/g,'');
var namePDF = VS + "_" + firma + "_Autonapul.pdf";
// Load it to specific directory
var dir = DriveApp.getFoldersByName("Rucnifaktury").next();
var pdfFile = dir.createFile(response).setName(namePDF);
// Display a modal dialog box with custom HtmlService content.
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open ' + spreadSheet.getName() + '</p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful');
//Email it
/* MailApp.sendEmail('trnka#trnka.cz', 'Pokus', 'Nějaký text', {
attachments: [{
fileName: "Faktura_pokusna" + ".pdf",
content: response.getBytes(),
mimeType: "application/pdf"
}]
});
*/
}
More details More details More details More details More details More details More details More details More details More details More details More details
You can do it in a different way:
Replace buttons through checkboxes and bind to your script an onEdit(e) trigger which will automatically fire the script on each edit.
You can implement a statement to verify either the edited column was your checkbox column and if so - which checkbox has been checked.
Sample:
function onEdit(e) {
if(e.range.getColumn()==2&&e.range.getValue()==true){
Logger.log(e.range.getA1Notation());
}
}
References:
Event objects
getValue()
getColumn
A1 notation
You can use two more functions who just call the main function with a different parameter, so button 1 calls pressButton1 and button 2 calls pressButton2.
function MakePDF(number) {
//do stuff
}
function pressButton1(){
MakePDF(1);
}
function pressButton2(){
MakePDF(2);
}
This is the easiest way to handle the situation.

How to get file name before upload using CodeIgniter

I want to upload files to my server with CodeIgniter, and I need to change the file name dynamically with some random numbers.
But before changing the name I also need the original name to store it in the database. How can I do that?
Depending on which browsers you support you can use some of the functional extensions to the array prototype. Namely filter and every.
var arr = [[1,null,null],[1,null,null],[1,5,2],[null,null,null],[null,1,null],[1,2,3]];
var filtered = arr.filter(function(x){
return x.every(function(value){
return value != undefined;
});
});
console.log(filtered);
Just add these arrays to new one:
$newArray = [
$oldArray[4],
$oldArray[5],
$oldArray[7],
$oldArray[8],
$oldArray[10],
$oldArray[11],
];
EDIT
for dynamic, use something like that (not tested):
var newArray = [];
var oldArray = [/* ... */];
function addElement(eId){
newArray.push(oldArray[eId]);
}
$.each(SomeRandomArrayIndexes, function(k, eId){
addElement(eId);
});

Uploading images with redactor to MVC

This might be a bit too specific for here and I may need to contact redactor support but i've seen other questions about redactor here so i figured i'd give it a shot ...
Ok ...
So i'm trying to get get image uploading to work following the example here ...
http://imperavi.com/redactor/docs/images/
My client side code ...
$("textarea").redactor({
focus: true,
imageUpload: '/MyController/UploadImage'
});
My MVC controller action looks like this ...
public JsonResult UploadImage(object image)
{
// Do something with whatever that was i got from redactor
var result = new { filelink = "" };
return Json(result);
}
The problem is ... what did redactor actually give me?
Was it the whole file? a chunk? i can't seem to tell because the object has no type information at all and the raw post information seems way too little to actually be a whole image file.
Has anyone had any experience with this / actually done it before?
I don't really want to setup php on my server for this 1 function.
EDIT:
Ok a bit more digging reveals that if i pull the underlying Request object it has a files property which apparently contains my posted image file.
I think i might be able to figure it out from here.
Where I get a code block in place i'll post it as an answer.
You are receiving a HttpPostedFileBase object. Here is my implementation:
jQuery:
$('#blog-post').redactor(
{
imageUpload: '/blog/images/',
imageGetJson: '/images/locations/blogs/'
});
Then in the controller:
public ActionResult Images(HttpPostedFileBase file)
{
// Verify that the user selected a file
if( file != null && file.ContentLength > 0 )
{
// extract only the fielname
var fileName = Path.GetFileName( file.FileName );
// store the file
var path = Path.Combine( ImageLocation.BlogPicturePath, fileName );
file.SaveAs( path );
}
return Json( new { filelink = ImageLocation.BlogPictureUrl + "/" + file.FileName } );
}
ok um ... i think im there ...
This needs a bit of cleaning up and I don't expect you guys to understand what goes on under the bonnet of my custom DMS code but just assume it takes the stream and returns a FileInfo object and in theory this should work for you too ...
public ActionResult Upload()
{
// this object is specific to my system but all it does is
// stream the file to a path on the server (code not needed for this Q)
var dmsService = _kernel.Get<IDMSFileSystemService>();
List<FileInfo> savedFiles = new List<FileInfo>();
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
using (file.InputStream)
{
savedFiles.Add(dmsService.AddFromStream(file.InputStream, file.FileName);
}
}
var result = savedFiles.Select(f => new { filelink = f.Path}).ToArray();
return Json(result);
}
Suprisingly simple right ... :)

Resources