How prefill/preload images in uppy.io library - laravel

I have an article post service, which has an upload form with uppy.io
Everything works great, but I need to edit those articles and their linked images.
How can I prefill already uploaded images to the uppy.io DashBoard?
My actual code:
<div class="DashboardContainer"></div>
<!-- AJAX Uploading for Add Post -->
<script src="https://transloadit.edgly.net/releases/uppy/v1.8.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/locales/v1.11.0/es_ES.min.js"></script>
<script>
const uppy = Uppy.Core({
debug: true,
autoProceed: true,
restrictions: {
maxFileSize: 600000,
maxNumberOfFiles: 10,
minNumberOfFiles: 1,
allowedFileTypes: ['.jpg', '.jpeg', '.png', '.gif']
},
locale: Uppy.locales.es_ES
})
.use(Uppy.Dashboard, {
inline: true,
target: '.DashboardContainer',
replaceTargetContent: true,
showProgressDetails: true,
note: 'Sólo imágenes, hasta 10 fotos, de no más de 800kb',
height: 350,
width: '100%',
metaFields: [{
id: 'name',
name: 'Name',
placeholder: 'Nombre del fichero subido'
},
{
id: 'caption',
name: 'Caption',
placeholder: 'Describe la imagen que estás subiendo'
}
],
browserBackButtonClose: true,
plugins: ['Webcam']
})
.use(Uppy.XHRUpload, {
endpoint: "{{ route('save-image-ajax') }}",
formData: true,
fieldName: 'files[]',
headers: {
'X-CSRF-TOKEN': $('meta[name="token"]').attr('content')
},
})
uppy.on('upload-success', (file, response) => {
response.status // HTTP status code
response.body // extracted response data
// do something with file and response
$('<input>', {
type: 'hidden',
name: 'imageID[]',
value: response.body.imageID
}).appendTo("#add");
})
uppy.on('complete', result => {
console.log('successful files:', result.successful)
console.log('failed files:', result.failed)
})
</script>
The form works great for publishing an article, I just want to edit them, even the linked images.

You can prefill images from url (first converting the remote image into blob):
fetch({{your_image_url}})
.then((response) => response.blob())
.then((blob) => {
uppy.addFile({
name: "image.jpg",
type: blob.type,
data: blob
});
});
And then, set the state of the loaded images to "Completed" to avoid Uppy re upload them:
uppy.getFiles().forEach(file => {
uppy.setFileState(file.id, {
progress: { uploadComplete: true, uploadStarted: false }
})
})
Also, the property "autoProceed" must be false in the Uppy object configuration.
Source: https://github.com/transloadit/uppy/issues/1112#issuecomment-432339569

Related

How to sync my Store when I update the bounded record using form (onUpdateClick). I'm using Extjs 7.5 (Sencha CMD)

