console log dangerouslySetInnerHTML={{ __html: article.description }} - reactjs

I built a wyziwig following the instructions here: https://blog.learningdollars.com/2020/04/01/how-to-add-a-rich-text-editor-in-your-react-app-using-draft-js-and-react-draft-wysiwyg/
Now I want to add a show/hide container based on 3 lines of text in the output.
I'm just trying to console.log(dangerouslySetInnerHTML={{ __html: output }}), so I can test the show/hide as well as add an ellipsis. Anyone have any idea how to do this?
Edit:
If you don't want to follow the link, I have setup a sandbox here: https://codesandbox.io/s/react-draft-wysiwyg-fjfh9
More Details:
<div class="modal-body" dangerouslySetInnerHTML={{ __html: output }} /> comes from a library draftjs-to-html. It takes a string such as the following <p>This text is <strong><em>BOLD AND ITALIC</em></strong> with this wyziwyg.</p>, and outputs a string display to the html page such as the following...
"This text is BOLD AND ITALIC from a wyziwyg."
What I want to be able to is determine the .length() of the html displayed output string(above). To do this, I need to see if there is a way to console.log(dangerouslySetInnerHTML={{ __html: output }});

When you want to get the length to the text from a html string, you could do the following, since you assume the contents to be safe (coming from the user's editor):
const getTextLength = (html) => {
// This will never get added to the DOM.
const element = document.createElement("div")
element.innerHTML = html
return element.textContent.length
}
// Some test cases.
const outputs = [
"Some text",
"<p>Some text</p>",
"<p><strong>Some</strong> text</p>"
]
// Should ouput `9` for all test inputs.
console.log(outputs.map(getTextLength))

Related

Unexpected EOF in Flask

I have a HTML textarea in which someone can place their own text. This text has to be able to support enters.
So when I submit this textarea to the database, everything works. For this example, I have put the following text in the textarea:
I now placed an enter. And I want to save this.
Thanks!
Now when I try to load this text back from the database to the browser, I get an Unexpected End of File error. See image below.
Unexpected EOF
I have looked everywhere, but I don’t know how to fix this. The only 'solution' I can find, is to remove the enters. This however only works in Jquery/JS and not in Python (flask). Also, this is not really a solution, because the message needs to be with enters/new lines.
Could you people help me with this?
Thanks in advance!
My code (as you can see, I already tried some things):
The textarea itself:
<div class="col-" id="textarea-div">
<label><b>Your message: </b></label>
<br>
<textarea rows="5" cols="60" id="campagne_bericht" name="campagne_bericht" maxlength="300" class="form-control" placeholder="Plaats uw bericht hier..." required></textarea>
<script>
// $("#campagne_bericht").keyup(function(e) {
// if(e.keyCode === 13) {
// console.log("Enter");
// //{# $("#campagne_bericht").val($("#campagne_bericht").val() + "test"); #}
// let bericht = $("#campagne_bericht").val().replace(/[\u00A0\u1680​\u180e\u2000-\u2009\u200a​\u200b​\u202f\u205f​\u3000]/g, 'test');
// console.log($("#campagne_bericht").val());
// }
// //{# $("#campagne_bericht").text($("#campagne_bericht").text().replace("\n", "Enter")); #}
// });
// Key Press Listener Attachment for #area.
$("#campagne_bericht").keypress(function (event) {
// If the key code is not associated with the ENTER key...
if (event.keyCode == 13) {
// Otherwise prevent the default event.
// event.preventDefault();
// remove new lines from the textarea
// let bericht = $("#campagne_bericht").val().replace(/\s+/g, '\n');
let bericht = $("#campagne_bericht").val().replace(/\r\n|\r|\n/g, '\r');
$("#campagne_bericht").val(bericht);
console.log(bericht);
}
});
</script>
</div>
To load the text into the textarea with JQuery:
$('#campagne_bericht').val('{{ campagne[7] }}'); //{{ campagne[7] }} is to load the message from Python to the html.
In order to put multiline text in JS you can do something like this:
$('#campagne_bericht').val({{ campagne[7] }});
Basically using `` instead of ''

How to make the link is clickable in textarea in ReactJS?

I have a page named Community where user can comment on another post
I have a problem when user comments the link but it's not displayed true
When user comments, the link is not displayed true
The function I used to convert the text to link
const convertToLink = (text) => {
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
var text1 = text.replace(exp, "<a href='$1'>$1</a>");
var exp2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
return text1.replace(exp2, '$1$2');
}
You cannot render HTML inside of textarea. Use <p> instead
<p dangerouslySetInnerHTML={{ __html: convertToLink(text) }}></p>

Replace string with react component with .replace

I have a long text (string), I want the user to be able to highlight any word he wants, and make this word a Tag component.
function highlightingString() {
document.onmouseup = () => {
const myHighlightedString = window.getSelection().toString(); // Gives me the word I highglight
const startHighlightedString = docText.indexOf(myHighlightedString) // Give me the start index of my word in the document
const endHighlightedString = startHighlightedString + myHighlightedString.length // Give me the end index of my word in the document
newDocText = docText.replace(myHighlightedString, <Tag name={"Highlighted"}/>)
setOpenedFile(newDocText)
};
}
Tag component
function Tag({name}){
const color = colors[name];
return <div style={{backgroundColor: color, ...tagStyle}}>{name}<span style={{cursor: "pointer", paddingLeft: '10px'}}</span></div>
}
Example:
Initial document text: "Hello, I would like to order a pizza with peperoni"
If the user selects "pizza with", I would like to happen:
"Hello, I would like to order a Tag name={highlighted} /> peperoni" # Where Tag is simply adding a to the selected word
Instead, I get:
"Hello, I would like to order a [object Object] peperoni"
It seems that I am replacing correctly the string I highlight with the <Tag /> component, however I do not get why is not rendering the text within <span> but [object Object]
Well, replacing part of the string with an object will not magically insert that object into that string :) What it does is converting your object to its string representation (which is [object Object]) and then inserting that representation into the string.
What you want to do is to create a proper React component.
Something like this:
<>
{openFile.textBeforeHighlighted}
<Tag name={openFile.highlighted}/>
{openFile.textAfterHighlighted}
</>
while your handler function sets openFile to something like this:
setOpenFile({
textBeforeHighlighted:textBeforeHighlighted,
highlighted:highlighted,
textAfterHighlighted:textAfterHighlighted
});

