How to convert an element into 2 elements with jquery - javascript

I have this element:
<h4>username (role) on 26 Nov 2018 20:39:42 +00:00:</h4>
and I need it to be like this:
<h4>username (role)</h4>
<p>on 26 Nov 2018 20:39:42 +00:00:</p>
There will always be 2 words in the <h4> element, but those words will vary. The <p> element will be dynamically updated to the current date and time, but will always start with "on" and end with "00:".
How can I achieve this outcome? I'm using jQuery but am fairly new to it, so I can't seem to find the right approach.

You can split on on and then use after() to create a new p:
$('h4').each(function() { // use an each so it will work if there are multiple on a page
var $h4 = $(this),
text = $h4.text(),
textParts = text.split(' on'); // split on ` on`
if (textParts.length == 2) { // only update if there is a paragraph
$h4.text(textParts[0]).after('<p>on ' + textParts[1] + '</p>'); // update the h4 text and put the new paragraph after it
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h4>username (role) on 26 Nov 2018 20:39:42 +00:00:</h4>

It will be better to fix this kind of cases without the use of the JS code, but if you don't have access to the source and you really need a JS soltion, check this one:
var h4_p = $('h4').text().split(' on');
$('h4').text(h4_p[0]);
$('<p>on ' + h4_p[1] + '</p>').insertAfter($('h4'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h4>username (role) on 26 Nov 2018 20:39:42 +00:00:</h4>

Code
// gets the header element and caches it since we use it twice
let header = $('h4');
// get header text
let headerText = header.text();
// run regex to get the items we need
let result = /(.*?) (on .*)/i.exec(headerText);
// create a new header for the first group found
let newHeader = '<h4>' + result[1] + '</h4>';
// create the paragraph with the second group found
let newParagraph = '<p>' + result[2] + '</p>';
// replace the current header with the new one
header.replaceWith(newHeader + newParagraph);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h4>username (role) on 26 Nov 2018 20:39:42 +00:00:</h4>
Description
This answer utilizes regex and jquery to get the current header and then create the new elements.

Quick and dirty solution:
var split = $("h4").text().split(" ");
var newhtml = "<h4>"+split[0]+" "+split[1]+"</h4>";
newhtml += "<p>";
for(i = 2; i < split.length;i++){
newhtml += split[i]+" ";
}
newhtml += "</p>";
alert(newhtml)

Related

How to split a single line of text after n words + style separately?

I have a single line of text which is the post title and it looks like this:
<h2 class="title">
Report 10/2019 The name of the report
</h2>
I'd like to be able to:
a) split the name of the link title after the year;
b) style separately the "Report 10/2019" and the rest of the name in two different ways (preferable adding a class to each part - or at least the first part).
I managed to split the text using this:
var breakAt = 17;
var brokenString = $(".title a").html();
brokenString = brokenString.substring(0, breakAt) + "<br>" + brokenString.substring(breakAt);
$(".title a").html(brokenString);
But this divides the name by number of characters, whereas it would be safer to split after X number of spaces (in this case after second space) - the number of the month will be one character or two.
And don't know how to apply different styling to the two parts of the title link.
Loop over all the titles, get their content, apply a regular expression and wrap the substring from the beginning to the year (4 digits) into a span (or another element if you prefer)
Then apply a style to the span (e.g a bolder font and display: block) so the remaining part starts on a new line)
var titles = document.querySelectorAll('.title a');
[...titles].forEach((title) => {
var content = title.textContent;
content = content.replace(/(^.+?\d{4})/, '<span>$1</span>');
title.innerHTML = content;
})
.title a {
color: #333;
font-weight: 400;
}
.title span {
font-weight: 700;
display: block;
}
<h2 class="title">
Report 10/2019 The name of the report
</h2>
<h2 class="title">
Another Report 3 / 2019 The name of the report
</h2>
You can try using split function and second space from string:
$(document).ready(function(){
var string = $('.title a').text();
var report_date = string.split(' ').slice(0, 2).join(' ');
var report_title = string.replace(report_date, '').trim();
});
There's two key things you need:
RegExp, for better and more dynamic pattern matching
span tags, since you want to add classes (you can't do this if you just split the two parts with a br - they're still just text nodes)
So, the question for the RegExp is, how do we define the breakpoint? Well, it seems sensible to use the datestamp for that. First we'll grab it:
let a = $(".title a"),
let part_1 = a.text().match(/^.+\d{2}\/\d{4}/);
Then we need to remove what we just matched from the overall string, to give us the second part. We'll also remove the whitespace between the two parts.
let part_2 = a.text().replace(part_1[0], '').trim();
The last thing is to put these two parts into span tags inside the a.
$('<span>').addClass('part-1').text(part_1[0]).appendTo(a);
$('<span>').addClass('part-2').text(part_2).appendTo(a);
You might want to use regular expression, since the length of the first part of the string might be dynamic. This pattern should do the work of splitting your string into two parts: one with the report + month/year, and the other with the report name:
/^(.*?\/\d{4})(.*?)$/
See proof-of-concept here:
const links = document.querySelectorAll('h2.title a');
Array.prototype.forEach.call(links, (link) => {
const textRegex = /^(.*?\/\d{4})(.*?)$/gi;
const matches = textRegex.exec(link.textContent);
const reportYear = matches[1].trim();
const reportName = matches[2].trim();
link.innerHTML = `<span class="year">${reportYear}</span><span class="name">${reportName}</span>`;
});
.title a span {
display: block;
}
.year {
color: red;
}
.name {
color: green;
}
<h2 class="title">
Report 10/2019 The name of the report
</h2>
If you want to break the string based on the number of spaces, you can use split.
Here is an example:
var stringToBreak = $(".title a").html();
var brokenArr = stringToBreak.split(' ');
var txtToStyle1 = brokenArr.slice(0, 2).join(' ');
var txtToStyle2 = brokenArr.slice(2).join(' ');
$(".title a").empty();
$(".title a").append(
$("<span>").html(txtToStyle1).css('color', 'red')
).append(
$("<span>").html(' ' + txtToStyle2)
);
a {
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2 class="title">
Report 10/2019 The name of the report
</h2>
here is a solution.
var brokenString = $(".title a").html();
var stringArray = brokenString.split(" ");
var firstPart = stringArray[0] + " " + stringArray[1];
// firsPart delete from array
stringArray.shift();
stringArray.shift();
// now assign in html
$(".title a").html(firstPart + ' <br>' + stringArray.join(' '));
const anchorText = document.getElementsByTagName('a')[0].innerText;
const splitBy = '2019 ';
const splittedText = anchorText.split(splitBy);
const firstElement = "<span class='first'>" + splittedText[0] + splitBy + "</span>";
const secondElement = "<span class='second'>" + splittedText[1] + "</span>";
document.getElementsByTagName('a')[0].innerHTML = firstElement + secondElement;
.first {
color: red;
}
.second {
color: green;
}
<h2 class="title">
Report 10/2019 The name of the report
</h2>
If 2019 it's a dynamical value like (current year) you can retrieve that from the new Date() date object and add it there.

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

Display select option text date

I have a select option drop down that shows only Mondays (to select a particular week).
<select id="monday" name="monday">
<option value="7">
Mon 1/7/2013 (Week 02)
</option><option value="14">
Mon 1/14/2013 (Week 03)
</option>
// etc...
</select>
I would like to grab the option text (i.e. Mon 1/7/2013 (Week 02)) and use it to display that week's dates in a table:
<div id='mondaydate'>Mon 1/7/2013 (Week 02)</div> | <div id='tuesdaydate'>Tue 1/8/2013 (Week 02)</div> | <div id='wednesdaydate'>Wed 1/9/2013 (Week 02)</div>...
When the select option changes I would like the dates in the <div>'s to change as well. Right now the JavaScript I have (which isn't working) is:
<script type='text/javascript'>
var sel = document.getElementById("monday");
var text = sel.options[sel.selectedIndex].text;
var mon=new Date("text");
document.getElementById("mondaydate").innerHTML = "mon.setDate(mon.getDate()+0)";
document.getElementById("tuesdaydate").innerHTML = "mon.setDate(mon.getDate()+1)";
document.getElementById("wednesdaydate").innerHTML = "mon.setDate(mon.getDate()+2)";
document.getElementById("thursdaydate").innerHTML = "mon.setDate(mon.getDate()+3)";
document.getElementById("fridaydate").innerHTML = "mon.setDate(mon.getDate()+4)";
document.getElementById("saturdaydate").innerHTML = "mon.setDate(mon.getDate()+5)";
document.getElementById("sundaydate").innerHTML = "mon.setDate(mon.getDate()+6)";
</script>
Can this be done, or am I spinning my wheels?
UPDATE - SOLUTION
As was suggested, I got a little quote happy, so I got rid of those. Also as suggested, the dates would need to be formatted as the first attempt only provided timestamps. Using this date format solution I was able to format the dates into something readable by humans.
Full working JavaScript code:
<script type='text/javascript'>
function formatDate(date, fmt) {
function pad(value) {
return (value.toString().length < 2) ? '0' + value : value;
}
return fmt.replace(/%([a-zA-Z])/g, function (_, fmtCode) {
switch (fmtCode) {
case 'Y':
return date.getUTCFullYear();
case 'M':
return pad(date.getUTCMonth() + 1);
case 'd':
return pad(date.getUTCDate());
case 'H':
return pad(date.getUTCHours());
case 'm':
return pad(date.getUTCMinutes());
case 's':
return pad(date.getUTCSeconds());
default:
throw new Error('Unsupported format code: ' + fmtCode);
}
});
}
function changeDate()
{
var sel = document.getElementById("monday");
var text = sel.options[sel.selectedIndex].text;
var mon = new Date(text);
document.getElementById("mondaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+0)), '%M/%d/%Y');
document.getElementById("tuesdaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+1)), '%M/%d/%Y');
document.getElementById("wednesdaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+1)), '%M/%d/%Y');
document.getElementById("thursdaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+1)), '%M/%d/%Y');
document.getElementById("fridaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+1)), '%M/%d/%Y');
document.getElementById("saturdaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+1)), '%M/%d/%Y');
document.getElementById("sundaydate").innerHTML = formatDate(new Date(mon.setDate(mon.getDate()+1)), '%M/%d/%Y');
}
</script>
Also, note that originally I was setting the dates incorrectly with Monday +0, Tuesday +1, Wednesday +2, etc. (didn't notice it as all I got were timestamps). This really seemed to be setting the date, so Monday and Tuesday displayed correctly, but then Wednesday was displaying Thursday's date, Thursday displayed Sunday's date, etc. incrementing each by +1 instead solved that problem.
Remove the quotes around your variables or else it'll just display what's in the quotes and not perform any logic:
var sel = document.getElementById("monday");
var text = sel.options[sel.selectedIndex].text;
var mon=new Date(text); <--- No quotes around text variable
document.getElementById("mondaydate").innerHTML = mon.setDate(mon.getDate()+0); <--- No quotes
//Same with everything below, stop with the quotes!
document.getElementById("tuesdaydate").innerHTML = mon.setDate(mon.getDate()+1);
document.getElementById("wednesdaydate").innerHTML = mon.setDate(mon.getDate()+2);
document.getElementById("thursdaydate").innerHTML = mon.setDate(mon.getDate()+3);
document.getElementById("fridaydate").innerHTML = mon.setDate(mon.getDate()+4);
document.getElementById("saturdaydate").innerHTML = mon.setDate(mon.getDate()+5);
document.getElementById("sundaydate").innerHTML = mon.setDate(mon.getDate()+6);
You have a lot of unnecessary quotes, which is screwing up your code.
Have a look at this :
JS :
$("#monday").click(function(){
var sel = document.getElementById("monday");
var text = sel.options[sel.selectedIndex].text;
var mon=new Date(text);
console.log(mon);
document.getElementById("mondaydate").innerHTML = mon.setDate(mon.getDate()+0);
});
Find the working fiddle here : http://jsfiddle.net/bnWRU/1/
tymeJV already answered, but I think you might have some trouble with date format in javascript.
I sugest this post: Javascript get date in format

How to display JS values on my HTML page

I'm trying to get three different dynamic timezone clocks on my site. i've got the following js code which i found on this site (saved as myClocks.js and included on the header of my html site):
var clock1 = new Date();
var clock2 = new Date();
var clock3 = new Date();
clock2.setHours(clock2.getHours() + 3);
clock3.setHours(clock3.getHours() - 5);
clock1.getUTCHours();
clock1.getUTCMinutes();
clock1.getUTCSeconds();
clock2.getUTCHours();
clock2.getUTCMinutes();
clock2.getUTCSeconds();
clock3.getUTCHours();
clock3.getUTCMinutes();
clock3.getUTCSeconds();
How do I code the "display" to show it anywhere I want on my HTML page? For example as an id called clocks, to look like the following:
New York: 02:12:02 Paris: 17:01:24 Moscow: 22:23:42
Many thanks in advance.
<html><head></head><body>
<script language="javascript">
ourDate = new Date();
document.write("The time and date at your computer's location is: "
+ ourDate.toLocaleString()
+ ".<br/>");
document.write("The time zone offset between local time and GMT is "
+ ourDate.getTimezoneOffset()
+ " minutes.<br/>");
document.write("The time and date (GMT) is: "
+ ourDate.toGMTString()
+ ".<br/>");
</script>
</body></html>
innerHTML is what you need. Try something like:
window.onload = function(){ // It is important to wait till DOM is ready!
var clocks_str = clock3.getUTCHours()+" "+ clock3.getUTCMinutes()+" "+clock3.getUTCSeconds();
document.getElementById("clocks").innerHTML = clocks_str ;
}
And if you want it dynamic , use setInterval method , like this:
var clocks_interval;
var clocks_box;
window.onload = startClocks;
function startClocks(){
clocks_box = document.getElementById("clocks");
clocks_interval = setInterval(updateClocks , 1000); // 1000 means 1 second
}
function updateClocks (){
var clocks_str = clock3.getUTCHours()+" "+ clock3.getUTCMinutes()+" "+clock3.getUTCSeconds();
clocks_box.innerHTML = clocks_str ;
}
You can create a div or other HTML and use "innerHTML".
document.getElementById("clocks").innerHTML = clock1.getUTCHours();

JavaScript that prints date and time with a link won't work

I'm currently enrolled in a JavaScript class at my community college, and we're supposed to create a page with the following:
"Today's date is (date)"
"Kids Club"
"The time is (time)"
Then, I don't seem to get this part, the instructions state: "Have a link to the new kidsnew.htm page that contains the text "Go To Kids Club". Use onClick and widow.location to open kidsnew.htm.
Before switching, you should use the navigator object and the method to test for the name and version of the browser. Display the name and version of the browser with an alert box and advise the user to upgrade for better results with the new page if their browser is out of date.
The kidsnew page should contain an HTML form button that will take you back to the "kidsold.htm" page."
So. I assume that I'll need the browser verification, where you can find in the first part of the code. I don't get what else I'm supposed to be using, as we were not told of a "onClick" method in the chapter's were reading. Can anyone help me refine the code and get it to display as stated? I did most of it correctly, I think;
Here's my code:
<html>
<head>
<title>Kids Club</title>
<script type = "text/javascript" src = "brwsniff.js"></script>
<script type = "text/javascript">
<!-- hide me from older browsers>
//==============================Browser Info=================================
var browser_info = getBrowser();
var browser_name = browser_info[0];
var browser_version = browser_info[1];
var this_browser = "unknown";
if (browser_name == "msie")
{
if(browser_version < 5.5)
{
this_browser = "old Microsoft";
}
else
{
this_browser = "modern";
}
}
//end
if (browser_name == "netscape")
{
if (browser_version < 6.0){
this_browser = "old Netscape";
else
{
this_browser = "modern";
}
} //end
</script>
//=========================End Browser Info============================
//==========================Start Date Script============================
var date = new Date();
//new is keyword for object Date
//
//getting info from object Date
//
var month = date.getMonth();
var day = date.getDate();
var year = date.getYear();
var hour = date.getHours();
var minutes = date.getMinutes();
//january is month 0, think of arrays
//
month = month + 1;
//fix y2k
//
year = fixY2k(year);
//fix minutes by adding 0 infrotn if less than 10
//
minutes = fixTime(minutes);
var date_string = month + "/" + day + "/" + year;
var time_string = hour + ":" + minutes;
var date = "Today is " + date_string";
var time = "The time is " + time_string;
//y2k fix
//
function fixY2k(number) {
if (number < 1000){
number = number + 1900;
return number;
}
//time fixer
//
function fixTime(number){
if(number < 10) {
number = "0" + number;
}
return number;
}
//========================End Time Script==================================
// show me -->
</script>
</head>
<body>
<script type = "text/javascript">
<!-- hide me from older browsers
document.write(date);
</script>
//show me -->
<h1>Kids Club</h1>
<script type = "text/javascript">
<!-- hide me from older browsers
document.write(time);
</script>
//show me -->
</body>
</html>
Some comments:
> <script type = "text/javascript">
> <!-- hide me from older browsers>
That's rubbish, HTML comment delimiters were never needed to hide script element content, just remove them.
> var year = date.getYear();
You should use the getFullYear method, it avoids the two digit year issue.
> var date = "Today is " + date_string";
There is no need to declare date a second time. It's not harmful, just unnecessary. date started out as a Date object, now it's a string. That's not good programming style, just modify the existing date_string, e.g.
date_string = "Today is " + date_string";
In the body of the page you have:
> <script type = "text/javascript">
> <!-- hide me from older browsers
> document.write(date);
> </script>
> //show me -->
Note that the comment delimiters start inside the script element, then finish outside it. So the browser is left with invalid HTML and whatever happens next is a result of error correction (the same for the next script element too).
Fix that and you may have solved your problem.

Categories