This is my first time using a javascript framework, I would like to implement MVVM in my EXT JS application and the data is coming from my WEB API (ASP.NET FRAMEWORK).
My problem is that, I don't seem to understand how to fully use viewModel which looks up to my store. I successfully bound my ViewModel in my grid but now I don't know how to update the selected record using a form (modal) and sync my store (send update request through API)
I have a feeling that I'm doing it the wrong way. I don't know how to do this in fiddle so I'll just paste my code here.
Genre.js [Model]
Ext.define('VAM2.model.Genre', {
extend: 'VAM2.model.Base',
alias: 'model.genre',
fields: [
{name: 'GenreId', type: 'int'},
{name: 'Code', type: 'string'},
{name: 'CreatedBy', type: 'string'},
]
});
Genre.js [Store]
Ext.define('VAM2.store.Genre', {
extend: 'Ext.data.Store',
alias: 'store.genre',
model: 'VAM2.model.Genre',
autoLoad: false,
pageSize: 10,
storeId: 'GenreId',
proxy : {
type : 'rest',
actionMethods : {
read : 'GET'
},
cors:true,
url: 'https://localhost:44332/api/Genre/GetGenresExtJs',
api:{
create: 'https://localhost:44332/api/Genre/CreateGenreExtJS',
read: 'https://localhost:44332/api/Genre/GetGenresExtJs',
update: 'https://localhost:44332/api/Genre/EditGenreExtJS',
destroy: 'https://localhost:44332/api/Genre/CreateGenreExtJS'
},
useDefaultXhrHeader: false,
reader: {
type : 'json',
headers: { 'Accept': 'application/json' },
allDataOptions: {
associated: true,
persist: true
},
rootProperty : 'data',
totalProperty: 'total'
},
}
});
GenreViewModel.js - I'm not sure if this is okay but the read is working
Ext.define('VAM2.view.genre.GenreViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.genre',
requires:[
'VAM2.model.Genre'
],
stores: {
myGenres : {
model: 'VAM2.model.Genre',
autoLoad: true,
proxy : {
type : 'rest',
actionMethods : {
read : 'GET'
},
cors:true,
url: 'https://localhost:44332/api/Genre/GetGenresExtJs',
api:{
create: 'https://localhost:44332/api/Genre/CreateGenreExtJS',
read: 'https://localhost:44332/api/Genre/GetGenresExtJs',
update: 'https://localhost:44332/api/Genre/EditGenreExtJS',
destroy: 'https://localhost:44332/api/Genre/CreateGenreExtJS'
},
useDefaultXhrHeader: false,
reader: {
type : 'json',
headers: { 'Accept': 'application/json' },
allDataOptions: {
associated: true,
persist: true
},
rootProperty : 'data',
totalProperty: 'total'
},
}
}
},
data:{
title:'Sample Binding'
},
formulas: {
currentRecord: {
bind: {
bindTo: '{groupGrid.selection}', //--> reference configurated
//--> on the grid view (reference: groupGrid)
deep: true
},
get: function(record) {
return record;
},
set: function(record) {
if (!record.isModel) {
record = this.get('records').getById(record);
}
this.set('currentRecord', record);
}
}
}
});
View -- This is where it gets confusing. I don't know how to put the bounded data from grid to a form modal and then save and sync my store.
Ext.define('VAM2.view.genre.GenreList', {
extend: 'Ext.container.Container',
xtype: 'myGenreList',
requires: [
'VAM2.view.genre.GenreController',
'VAM2.view.genre.GenreViewModel',
'Ext.grid.column.Boolean',
'Ext.form.field.Checkbox',
'Ext.form.field.TextArea',
'Ext.form.field.Text'
],
controller: "genre",
viewModel: {
type: "genre"
},
width:'100%',
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
style: {
backgroundColor: '#f5f5f5'
},
items: [{
xtype: 'grid',
reference: 'groupGrid', //--> used in the viewmodel,
bind: {
title: '{title}',
store: '{myGenres}'
},
columns: [{
text:'GenreIdField',
id:'GenreIdField',
dataIndex:'GenreId',
hidden:true
},{
text: 'Code',
dataIndex: 'Code',
flex:1
}, {
text: 'Created By',
dataIndex: 'CreatedBy',
flex: 1
}],
listeners:{
select:'onGenreSelected_FORMA' //--> I'm thinking this will trigger
//-> a form (modal) containing the data to update
}
}]
});
A fiddle example would be great! Thank you!
Screenshot:
This is where I would like to display form modal that can sync/update my store when I modify some data.
To do store.sync() you need to set values on the record first.
Example is without ViewModel:
https://fiddle.sencha.com/#fiddle/3isg&view/editor
select: function (grid, record) {
console.log(record);
let win = Ext.create("Ext.window.Window", {
title: 'Edit',
modal: true,
autoShow: true,
width: 400,
height: 500,
controller: {},
items: [{
xtype: 'form',
reference: 'form',
fieldLabel: 'name',
items: [{
xtype: 'textfield',
name: 'name'
}]
}],
buttons: [{
text: 'cancel',
handler: function () {
win.close();
}
}, {
text: 'save',
handler: function () {
var values = this.lookupController().lookup('form').getValues();
record.set(values);
grid.getStore().sync({
scope: this,
success: function () {
win.close();
Ext.toast({
html: 'Well done',
align: 't'
});
},
failure: function () {
Ext.toast({
html: 'Problem occurred',
align: 't'
});
}
});
}
}],
listeners: {
afterrender: function () {
this.lookupController().lookup('form').loadRecord(record);
}
}
})
}

