storing content from a Quill form in the database - javascript

I've been trying a couple of rich text editors, and Quill seems to be the best tool to implement into my projects. I'm using Node/Express and MongoDB/Mongoose. In my 'newPost route', I have a form that just takes a title and the main content. Since I'm just testing it out, the title field is outside of the Quill editor. Here the error I'm getting:
This is after I hit "submit". The console shows not only the title but also the main content that has a code-block with syntax highlight which is exactly what I wanted. But it's not being added to the database.
There's also this message Use of Mutation Events is deprecated. Use MutationObserver instead., and it seems I'm required to change Quill's source code myself to fix this.
Getting the main content of the post on the console kind of gave me a feeling that I'm halfway of getting this to work.
Is there a not-so-hard way to get this to work? Thanks!!
js
var quill;
var metaData = [];
hljs.configure({ // optionally configure hljs
languages: ['javascript', 'ruby', 'python']
});
hljs.initHighlighting();
$(document).ready(function() {
var toolbarOptions = [['blockquote', 'code-block'],
["bold", "italic", "underline", "strike"], // toggled buttons
//['blockquote'],
[{ list: "ordered" }, { list: "bullet" }],
[{ script: "sub" }, { script: "super" }], // superscript/subscript
[{ indent: "-1" }, { indent: "+1" }], // outdent/indent
[{ direction: "rtl" }], // text direction
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
["clean"] // remove formatting button
];
quill = new Quill("#snow-container", {
placeholder: "Compose an epic...",
modules: {
syntax: true,
toolbar: toolbarOptions
},
theme: "snow"
});
var oldDelta = {"ops":[{"attributes":{"color":"#000000"},"insert":"This is sample text."}]};
quill.setContents(oldDelta);
});
var form = document.querySelector('form');
form.onsubmit = function() {
// Populate hidden form on submit
var formContent = document.querySelector('input[name=content]');
formContent.value = JSON.stringify(quill.getContents());
console.log("Submitted", $(form).serialize(), $(form).serializeArray());
// No back end to actually submit to!
//alert('Open the console to see the submit data!')
return false;
};

Related

QuillJs - jumps to top

I'm using QuillJs as a text editor on my website. In a long post the screen view jumps to top when pasting text or changing heading type or alignment or color or inserting a link or video. Can't find out why.
QuillJs version: 1.2.6
Browser: Chrome 58.0.3029.110
OS: Windows 10
Initialization:
var toolbarOptions = [
[{ 'header': [1, 2, 3, 4, 5, 6, false] },
'bold', 'italic', 'underline', 'strike', { 'align': [] },
{ 'list': 'ordered' }, { 'list': 'bullet' },
{ 'color': [] }, { 'background': [] }],
['image', 'blockquote', 'code-block', 'link', 'video'],
['clean']
];
var quill = new Quill('#editor', {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
});
This happens when any option is clicked from the quill toolbar. I had similar issue and I was using react-quill 0.4.1.
Try using event.preventDefault and event.stopPropagation on quill toolbar to fix this.
The following fixed the issue for me.
componentDidMount()
{
$('.quill-toolbar').on("mousedown", function(event){
event.preventDefault();
event.stopPropagation();
});
}
If you want an editor to be scrolled and maintained by a web page's main scrollbar, you need to set scrollingContainer property to 'body' during configuration of Quill object.
var quill = new Quill('#editor', {
modules: { toolbar: toolbarOptions },
theme: 'snow',
scrollingContainer: 'body'
});
Setting scrollingContainer to html was the only solution that worked for me:
var quill = new Quill('#editor', {
modules: { toolbar: toolbarOptions },
theme: 'snow',
scrollingContainer: 'html'
});
this is happening because of these two lines:
https://github.com/quilljs/quill/blob/5715499c57091db262c176985f6c5370d73db5dd/modules/toolbar.js#L86
and
https://github.com/quilljs/quill/blob/5b28603337f3a7a2b651f94cffc9754b61eaeec7/core/quill.js#L171
this.scrollingContainer => could be not an actual scrolling element.
The fix could be is to assign the nearest scrolling element directly.
If you are not sure what it is you can use this snippet to find it:
const regex = /(scroll)/;
const style = (node, prop) => window.getComputedStyle(node, null).getPropertyValue(prop);
const scroll = (node) => regex.test( style(node, "overflow") + style(node, "overflow-y") + style(node, "overflow-x"));
export const scrollparent = (node) => {
return !node || node===document.body ? document.body : scroll(node) ? node : scrollparent(node.parentNode);
};
editor.scrollingContainer = scrollparent(editor.container);

