Regex to extract particular attribute and innerHTML of a div inside contentEditable - javascript

Background
I am creating a #Name Tagging system for my webpage. and I've succeeded in finding names on keystroke and replace the content with equivalent div class='tag' data-id='User-id'>Name</div>(at least for displaying). Now before submitting those contents from contentEditable div. I modify them in a textarea (which is usually hidden).
Working
As soon as .keyup event occurs on contentEditable all the contents of contentEditable are processed by function MakeItForWeb(contentEditable). Which then Manipulates the contents of textarea which will be processed by server side php script. that php script will strip all the tags and then store data in DB. so before submitting I try to replace all the .tag div with following format of data:
#["id":"User-id","Tag":"User-Name"];
In <textarea>, I have created a regular expression in javascript to achieve the task. and it is working fine, when there is single .tag in single line, You can see it Here.
Problem
When More than 1 .tag occurs in a single line then My regex fails to recognize all of them correctly, and recognize only last of them. And thus whole tagging system crashes, You can see it Here. May be My approach is wrong. Can Experts here help me out please? any suggestion is welcome.
My Efforts(Code)
JavaScript + JQuery:
$(document).ready(function(){
$("body").attr("spellcheck","false");
$("#tarea").keyup(function(e){ // Process KeyUp Event
/* Code to find Names on #N..and create a tag is omitted purposefully as it is working fine */
// Make each tag Un-editable, So that User cant change it
$(".tag").each(function(){
$(this).attr("contentEditable","false");
});
//Manipulate the textarea with equivalent value
MakeItForWeb(this);
}).focus(function(){
//Manipulate the textarea with equivalent value from contentEditable
MakeItForWeb(this);
});
$("#tarea").trigger("keyup"); // Trigger keyUp event as soon as DOM ready.
});
function MakeItForWeb(x){
var htm=$(x).html(); // Contents of contentEditable
htm=htm.split("<br>").join("\n"); // Replace <br> with \n character
htm=htm.split(" ").join(" ");
htm=htm.trim(); // Trim contents
/* Here is My regex which does the mentioned task */
htm=htm.replace(/<div(.*) data-id=\"(.*)\" (.*)>(.*)<\/div>/g,"#['id':'$2','tag':'$4'];");
document.getElementById("opc").value=htm; // <textarea> = ContentEditable processed.
}
Note the Line:
htm=htm.replace(/<div(.*) data-id=\"(.*)\" (.*)>(.*)<\/div>/g,"#['id':'$2','tag':'$4'];");
// This is My Regex.
// where var htm=contentEditable.innerHTML;
HTML:
<div id="tarea" contentEditable="true" class="tarea" autocorrect="false" spellCheck="off">
Hello Says! <div class="tag" data-id="1005">Vedant Terkar</div> , <br />To all <div class="tag" data-id="1006">SO Users</div> :-).
</div>
<!-- This textarea is Usually Hidden -->
<textarea id="opc" rows="5" cols="97">
</textarea>
css is irrelevant to problem, so not posting it.
Hope experts here will help me out. Thanks in advance :-) !

Regex:
<div\b.*?\bdata-id=\"([^"]*)\">([^<]*).*?\/>([^<]*)<div\b.*?\bdata-id=\"([^"]*)\">([^<]*).*
Replacement string:
#['id':'$1','tag':'$2']; , $3#['id':'$4','tag':'$5'];
DEMO

Get the matched group from index 1 and 2. I used Lazy way.
<div class="tag" data-id=\"([^\"]*?)\">([^<>]*?)<\/div>
here is online DEMO
Try this one to get the "Hello Says!" and "To all" as well in 3 catapulting groups.
>\s*([^<>]*)<div class="tag" data-id=\"([^\"]*?)\">([^<>]*?)<\/div>
here is online DEMO

Related

javascript replace text after the page has loaded

