Replacing one specific word in the textarea - javascript

I have created a hashtag and user mention input, so that when you type an '#' it displays a list of users you may know.
To this point, everything is Okey, But when I click on a user a href tag :
<a href="javascript:void(0);">
<span style="background:url('/uploads/user_00010/thumbs/32x32_d30302e9-07d7-8fd7-dba0-1a217c9c5534.jpg') no-repeat" class="tny_avatar"></span>
<span class="username">Sara</span>
<span style="height:0px;display:block;" class="clr"></span>
</a>
I want to take its username, and put it directly in the right place in the textarea...
What I did:
I take the current word in the textarea (currentWord = 'sa' in the previous screenshot)... and replace this current word with the word in the username span from the list.
The problem with this solution is that, if the substring "sa" exists in another word in the textarea, it will replace it too.
This is my js code :
$('.suggest ul li a').live('click', function () {
var text = $('.quote textarea').val();
var newVal = $(this).find('.username').html();
text = text.replace(lastWord, '#' + newVal);
$('.advText').val(text);
$('.advText').trigger('keyup');
$('.tglst').hide();
});
lastWord is the current word, where the blanking cursor is pointing; It's a global js variable.
trigger('keyup') , is just triggering some functions creating a div containing the hashtags and mentions in different color (blue). That's all it's about.
$('.tglst').hide(); is hiding the dropdown.
Does anyone know how to replace the current word only?
Thanks in advance

As mentioned in my comment, you could replace the very last word, that is most probably the one you're currently typing.
Or you can take a look here and see how to get the current cursor position. You'll have the exact word to replace afterwards.

Related

Replace Label/span with an already made Label/span

I'm trying to replace the words in a span ("Grades")
<span class="vui-heading-1">Grades</span>
with a more definite name from another label (the title="Peer Tutor Training")
<a class="d2l-menuflyout-link-link" title="Peer Tutor Training" href="/d2l/home/419542">Peer Tutor Training</a>
Wanting the title to replace when the page loads, as I'm using this to replace a span wording in an iframe with the title within the same iframe.
Not entirely sure how to go about this. Thanks in advance!
NOTE Upon further inspection, it turns out that the from the original page is not actually included into the iframe. Workaround method I'm requesting help with is an onload function to replace the "Grades" text in to "Peer Tutoring Training" (or other text since this is only one example)
var $iframe = $('iframe#your-iframe'); // iframe that u wanna modify
$iframe.on('load',function(e) {
// get the title value
var title = $(this).find('a.d2l-menuflyout-link-link').attr('title');
// get the span element
var $span = $(this).find('span.vui-heading-1');
// replace the text in the span
$span.text(title);
});

Make substring uneditable within larger div string, while also preserving the unique substring CSS (distinct from rest of text styling in div)