Vue table does not show data

I am trying to show data in vue table using api in api url. Basically I am doing a post request in created method that is sending an id to the server and the server is returning data associated with the id. And simply I am using the api that is returning data. Every thing looks okay but data is not showing in vue table.
vue table
`
<vuetable ref="vuetable"
api-url="http://127.0.0.1:8000/api/patient_previous_appointments"
:fields="fields"
pagination-path=""
:per-page="5"
:multi-sort="true"
:sort-order="sortOrder"
:append-params="moreParams"
:data = "data"
#vuetable:pagination-data="onPaginationData"
>
`
data property
`
data () {
return {
data: [],
fields: FieldsDef_previous_appointment,
sortOrder: [],
moreParams: {}
}
}
`
Fields
`
export const FieldsDef_previous_appointment = [
{
name:'date',
title: 'Date',
sortField: 'date',
titleClass: 'center aligned',
dataClass: 'center aligned',
},
{
name:'doctor',
title: '<i class="fa fa-tag"></i> Doctor',
sortField: 'doctor'
},
{
name:'appointed_by',
title: '<i class="fa fa-tag"></i> Appointed By',
sortField: 'appointed_by'
},
{
name: '__slot:actions',
title: 'Actions',
dataClass: 'center aligned'
}
]
`
Created
`
created () {
const tokenData = JSON.parse(window.localStorage.getItem('authUser'))
var pt_id = tokenData.patient_id
this.$http.get(apiDomain + 'api/patient_previous_appointments',
{patientID:
pt_id})
.then(response => {
console.log(response)
}).catch((e) => {
console.log(e)
})
}
`
response
enter image description here

Filepond: Load default image files

I want to use filepond as my product editor.
How to load current images that is stored on the server? So visitor can decide wheter to change the current images or add a new image.
It's like this form:
=> https://stackoverflow.com/users/edit/{your_user_id}
prefill some data if it has been filled before, but shows nothing when its hasnt been filled before.
I'm mentioning this filepond:
=> https://github.com/pqina/filepond
This is my code on how I show a default image.
const inputElement = document.querySelector('#image');
const pond = FilePond.create(inputElement, options);
pond.setOptions({
allowImagePreview: true,
acceptedFileTypes: ['image/*'],
server: {
process: {
url: 'upload.php',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
},
revert: {
url: 'deleteTmpImage.php',
method: 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'_method': 'DELETE',
},
},
load: (uniqueFileId, load) => {
fetch(uniqueFileId)
.then(res => res.blob())
.then(load);
},
},
files: [
{
source: 'https://www.example.com/default_image.jpg',
options: {
type: 'local',
}
},
]
});

Creating a select tag with size>1 CKEDITOR Plugin