I want to remove/hide a piece of text that loads on my page.
The element doesn't have an id to relate to so I want to use a text-specific method.
Let's say the text is:"remove this line of text".
The html looks like this:
<div class="aClassName">
<p>
<strong>remove this line of text</strong>
... the rest of the content.
</p>
I have tried the following:
jQuery(document).ready(function($){
document.body.innerHTML = document.body.innerHTML.replace('remove this line of text', '');
});
Didn't work. So I tried this:
jQuery(document).ready(function($){
$("body").children().each(function () {
$(this).html( $(this).html().replace(/remove this line of text/g,"") );
});
});
Didn't work. The idea is that after the page is loaded it removes the line.It doesn't produces any errors as well. Not even in the firebug.
Anyone?
Target Elements Based On Their Content
You could accomplish this using the :contains() pseudoselector in jQuery that would allow you to target certain elements based on their contents :
$(function(){
// This will remove any strong elements that contain "remove this line of text"
$('strong:contains("remove this line of text")').remove();
});
You can see a working example of this here.
Broader Approach (Just Targets Elements Based On Selectors)
If you wanted a more simply target it by a more general selector (i.e. any <strong> tags that appear beneath a class called aClassName :
$('.aClassName strong').remove();
You can see an example of this approach here.
I guess you can use find() and text(), i.e.:
$('.aClassName').find('strong').text("123");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="aClassName">
<p>
<strong>remove this line of text</strong>
... the rest of the content.
</p>
Or simply:
$('strong:contains("remove this line of text")').text("New text");
Update:
After analyzing the link supplied on the comments, you can use the following:
$('.payment_method_mollie_wc_gateway_ideal').find('strong').text("");

Using one onchange javascript function for all div

I have multiple <textarea>, sometime they are blank and sometime they are filled with text.
I want to insert a simple text code such as "<check>" which will automatically change to a check (\u2713).
Presently, my code is like this:
<textarea name="1-S" onchange="check(this.value)">
<check> //an input written by a user
</textarea>
<textarea name="1-NI" onchange="check(this.value)">
<check> //an input written by a user
</textarea>
<textarea name="1-C" onchange="check(this.value)">
<check> //an input written by a user
</textarea>
(This block of <textarea> gets repeated, but of course, with different name in each one.)
<script type="text/javascript">
function check(str){
var res = str.replace("<check>", "\u2713");
????
}
</script>
The output will then replace <check> into actual check symbol (\u2713)
The challenge is, I don't want to have to add ID to every <textarea> and then write a script for each one. So is there a way for me to use this one script to apply to all <textarea>???
Many thanks in advance!
You could use the getElementsByTagName method to create an array of your text area tags.
Since you're using jQuery:
$("textarea").each(function(index, textarea) {
// do replacement here
});
Note that you need to use HTML entities to put <check> into a textarea: <check>
Also, you can put a checkmark in without any Javascript like this: ✓
Yes. You can bind an event handler to all elements of a type using jquery.
$('textarea').on('change', function() {
var text = $(this).val();
if (text.match(/\<check\>/)) {
$(this).val(text.replace(/\<check\>/, "\u2713"));
}
});
The benefit of doing it this way is that you can remove your inline 'onchange' handlers from the html and consolidate your validation logic strictly to JavaScript.
To replace the actual textarea content you need to update the value of the textarea with the result of your String-replace regexp. var text = $(this).val() is just assigning the content of the textarea to the variable text, it's not a reference to the innerHTML portion of your textarea.
On a sidenote if you'd like to allow users to use shortcodes in a form, prefer square bracket syntax, e.g., [check].

Input field with attached text to the right

I'm doing a fancy comment list on my project, structured like this:
As you see, there's a comments list and at his bottom there's an input field (textarea) to submit a comment. Note that there's the current username attached to the right (let's call it a simple static appended text).
I just found this little JS to make an input field resize automatically by adapting it to the content.
function resizeInput() {
$(this).attr('size', $(this).val().length);
}
$('input[type="text"]').keyup(resizeInput).each(resizeInput);
But it's not enough. I need it for a textarea and I want it to behave correctly when a comment is long enough to wrap on another line. By definition, the input field is a box, and it obviously acts badly compared to what I want:
Instead, this should be the right behavior:
I looked everywhere and I can't think any way to implement this. Can somebody help me?
Here is a good plugin for textarea. But it using jQuery.
usage simple as always.
$(document).ready(function(){
$('textarea').autosize();
});
You could use the contenteditable attribute:
<span contenteditable="true">comment</span> by <span class="userName">someone</span>
It is supported in practically all browsers. Using the right CSS, you can underline the content and also limit the width.
I think you mean this
NOTE: No check for selection and bound to document. Exercise for the reader to bind to a specific field and swap it for a span
FiDDLE
$(document).keypress(function(e) {
var char = String.fromCharCode(e.which);
if (e.which==13) char = '<br/>'; // needs to handle backspace etc.
$("#textfield").append(char);
$("#hiddenfield").val($("#textfield").text()); // or .html if you want the BRs
e.preventDefault();
});
using
<span id="textfield"></span> - by My Username
If you make the field contenteditable you will get this in Chrome so some additional CSS may be needed
Use a <span> with contenteditable (supported in IE too). Here is a fiddle: http://jsfiddle.net/goabqjLn/2/
<span contenteditable>Insert a comment...</span> by My Username
Then, using JavaScript, attach an event listener that mirrors the inner text of the span into a hidden input field, so it gets submitted with your <form>.
Edit: I have updated the fiddle to also include the JS code. Here is the updated code:
<span class="editor" id="editor" contenteditable data-placeholder="Insert a comment...">Insert a comment...</span> by My Username
<!-- Hide this textarea in production: -->
<textarea type="text" id="comment"></textarea>
And the JS:
function mirror() {
var text = $('#editor').html().trim()
.replace(' ', ' ')
.replace(/<br(\s*)\/*>/ig, '\n') // replace single line-breaks
.replace(/<[p|div]\s/ig, '\n$0') // add a line break before all div and p tags
.replace(/(<([^>]+)>)/ig, ""); // remove any remaining tags
$('#comment').val(text);
}
$('#editor').focus(function () {
var editor = $(this);
if (editor.text() == editor.attr('data-placeholder')) {
editor.text('');
}
}).blur(function () {
var editor = $(this);
if (editor.text() == editor.attr('data-placeholder')) {
editor.text(editor.attr('data-placeholder'));
}
}).blur(mirror).keyup(mirror);

Can jQuery or Javascript change elements within textareas?

My first SO question! Here's what I am trying to do:
I'm rewriting a tool that generates some code a user can paste directly into Craigslist and other classified ad posting websites. I have created a list of websites (they populate from a database with PHP) the user can choose from with a radio button, and I want their choice to populate as bare text (not a link) between some <p></p> elements in a textarea. I'm using jQuery for this.
Textarea before the user chooses:
<p id="thing"></p>
Textarea after the user chooses:
<p id="thing">www.somewebsite.com</p>
HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<textarea>
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
JS
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
alert(website);
$("#thing2").html(website);
});
});
JS Fiddle (With comments)
If you see the JS Fiddle, you can see that I put another p element on the page outside the textarea, and it updates just fine, but the one inside the textarea does not. I have read many other like questions on SO and I'm starting to think that I can't change an element that's between textarea tags, I can only change the entire textarea itself. Please, lead me to enlightenment!
You actually can fairly easily manipulate the text contents of the textarea like it is part of the DOM, by transforming its contents into a jQuery object.
Here is a jsFiddle demonstrating this solution: http://jsfiddle.net/YxtH4/2/
The relevant code, inside the input change event:
// Your normal code
var website = $(this).val();
$("#thing2").html(website);
// This turns the textarea's val into a jQuery object ...
// And inserts it into an empty div that is created
var textareaHtml = $('<div>' + $("#textarea").val() + '</div>');
// Here you can do your normal selectors
textareaHtml.find("#thing").html(website);
// And this sets the textarea's content to the empty div's content
$("#textarea").val(textareaHtml.html());
The empty div wrapping your HTML is so that you can easily retrieve it as a string later using jQuery's .html() method, and so the parse does not fail if additional text is entered around the p element inside the textarea.
The real magic is $($("#textarea").val()), which takes your textarea's text and parses it into an HTML node contained in a jQuery object.
It can't do it the way that you are thinking (i.e., manipulate it as if it were a DOM element), but it is still accessible as the value of the textarea, so you can retrieve it like that, use basic string manipulation to alter it, and then set the updated string as the new value of the textarea again.
Something like this . . . first give the <textarea> an id value:
<textarea id="taTarget">
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
Then alter your script like this:
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
var currentTAVal = $("#taTarget").val();
$("#taTarget").val(currentTAVal.replace(/(<p id="thing">)([^<]*)(<\/p>)/, "$1" + website + "$3"));
});
});
Unless you need the <p> element in there, you might consider using a more simple placeholder, since it won't actually act as an HTML element within the textarea. :)
EDIT : Fixed a typo in the .replace() regex.
I know that this answer is a little bit late, but here it goes =)
You can do exactly the way you want to do. But for that, you need to implement a small trick.
by having this HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com
<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<p id="thing2"></p>
<textarea id="textarea">
<p id="thing"></p>
</textarea>
you can edit textarea content, as a DOM by implementing something like the function changeInnerText
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val(); // Gets value of input
changeInnerText(website);
//$("#thing").html(website); // Changes
//$("#thing2").html(website); // Does not change
});
var changeInnerText = function(text) {
var v = $("#textarea").val();
var span = $("<span>");
span.html(v);
var obj = span.find("#thing")[0];
$(obj).html(text);
console.log(obj);
console.log(span.html());
$("#textarea").val(span.html());
}
});
As you can see, I just get the information from the textarea, I create a temporary variable span to place textarea's content. and then manipulate it as DOM.
Instead of attempting to insert the text into the <p> element, insert the text into <textarea> element and include the <p> tag. Something like this should do the trick:
Change:
$("#thing").html(website);
to:
$("textarea").html('<p id="thing">'+website+'</p>');
And here is a fiddle: http://jsfiddle.net/nR94s/

Add code examples on your page with Javascript

I have a html code inside string
string_eng += '<b>Year Bonus</b> - bonus for each year</br></br>';
And I want to put this inside textarea, but when I do it, the result is:
- bonus for each year
It simply deletes all things inside the html tags. I just want to show all the code inside the string. I already tried <xmp>,<pre>, but none of them worked.
Thanks for any help.
EDIT.
Code with which I input data from the array to the textarea/code.
$('body').append('<code class="code_text"></code>');
for(var i=0; i<tag_list.length; i++){
var string='';
string+='---------------------------------------------------------------------------------\n';
string+='tag: '+tag_list[i][0]+'\n';
string+='nazwa_pl '+tag_list[i][1]+'\n';
string+='nazwa_eng '+tag_list[i][2]+'\n';
string+='tekst_pl '+tag_list[i][3]+'\n';
string+='tekst_eng '+tag_list[i][4]+'\n';
string+='\n\n\n';
$('.code_text').append(string);
}
I tried this using jsfiddle:
HTML
<textarea id="code"></textarea>
JavaScript
$(document).ready(function() {
var string_eng = '';
string_eng += '<b>Year Bonus</b> - bonus for each year</br></br>';
$("#code").html(string_eng);
});
Output (contained in textarea)
<b>Year Bonus</b> - bonus for each year</br></br>
Try it here: http://jsfiddle.net/UH53y/
It does not omit values held within tags, however if you were expecting the <b></b> tags to render as bold within the textarea, or the <br /> tags to render as line breaks, this wont happen either. textarea does not support formatting.
See this question for more information: HTML : How to retain formatting in textarea?
It's because you're using the jQuery .append method which seems to parse the string and insert it afterwards. I don't know jQuery at all, so there might be another special jQuery method, but here is a simple fix:
$('.code_text').append(document.createTextNode(string));
Edit:
I just read and tried the answer of Salman A. The "special jQuery method" exists and he used it. You can use this:
$('.code_text').text(string);

Categories

Resources