parse text using regex using jquery/javascript - javascript

txt = '<a class="info" href="/some/link" original-title="hello world <br/> Monday <br/> 2 days <br/> Test"> 10 </a>';
var pattern = /\s\d+/;
var parsed_data = parseInt((txt.match(pattern)||['0'])[0]);
Got this regex pattern from some example. I am trying to parse the text i.e. value 10 from the anchor tag. But the value obtained is 2.
EDIT:
I am using datatables to populate the tables.
And problem is the string i.e. txt is a row element, extracted from table using loop and need to add these values e.g.
var parsed_data += parseInt((txt.match(pattern)||['0'])[0]);

It is a very bad idea to parse a html content with regex, in this case use jQuery to fix it
var txt = '<a class="info" href="/some/link" original-title="hello world <br/> Monday <br/> 2 days <br/> Test"> 10 </a>';
var parsed_data = parseInt($(txt).text(), 10);
console.log(parsed_data)
Demo: Fiddle

You could have something like that:
var txt = '<a class="info" href="/some/link" original-title="hello world <br/> Monday <br/> 2 days <br/> Test"> 10 </a>';
var pattern = /.*>\s*(\d+)/;
var matches = txt.match(pattern);
var parsed = matches ? +matches[1] : 0;
However, this regexp takes just the last digit inside a tag (>): if you want to have something more precise, you should parse the HTML using the DOM – that is more expensive. It's really depends by what is your data, if you always have such format, you don't need the DOM.

Related

regex to replace "<p><br/></p>" string with empty string- Javascript [duplicate]

This question already has answers here:
How to keep Quill from inserting blank paragraphs (`<p><br></p>`) before headings with a 10px top margin?
(3 answers)
Closed 1 year ago.
I have some HTML as a string
var str= "<p><br/></p>"
How do I strip the p tags from this string using JS.
here is what I have tried so far:
str.replace(/<p[^>]*>(?:\s| )*<\/p>/, "") // o/p: <p><br></p>'
str.replace("/<p[^>]*><\\/p[^>]*>/", "")// o/p: <p><br></p>'
str.replace(/<p><br><\/p>/g, "")// o/p: <p><br></p>'
all of them return me same str as above, expected o/p is:
str should be ""
what im doing wrong here?
Thanks
You probably should not be using RegExp to parse HTML - it's not particularly useful with (X)HTML-style markup as there are way too many edge cases.
Instead, parse the HTML as you would an element in the DOM, then compare the trim()med innerText value of each <p> with a blank string, and remove those that are equal:
var str = "<p><br/></p><p>This paragraph has text</p>"
var ele = document.createElement('body');
ele.innerHTML = str;
[...ele.querySelectorAll('p')].forEach(para => {
if (para.innerText.trim() === "") ele.removeChild(para);
});
console.log(ele.innerHTML);
You should be able to use the following expression: <p[^>]*>( |\s+|<br\s*\/?>)*<\/p>
The expression above looks at expressions enclosed in <p>...</p> and matches them against , whitespace (\s+) and <br> (and / variations).
I think you were mostly there with /<p[^>]*>(?:\s| )*<\/p>/, but you just needed to remove ?: (not sure what you were trying to do here), and adding an additional case for <br>.
const str = `
<p><br></p>
<p><br/></p>
<p><br /></p>
<p> <br/> </p>
<p> </p>
<p> </p>
<p><br/> </p>
<p>
<br>
</p><!-- multiline -->
<p><br/> don't replace me</p>
<p>don't replace me</p>
`;
const exp = /<p[^>]*>( |\s+|<br\s*\/?>)*<\/p>/g;
console.log(str.replace(exp, ''));

add element/class to a first unique word from a string in javascript / jquery