My CKEDITOR plugin needs to create <select size="15"><option ...></select>, but the size attribute is not directly supported by the creation mechanism. I have tried various ways of adding the size attribute after creation, but so far no joy. Here is what I have; the select is created but it does not get the size attribute.
CKEDITOR.dialog.add('macrosDialog', function(editor) {
return {
// Basic properties of the dialog window: title, minimum size.
title: 'Cadenza Macros',
resizable: CKEDITOR.DIALOG_RESIZE_BOTH,
minWidth: 400,
minHeight: 200,
// Dialog window contents definition.
contents: [
{
// Definition of the Basic Settings dialog tab (page).
id: 'tab-basic',
label: 'Basic Settings',
// The tab contents.
elements: [
{
type: 'select',
id: 'groups',
name: 'groups',
label: 'Groups',
style: "height: 300",
items: [ [ 'Core Scala' ], [ 'Create Courses with Micronautics Cadenza' ], [ 'Java / Scala Interoperability' ], [ 'Play Framework' ] ],
'default': 'Play Framework'
},
{
// Text input field for the macro title (explanation).
type: 'text',
id: 'macroComment',
label: 'Comment',
validate: CKEDITOR.dialog.validate.notEmpty("Explanation field cannot be empty")
}
]
}
],
onLoad: function(e) {
var groups = editor.document.getElement("groups");
groups.setAttribute("size", 15);
//$("#groups").setAttr("size", 15);
},
onChange: function(e) {
alert('Group: ' + this.getValue());
},
// This method is invoked once a user clicks the OK button, confirming the dialog.
onOk: function() {
// The context of this function is the dialog object itself.
// http://docs.ckeditor.com/#!/api/CKEDITOR.dialog
var dialog = this;
// Creates a new <abbr> element.
var abbr = editor.document.createElement('abbr');
// Set element attribute and text, by getting the defined field values.
abbr.setAttribute('title', dialog.getValueOf('tab-basic', 'title'));
abbr.setText(dialog.getValueOf('tab-basic', 'abbr'));
// Finally, inserts the element at the editor caret position.
editor.insertElement(abbr);
}
};
});
I used the html element to insert whatever I wanted:
contents: [
{
id: 'macrosDialog',
label: 'Basic Settings',
// The tab contents.
elements: [
{
type: 'hbox',
id: 'lists',
//style: "vertical-align: top",
widths: [ '25%', '25%', '25%', '25%' ],
children: [
{
type: 'html',
id: 'groups',
name: 'groups',
html: '<select size="15"></select>'
},{
type: 'html',
id: 'courses',
name: 'courses',
html: '<select size="15"></select>'
},{
type: 'html',
id: 'sections',
name: 'sections',
html: '<select size="15"></select>'
},{
type: 'html',
id: 'lectures',
name: 'lectures',
html: '<select size="15"></select>'
},
],
onLoad: function(data) {
var dialog = this.getDialog();
var groups = dialog.getContentElement('macrosDialog', 'lists', 'groups');
console.log(groups);
var courses = dialog.getContentElement('macrosDialog', 'lists', 'courses');
console.log(courses);
var sections = dialog.getContentElement('macrosDialog', 'lists', 'sections');
console.log(sections);
var lectures = dialog.getContentElement('macrosDialog', 'lists', 'lectures');
console.log(lectures);
}
}
]
}
]

Load another view after login with sencha touch 2.0