Setup:
Below is a tweet example appearing as an editable text:
"First words of tweet, #tweetaddress last words of tweet"
Requirement and Problem:
I'd like the user to be able to edit the text, but NOT change the #tweetaddress, which I have working. However, I also would like the #tweetAddress to be color:blue while the rest of the text is color:white. I can achieve this result initially through the use of a span wrapped around the #tweetaddress. (shown is code below.)
I'm fine on JavaScript detecting if the #tweetaddress has changed. BUT...
The problem:
...if the user starts typing right next to the #tweetaddress, the styling from the 'never-change' class applies to all the new text. Is there a way to limit my to only include the #tweetaddress, so that all new text into the div is outside it and not blue?
I've tried initially putting different spans on either side of the #tweetaddress 'never-change' span, but if the user deletes the characters in the other spans and then retypes, the new letters still come out blue.
I'd really love to hear any ideas on how I could proceed.
HTML
<div contenteditable id="text-input" placeholder="Tweet text here">First words of tweet,<span class="never-change">#tweetaddress</span> last words of tweet</div>
CSS:
.never-change{
color:blue;
}
JS:
$('#text-input').keydown(function() {
textStart = $(this).html();
tweetAddress = '#tweetaddress';
}
$('#text-input').keyup(function() {
textEnd = $(this).text();
if (textEnd.indexOf(placeholderText) > -1){
return false;
} else {
alert("Twiiter name. Cannot edit");
$(this).html(textStart);
}
Thank you in advance.

js regex: replace a word not follows or not followed by a certain word

I want to replace the "word" that is outside "span", and keep the other that is inside "span". By now, the following code works when both are following "mark>" and followed by "span". But I want to go further, following "mark>" OR being followed by "span", any one of the two condition should cause replacing action.
var replaceString = "newWord";
var htmlString = "This <span style='color:red' title='mark'>normal word</span> need no change. This word is to be replaced. <span>Another word</span> need no change.";
var reg=new RegExp("(?!mark>)"+replaceString+"(?!<\/span>)","gi");
var bb=htmlString.replace(reg,replaceString);
alert(bb)
// Final result should be "This <span style='color:red' title='mark'>normal word</span> need no change. This newWord is to be replaced. <span>Another word</span> need no change.";
UPDATE: using title as mark. adding starting tag span
UPDATE: Follow the suggestion below, I'm trying to solve the problem in anohter way, see here: js regex: replace words not in a span tag
Would you be comfortable using another span tag ?
By putting a class name inside it, you should be able to change the words you need to change by changing the content of every span containing that class.
Something like :
This <span style='color:red' mark>word</span> need no change. This <span class='changeMe'>word</span> is to be replaced. Another word</span> need no change.
And a jQuery script going
$('.changeMe').text("newWord")
If you still want to use Regexp, for an OR condition, you might just do it twice :
var reg=new RegExp("(?!mark>)"+replaceString,"gi");
var bb=htmlString.replace(reg,replaceString);
reg=new RegExp(replaceString+"(?!<\/span>)","gi");
bb=htmlString.replace(reg,replaceString);
You are looking for negative look-aheads (or Lookbehinds) which JS, unfortunately, doesn't support. Check http://www.regular-expressions.info/javascript.html
You may try the following Regex:
var reg = new RegExp('[^(mark>)]word[^(</span>)]', "gi")
htmlString.replace(reg, " newWord "); //Check the spaces
I would rather suggest using JS to get DOM elements and replace text iterative-lly (not sure if it's a word, even a jargon).
HTH

Select text and add a tag to it

There are a lot of question about this topic on SO but i can't seem to find any solution for my problem so i decide to ask my question. My situation is i have a dropdown list with several option and a textarea inside iframe. When user select some text in the textarea and choose one option from dropdown list then the selected text will have an a tag wrap around it and the option value will become tag href. Here my code:
var optionTag = document.getElementById("option-id");
var optionValue = optionTag.options[optionTag.selectedIndex].value;
var iframe = document.getElementById("my-frame");
var iframeContent = iframe.contentDocument.body.innerHTML.split("<br>")[0];
//get user selected text
var iframeSelection = iframe.contentWindow.getSelection().toString();
// and wrap a tag around it then add href equal to value of option
var aTag = "" + iframeSelection +"";
// replace user selected text with new a tag
iframe.contentDocument.body.innerHTML = iframeContent.replace(iframeSelection,aTag)
This code work but it only replace the first word if that word already exist. For example:
lorem ipsum click dolor sit amet click spum
If user select the second word "click" and choose one option then my code will replace the only the first word "click" and if i have several word "click" it still only replace the first word, but if user select the word "ipsum" or "lorem" then it work fine. I don't know how to fix this please help. Thank!
p/s:
I don't want to replace all the "click" word, i only want to replace exact piece user selected.
The problem is that iframeSelection in your replace() call is "click", not the element you previously selected, so it's replacing the first occurence.
Instead, try getting the range of your selection, deleting it and appending your new element to that range.
var selection = iframe.contentWindow.getSelection();
range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(document.createElement(your_new_element));
I couldn't test without your HTML, a JSFiddle would help.
The problem is that Javascript String.replace() only works like you expect when using it with a RegExp pattern with the global flag set. Luckily, this answer has a nice solution.
Change this:
iframe.contentDocument.body.innerHTML = iframeContent.replace(iframeSelection,aTag);
...into this:
iframe.contentDocument.body.innerHTML = iframeContent.replace( new RegExp(iframeSelection, 'g'), aTag );
What it does is that it converts your search string into a RegExp object with the global flag set, so each occurrence gets replaced.
If your intention was to only replace the exact piece the user had selected it gets more complex, but you can find all the required bits from this answer.

jQuery to select text (inside a div tag) within text editor on tab event

I am currently using a html5 text editor (bootstrap-wysihtml5). I'm trying to use a "keypress" event (on tab) to select specific words within the text editor.
Here is an example of my text:
<div>
My name is {{name}} and I enjoy {{programming in Rails}}.
</div>
<div>
{{Friend Name}} suggested that we get in touch to {{catch up}}.
He spoke {{highly}} about you and said that we should {{get together sometime}}.
</div>
Goal: on 'keypress' tab event, highlight each word within {{ }}.
i.e.
1. Press tab once, will highlight {{name}}.
2. Press tab on the 2nd time, will highlight {{programming in Rails}}, & so on.
Here is what I have implemented so far:
$('#wysihtml5').each(function(i, elem) {
$(elem).wysihtml5({
"font-styles": true,
"events": {
"focus": function() {
$('.wysihtml5-sandbox').contents().find('body').on("keydown",function(event) {
event.preventDefault();
var numLoops = _.size($(this).children());
var keyCode = event.keyCode || event.which;
if (keyCode == 9){
// loop thru all children divs
for (var i = 0; i < numLoops; i++) {
// get array of all matched items {{}}
var sentence = $($(this).children()[i]).html();
var toSwap = sentence.match(/\{{(.*?)\}}/g);
var numSwap = _.size(toSwap);
// NEED TO FIGURE OUT: How to select matched item..and move to the next one on tab
}
}
});
}
}
});
});
Any thoughts? I've been spending 2 days on finding how to make this work. The following are the references for what I have looked at:
jQuery Set Cursor Position in Text Area
Selecting text in an element (akin to highlighting with your mouse)
javascript regex replace html chars
What Is A Text Node, Its Uses? //document.createTextNode()
What you want is the index of the Regex matches.
If you perform the Regex as follows:
var reg = /\{{(.*?)\}}/g; // The Regex selector
while(match=reg.exec(sentence)) { // Iterate all the matched strings
// match.index gives the starting position of the matched string
// match.length gives the length of the matched string, number of characters
}
You will get the position and length of all the matches which can be used for selection. The while loop iterates all the matches.
Save the matches and user their index and length values to select them one by one.
Edit
Back again. As you probably have experienced, selecting text in javascript is not the easiest task but it is completely doable.
I put together a small JSFiddle to demonstrate the technique I used to get the correct result. You can find it here.
I hope it's kind of clear and I tried to comment it well.
Of course, if you have any question, just ask!
Cheers!

Categories

Resources