Kendo UI Grid: if I make changes and save them, I can still cancel them afterwards. How to lock them in?

I have a Kendo UI Grid bound to a local data source. If I make some changes and click on "Save changes", and then I click on "Cancel changes", the changes are rolled back. I expected them to be "locked in" because I saved them.
Furthermore, if I make a change, save it, make another change, save again and finally cancel, both changes are rolled back.
See UPDATED fiddle, with problem and solution:
http://jsfiddle.net/q24ennne/7/
My HTML:
<div id="grid"></div>
My JavaScript:
window.gridData = [
{ id: 1, text: "Uno" },
{ id: 2, text: "Dos" },
{ id: 3, text: "Tres" },
{ id: 14, text: "Catorce" },
];
(function() {
$('#grid').kendoGrid({
toolbar: ["save", "cancel"],
editable: true,
saveChanges: function(e) {
gridData = $('#grid').getKendoGrid().dataSource.data();
$('#grid').getKendoGrid().refresh();
console.log("gridData:");
console.log(gridData);
},
columns: [{
field: "text",
title: "No."
}],
dataSource: {
data: gridData,
}
});
})();
Thanks!
You need to include a schema for your datasource that specifies which property is the id of each item. In your case this happens to also be called "id" so add this:
dataSource: {
data: gridData,
schema: {
model: { id: "id" }
}
}
The grid will then correctly track and keep your saved changes.

How to dynamically add and remove GROUPS to KendoUI Scheduler