I want to insert a tag from the first unique word from a string using javascript / jquery. It is something like:
jQuery(document).ready(function($){
$(".product_title:contains(NEW)").replace('NEW', '<span class="new">NEW</span>');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
FROM: <h2 class="product_title">NEW Jeep Wrangler</h2>
INTO: <h2 class="product_title"><span class="new">NEW</span>Jeep Wrangler</h2>
FROM: <h2 class="product_title">REBUILT Jeep Wrangler</h2>
INTO: <h2 class="product_title"><span class="rebuilt">REBUILT</span>Jeep Wrangler</h2>
I tried below approach to replace the first word with html code but didn't work: I received a Uncaught TypeError: $(...).replace is not a function on console.
How to achieve this? I can't find any examples on the web that is applying this similar approach. Please advise.
UPDATE: I think I'm close, I use below approach:
$('.product_title').each(function() {
var text = $(this).text();
$(this).text(text.replace('NEW', '<span class="cust-woo-title-tag-new">NEW</span>'));
});
But the tags are displaying on the front end.
get all the product_title that contains "NEW"
store the previous html value (eg. NEW Jeep Wrangler)
remove the "NEW" word (NEW Jeep Wrangler becomes Jeep Wrangler)
update the innerHTML
$(document).ready(function($){
//get all the product_title that contains "NEW"
let contains_new = $(".product_title:contains(NEW)");
for(let x = 0; x < contains_new.length; x++) {
//store the previous html value
let prev_html = contains_new[x].innerHTML;
//remove the "NEW" word in the prev_html
let new_html = prev_html.replace('NEW','');
//update the inner html
contains_new[x].innerHTML = `<span class"new">NEW</span>${new_html}`;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2 class="product_title">NEW Jeep Wrangler</h2>
<h2 class="product_title">NEW Jeep Wrangler</h2>
try to inspect element the result to view the html structure.
Something like this could work:
$('h2').each((i)=>{
txt=$(i).text().split(' ')
i_html = `
<span class ='${txt[0]}.toLocaleLowerCase()' >${txt.pop(0)}</span> ${txt.join(' ')}
`
$(i).html(i_html)
})
If you just want to do it for certain words, create a array with them and check with keywords.include(txt[0])

Save the textarea value and format [duplicate]

I am getting the value in a textarea when the user hits submit. I then take this value and place it elsewhere on the page. However, when I do this, it loses newline characters making the output pretty ugly.
Here is the textarea I am accessing:
<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required></textarea>
Here is the JavaScript code accessing the post and transcribing it.
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.append(postText);
var card = document.createElement('div');
card.append(post);
var cardStack = document.getElementById('#card-stack');
cardStack.prepend(card);
When the input is something like:
Group Schedule:
Tuesday practice # 5th floor (8 pm - 11 pm)
Thursday practice # 5th floor (8 pm - 11 pm)
Sunday practice # (9 pm - 12 am)
The output is:
Group Schedule: Tuesday practice # 5th floor (8 pm - 11 pm) Thursday practice # 5th floor (8 pm - 11 pm) Sunday practice # (9 pm - 12 am)
So is there a way to preserve line breaks?
The easiest solution is to simply style the element you're inserting the text into with the following CSS property:
white-space: pre-wrap;
This property causes whitespace and newlines within the matching elements to be treated in the same way as inside a <textarea>. That is, consecutive whitespace is not collapsed, and lines are broken at explicit newlines (but are also wrapped automatically if they exceed the width of the element).
Given that several of the answers posted here so far have been vulnerable to HTML injection (e.g. because they assign unescaped user input to innerHTML) or otherwise buggy, let me give an example of how to do this safely and correctly, based on your original code:
document.getElementById('post-button').addEventListener('click', function () {
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.append(postText);
var card = document.createElement('div');
card.append(post);
var cardStack = document.getElementById('card-stack');
cardStack.prepend(card);
});
#card-stack p {
background: #ddd;
white-space: pre-wrap; /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
width: 100%;
}
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:
Tuesday practice # 5th floor (8pm - 11 pm)
Thursday practice # 5th floor (8pm - 11 pm)
Sunday practice # (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>
Note that, like your original code, the snippet above uses append() and prepend(). As of this writing, those functions are still considered experimental and not fully supported by all browsers. If you want to be safe and remain compatible with older browsers, you can substitute them pretty easily as follows:
element.append(otherElement) can be replaced with element.appendChild(otherElement);
element.prepend(otherElement) can be replaced with element.insertBefore(otherElement, element.firstChild);
element.append(stringOfText) can be replaced with element.appendChild(document.createTextNode(stringOfText));
element.prepend(stringOfText) can be replaced with element.insertBefore(document.createTextNode(stringOfText), element.firstChild);
as a special case, if element is empty, both element.append(stringOfText) and element.prepend(stringOfText) can simply be replaced with element.textContent = stringOfText.
Here's the same snippet as above, but without using append() or prepend():
document.getElementById('post-button').addEventListener('click', function () {
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.textContent = postText;
var card = document.createElement('div');
card.appendChild(post);
var cardStack = document.getElementById('card-stack');
cardStack.insertBefore(card, cardStack.firstChild);
});
#card-stack p {
background: #ddd;
white-space: pre-wrap; /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
width: 100%;
}
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:
Tuesday practice # 5th floor (8pm - 11 pm)
Thursday practice # 5th floor (8pm - 11 pm)
Sunday practice # (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>
Ps. If you really want to do this without using the CSS white-space property, an alternative solution would be to explicitly replace any newline characters in the text with <br> HTML tags. The tricky part is that, to avoid introducing subtle bugs and potential security holes, you have to first escape any HTML metacharacters (at a minimum, & and <) in the text before you do this replacement.
Probably the simplest and safest way to do that is to let the browser handle the HTML-escaping for you, like this:
var post = document.createElement('p');
post.textContent = postText;
post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');
document.getElementById('post-button').addEventListener('click', function () {
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.textContent = postText;
post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n'); // <-- THIS FIXES THE LINE BREAKS
var card = document.createElement('div');
card.appendChild(post);
var cardStack = document.getElementById('card-stack');
cardStack.insertBefore(card, cardStack.firstChild);
});
#card-stack p {
background: #ddd;
}
textarea {
width: 100%;
}
<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:
Tuesday practice # 5th floor (8pm - 11 pm)
Thursday practice # 5th floor (8pm - 11 pm)
Sunday practice # (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>
Note that, while this will fix the line breaks, it won't prevent consecutive whitespace from being collapsed by the HTML renderer. It's possible to (sort of) emulate that by replacing some of the whitespace in the text with non-breaking spaces, but honestly, that's getting rather complicated for something that can be trivially solved with a single line of CSS.
The target container should have the white-space:pre style.
Try it below.
<script>
function copycontent(){
var content = document.getElementById('ta').value;
document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
line 1
line 2
line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target' style='white-space:pre'>
</p>
function get() {
var arrayOfRows = document.getElementById("ta").value.split("\n");
var docfrag = document.createDocumentFragment();
var p = document.getElementById("result");
while (p.firstChild) {
p.removeChild(p.firstChild);
}
arrayOfRows.forEach(function(row, index, array) {
var span = document.createElement("span");
span.textContent = row;
docfrag.appendChild(span);
if(index < array.length - 1) {
docfrag.appendChild(document.createElement("br"));
}
});
p.appendChild(docfrag);
}
<textarea id="ta" rows=3></textarea><br>
<button onclick="get()">get</button>
<p id="result"></p>
You can split textarea rows into array:
var arrayOfRows = postText.value.split("\n");
Then use it to generate, maybe, more p tags...
Here is an idea as you may have multiple newline in a textbox:
var text=document.getElementById('post-text').value.split('\n');
var html = text.join('<br />');
This HTML value will preserve newline. Hope this helps.
You could set width of div using Javascript and add white-space:pre-wrap to p tag, this break your textarea content at end of each line.
document.querySelector("button").onclick = function gt(){
var card = document.createElement('div');
card.style.width = "160px";
card.style.background = "#eee";
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.style.whiteSpace = "pre-wrap";
card.append(post);
post.append(postText);
document.body.append(card);
}
<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required>
Group Schedule:
Tuesday practice # 5th floor (8pm - 11 pm)
Thursday practice # 5th floor (8pm - 11 pm)
Sunday practice # (9pm - 12 am)</textarea>
<br><br>
<button>Copy!!</button>
I suppose you don't want your textarea-content to be parsed as HTML. In this case, you can just set it as plaintext so the browser doesn't treat it as HTML and doesn't remove newlines No CSS or preprocessing required.
<script>
function copycontent(){
var content = document.getElementById('ta').value;
document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
line 1
line 2
line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target'></p>
Similar questions are here
detect line breaks in a text area input
detect line break in textarea
You can try this:
var submit = document.getElementById('submit');
submit.addEventListener('click', function(){
var textContent = document.querySelector('textarea').value;
document.getElementById('output').innerHTML = textContent.replace(/\n/g, '<br/>');
});
<textarea cols=30 rows=10 >This is some text
this is another text
Another text again and again</textarea>
<input type='submit' id='submit'>
<p id='output'></p>
document.querySelector('textarea').value; will get the text content of the
textarea and textContent.replace(/\n/g, '<br/>') will find all the newline character in the source code /\n/g in the content and replace it with the html line-break <br/>.
Another option is to use the html <pre> tag. See the demo below
var submit = document.getElementById('submit');
submit.addEventListener('click', function(){
var content = '<pre>';
var textContent = document.querySelector('textarea').value;
content += textContent;
content += '</pre>';
document.getElementById('output').innerHTML = content;
});
<textarea cols=30 rows=10>This is some text
this is another text
Another text again and again </textarea>
<input type='submit' id='submit'>
<div id='output'> </div>

only first value is changed when iterating through express-handlebars each

I am using express-handlebars in my node application. In one of my forms I am storing data in the format 2018-12-01 (YYYY MM DD) as a string. I am also storing time as string in 24 hour format 13:45:00
I have defined a script to use moment for changing the date format:
<script type="text/javascript">
(function () {
var NowMoment = $('#displayMoment').val();
var Date = moment(NowMoment);
var eDisplayMoment = document.getElementById('output');
// display output in the preferred format
eDisplayMoment.innerHTML = Date.format('MMM Do YYYY');
})();
</script>
in my .handlebars template I am displaying the data received using the following code:
{{#each tasks}}
<input id="displayMoment" value="{{taskDate}}" hidden>
<p>{{taskName}} {{taskDate}} {{taskTime}} {{taskStatus}} <span id="output"></span>
<a class="btn u-btn-primary g-rounded-50 g-py-5" href="/starttask/{{id}}">
<i class="fa fa-edit g-mr-5"></i> start task
</a>
</p>
{{/each}}
as you can see I have a hidden input which is assigned the {{taskDate}}, I fetch its value in the script and format it to display in the span tag.
The Problem is:
Only the first task is formatting the date and showing it, the second or consecutive tasks do not show the formatted date.
The id cannot be the same. The HTML specification requires it to be unique. So can lets remove the id attribute from your span and input elements and instead give them an appropriate class attribute definition instead:
<span class="output"></span>
<input class="displayMoment" value="{{taskDate}}" hidden>
Then lets use getElementsByClassName(...) instead of document.getElementById(...) since according to the documentation, getElementById() returns a single element object representing the element whose id property matches the specified string. Assuming a 1 to 1 relationship between input values and the spans we are trying to change the value for we can do something along the lines of this:
<script type="text/javascript">
(function () {
var inputEles = document.getElementsByClassName("displayMoment");
var spanEles = document.getElementsByClassName("output");
for(var i=0; i<spanEles.length; i++) {
var Date = moment(inputEles[i].value);
spanEles[i].innerHTML = Date.format('MMM Do YYYY');
}
})();
</script>
Hopefully that helps!

Get text between tags using javascript

I am trying to get prices from between span tags. I would like to have all prices in an array. I cant seem to get it to work, I am guessing my regex is incorrect.
I am looking for any span tags with the class 'amount', the tag has no other attributes set and only has one class. E.g. <span class="amount">£9.99</span>
var prices = resp.fragments['data'].match(/<span class=\"amount\">(.*?)<\/span>/g)
.map(function(val){
return val;
});
Output
[ '£9.99', '£100.00' ]
I am trying to get prices from between span tags. I would like to have all prices in an array. I cant seem to get it to work, I am guessing my regex is incorrect.
I am looking for any span tags with the class 'amount', the tag has no other attributes set and only has one class. E.g. <span class="amount">£9.99</span>
var prices = resp.fragments['data'].match(/<span class=\"amount\">(.*?)<\/span>/g)
.map(function(val){
return val;
});
Output
[ '£9.99', '£100.00' ]
* UPDATE *
Turns out it was an encoding with the ajax response resp.fragments['data'].
I was using regex as it is something I have not really used before in JS and thought I would have a play. I did look at many examples and after about 45 mins with no success I thought a fresh set of eyes would fix it.
#spaceman
Thanks for the helpful comment. Your one of those people if someone asked "Is there is a doctor in the house?", you would stand up and say "Sweet load there are loads of doctors out there".
While a regular expression could work for this, it might be easier to simply select the <span class='amount'> elements and map their innerHTML content to an array via the map() function:
// This would yield an array containing your values
var amounts = Array.prototype.slice
.call(document.querySelectorAll('span.amount'))
.map(function(a){ return a.innerHTML; });
You can see a working example of this demonstrated here.
Simplest method will be to add this to an invisible DOM object and then traverse it via DOM API
var text = '<span class="amount">£9.99</span><span class="amount">£9.99</span>'
//now append it to an DOM object
var wrapperDiv = "<div style='display:none' id='tmpDiv'>" + text + "</div>";
document.body.innerHTML += wrapperDiv;
var elements = document.querySelectorAll( "#tmpDiv amount" );
var output = Array.prototype.slice.call( elements ).map( function(val){
return val.innerText;
})
Another approach could be split the text by <span class="amount"> and get the value after first index
DEMO
var text = '<span class="amount">£9.99</span><span class="amount">£9.99</span>'
var output = [];
text.split('<span class="amount">').forEach( function(val, index) {
if (index > 0 )
{
output.push( val.replace( "</span>", "" ) );
}
});
document.body.innerHTML += JSON.stringify( output, 0, 4 );
You can use this instead.
var prices = document.getElementsByClassName('amount');
var price_array = [];
for (i= 0; i < prices.length; ++i) {
price_array.push(prices[i].innerHTML);
}
document.write(" | " + price_array);
<span class='amount'>£123</span>
<span class='amount'>£3</span>
<span class='amount'>£5</span>
<span class='amount'>£64</span>
You don't need to use regex or jQuery for this.

Categories