Replace HTML Comment along with string variable - javascript

In my project I have some html with comments surrounding text so I can find the text between particular comments and replace that text whilst leaving the comments so I can do it again.
I am having trouble getting the regex to work.
Here is an html line I am working on:
<td class="spaced" style="font-family: Garamond,Palatino,sans-serif;font-size: medium;padding-top: 10px;"><!--firstname-->Harrison<!--firstname--> <!--lastname-->Ford<!--lastname--> <span class="spacer"></span></td>
Now, here is the javascript/jquery that I have at the moment:
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
currentTemplate = $("#gentextCodeArea").text(); //fetch the text
var tokenstring = "<!--" + thistoken + "-->"
var pattern = new RegExp(tokenstring + '\\w+' + tokenstring,'i');
currentTemplate.replace(pattern, tokenstring + thisval + tokenstring);
$("#gentextCodeArea").text(currentTemplate); //put the new text back
I think I'm pretty close, but I don't have the regex right yet.
The regex ought to replace the firstname with whatever is entered in the textbox for $thisval (method is attached to keyup procedure on textbox).

Using plain span tags instead of comments would make things easier, but either way, I would suggest not using regular expressions for this. There can be border cases that may lead to undesired results.
If you stick with comment tags, I would iterate over the child nodes and then make the replacement, like so:
$("#fname").on("input", function () {
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
var between = false;
$("#gentextCodeArea").contents().each(function () {
if (this.nodeType === 8 && this.nodeValue.trim() === thistoken) {
if (between) return false;
between = true;
} else if (between) {
this.nodeValue = thisval;
thisval = '';
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
New first name: <input id="fname">
<div id="gentextCodeArea">
<!--firstname-->Harrison<!--firstname-->
<!--lastname-->Ford<!--lastname-->
<span class="spacer"></span></div>
What went wrong in your code
By using text() you don't get the comment tags. To get those, you need to use html() instead
replace() does not mutate the variable given in the first argument, but returns the modified string. So you need to assign that back to currentTemplate
It would be better to use [^<]* instead of \w+ for matching the first name, as some first names have non-letters in them (hyphen, space, ...), and it may even be empty.
Here is the corrected version, but I insist that regular expressions are not the best solution for such a task:
$("#fname").on("input", function () {
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
currentTemplate = $("#gentextCodeArea").html(); //fetch the html
var tokenstring = "<!--" + thistoken + "-->"
var pattern = new RegExp(tokenstring + '[^<]*' + tokenstring,'i');
currentTemplate = currentTemplate.replace(pattern, tokenstring + thisval + tokenstring);
$("#gentextCodeArea").html(currentTemplate); //put the new text back
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
New first name: <input id="fname">
<div id="gentextCodeArea">
<!--firstname-->Harrison<!--firstname-->
<!--lastname-->Ford<!--lastname-->
<span class="spacer"></span></div>

here is a function which will generate an appropriate Regular expression:
function templatePattern(key) {
return new RegExp(`<!--${key}-->(.*?)<!--${key}-->`);
}
the (.*?) means "match as little as possible," so it will stop at the first instance of the closing tag.
Example:
'<!--firstname-->Harrison<!--firstname--> <!--lastname-->Ford<!--lastname-->'
.replace(templatePattern('firstname'), 'Bob')
.replace(templatePattern('lastname'), 'Johnson') // "Bob Johnson"

$(function(){
function onKeyUp(event)
{
if(event.which === 38) // if key press was the up key
{
$('.firstname_placeholder').text($(this).val());
}
}
$('#firstname_input').keyup(onKeyUp);
});
input[type=text]{width:200px}
<input id='firstname_input' type='text' placeholder='type in a name then press the up key'/>
<table>
<tr>
<td ><span class='firstname_placeholder'>Harrison</span> <span class='lastname_placeholder'>Ford</span> <span class="spacer"></span></td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Related

Search that highlights text is having problems with special characters

I took this code from a blog which I don't remember the URL. The code is supposed to find in a list with many sections the text written by the user in an input field. If there is a match, the text will be highlighted; and if there is no match, the whole section will hide.
I've made a plunker so you can see how it works: Here's the link
This is the JS code:
$(document).ready(function() {
var $container = $('#global_div');
if (!$container.length) return true;
var $input = $('#searcher'),
$notfound = $('.not-found'),
$items = $container.find('.row'),
$item = $(),
itemsIndexed = [];
$items.each(function() {
itemsIndexed.push($(this).text().replace(/\s{2,}/g, ' ').toLowerCase());
});
$input.on('keyup', function(e) {
$items.each(function() {
$item = $(this);
$item.html($item.html().replace(/<span class="highlight">([^<]+)<\/span>/gi, '$1'));
});
var searchVal = $.trim($input.val()).toLowerCase();
if (searchVal.length) {
for (var i in itemsIndexed) {
$item = $items.eq(i);
if (itemsIndexed[i].indexOf(searchVal) != -1)
$item.removeClass('is-hidden').html($item.html().replace(new RegExp(searchVal + '(?!([^<]+)?>)', 'gi'), '<span class="highlight">$&</span>'));
else
$item.addClass('is-hidden');
}
} else $items.removeClass('is-hidden');
$notfound.toggleClass('is-visible', $items.not('.is-hidden').length == 0);
});
});
So far so good, but the problem is when there are certain characters in the html text or when writing some special characters in the input field. Please open the plunker so you can do the tests I'm about to tell you:
When writing down the letters "a", "s" or "n", you can see how it shows the &amp ; and &nbsp ; of the html. Also when writing down "&", and the whole thing breaks when writing a "." (point).
As I couldn't fix this, I added this code to avoid people from writing special characters in the input (this code isn't in the plunker, so you can test the errors):
$("#searcher").keypress(function(event) {
var character = String.fromCharCode(event.keyCode);
return isValid(character);
});
function isValid(str) {
return !/[~`!##$%\^&*()+=\-\[\]\\';/{}|\\":.<>\?]/g.test(str);
}
But there is still the problem when there are characters like &amp ; and &nbsp ; in the html and users write in the input field the letter "a", "s" or "n" ..or depending which other weird character be on the html.

Add a space between each character, but in a method

Hey :) I know a similiar question was asked before, but i just cant get it through. I want to create a method called something like makeMeSpaces, so my h2 text will have a space between each character.. and i might want to use it elsewhere aswell. I have this until now, from the logic point of view:
var text = "hello";
var betweenChars = ' '; // a space
document.querySelector("h1").innerHTML = (text.split('').join(betweenChars));
it also works pretty fine, but i think i want to do
<h2>Hello.makeMeSpaces()</h2>
or something like this
Thank you guys!
If you really want this in a 'reusable function,' you'd have to write your own:
function addSpaces(text) {
return text.split('').join(' ');
}
Then, elsewhere in code, you could call it like so:
var elem = document.querySelector('h2');
elem.innerHTML = addSpaces(elem.innerHTML);
Maybe this is what you want , not exactly what you showed but some what similar
Element.prototype.Spacefy = function() {
// innerText for IE < 9
// for others it's just textContent
var elem = (this.innerText) ? this.innerText : this.textContent,
// replacing HTML spaces (' ') with simple spaces (' ')
text = elem.replace(/ /g, " ");
// here , space = " " because HTML ASCII spaces are " "
space = " ",
// The output variable
output = "";
for (var i = 0; i < text.length; i++) {
// first take a character form element text
output += text[i];
// then add a space
output += space;
};
// return output
this.innerHTML = output;
};
function myFunction() {
var H1 = document.getElementById("H1");
// calling function
H1.Spacefy();
};
<h1 id="H1">
<!-- The tags inside the h1 will not be taken as text -->
<div>
Hello
</div>
</h1>
<br />
<button onclick="myFunction ()">Space-fy</button>
You can also click the button more than once :)
Note :- this script has a flow, it will not work for a nested DOM structure refer to chat to know more
Here is a link to chat if you need to discuss anything
Here is a good codepen provided by bgran which works better

Jquery: Copy text from a form to a DIV while checking the last letter

On my HTML form, users can enter their name.
Their name will then appear in a DIV as part of a book title.
The book title uses apostrophe 's (e.g. Amy's Holiday Album).
If the user enters a name which ends in a S, I don't want the apostrophe s to appear.
(e.g. it should be Chris' Holiday Album instead of Chris's Holiday Album).
I also only want this to occur if the form has a class of apostrophe. If this class does not exist, then the name should be copied as is without any apostrophe or 's'.
I know you can use slice() to get the last character of an element, so I thought I could combine this with an if statement. But it doesn't seem to work.
Here is JSFiddle
Here is my HTML:
<div><b class="title"></b> Holiday Album</div>
Here is my Jquery (1.8.3):
$(document).ready(function() {
$('.name').keyup(function() {
var finalname = text($(this).val());
var scheck = finalname.slice(-1);
var finaltitle;
if ($(".apostrophe")[0]) {
if (scheck == 's') {
finaltitle = finalname + "'";
}
else {
finaltitle = finalname + "'s";
}
$('.title').text(finaltitle);
}
else {
$('.title').text(finalname);
}
});
});
text method is not needed on
var finalname = $(this).val();
check fiddle
Use
var finalname = $(this).val();
instead of
var finalname = text($(this).val());
Simplified version
$(document).ready(function() {
//Code fires when user starts typing:
$('.name.apostrophe').keyup(function() {
if (this.value.indexOf("'s") != -1 ) {
$('.title').text(this.value.replace(/'s/g, "'"));
} else {
$('.title').text(this.value)
}
}); /* Capture Personalised Message */
});
This will also replace all occurrences of the 's with ' only.
Hope it helps!.

How to add html element to the current textarea value, and output it as raw html

I need to style the total cost for user added in a textarea.
I have this fragment of code:
$("#student_teacher_profile_for_teaching_amount").keyup(function(e) {
var new_str, price, regex, str;
regex = /[0-9]+\.[0-9]{1,2}|[0-9]/;
str = $(this).val();
console.log(str);
price = str.match(regex);
if(price) {
if( $("#to_teach_ammount").length > 0 ) {
$("#to_teach_ammount").html(price[0]);
} else {
new_str = str.replace(regex, "<span id='to_teach_ammount'>" + price[0] + "</span>");
$(this).val(new_str);
}
$("#to_teach_total").val(price[0]); #this is and hiddent input filed
}
});
As a result of it I get:
some text before numbers <span id='to_teach_ammount'>2</span>
in my textarea.
How can I convert this into raw HTML?
This is not possible with a common <textarea> element, which only accepts plain text. You will have to use a (rich-text)-plugin, for example with jQuery. Have a look here: http://www.strangeplanet.fr/work/jquery-highlighttextarea/
The to_teach_total should not be a textarea. Instead it should be an element which expects html
Then use $(this).html(new_str) to set html
This html() method can also be passed a function which can take old html as parameter and return a new string to be set as new html

jQuery / JavaScript - string replace

Assuming we have a comment textarea where the user can enter this code:
[quote="comment-1"]
How can I replace that code before the form submits with the actual html content from <div id="comment-1"> ?
You could try something like this:
http://jsfiddle.net/5sYFT/1/
var text = $('textarea').val();
text = text.replace(/\[quote="comment-(\d+)"\]/g, function(str,p1) { return $('#comment-' + p1).text(); });
$('textarea').val(text);
It should match agains any numbered quote in the format you gave.
You can use regular expressions:
text = text.replace(/\[quote="([a-z0-9-]+)"]/gi,
function(s, id) { return $('#' + id).text(); }
);
If I understand you correctly, you wish to replace something like '[quote="comment-1"]' with ''.
In JavaScript:
// Where textarea is the reference to the textarea, as returned by document.getElementById
var text = textarea.value;
text = text.replace(/\[quote\="(comment\-1)"\]/g, '<div id="$1">');
In jQuery:
// Where textarea is the reference to the textarea, as returned by $()
var text = textarea.val();
text = text.replace(/\[quote\="(comment\-1)"\]/, '<div id="$1">');
Hope this helps!

Categories