Skip to content

Commit 326d47f

Browse files
committed
Merged new image upload feature
1 parent 7920927 commit 326d47f

File tree

7 files changed

+241
-40
lines changed

7 files changed

+241
-40
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ npm-debug.log
1111
# produced by vbuild
1212
dist
1313
dist-example
14+
15+
example/cloudinary.vue

README.md

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Vue2-Editor 2.0
1+
# Vue2-Editor
22

3-
![Vue2Editor-Centered](https://www.dropbox.com/s/7com4d32zct44nc/Vue2Editor-Centered.png?raw=1) HTML Editor using Vue.js 2.0 and Quilljs
3+
![Vue2Editor-Centered](https://www.dropbox.com/s/7com4d32zct44nc/Vue2Editor-Centered.png?raw=1) HTML Editor using Vue.js and Quilljs
44

55
[Vue.js](https://vuejs.org)
66

@@ -32,12 +32,17 @@ import { VueEditor } from 'vue2-editor'
3232
Name | Type | Default | Description
3333
-------------- | ------ | -------------------------------------------------- | ----------------------------------------------------------------------
3434
id | String | quill-container | Set the id (necessary if multiple editors in the same view)
35-
v-model | String | - | Set v-model to the the content or data property you wish to bind it to
35+
v-model | String | - | Set v-model to the the content or data property you wish to bind it to
36+
useCustomImageHandler | Boolean | false | Handle image uploading instead of using default conversion to Base64
3637
placeholder | String | - | Placeholder text for the editor
3738
disabled | Boolean | false | Set to true to disable editor
3839
editorToolbar | Array | ** _Too long for table. See toolbar example below_ | Use a custom toolbar
3940

40-
<!-- ## Events Name | Description ---------------- | ----------- editor-updated | Emitted when the editor contents change save-content | Emitted when the default save button is clicked -->
41+
# Events
42+
Name | Parameters | Description
43+
-------------- | ------------ | ----------------------------------------------------------------------
44+
imageAdded | file, Editor, cursorLocation | Emitted when useCustomImageHandler is true and photo is being added to the editor
45+
<!-- Emitted when the default save button is clicked -->
4146

4247
## Example
4348
**_Basic Setup_**
@@ -69,6 +74,68 @@ editorToolbar | Array | ** _Too long for table. See toolbar example below_ | Us
6974

7075
## Example
7176

77+
**_Upload image to server and use returned url instead of data URL_**
78+
If you choose to use the custom image handler, an event is emitted when a a photo is selected.
79+
You can see below that 3 parameters are passed.
80+
1. It passes the file to be handled however you need
81+
2. The Editor instance
82+
4. The cursor position at the time of upload so the image can be inserted at the correct position on success
83+
84+
**NOTE** In addition to this example, I have created a [new example repo](https://github.com/davidroyer/vue2editor-images) demonstrating this new feature with an actual server.
85+
86+
```html
87+
<template>
88+
<div id="app">
89+
<vue-editor id="editor"
90+
useCustomImageHandler
91+
@imageAdded="handleImageAdded" v-model="htmlForEditor">
92+
</vue-editor>
93+
</div>
94+
</template>
95+
96+
<script>
97+
import { VueEditor } from 'vue2-editor'
98+
import axios from 'axios'
99+
export default {
100+
components: {
101+
VueEditor
102+
},
103+
104+
data() {
105+
return {
106+
htmlForEditor: ''
107+
}
108+
},
109+
110+
methods: {
111+
handleImageAdded: function(file, Editor, cursorLocation) {
112+
// An example of using FormData
113+
// NOTE: Your key could be different such as:
114+
// formData.append('file', file)
115+
116+
var formData = new FormData();
117+
formData.append('image', file)
118+
119+
axios({
120+
url: 'https://fakeapi.yoursite.com/images',
121+
method: 'POST',
122+
data: formData
123+
})
124+
.then((result) => {
125+
let url = result.data.url // Get url from response
126+
Editor.insertEmbed(cursorLocation, 'image', url);
127+
})
128+
.catch((err) => {
129+
console.log(err);
130+
})
131+
}
132+
}
133+
}
134+
</script>
135+
```
136+
137+
## Example
138+
72139
**_Set Contents After Page Load_**
73140

74141
```html

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/App.vue

Lines changed: 111 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,26 @@
11
<template>
22
<div id="app">
33
<div class="container grid-960">
4-
<h1>Vue2Editor 2.0 (In Development)</h1>
5-
<!-- <vue-editor
6-
v-model="content"
7-
:editor-toolbar="customToolbar">
8-
</vue-editor> -->
9-
<!-- <button class="btn btn-primary" @click="saveContent(content)">Save</button> -->
10-
<!-- <button class="btn btn-primary" @click="setEditor">Set Editor</button> -->
11-
<!-- <button class="btn btn-primary" @click="toggleDisabled">Toggle Disabled</button> -->
4+
<h1>Vue2Editor - Upload Images Example </h1>
125
<div class="columns">
136
<div class="editorWrapper column col-6 col-sm-12">
14-
<vue-editor id="editor1" v-model="editor1Content" :disabled="editor1IsDisabled"></vue-editor>
7+
<vue-editor id="editor1" @imageAdded="handleImageAdded" useCustomImageHandler v-model="editor1Content"></vue-editor>
158
<button class="btn btn-primary" @click="saveContent(editor1Content)">Save</button>
16-
<button class="btn btn-primary" @click="toggleDisabledForEditor1">Toggle Disabled</button>
17-
<button class="btn btn-primary" @click="setEditor1">Set Editor</button>
18-
19-
<vue-editor id="editor2" v-model="editor2Content" :disabled="editor2IsDisabled"></vue-editor>
20-
<button class="btn btn-primary" @click="saveContent(editor2Content)">Save</button>
21-
<button class="btn btn-primary" @click="toggleDisabledForEditor2">Toggle Disabled</button>
22-
<button class="btn btn-primary" @click="setEditor2">Set Editor</button>
23-
24-
<!-- <vue-editor v-model="editorContent" :editorToolbar="customToolbar"></vue-editor> -->
259
</div>
26-
<!-- <div id="preview" class="column col-6 col-sm-12" v-if="showPreview" v-html="editorContent"></div> -->
2710
</div>
2811
</div>
2912
</div>
3013
</template>
3114

3215
<script>
16+
17+
const CLIENT_ID = '993793b1d8d3e2e'
18+
const CLOUDINARY_URL = 'https://api.cloudinary.com/v1_1/dkrcloudinary/upload'
19+
const UPLOAD_PRESET = 'ptvbj5nu'
3320
import {
3421
VueEditor
3522
} from '../src/index.js'
36-
23+
import axios from 'axios'
3724
export default {
3825
components: {
3926
VueEditor,
@@ -57,7 +44,9 @@ export default {
5744
]
5845
}
5946
},
47+
created() {
6048
49+
},
6150
methods: {
6251
setEditor1(editor) {
6352
this.editor1Content = 'Set Editor 1 Content'
@@ -77,8 +66,109 @@ export default {
7766
},
7867
toggleDisabledForEditor2() {
7968
this.editor2IsDisabled = !this.editor2IsDisabled
80-
}
69+
},
70+
sendUrlToEditor() {
71+
console.log('worked');
72+
},
73+
handleImageAdded(file, Editor, cursorLocation) {
74+
75+
console.log('Using Method in Parent');
76+
77+
var formData = new FormData();
78+
formData.append('image', file)
8179
80+
81+
82+
83+
axios({
84+
url: 'https://api.imgur.com/3/image',
85+
method: 'POST',
86+
headers:{
87+
'Authorization': 'Client-ID ' + CLIENT_ID
88+
},
89+
data: formData
90+
})
91+
.then((result) => {
92+
console.log(result);
93+
let url = result.data.data.link
94+
Editor.insertEmbed(cursorLocation, 'image', url);
95+
})
96+
.catch((err) => {
97+
console.log(err);
98+
})
99+
// axios({
100+
// url: CLOUDINARY_URL,
101+
// method: 'POST',
102+
// headers:{
103+
// 'Content-Type': 'application/x-www-form-urlencoded'
104+
// },
105+
// data: formData
106+
// })
107+
// .then((result) => {
108+
// let url = result.data.url
109+
// Editor.insertEmbed(cursorLocation, 'image', url);
110+
// })
111+
// .catch((err) => {
112+
// console.log(err);
113+
// })
114+
115+
},
116+
uploadImage(file, Editor, cursorLocation) {
117+
var formData = new FormData();
118+
// formData.append('file', file)
119+
// formData.append('upload_preset', UPLOAD_PRESET)
120+
//
121+
//
122+
123+
// var settings = {
124+
// "async": true,
125+
// "crossDomain": true,
126+
// "url": "https://api.imgur.com/3/image",
127+
// "method": "POST",
128+
// "headers": {
129+
// "authorization":
130+
// },
131+
// "processData": false,
132+
// "contentType": false,
133+
// "mimeType": "multipart/form-data",
134+
// "data": formData
135+
// }
136+
137+
138+
axios({
139+
url: 'https://api.imgur.com/3/image',
140+
method: 'POST',
141+
headers:{
142+
'Content-Type': 'application/x-www-form-urlencoded',
143+
'authorization': 'Client-ID' + CLIENT_ID
144+
},
145+
data: formData
146+
})
147+
.then((result) => {
148+
let url = result.data.url
149+
Editor.insertEmbed(cursorLocation, 'image', url);
150+
})
151+
.catch((err) => {
152+
console.log(err);
153+
})
154+
155+
//
156+
// axios({
157+
// url: CLOUDINARY_URL,
158+
// method: 'POST',
159+
// headers:{
160+
// 'Content-Type': 'application/x-www-form-urlencoded'
161+
// },
162+
// data: formData
163+
// })
164+
// .then((result) => {
165+
// let url = result.data.url
166+
// Editor.insertEmbed(cursorLocation, 'image', url);
167+
// })
168+
// .catch((err) => {
169+
// console.log(err);
170+
// })
171+
}
82172
}
83173
}
84174
</script>

package.json

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
{
22
"name": "vue2-editor",
3-
"version": "2.0.24",
4-
"description": "HTML editor using Vue.js 2.0 and Quill.js, an open source editor",
3+
"version": "2.0.25",
4+
"description": "HTML editor using Vue.js 2 and Quill.js, an open source editor",
55
"keywords": [
6-
"vue",
7-
"vue-component",
8-
"quill",
9-
"html editor",
10-
"text editor"
11-
],
6+
"vue",
7+
"vue-component",
8+
"quill",
9+
"html editor",
10+
"text editor"
11+
],
1212
"author": "David Royer <droyer01@gmail.com>",
1313
"repository": {
14-
"type": "git",
15-
"url": "https://github.com/davidroyer/vue2-editor"
16-
},
14+
"type": "git",
15+
"url": "https://github.com/davidroyer/vue2-editor"
16+
},
1717
"main": "dist/index.js",
1818
"files": [
1919
"dist"
@@ -36,6 +36,7 @@
3636
},
3737
"license": "MIT",
3838
"dependencies": {
39+
"axios": "^0.16.2",
3940
"quill": "^1.2.3"
4041
}
4142
}

src/VueEditor.vue

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<template>
22
<div class="quillWrapper">
33
<div ref="quillContainer" :id="id"></div>
4+
<input v-if="useCustomImageHandler" @change="emitImageInfo($event)" ref="fileInput" id="file-upload" type="file" style="display:none;">
45
</div>
56
</template>
7+
68
<script>
79
import Quill from 'quill'
810
import 'quill/dist/quill.core.css'
@@ -35,13 +37,17 @@ export default {
3537
placeholder: String,
3638
disabled: Boolean,
3739
editorToolbar: Array,
40+
useCustomImageHandler: {
41+
type: Boolean,
42+
default: false
43+
}
3844
},
3945
4046
data() {
4147
return {
4248
quill: null,
4349
editor: null,
44-
toolbar: this.editorToolbar ? this.editorToolbar : defaultToolbar
50+
toolbar: this.editorToolbar ? this.editorToolbar : defaultToolbar,
4551
}
4652
},
4753
@@ -77,6 +83,7 @@ export default {
7783
theme: 'snow',
7884
readOnly: this.disabled ? this.disabled : false,
7985
})
86+
this.checkForCustomImageHandler()
8087
},
8188
8289
setEditorElement() {
@@ -87,10 +94,31 @@ export default {
8794
this.editor.innerHTML = this.value || ''
8895
},
8996
97+
checkForCustomImageHandler() {
98+
this.useCustomImageHandler === true ? this.setupCustomImageHandler() : ''
99+
},
100+
101+
setupCustomImageHandler() {
102+
let toolbar = this.quill.getModule('toolbar');
103+
toolbar.addHandler('image', this.customImageHandler);
104+
},
105+
90106
handleUpdatedEditor() {
91107
this.quill.on('text-change', () => {
92108
this.$emit('input', this.editor.innerHTML)
93109
})
110+
},
111+
112+
customImageHandler(image, callback) {
113+
this.$refs.fileInput.click();
114+
},
115+
116+
emitImageInfo($event) {
117+
let file = $event.target.files[0]
118+
let Editor = this.quill
119+
let range = Editor.getSelection();
120+
let cursorLocation = range.index
121+
this.$emit('imageAdded', file, Editor, cursorLocation)
94122
}
95123
}
96124
}

0 commit comments

Comments
 (0)