Annotations using Jquery - javascript

I am trying to make an essay writing test website, I input an essay using a text area and then I want to comment on that inputted text like PDF annotations/highlighted the comment I have tried the annotation API for TinyMCE but it throws an error
invalid call to Attr.set. Key data-mce-alpha :: Value undefined :: Element
tinymce.min.js:8:48481
Error: Attribute value was not simple
and Annotation.js is 5 years old and jquery throws an error on that
any idea how I can do it using JS and store it?

If you used example code from here https://www.tiny.cloud/docs/advanced/annotations/ then that example code did not work for me either.
This is a part of code which was in documentation:
ed.on('init', function() {
ed.annotator.register('alpha', {
persistent: true,
decorate: function(uid, data) {
return {
attributes: {
'data-mce-alpha': data.alpha
}
};
}
});
});
Change data.alpha to data.comment, so that piece of code should look like this:
ed.on('init', function() {
ed.annotator.register('alpha', {
persistent: true,
decorate: function(uid, data) {
return {
attributes: {
'data-mce-alpha': data.comment
}
};
}
});
});
Then example will work - just need to write some text in comment prompt dialog otherwise it will throw the same error - so make sure that you will implement some kind of check if comment string is not empty.
Hope that helps.

Well I solved the issue by adding an older Jquery,
here is the code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="/js/annotator-full.min.js"></script>
<link rel="stylesheet" href="/css/annotator.min.css">
<script type="text/javascript">
jQuery(function ($) {
var annotation{{ $questionss->id }} = $('#content{{ $questionss->id }}').annotator().annotator('addPlugin', 'Tags');;
annotation{{ $questionss->id }}.annotator('addPlugin', 'Store', {
prefix: '/annotation',
loadFromSearch : {
page : {{ $questionss->q_type_id }}
},
annotationData : {
page : {{ $questionss->q_type_id }}
},
urls: {
create: '/store',
update: '/update/:id',
destroy: '/delete/:id',
search: '/search'
}
});
hope it helps

Related

Spaces are not recognized correctly in the TipTap Editor

we use the rich text editor of TipTap in our project.
But we have the problem, that spaces are not recognized correctly and only after every 2 click a space is created. As framework we use Vue.JS.
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
import {
HardBreak,
Heading,
OrderedList,
BulletList,
ListItem,
Bold,
Italic,
History
} from 'tiptap-extensions'
import EditorMenuButton from './EditorMenuButton.vue'
export default {
name: 'editor',
components: {
EditorMenuButton,
EditorMenuBar,
EditorContent
},
props: {
value: {
type: null,
default: ' '
}
},
data () {
return {
innerValue: ' ',
editor: new Editor({
extensions: [
new HardBreak(),
new Heading({ levels: [1, 2, 3] }),
new BulletList(),
new OrderedList(),
new ListItem(),
new Bold(),
new Italic(),
new History()
],
content: `${this.innerValue}`,
onUpdate: ({ getHTML }) => {
this.innerValue = getHTML()
}
})
}
},
watch: {
// Handles internal model changes.
innerValue (newVal) {
this.$emit('input', newVal)
},
// Handles external model changes.
value (newVal) {
this.innerValue = newVal
this.editor.setContent(this.innerValue)
}
},
mounted () {
if (this.value) {
this.innerValue = this.value
this.editor.setContent(this.innerValue)
}
},
beforeDestroy () {
this.editor.destroy()
}
}
</script>
does anyone have any idea what could be the reason for assuming only every two spaces?
We had the same problem, we kept the onUpdate trigger but changed the watch so that it would only invoke editor.setContent when the value was actually different.
watch: {
value() {
let html = this.editor.getHTML();
if (html !== this.value) {
this.editor.setContent(this.value);
}
},
},
"Okay the problem is that the watcher will get fired when you type in the editor. So this will check if the editor has focus an will only update the editor content if that's not the case."
watch: {
value(val) {
if (!this.editor.focused) {
this.editor.setContent(val, false);
}
}
},
issue: https://github.com/ueberdosis/tiptap/issues/776#issuecomment-667077233
This bug for me was caused by doing something like this:
watch: {
value: {
immediate: true,
handler(newValue) {
this.editor.setContent(newValue)
},
},
},
Removed this entirely and the bug went away. Maybe this will help someone in future.
Remove onUpdate section and the bug will disapear. I don't know why, but it's interesting to know how to reproduce the bug.
That does help. Following this advice, I am currently using the onBlur event instead of onUpdate, while obtaining the content's HTML using the editor instance and the getHTML() function, as such: this.editor.getHTML().
(In my case I $emit this value in order for it to be reactive to my parent component, but that may be irrelevant for the original question).
Maybe you should try this.
watch: {
// Handles external model changes.
value (newVal) {
// convert whitespace into \u00a0 ->
let content = newVal.replace(/\s/g, "\u00a0");
this.editor.setContent(content)
}
},
It seems like the normal white space has been removed by html automatically. Therefore, I convert whitespace into 'nbsp;' and it's worked.
The code you provided seems to be working just fine. So the issue most likely is produced by a side effect in either your code or some dependency.
To debug this issue you could look for event listeners, especially regarding key press or key down events and looking if you are checking for space key specifically somewhere (event.keyCode === 32 or event.key === " "). In conjunction with event.preventDefault this could explain such an issue.
Another more broad way to debug this is to strip away parts from your code until the bug disappears or add to a minimal example until the bug appears.
Remove onUpdate section and the bug will disapear. I don't know why, but it's interessing to know how to reproduce the bug.
However if you create a "minimal reproductible example" the bug does not appear.
So what ? I don't know.
I found a workaround which is to use vuex.
Rather than assign the value returned by getHTML() in the innerValue variable and then issue an 'input' event, I put this value in the store.

TinyMCE is not defined on WordPress

I have a console error that says Uncaught ReferenceError: tinymce is not defined and I really don't know how to solve that. It says that the error is in the javascript file below:
(function() {
"use strict";
tinymce.PluginManager.add('wdm_mce_button', function( editor, url ) {
editor.addButton('wdm_mce_button', {
text: 'Team',
icon: false,
onclick: function() {
// change the shortcode as per your requirement
editor.insertContent('[team_section]');
}
});
editor.addButton('services', {
text: 'Services',
icon: false,
onclick: function() {
// change the shortcode as per your requirement
editor.insertContent('[services_section]');
}
});
});
})();
So the error should be in the "tinymce.PluginManager.add" line. I must mention that this code is running on wordpress and I use it to add some buttons in my classic editor. I'm waiting for some help please.
Thank you!

Semantic UI Search Module does not display json response

I am trying to get Semantic UI's Search autocomplete to work. Everything seems to be working, except for the fact that the autocomplete always says no results found.
This is an example search:
This is the case even though the server response seems to work fine.
Here is the server responding with JSON:
Finally, here is my JQuery code:
$(".ui.search").search({
apiSettings: {
url : "/subtopics/search.json?query={query}"
},
fields: {
results : 'subtopics',
title : 'name'
},
minCharacters : 2
})
;
From all the examples I've seen this is the proper way to tell Semantic UI what fields to look at, but it's not working.
Any help with this issue would be greatly appreciated.
It turns out using the onResponse callback included in the Semantic UI documentation (http://semantic-ui.com/behaviors/api.html#response-callbacks) is the solution to this problem.
Here is the code that ended up working:
$(".ui.search").search({
type: 'category',
minCharacters: 3,
apiSettings: {
onResponse: function(serverResponse) {
var
response = {
results: {}
}
;
//translate Server API response to work with search
$.each(serverResponse.subtopics, function(index, subtopic) {
var
topic = subtopic.topic || 'Unknown',
maxResults = 8
;
if(response.results[topic] === undefined) {
response.results[topic] = {
name: topic,
results: []
};
}
//add result to category
response.results[topic].results.push({
title: subtopic.name
});
});
return response;
},
url: "/subtopics/search.json?query={query}"
}
})
;

select2 as input text to add new options [duplicate]

I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();

jQuery required( dependency-expression ) is not working properly

I am using jquery validation plugin. When I was using required( dependency-expression ) i noticed that
required( dependency-expression ) are not working properly. as mentioned that i tried for
$("#flight_availability").validate({
rules: {
Trip: { required: true },
DepartDate: { required : "#OneTrip:checked" },
Origin: { required:"#OriginId:blank" }
},
});
In the above mentioned code the code DepartDate: { required : "#OneTrip:checked" }, works fine but Origin: { required:"#OriginId:blank" } does not work.
Whats wrong with the code? I used firebug. It did not show any errors. even used validation debug option too, but :(
As per OP's comments:
"even if OriginId is empty(blank), it validates it as true"
Yes, that is exactly how you programmed it.
Origin: {
required: "#OriginId:blank"
}
The above code is saying that the Origin field is only required when the #OriginId field is left blank. Using #OriginId:filled, this logic is saying that the Origin field must remain empty if the #OriginId is filled in. If that's not exactly correct, then you can use the :blank selector instead.
http://jsfiddle.net/xMAs5/
If you want the opposite behavior then use the :filled selector instead.
Origin: {
required: "#OriginId:filled"
}
http://jsfiddle.net/xMAs5/1/
Otherwise, here is a demo using a custom method called empty that works as per your comment: "So if OriginId is empty means Origin value (anything) is invalid."
$(document).ready(function () {
$.validator.addMethod('empty', function (value, element) {
return (value === '');
}, "This field must remain empty!");
$("#flight_availability").validate({
rules: {
Trip: {
required: true
},
DepartDate: {
required: "#OneTrip:checked"
},
Origin: {
empty: {
depends: function (element) {
return $("#OriginId").is(":blank")
}
}
}
}
});
});
DEMO: http://jsfiddle.net/Ab8bT/
It might be the jQuery puesdo selector try using :empty instead of :blank.

Categories

Resources