I am using KendoUI Scheduler control and here is initialization code
$("#Scheduler").kendoScheduler({
dataSource: [],
selectable: true,
height: 500,
editable: false,
eventTemplate: $("#event-template").html(),
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
resources: [
{
field: "resourceviewid",
name: "ResourceViews",
dataColorField: "key",
dataSource: [
{ text: "Appointments", value: 1, key: "orange" },
{ text: "Delivery Specialist", value: 2, key: "blue" },
{ text: "Orientation Specialist", value: 3, key: "green" }
]
}
],
group: {
resources: ["ResourceViews"],
orientation: "horizontal"
}
});
Here "Appointments" group is default, it will be available always
I have check box in my screen
<div id="divResourceView">
<label><input checked type="checkbox" value="1" />Delivery Specialist</label>
<label><input checked type="checkbox" value="2" />Orientation Specialist</label>
</div>
On change event I wrote below code to get selected values from checkbox and updating GROUP datasource of KendoUI scheduler as below
$("#divResourceView :checkbox").change(function (e) {
var checked = $.map($("#divResourceView :checked"), function (checkbox) {
return parseInt($(checkbox).val());
});
});
var scheduler = $("#Scheduler").data("kendoScheduler");
var arrayOfStrings = checked.toString().split(",");
for (var i = 0; i < arrayOfStrings.length; i++)
{
if(arrayOfStrings[i] == 1)
{
var data = [{ text: "Delivery Specialist", value: 2, color: "blue" }];
scheduler.resources[1].dataSource.data(data);
}
if (arrayOfStrings[i] == 2) {
var data = [{ text: "Orientation Specialist", value: 3, color: "green" }];
scheduler.resources[2].dataSource.data(data);
}
}
scheduler.refresh();
But it removes all groups and add only one. I want to see both groups when arrayOfStrings has values "1,2",
I can see all groups during initialization But it disappears when i check the check box.
Images for reference
During Initialization
After
As you can see clearly, Delivery Specialist is missing in scheduler control
Found some link: http://www.telerik.com/forums/add-filter-to-resource-datasource
But not sure what they talking about? seems like refresh issue.
I have done this I believe you're right and your issue is to do with refreshing, I use the following to refresh it.
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.view(scheduler.view().name);
hope this helps through it is stupidly late (I'm currently looking up how to do this lazerly

Uncaught TypeError: Cannot call method 'removeClass' of undefined, kendo widgets not working

I am trying to implement few KendoUI web widgets over of my page, but the widgets are not working as expected and having following issues:
Editor initializes ok, but have few issues like when you hover
over an options it highlights but when you move away it should get
back to normal which it doesn’t
If I refresh page a couple of times
than some time Editor initializes fine but some time it doesn’t
Other widgets kendoDatePicker(); and kendoDropDownList(); are
not even initializing
My JQ Form Validation is also not working on this page
Furthermore in chrome console I have following error
Uncaught TypeError: Cannot call method 'removeClass' of undefined on line # 23679 of kendo.web.js which states this:
if (value !== DropDownList.fn.value.call(that)) {
that.text(that.options.title);
that._current.removeClass("k-state-selected");//This is line # 23679
that.current(null);
that._oldIndex = that.selectedIndex = -1;
}
I have following scripts included on page:
<script src="/Scripts/jquery-1.7.1.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/modernizr-2.5.3.js"></script>
<script src="/Scripts/kndu/kendo.web.js"></script>
…
….
<script>
$(document).ready(function () {
$("#editor").kendoEditor({
tools: [
"bold",
"italic",
"underline",
"strikethrough",
"justifyLeft",
"justifyCenter",
"justifyRight",
"justifyFull", "insertUnorderedList",
"insertOrderedList",
"formatBlock",
"createLink",
"unlink",
"insertImage",
"insertHtml",
"viewHtml",
{
name: "customTool",
tooltip: "Format as Code",
exec: function (e) {
var editor = $(this).data("kendoEditor");
editor.exec("inserthtml", { value: "<pre>" });
}
}],
});
$("#date").kendoDatePicker();
$("#categry").kendoDropDownList();
$("#newpost").validate({
rules: {
ttle: {
maxlength: 150,
required: true,
onlyChars: true
},
smmry: {
maxlength: 250,
required: true
},
editor: {
maxlength: 35,
required: true
},
categry: {
required: true
}
}
});
});
$.validator.addMethod('onlyChars', function (value) {
return /^[a-zA-Z ]+$/.test(value);
}, 'Please enter a valid name with only alphabets');
</script>
About insertHTML documentation says in here:
the insertHtml tool requires a collection of text-value pairs. A
separator may be included multiple times.
So you should have something like:
$("#editor").kendoEditor({
tools: [
...
"insertHtml",
...
],
insertHtml: [
{ text: "label 1", value: "<p>snippet 1</p>" },
{ text: "label 2", value: "<p>snippet 2</p>" }
]
});

How to do the same without using Ext.getCmp in this code?

This is the code im using and im firing button click event once the window show event is called. this works fine. but how to do the same without using Ext.getCmp
this is the line
Ext.getCmp('recent_refresh').fireEvent('click');
this is the code
Ext.create('widget.window', {
title: 'Activity',
closable: true,
closeAction: 'hide',
width: 250,
height: 300,
bodyBorder: true,
tbar: {
xtype: 'toolbar',
ui: 'plain',
items: [{
iconCls:'refresh',
id: 'recent_refresh',
listeners: {
click: function(){
Ext.Ajax.request({
url: 'control.php',
params: {
'case': '18'
},
success: function(response){
var json = Ext.decode(response.responseText);
}
});
}
}
},
'->',
{
xtype: 'displayfield',
name: 'act_date',
id: 'act_date',
value: new Date(),
formatValue: Ext.util.Format.dateRenderer('Y-m-d')
}]
},
layout:'accordion',
border: false,
items: [ grid1, grid2, grid3 ],
listeners: {
show: function() { Ext.getCmp('recent_refresh').fireEvent('click'); }
}
}).show();
Regards
There are many ways to do this. One way is to make an assignment with the Ext.create call since Ext.create returns such a reference. The app namespace in the example below is a filler since any namespaces you are using are unknown from your text. Once you have the variable reference to the widget, you can get use it to get a reference to the top toolbar and then get a reference to the item you want inside of the toolbar.
Ext.ns('app');
app.activityWin = Ext.create('widget.window', {...}
app.activityWin.getTopToolbar().get('recent_refresh').fireEvent('click');
Use the ref property.. I don't know if it has been carried forward to Ext JS 4, but here's how we do it in Ext Js 3.3
var win = new Ext.Window({
..config..
buttons : [{
text : 'save'
ref : 'saveButton'
}],
listeners : {
show : function(win){
win.saveButton.fireEvent('click'); //saveButton here is the same as used in ref above.
}
}
});
ref can now been used directly and no need to use Ext.getCmp
check the correct usage of ref in your case and implement it..
Cheers.

Categories