I'd like to know how can I apply a regular expression to replace something inside a div.
Example:
<div class="counter">
Number of viewers: 12
</div>
I want to replace 12 with 13. I usually do
$var = $('.counter').text().replace(/\d+/g, '13');
$('.counter').text($var);
But I find this solution gross and unoptimized, I want an one line solution in order for Javascript/Jquery not to keep in memory a variable which may contains ten thousand characters.
A one-liner will still suffer from the same problem: a string with 10,000 characters will be needlessly created.
The real problem is your HTML. Structure it better:
<div class="counter">
Number of viewers: <span id="num-viewers">12</span>
</div>
You can now update the number directly:
$('#num-viewers').text('13');
Related
I have some HTML code where at the most nested level there is some text I'm interested in:
<div class="main">
<div class="container">
<div class="output_area">
<pre>WHITE 34</pre>
</div>
<div class="output_area">
<pre>RED 05</pre>
</div>
<div class="output_area">
<pre>WHITE 16</pre>
</div>
<div class="output_area">
<pre>BLACK</pre>
</div>
</div>
</div>
What I need to do is I need to return the output_area elements only when their nested <PRE> element contains a word + a number (for example WHITE 05, and not just BLACK).
So this is what I did:
I made an array from all output_area elements:
output_areas = Array.from(document.getElementsByClassName('output_area'));
I filtered the output_areas array to only return those output_area elements whose nested <PRE> satisfies my condition of a word + a number, using a regexp, like so:
output_areas.filter(el => el.textContent.match(/^WHITE \d+$/g));
Now, what happens is this function will only return the first matching result, so I will get an object of length 1 containing just :
<div class="output_area">
<pre>WHITE 34</pre>
</div>
and the output_area element containing <PRE> with "WHITE 16" is not returned.
As you can see at the end of the regular expression I put a "g" to request a global search and not just stop at the first result.
Not understanding why this did not work, I tried to verify what would happen if I would use includes() to perform a search:
output_areas.filter(el => el.textContent.includes('WHITE')
(let's just forget about the numbers now, it's not important)
And what happens? This will also return only the first output_area...
But why??? What am I doing wrong?
I am not ashamed to say I've been banging my head on this for the last couple of hours... and at this point I just want to understand what is not working.
The only clue I think I got is that if I simplify my search using just a == or !=, for example:
output_areas.filter(el => el.textContent != "")) // return all not empty elements
I get back all output_area elements and not just the first one!
So I suspect there must be some kind of problem when using together filter() & match(), or filter() & includes(), but with relation to that my google searches did not take me anywhere useful...
So I hope you can help!
You should use trim here to remove space before and after the text
output_areas.filter( el => el.textContent.trim().match( /^WHITE \d+$/g ))
const output_areas = Array.from(document.getElementsByClassName('output_area'));
const result = output_areas.filter(el => el.textContent.trim().match(/^WHITE \d+$/g));
console.log(result);
<div class="main">
<div class="container">
<div class="output_area">
<pre> WHITE 34 </pre>
</div>
<div class="output_area">
<pre> RED 05 </pre>
</div>
<div class="output_area">
<pre> WHITE 16 </pre>
</div>
<div class="output_area">
<pre> BLACK </pre>
</div>
</div>
</div>
Answering myself as for some reason it then begin to work without any changes from my side... Yes, just one of those typical IT cases we all know... :)
Jokes aside, I think for some reason the webpage (the DOM) got stuck...
Probably the Jupyter Runtime (which was serving the page) had crashed without me noticing, and this caused somehow the kind of inconsistency I was looking at.
Moral of the story: if you see weird behaviour in the interaction with a Python Notebook, always go check the Jupyter Runtime status before getting stupid at trying to fix impossible errors.
I'm not sure what the issue with the Jupyter notebooks is, but generally speaking - based only on the HTML in the question - what I believe you are trying to do can be achieved using xpath instead of css selectors:
html = `[your html above]
`
domdoc = new DOMParser().parseFromString(html, "text/html")
const areas = domdoc.evaluate('//div[contains(./pre," ")]', domdoc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < areas.snapshotLength; i++) {
console.log(areas.snapshotItem(i).outerHTML)
}
The output should be the 3 divs meeting the condition.
I'm currently using 'data:post.snippet' for blogger mobile snippet.
<div class='post-body' style='color:black;'>
<b:if cond='data:post.snippet'><data:post.snippet/></b:if>
</div>
But its character length(140) is too low, and it doesn't give a line break between the headings and paragraphs. When there's a heading at the very start line break is necessary. Can someone please suggest me a javascript code to replace above code to overcome those two issues.
You can utilize the data:post.longSnippet data tag which has the limit of upto 300-400 character
<div class='post-body' style='color:black;'>
<b:if cond='data:post.snippet'><data:post.longSnippet/></b:if>
</div>
Otherwise, if you want to control the exact amount of text that you want to be visible in the snippet, then you can utilize the newly launched operator in the new themes
<div class='post-body' style='color:black;'>
<b:eval expr='snippet(data:post.body, {length: 450, links: false})' />
</div>
snippet(string, options)
Produces a short snippet from an HTML string.
options: Object specifying the snippeting options, which are:
links: boolean for whether to preserve anchors/links in the snippet.
Defaults to true.
linebreaks: boolean for whether to preserve linebreaks (tags) in the
snippet. Defaults to true.
ellipsis: boolean for whether to append an ellipsis (…) to the end of
the snippet. Defaults to true.
length: Number specifying the maximum length of the snippet.
Change
<div class='post-body' style='color:black;'>
<b:if cond='data:post.snippet'><data:post.snippet/></b:if>
</div>
To
<div class='post-body' style='color:black;'>
<data:post.body/>
</div>
It will render your post body with proper HTML markup till any jump break (if exists) or otherwise the full post body.
Consider including jump breaks for all your posts, you can do it through the rich post editor or directly in the post HTML using the code <!--more--> in the exact place where you want the break.
Javascript approaches are not mandatory to retreive post contents, Blogger natively do it.
I hope this is what you are looking for,
<div class='post-body' style='color:black;'>
<b:eval expr='snippet(data:post.body, {length: 200, links: false, linebreaks: false})' />
</div>
I'm editing a web page that has a list of doctors names and images wrapped in a div. I'm adding more to that list and my client wants all of the names in alphabetical order now. As apposed to manually doing that (I know my client will also be adding more doctors in the future)I tried writing a script to do the work for me. I wrapped each doctor in a div called "alphabetize," and set a span id of "lastName" around each doctor's last name.
<div class="alphabetize large-6 columns sameheight-wrap">
<div class="large-4 medium-4 columns sameheight PadT20"> <img src="../imgs/dev/crna-staff/John-Doe.jpg" alt=" John Doe, CRNA" class="pictureBottomBorder"> </div>
<div class="large-8 medium-8 columns contenttable sameheight PadT20">
<div class="border vmid text-center bgdblue PadB"> <span class="white medium"><strong>John<span id="lastName">Doe</span></strong><br>
</span> <span class="white PadT5"> MSN, Thomas Jefferson University School of Nurse Anesthesia</span> </div>
</div>
</div>
I placed the following script on that page;
<script>
var $divs = $("div.alphabetize");
$(function() {
var alphabeticallyOrderedDivs = $divs.sort(function (a, b) {
return $(a).find("#lastName").text() > $(b).find("#lastName").text();
});
$("#alpha").html(alphabeticallyOrderedDivs);
});
</script>
For some reason, the script is not working correctly. Doctors are out of order and i also need to add a variable to the code that sorts the last names with the first 3 letters. Can anyone help? Javascript is not my strong suit. Not sure if I missed something.
Below is a snippet that will show you how you can easily sort this. The major issue, however, is the following:
return $(a).find("#lastName").text() > $(b).find("#lastName").text();
The sort() function asks to return one of three values, 0 to maintain position, -1 to move it before the current element and 1 to move it after. That means that all you could ever return is after and not before, so your sort fails.
For the solution I would like to suggest using a data-attribute and no more HTML spans and styles that need to be rendered (and probably hidden afterwards), so here is my suggestion:
<div data-alphabetize="John Doe">John Does Content</div>
We can string together a couple of functions to get the correct output. We will need prototype.slice.call to convert the returned-by-querySelector NodeList to an Array, then we need to use sort to sort it alphabetically and finally we can use forEach to go through the array and insert the nodes in the correct position.
I am using vanilla JS - mostly to show how simple things can be done without loading up jQuery. You can, of course, do this with jQuery as well.
// Turn querySelectorAll NodeList into an Array
Array.prototype.slice.call(document.querySelectorAll('[data-alphabetize]'))
// Sort the array by data-alphabetize attribute (reverse order)
.sort(function(a, b){
return a.getAttribute('data-alphabetize') < b.getAttribute('data-alphabetize')
? 1 : -1;
})
// Insert every node in order
.forEach(function(v, i, a){
var parent = v.parentNode;
parent.removeChild(v);
parent.insertBefore(v, parent.childNodes[0]);
});
<div>
<div data-alphabetize="Beta">Joseph Alfred <strong>Beta</strong></div>
<div data-alphabetize="Alpha">Mark Unicode <strong>Alpha</strong></div>
<div data-alphabetize="Gamma">Graham <strong>Gamma</strong>-Python</div>
<div data-alphabetize="Omega">Matthew <strong>Omega</strong></div>
</div>
I have an ASP.NET website. Sometimes, an unknown DOM element with value "/n" appears in the source. Inspecting with Firebug shows that the HTML code is . Of course, I never added this code myself. It makes a long distance between two elements. Is there any way to prevent this?
Here is HTML:
<div id="ctl05_pnWareHouse">
<div class="detail_content_right_top">
<div class="detail_content_top_left">
<p class="name_content">
...
</p>
</div>
</div>
</div>
Building on bfavaretto's comment:
An invisible Unicode character may have sneaked into your code during a cut & paste. If this happened, your server-side source code may look fine, but ASP.NET is noticing a character you can't see, then encoding it as HTML.
As for how to fix it, try this:
1) Open the server-side code in your editor.
2) Manually highlight everything from the > in <div id="ctl05_pnWareHouse"> to the < at the beginning of <div class="detail_content_right_top">
3) Replace the characters there manually; i.e. type >, then enter, then <.
See if that solves your problem.
I'm having a problem writing a regular expression for matching HTML tags. I found a similar entry here, but this didn't quite work in my case.
Here's my test string:
<div id="div0" class="myclass">here's some text
that may include whitespace</div><div id="div1" class="myclass">
and some more here
</div>
And here's my regex based on the aforementioned entry:
<div[^>]*class="myclass">[^~]*?<\/div>
Note that I need to match the first instance of <div /> with class of "myclass." The content may have carriage returns. These <div> tags won't be nested.
Here's a rubular page for testing: http://rubular.com/r/vlfcikKMXk
That regex tested is not great. It is in fact matching as you want it to, but it is matching it multiple times (2 different matches), and not showing a difference, you only want the first match.
Go here:
http://gskinner.com/RegExr/
Test it there, turn off the 'global' you will see it working.