Emojis become question marks after re-render in contentEditable - reactjs

I've created a simple text editor and I've also created the possibility to add emojis. The problem is that when I click an emoji the emoji is added and visible, but the previous existing emojis are replaced with question marks. My contentEditable div is controlled, meaning that whenever an emoji is added it causes a re-render. I got this problem in the following if case of my algorithm:
childValue = childValue.substring(0, caretPosition) + emoji + childValue.substring(caretPosition + 1, childValue.length)
childValue isn't a state variable, it's value is used to update a constant variable that will be used to update the state variable representing the contentEditable's dangerouslySetInnerHTML property, the caretPosition is perfect.
Any ideas why I might have this issue?

This solution from https://stackoverflow.com/a/59793087/14550434 combined with HTML escaping should do the trick:
var p = document.querySelector("p");
var childValue = "Some sample text";
var caretPosition = 5;
var emoji = "😀";
const emojiToString = (emoji) =>
` &#x${emoji.codePointAt(0).toString(16)}; `;
childValue =
childValue.substring(0, caretPosition) + emojiToString(emoji) +
childValue.substring(caretPosition, childValue.length);
p.innerHTML = childValue;
<p></p>

I solved this issue. I figured out that 'substring' was messing everything up, so I did the following:
newChildValue = Array.from(childValue);
childValue = newChildValue.slice(0, caretPosition).join('') + emoji + newChildValue.slice(caretPosition).join('');
This way I avoid using 'substring' as Array.from(str) splits a string into individual unicode characters without breaking them between bytes.

Related

Strip all styling from pasted text in DraftJS?

When pasting text from word or another source into draftjs the formatting comes along for the ride, I tried stripping the styling data like so:
onChange={(newEditorState) => {
const raw = convertToRaw(newEditorState.getCurrentContent())
for (let i = 0; i < raw.blocks.length; i++){
raw.blocks[i].type = "unstyled"
}
let newContent = convertFromRaw(raw)
newEditorState
const newState = EditorState.push(state, newContent, "change-block-type")
setState(newState)
}} />
Which worked except typing ended up being reversed on input after that, which was very confusing.
It seems like the stripPastedStyles option is what you're looking for:
Set whether to remove all information except plaintext from pasted content.
This should be used if your editor does not support rich styles.
Default is false.

How do I get the text from the li tag

