When someone pastes content copied from a website or even a word document, textAngular adds additional break <br> tags before and after the content.
I'm using textAngular like this:
<text-angular name="summary" ng-model="summary" ta-paste="trimTags($html)" required>
</text-angular>
What I'd like to do is somehow trim the leading and trailing <br> tags.
The first approach I tried was writing a regex that will trim 2 leading and trailing <br> tags.
/(\<br\s*\/\>)(\<\/?body\>)(\<br\s*\/\>)/g
This works, but the changes are NOT reflected in the text presented. Is there a way to pass this $html being pasted and reflect the changes after modifying it?
Alternatively, I tried the ng-change approach, with no luck since it pastes the actual code, sometimes mixing <br> and <p> tags it adds.
Another problem is that, you could paste something in the middle of the text, which makes detecting changes difficult and time consuming.
A silly overlook, if anyone has trouble with this, use the ta-paste and the regex from the question, and after modifying the content simply return it.
$scope.trimTags = function(content){
//process the content
return content;
};
Related
In my MVC web application, I have a text area inside View, in that user will put HTML text so in that text, I want to replace html tags with my own custom tags.
For Example:
HTML tag:
<input type='text' name='MyList.First_Name' data-val='true' data-val-required='Please enter first name' />
Replace with:
[~TextFieldTag|MyList.First_Name|||0|data-val=>true|data-val-required=>Please enter first name|~]
Can anyone suggest what is the best approach to do this?
I was going to recommend a simple string replacement at first, but given the seemingly complicated nature of your replacements, that might not be the best approach.
Probably the best approach would be to take the HTML, convert it to DOM elements, which can be done simply by throwing it into an elements innerHTML:
document.querySelector('button').addEventListener('click', () => {
document.querySelector('#renderSpace').innerHTML = document.querySelector('textarea').value;
});
Add some HTML:
<textarea></textarea>
<button>Press Me</button>
<div id="renderSpace"></div>
You can position the area you render it inside of off-screen so users don't actually see it.
From there, I would walk the DOM tree (basically, start at the root, then look at all of its children, then their children, etc., recursively), reading off any properties that you deem appropriate and then writing your string replacement as you go along.
That does require that they have entered valid HTML (which is generally a requirement, but can be difficult to rely on users to enter), so you'll want to have some good, user-friendly, error handling in there.
I know this sounds like a bad move and I should just edit the html, however I really have no choice. I am working with a template for a rescue group and have no access to the html and just limited access to styles. To access the javascript I am hacking the tinymce plugin to inject scripts.
The html is pretty poorly formed and for the most part I can go in a hack around it, but I have found myself in the situation where I need to put a div around some of the html so I can give it a class and style them. However there is very little to go by.
The repeating html looks like this. This is the html I need wrapped in a div.
<b>Text</b>
<br>
"Some Text here annoyingly placed outside a tag."
<br>
"More text outside a tag."
<br>
"Title outside of tag"
<a>Link</a>
<br>
<br>
"More text and then a link"
<a>Link</a>
<br>
<br>
<a>Ending Link</a>
<hr>
The full html is in this fiddle https://jsfiddle.net/3h85vhcx/ There are very few id's and very little to work with.
Is there anyway to wrap this in a div tag using jquery/javascript?
It's not very clear.
But if I've understood a bit, you could get the body html as a string,
work on it adding what you need with a series of operations with substrings.
And then replace the body html with the new one.
But is it a client-side thing right?
Not best solution, but you can try this:
document.body.innerHTML = document.body.innerHTML.replace('<a name=Event' '<div><a name=Event');
document.body.innerHTML = document.body.innerHTML.replace('event.<br><br>', 'event.<br><br></div>');
It's far from best solution, but finding patterns and then replacing them will be a good start.
This stack helped me: Replace words in the body text
The jQuery function nextUntil associated with wrapAll can done that. According to your HTML, something like this could do the job:
$('hr').each(function() {
$(this).nextUntil('hr').wrapAll('<fieldset />')
});
Here is your jsfiddle updated: https://jsfiddle.net/5hudL6vk/
I wrapped the contents you want to match with a fieldset to be more obvious
After much trial an error and some progress I still can't mange to change every instance of ,- with kr on my website.
I'm very much a beginner at JS and have pieced together the following code from several sources. Is the code the problem or something else?
function skrivkr() {
var skrivkr = $('div').text().replace(/\,-/g, 'kr');
$('p').html(skrivkr);
}
window.onload = skrivkr();
Update:
Thanks for the replies. The site loads jquery 1.10.7.
#Niet the Dark Absol: No, I don't want to put anything in p elements. How do I remove that part? I just want to find all ,- and simply replace with kr without changing any formatting.
Update
OK! Progress, kind of. The ENTIRE content of every <strong> and <dd> now changes to (0), instead of kr. With the odd exception of those tags including ,-. I haven't designed the site myself.
If it helps, one of the ,- appears in the following markup:
<a href="xxxx" rel="nofollow">
<span class="amount">1</span>
<span class="photo">
<img src="xxxx" alt="product name" width="62" height="42">
</span>
<span class="description">
Prtoduct name
<strong>4444,-</strong>
</span>
</a>
And the lastest script I'm applying is:
$(document).ready(function() {
$('strong, dd').html($('strong, dd').html().replace(/,-/g, 'kr'));
});
As has been mentioned innumerable times here on SO, do not try to manipulate the DOM as a string. Pain awaits.
Instead, traverse the DOM, finding text nodes, and perform whatever transformation you want to make on each text node. There are many ways to do that.
In your case, you have many problems, as mentioned already by some of the commenters and responders:
You're setting window.onload to undefined (the result of calling skrivkr), instead of to skrivkr itself.
You're extracting the text value of an element, which consists of the concatenation of all text down all levels, performing the replacement, then sticking it back in with html. This will wipe out all the element structure below.
Minor point, but there's no need to escape the comma in the regexp.
You're extracting the textual content of all div elements in the entire document, transforming it, then adding that back as the content of all p elements in the entire document. It's hard to imagine that's what you want to do.
You can update the content of each div like this
$(document).ready(function() {
$('div').each(function(){
var newText = $(this).html().replace(/,-/g, 'kr');
$(this).html(newText);
});
});
You can remove the var "newText = " and replace it with $(this).html($(this).html().replace(/,-/g, 'kr'));
The first example is easier to understand perhaps if you are new to programming.
You will, however only change the content of text placed in tags.
I would place the text to replace in a div with some predefine class, like "autoKronor", it would then look like this:
<div class="autoKronor">123,-</div>
and
$(document).ready(function() {
$('.autoKronor').each(function(){
var newText = $(this).html().replace(/,-/g, 'kr');
$(this).html(newText);
});
});
to en sure that only text you intended to change gets changed..
Example here: http://jsfiddle.net/akm1uw8h/2/
Also note the use of $(document).ready(); instead of window.onload. It does what you intended to do with window.onload.
if you really want to change EVERY single instance of ",-" to "kr" then you could do this:
$(document).ready(function() {
$('body').html($('body').html().replace(/,-/g, 'kr'));
});
But i strongly advice against the last example because it will be the slowest to compute and more importantly you might change stuff you don't intend to, like any script block inside the page body (with that i mean other javascripts)
Currently I am working on storing textarea paragraph
<textarea rows="10"></textarea>
I can save the whole content but the problem is it does not include line breaks. I wonder what is the best practice of storing the space/line break from the textarea to database. Also, I need to prevent the user from inserting the inside the textarea.
Is it good parctice ?
e.g.
text=replace(text,"/n","<br>")
text=replace(text," "," ")
text=replace(text,"<script>","")
text=replace(text,"</script>","")
Thanks
It does store linebreaks, but when you do output in HTML you can not see it.
Use nl2br() function to convert linebreaks into <br /> tag so you can see linebreaks in HTML.
If you want to prevent some HTML tags in the text - use strip_tags() function (you can allow some tags if you wish). And don't forget to use mysql_real_escape_string() or something like this to escape data.
Another options except what Paul suggested are
Use the <pre> tag that actually brakes lines with /n .. that way you don't need to manipulate the text..
you will have to custom style the <pre> block as the defaults resembles console fonts and styles.
Use a disabled tag with custom styling to avoid manipulation of the text.
here is a fiddle to display both examples (I used JS to inject the values but it should work when you inject the from PHP as well):
http://jsfiddle.net/BvynR/
<pre id="pre">
</pre>
<textarea id="textarea" disabled="disabled">
</textarea>
var str = "Hello I'm a pre-formatedt text \nand this is a new line";
$("#pre").html(str);
$("#textarea").text(str);
#pre
{
font-family: verdana,helvetica,arial,sans-serif;
font-size:1em;
}
#textarea
{
font-family: verdana,helvetica,arial,sans-serif;
font-size:1em;
width:100%;
border:none;
background: none;
}
If it was me, I would be inserting the data in exactly as you received it from the user. This is because you might need to pull out that data sometime in the future, and not have it in HTML - eg for a report or putting into a spreadsheet or someething else.
Of course you then need to be extra careful about pulling data out and displaying it on the page - but you should be doing that anyway, and you don't want to be relying on your input sanitation being perfect - you might need to replace/update it in the future.
Suppose I have
<input type="hidden" id="in1">
...
<p id="editable_p"></p>
<script>
$('#some_button').click( function() {
$('#in1').val($('#editable_p').text());
});
</script>
Clearly, my intention is to set the value of the hidden field to be the content of the <p> tag. This works, however it does not maintain line breaks, which is important for me. Is there a basic library function that will copy the value of the editable paragraph that maintains the linebreaks, or is there some kind of extended hack that must be performed to get this to work as I intend?
Thanks much in advance.
You may find there are a number of text nodes in your #editable_p.p and calling text() as per a lot of XML type environments, will just concatenate the strings from the text nodes found in the descendant tree, potentially losing structure. This operation can do weird stuff to line breaks and other whitespace.
To avoid this, iterate over the actual text nodes, and concatenate the strings yourself, adding \n end of lines as necessary. Assuming you have succeeded in this and have the string with line breaks, I think talereader could be correct that a textarea or similar may be needed to represent the resulting string, and submit it faithfully to a server.
Selecting text nodes with JQuery is already outlined in
How do I select text nodes with jQuery?