I'm having a dumb problem and I would like you to give me a hand.Thanks in advance.
The situatios is as follows: I have 2 wiews (both created with sencha architect 2.0), one for login, and another for general purposes. And I would like to load the second view on successful response when trying to log in, this is, after any successful login. The main problem is that I've tried with Ex.create, Ext.Viewport.add, Ext.Viewport.setActiveItem, but I can't manage to make the second view to appear on screen, the login screen just keeps there and the app does not load the other view. Another thing, I don't have to use a navigation view for this.
Here is the code of my controller, from which I want to load my second view. And as you'll see, I even created a reference of the view, which has autoCreate enabled and has that ID "mainTabPanel":
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginButton: {
selector: '#login',
xtype: 'button'
},
username: {
selector: '#user',
xtype: 'textfield'
},
password: {
selector: '#pass',
xtype: 'passwordfield'
},
mainTabPanel: {
selector: '#mainTabPanel',
xtype: 'tabpanel',
autoCreate: true
}
},
control: {
"loginButton": {
tap: 'onLoginButtonTap'
}
}
},
onLoginButtonTap: function(button, e, options) {
Ext.Ajax.request({
url: '../../backend/auth.php',
method: 'POST',
params: {
user: this.getUsername().getValue(),
pass: this.getPassword().getValue()
},
success: function(response) {
var json = Ext.decode(response.responseText);
if (json.type == 'success') {
// LOAD THE DAMN SECOND VIEW HERE!
//var paneltab = Ext.create('MyApp.view.MainTabPanel');
//Ext.Viewport.add(paneltab);
//Ext.Viewport.setActiveItem(this.getMainTabPanel());
} else {
alert(json.value);
}
},
failure: function(response) {
alert('The request failed!');
}
});
}
});
And here is the code of my login view:
Ext.define('MyApp.view.LoginForm', {
extend: 'Ext.form.Panel',
config: {
id: 'loginForm',
ui: 'light',
items: [
{
xtype: 'fieldset',
ui: 'light',
title: 'Log into the system',
items: [
{
xtype: 'textfield',
id: 'user',
label: 'User',
name: 'user'
},
{
xtype: 'passwordfield',
id: 'pass',
label: 'Pass',
name: 'pass'
}
]
},
{
xtype: 'button',
id: 'login',
ui: 'confirm',
text: 'Login'
}
]
}
});
And finally, the code of the view I want to load. This view loads normally if I set it as the Initial View, but does not load when a successful login occurs:
Ext.define('MyApp.view.MainTabPanel', {
extend: 'Ext.tab.Panel',
config: {
id: 'mainTabPanel',
layout: {
animation: 'slide',
type: 'card'
},
items: [
{
xtype: 'container',
layout: {
type: 'vbox'
},
title: 'Tab 1',
iconCls: 'time',
items: [
{
xtype: 'titlebar',
docked: 'top',
title: 'General Report',
items: [
{
xtype: 'button',
iconCls: 'refresh',
iconMask: true,
text: '',
align: 'right'
}
]
},
{
xtype: 'container',
height: 138,
flex: 1,
items: [
{
xtype: 'datepickerfield',
label: 'From',
placeHolder: 'mm/dd/yyyy'
},
{
xtype: 'datepickerfield',
label: 'To',
placeHolder: 'mm/dd/yyyy'
},
{
xtype: 'numberfield',
label: 'Hours'
}
]
},
{
xtype: 'dataview',
ui: 'dark',
itemTpl: [
'<div style="height:50px; background-color: white; margin-bottom: 1px;">',
' <span style="color: #0000FF">{user}</span>',
' <span>{description}</span>',
'</div>'
],
store: 'hoursStore',
flex: 1
}
]
},
{
xtype: 'container',
title: 'Tab 2',
iconCls: 'maps'
},
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'favorites'
}
],
tabBar: {
docked: 'bottom'
}
}
});
Please, I need help... :)
I'm stuck here for like 3 days now and can't figure out what the problem is. Thank you.
Could you post your app.js too?
I'm trying your code here and it load the view as expected. Here is my app.js:
Ext.application({
name: 'MyApp',
requires: [
'Ext.MessageBox'
],
controllers: ['Login'],
views: ['LoginForm','MainTabPanel'],
icon: {
'57': 'resources/icons/Icon.png',
'72': 'resources/icons/Icon~ipad.png',
'114': 'resources/icons/Icon#2x.png',
'144': 'resources/icons/Icon~ipad#2x.png'
},
isIconPrecomposed: true,
startupImage: {
'320x460': 'resources/startup/320x460.jpg',
'640x920': 'resources/startup/640x920.png',
'768x1004': 'resources/startup/768x1004.png',
'748x1024': 'resources/startup/748x1024.png',
'1536x2008': 'resources/startup/1536x2008.png',
'1496x2048': 'resources/startup/1496x2048.png'
},
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
//Ext.Viewport.add(Ext.create('MyApp.view.Main'));
Ext.Viewport.add(Ext.create('MyApp.view.LoginForm'));
},
onUpdated: function() {
Ext.Msg.confirm(
"Application Update",
"This application has just successfully been updated to the latest version. Reload now?",
function(buttonId) {
if (buttonId === 'yes') {
window.location.reload();
}
}
);
}
});
Destroy the login panel, You don't really need it anymore...
success: function(response) {
var json = Ext.decode(response.responseText);
if (json.type == 'success') {
// LOAD THE DAMN SECOND VIEW HERE!
var paneltab = Ext.create('MyApp.view.MainTabPanel');
Ext.getCmp('loginForm').destroy();
Ext.Viewport.add(paneltab);
} else {
alert(json.value);
}
},
There are several problems here:
Your autoCreate rule uses an xtype: 'tabpanel' which will only ever create a vanilla Ext.TabPanel with no items in it. You'd need to assign an xtype attribute to your MyApp.view.MainTabPanel like xtype: 'mainTabPanel' and then use that xtype value in your autoCreate rule.
This then explains why this code won't work since this.getMainTabPanel() will return the wrong object. Simpler would be to just use Ext.Viewport.setActiveItem(paneltab).
In general, you usually don't want assign an id to a view (id: 'mainTabPanel'). Safer to just use an xtype to fetch it. Although you don't need it in this case, avoiding global id's allows you to create multiple instances of a view (or any other class type).

Resources