How do I get the text from the li tag? I want to find the text "Password is required." only, not the text inside strong tag.
<li><strong>Error:</strong> Password is required.</li>
You need to show your code for somebody to give a complete answer. I guess that you already know how to do something like the following
WebElement something = driver.FindElement(By.CssSelector(?))
string s = something.Text;
The next bit seems to be where you are stuck. There you need to parse the string s. That is nothing to do with Selenium-Webdriver. You could do something like
string[] s2 = s.split(new string[] {">","<"});
were the last element in s2 would be your answer here. This would be totally non generic though. Is this a situation in which you always want to purge html?
Here is the method developed in python.
def get_text_exclude_children(element):
return driver.execute_script(
"""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element).strip()
How to use in this:
liElement = driver.find_element_by_xpath("//li")
liOnlyText = get_text_exclude_children(liElement)
print(liOnlyText)
Please use your possible strategy to get the element, this method need an element from which you need the text (without children text).

Silverlight TelerikGrid 'EndsWith' Filter is Not Working for values having Leading Spaces (Trailing Spaces)

I'm having problem binding the data to the grid when I filter using the operator EndsWith.
fieldfilter.Filter1.Operator.ToString == "IsEqualTo"
fieldFilter.Filter1.Value = fieldFilter1.Value.ToString().PadRight(120, ' ');
In the database the values of the column have the Leading Spaces, and I had problem making it work for IsEqualTo also but I fixed it by padding leading spaces to the right of the input string. (as shown below)
But, I'm not sure how I should do it for the EndsWith Filter Operator.
I'm able to get the rows from the database by using where condition like '%ABC'.
But the rows are not binding to the grid.
When you get the callback from DB with the collection(collection).
queueColl = new HierarchyItemCollection();// the original collection- before
List<HierarchyItem> items = new List<HierarchyItem>(collection.OrderBy(item => item.Text));
items.ForEach(item =>
{
item.Tag = (stcQueue)item.Tag;
item.ObjectData = null;
queueColl.Add(item);
});
radTreeOH.DataContext = queueColl; // I am having a tree.

How can I add strings to array in javascript

I wanna create an array in javascript which looks like this:
[0,0,0,0,0,1,1,0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1,0,1,0,1,1,1,0],[0,0,0,0,1,1,1,1,0,1,0,0,1,1,0],[0,0,0,0,0,1,1,0,1,0,1,0,1,0,0]
My problem is that I don't know how to add the opening and closing square brackets to the start and the end of the output string.
here's my code:
game = new Array();
for(row=0;row<matrix.length;++row){
game[row]=matrix[row].join(',');
}
document.getElementById('jsvalue').value=game.join('],[');
document.getElementById('name2').value = name;
I tried a few things, but they didn't seem to work and all I got were errors or this output:
0,0,0,0,0,1,1,0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1,0,1,0,1,1,1,0],[0,0,0,0,1,1,1,1,0,1,0,0,1,1,0],[0,0,0,0,0,1,1,0,1,0,1,0,1,0,0
How could I add them? Is there a simple array method that I missed and would solve my problem?
Thanks in advance!
It looks like you are trying to set the value of an HTML element to the format you described in your question. However, you are not setting the value of that HTML element to an Array - you are setting it to a string. the .join function outputs a string. If indeed you want the value to be set to a string formatted in the way you described, then you could take advantage of .join, but have to do a little bit in addition to what you are doing:
game = new Array();
for(row=0;row<matrix.length;++row){
game[row]= "[" + matrix[row].join(',') + "]";
}
document.getElementById('jsvalue').value=game.join(',');
document.getElementById('name2').value = name;
If you are using join to create the string, then why not just manually add the brackets?
For example:
document.getElementById('jsvalue').value= '[' + game.join('],[') + ']';

image array and .src - image not changing

I have created an array which is being used to store a series of .gif images and I'm just trying to test everything out by using document.getElementById to change the .src value but when I change it and load the page the image stays the same as it was before.
function setImage()
{
var images = new Array();
images[0] = anemone.gif;
images[1] = ball.gif;
images[2] = crab.gif;
images[3] = fish2.gif;
images[4] = gull.gif;
images[5] = jellyfish.gif;
images[6] = moon.gif;
images[7] = sail.gif;
images[8] = shell.gif;
images[9] = snail.gif;
images[10] = sun.gif;
images[11] = sunnies.gif;
images[12] = whale.gif;
var slots = new Array();
slots[0] = document.getElementById("slot" + 0);
slots[1] = document.getElementById("slot" + 1);
slots[2] = document.getElementById("slot" + 2);
slots[0].src = "snail.gif";
document.getElementById('slot0').src = images[0];
alert(images.length);
}
I can't understand why the image wont change, but I know it has to be something very simple. I've been wasting hours trying to get this one thing to change but nothing works. can anyone please point out the error of my ways?
There are a couple of issues with your code:
Your filenames need to be Strings, so they'll have to be quoted (also you can simplify the Array creation):
var images = ['anemone.gif', 'ball.gif', 'crab.gif', 'fish2.gif', 'gull.gif', 'jellyfish.gif', 'moon.gif', 'sail.gif', 'shell.gif', 'snail.gif', 'sun.gif', 'sunnies.gif', 'whale.gif'];
Also make sure you are getting your slot-elements right, quote all the attributes like:
<img id="slot0" class="slot" src="crab.gif" width="120" height="80">
When you create the slots-Array you can do it like this (no need to concat the ID string):
var slots = [document.getElementById('slot0'), document.getElementById('slot1'), document.getElementById('slot2')];
Finally make sure you call your function when the document has loaded / the DOM is ready. If you don't want to use a framework like jQuery your easiest bet is probably still using window.onload:
window.onload = setImage; //note that the parens are missing as you want to refer to the function instead of executing it
Further reading on Arrays, window.onload and DOMReady:
https://developer.mozilla.org/de/docs/DOM/window.onload
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
javascript domready?

Resources