Removing inline formats in Quill

I'm having some trouble getting removeFormat to work as it should. Funnily, I thought I had this working a couple days ago; but now when I check it it's not right. It is removing the block-level formatting regardless of where the selection is. A simple example, using the Quill Quickstart with a few modifications:
var editor = new Quill('#editor', {
modules: { toolbar: '#toolbar' },
theme: 'snow'
});
let Block = Quill.import('blots/block');
let Parchment = Quill.import('parchment');
class BlockquoteBlot extends Block { }
BlockquoteBlot.scope = Parchment.Scope.BLOCK;
BlockquoteBlot.blotName = 'blockquote';
BlockquoteBlot.tagName = 'blockquote';
Quill.register(BlockquoteBlot);
let quill = new Quill('#editor');
$('#italic-button').click(function() {
quill.format('italic', true);
});
$('#bold-button').click(function() {
quill.format('bold', true);
});
$('#blockquote-button').click(function() {
quill.format('blockquote', true);
});
$('.cust-clear').click(function(ev) {
var range = quill.getSelection();
quill.removeFormat(range.index, range.length);
});
<link href="https://cdn.quilljs.com/1.0.3/quill.snow.css" rel="stylesheet"/>
<script src="https://cdn.quilljs.com/1.0.3/quill.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Create the toolbar container -->
<div id="toolbar">
<button id="bold-button" class="ql-bold">Bold</button>
<button id="italic-button" class="ql-italic">Italic</button>
<button id="blockquote-button" class="ql-blockquote">Blockquote</button>
<button class="cust-clear" title="Clear Formatting">X</button>
</div>
<!-- Create the editor container -->
<div id="editor">
<p>Hello World!</p>
</div>
In this example, if I apply bold to "Hello" and make the entire line a blockquote, all looks as it should. If I then select "Hello" and click my X button to remove the formatting, it removes the blockquote formatting even though I'm nowhere near a "\n" character. Am I misunderstanding removeFormat, or is there an error in how I've created my BlockquoteBlot? I took that code mostly from the Medium demo on the Quill site, but I found in some cases I needed to specifically define the scope so that the tag would be recognized as block (that may not be necessary for this demo, but I'm including it in case it poses an issue).
The way removeFormat is supposed to work currently does remove all block formats a user highlights, even if it is not across the "\n" character. This makes more sense when the user is selecting multiple lines Issue #649 but perhaps it should not work this way when there is only one line partially selected. I've created a Github Issue to discuss this. Please feel free to chime in.
I am aware that this is an old thread - as an additional to your code in case someone hasn't selected anything - works on Quilljs 1.2.6
$('.cust-clear').click(function(ev) {
var range = quill.getSelection();
if (range.length ===0) {
let leaf, offset = quill.getLeaf(range.index);
quill.removeFormat(range.index - offset, range.index + leaf.domNode.length);
} else {
quill.removeFormat(range.index, range.length);
}
});
This should work
$('.cust-clear').click(function()
{
var range = editor.getSelection();
if (range){
if (range.length > 0) {
editor.removeFormat(range, Quill.sources.USER);
}
}
});

Changing the template data not refreshing the elements

I have searched and tried suggestions mentioned in various posts but no luck so far.
Here is my issue.
I have created a custom element <month-view id="month-view-element"></month-view> in my mainpage.html. Inside mainpage.html when this page is initially loaded i created a empty json object for all the 30days of a month and print a placeholder type cards in UI. Using the code below.
var json = [];
for(var x = 0; x < total; x++) {
json.push({'hours': 0, 'day': x+1, 'year': year});
}
monthView.month = json; //Doing this line. Prints out the desired empty cards for me in the UI.
created a month-view.html something like below:
<dom-module id='month-view'>
<template>
<template is="dom-repeat" items= "{{month}}">
<paper-card class="day-paper-card" heading={{item.day}}>
<div class="card-content work">{{item.work}}</div>
<div class="card-actions containerDay layout horizontal">
<div style="display:inline-block" class="icon">
<paper-icon-button icon="icons:done" data-hours = "8" data-day$="{{item.day}}" data-month$={{item.month}} data-year$={{item.year}} on-click="updateWorkHours"></paper-icon-button>
<paper-tooltip>Full day</paper-tooltip>
</div>
</div>
</paper-card>
</template>
</template>
<script>
Polymer({
is: "month-view",
updateWorkHours: function (e, detail) {
console.log(e);
this.fire('updateWorkHour', {day: e.target.dataHost.dataset.day,
month: e.target.dataHost.dataset.month,
year: e.target.dataHost.dataset.year,
hours: e.target.dataHost.dataset.work
});
}
});
</script>
</dom-module>
There is another file script.js which contains the function document.addEventListener('updateWorkHour', function (e) { // doStuff });. I use this function to make a call to a google client API. I created a client request and then do request.execute(handleCallback);
Once this call is passed i landed in handleCallback function. In this function i do some processing of the response data and save parts of data into json variable available in the file already. And once all processing is done i did something like below.
monthView.month = json;
But this above line is not refreshing my UI with the latest data. Is there anything I am missing? Any suggestions or anything i am doing incorrectly.
You need to use 'set' or 'notifyPath' while changing Polymer Object or Arrays in javascript for the databinding/obserers to work. You can read more about it in https://www.polymer-project.org/1.0/docs/devguide/data-binding.html#path-binding
In your case try below code
monthView.set('month',json);
Updated suggestions:
Wrap your script on main page with. This is required for non-chrome browsers.
addEventListener('WebComponentsReady', function() {})
This could be scoping issue. Try executing 'document.querySelector('#month-view-element');' inside your callback addWorkHoursCallBack. Also, Use .notifyPath instead of .set.

Resources