When doing our inhouse testing for Event Calendar Collaboration Tutorial the other day, it got us โpeevedโ, shall we say. We wanted a mechanism, with those โaโ link โmailto:โ emailing arrangements, of not having to fill out the email address in the โTo:โ field each time. First world problem alert! Still and all โฆ
- When it comes to procedures โฆ
- Aaaaaarrrrgggghhhh โฆ
- Nuances count โฆ regarding โฆ
- Errrrrrr โฆ
- Saving time โฆ
- Saving frustration
โฆ resulting in the โeasy to rememberโ acronym WANESS โฆ we rest our cases!
What can help here? Well, it is a personalization โฆ so โฆ anyone, anyone? Yes, Lou, back from holidays, a month late โฆ yes, well, okay โฆ we can see youโve put some thought into this โฆ HTTP Cookies could be used. Yes, Shwetank, youโve had your hand up some time now. We agree, Web Storage window.localStorage allows for more data, so weโll go with that, though either style of approach would work here.
Global variables initialization โฆ |
---|
|
Within document.body onload event logic โฆ |
|
Calling these two Javascript function helpers โฆ |
|
And allow control, as well, at the SMS prompt window logic โฆ |
|
Also, today, we battled the logic to allow the textarea element onblur events also open the door to emailing and SMS โwork in progressโ. Believe it or not, this timing change was quite difficult in thechanged events_in_monthhtm parent of the Events in Month web application. Never a dull moment in web application I.T. weโd say!
Previous relevant Event Calendar Collaboration Tutorial is shown below.
The Event Calendar web application project, of Event Calendar PHP Bookmark Tutorial, from last year is worth a revisit, the reason being โฆ
- it did not have a fully fleshed out collaboration or sharing set of functionalities โฆ at the time, probably, because โฆ
- each Monthly calendar filled out, and wanting to be saved, could involve much more than the 850 characters available to previous โmailto:โ or โsms:โ communication conduits, back to when we first tackled this project โฆ but now โฆ
- hashtagging parts to the โmailto:โ URLs (and maybe sometimes the โsms:โ URL) might cover the data length needs
โฆ so that this Event Calendar could be a web application at the center of a collaboration network of people working on that event organization. Much more useful, we figure!
Timing became really important with this integration of โฆ
- SMS
โฆ communication conduit possibilities. With its design we have to wait until the point where the user is filling in textarea elements regarding a designated โฆ
- Month
- Year
โฆ of relevance, before we allow the email and SMS
emoji buttons be shown. In the code โฆ
Amended HTML h1 element static HTML to add, later shown, perhaps, email |
---|
|
New static HTML div element placed to the bottom of the body element โฆ |
|
New Javascript global variables (picking up hashtagging parts of the address bar URL, perhaps linked off an email or SMS link clicked) โฆ |
|
On or around document.body onload event we can analyze any such location.hash hashtagging data โฆ |
|
A window.open wrapper windowopen Javascript function โฆ |
|
Is augmented by other new Javascript functions โฆ |
|
โฆ to help bed down this new sharing and collaboration functionality in achanged events_in_monthhtm parent of the Events in Month web application.
Previous relevant Event Calendar PHP Bookmark Tutorial is shown below.
Client meets server today, allowing the PHP data storage talents in yesterdayโs Event Calendar PHP Tutorialโs work to meet a โclientsideโ way to โฆ
Record to Remember via Bookmark
โฆ use the web browser Bookmarks to help you recall an Events in Month report with long entries.
Involving a Bookmark still needs those โgetโ ? and & arguments, and we allow the PHP to lookup for us the data underscoring an address bar URL such as โฆ
https://www.rjmprogramming.com.au/HTMLCSS/events_in_month.php?exactlabel=August__2023_00000__1
โฆ that mapping being possible, now, making use of a pseudo hashtag arrangement โฆ your Claytonโs hashtag, if you will!
To start to use a hashtag suits, as your hashtag navigation only makes sense in the โclientsideโ woooorrrrrllllddd, and even there, really using one only tries to position a webpage where an element with an ID matching the hashtag sits (and we are never going to have this ID element in our work), and in the meantime weโve passed across from the child PHP to the parent HTML a valuable piece of information helping the link to the Bookmark system be possible. The Javascript codeline (you may have noticed) โฆ
var documentURL=document.URL;
โฆ as stupid and simple looking as it is, is crucial for us. We get child webpage parts (like our PHP) to change document.URL to a far too long in normal circumstances address bar URL the rest of the code feeds off. Itโs just that now, that far too long in normal circumstances address bar URL has a #[hashtag] appended such as โฆ
#August__2023_00000__1
โฆ uniquifying a Month, Year Events in Month identifier part with a version of the userโs IP address (so that they only see what is relevant to them).
Address bar URLs such as โhttps://www.rjmprogramming.com.au/HTMLCSS/events_in_month.php?exactlabel=August__2023_00000__1โ are Bookmarkable, and so we allow for similar outcomes with less concern about how much data is being โrecordedโ and recallable (via that web browserโs Bookmark system).
Also, today, a lot of CSS tweaks, so that the CSS styling now looks like โฆ
<style>
#eventcalendar {
background-color: #fcfcfc;
}
td {
padding-top: 2px;
padding-left: 2px;
padding-right: 2px;
padding-bottom: 12px;
}
.dayb {
color: white;
background-color: red;
padding: 5 5 5 5;
border-radius: 80px;
margin-bottom: 15px;
}
.dow {
color: purple;
font-style: bold;
}
.selday {
margin-left: 8px;
background-color: rgba(255,0,0,0.7);
display: inline-block;
width: 50px;
border-color: transparent;
text-overflow: ellipsis;
}
.tablurb {
background: linear-gradient(to right, white, lightpink, pink);
}
input[type="submit"] {
margin-bottom: 3px;
border-radius: 180px;
}
input[type="number"] {
margin-left: 3px;
margin-right: 3px;
border-radius: 180px;
background-color: #f3f3f3;
padding: 2 2 2 2;
}
#smonth {
margin-left: 3px;
margin-right: 3px;
border-radius: 180px;
background-color: #f9f9f9;
padding: 2 2 2 2;
}
.boldtitle {
background-color: rgba(0, 211, 107, 0.2);
}
.boldtitle + .tablurb {
margin-top: 8px;
}
.selhistory {
border-radius: 180px;
background-color: lightpink;
padding: 2 2 2 2;
}
</style>
โฆ and we thank this webpage for the heads up regarding how to calculate week numbers within a year data item displays now available in โฆ
- achanged events_in_month
htm parent of the Events in Month web application
- helped out by its changedchild PHP events_in_month
php
Previous relevant Event Calendar PHP Tutorial is shown below.
Letโs face it. Serverside PHP is just great! It opens up so many opportunities regarding data in your web applications.
As such, onto yesterdayโs Event Calendar New Window Tutorial logic we now have a โฆ
Record to Remember
โฆ form submit button (toggling) value to start involving PHP with those longer datasets of Event in Month descriptions, in our most recent project. What do we use as the data conduit? No, not a database. No, not a serverside flat file. No, not clientside window.localStorage nor window.sessionStorage nor HTTP Cookies. We store long Event in Month description data in our new events_in_monthphp PHP itself. And this same PHP can populate options in a new dropdown element in the parent to facilitate the recalling of any relevant โRecord to Rememberโ recordings.
The PHP is kind of short, so we will show it below, including one MAMP example of that โself storageโ โฆ
<?php
// events_in_month.php
// RJM Programming
// August, 2023
// Help out events_in_month.htm
$hcont=file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'events_in_month.htm');
$cont=file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'events_in_month.php');
$ipad=server_remote_addr();
$ipadless=$ipad;
$js='';
function server_remote_addr() {
global $ipadless;
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
$ipadless=str_replace(".", "_", str_replace(":", "_", $rma));
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
return str_replace(".", "_", str_replace(":", "_", $rma));
}
$itdone=false;
if (isset($_GET['init'])) {
if (strpos($cont, '_' . $ipad . '=') !== false) {
$things=explode('_' . $ipad . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
if (strpos($cont, '0' . $ipadless . '=') !== false) {
$things=explode('0' . $ipadless . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
echo "<html><head><script type='text/javascript'> " . $js . " </script></head><body><p>" . $ipad . "</p></body></html>";
} else if (isset($_POST['phpthere']) && isset($_POST['bigurl']) && isset($_POST['caltitle'])) {
//file_put_contents('xz.xz', 'l');
if (strpos($cont, '// ' . str_replace(' ','_',str_replace(',','_',str_replace('+',' ',urldecode($_POST['caltitle'])))) . '_' . str_replace('+',' ',urldecode($_POST['phpthere'])) . '=' . $_POST['bigurl'] . "\n") === false) {
//file_put_contents('xz.xzz', 'l');
$cont=str_replace('?' . '>', '// ' . str_replace(' ','_',str_replace(',','_',str_replace('+',' ',urldecode($_POST['caltitle'])))) . '_' . str_replace('+',' ',urldecode($_POST['phpthere'])) . '=' . $_POST['bigurl'] . "\n" . '?' . '>', $cont);
file_put_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'events_in_month.php', $cont);
}
if (strpos($cont, '_' . $ipad . '=') !== false) {
$things=explode('_' . $ipad . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
if (strpos($cont, '0' . $ipadless . '=') !== false) {
$things=explode('0' . $ipadless . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
//file_put_contents('xz.xzzz', "<html><head><script type='text/javascript'> " . $js . "\n parent.checkif(parent.document.getElementById('phpif')); \n" . " </script></head><body><p>" . str_replace(' ','%20',str_replace('+',' ',urldecode($_POST['bigurl']))) . "</p></body></html>");
echo "<html><head><script type='text/javascript'> " . $js . "\n parent.checkif(parent.document.getElementById('phpif')); \n" . " </script></head><body><p>" . str_replace(' ','%20',str_replace('+',' ',urldecode($_POST['bigurl']))) . "</p></body></html>";
} else {
echo $hcont;
}
exit;
//
//
// January__1970_00000__1=http://localhost:8888/events_in_month.htm?caltitle=January%2C%201970&i01.00=&ta01.00=kgjfjhf%20jhgfjhf%20jhkgkjhg%20jhgkjhg%20jkghhg%20jkhgkjhg%20kjhgkjhg&i02.00=&ta02.00=kjhgkjh%20kjhgkjhg%20jkhgkjhg%20kjhgkjhg%20kjhgkjhg%20jhkgkjhg%20kjgkjhg&i03.00=&ta03.00=kjhgkjhg%20kjhgkjhg%20kjhgkjhg%20kjhgkjhg%20kjhgkjhg%20jhkgkjhg&i04.00=&ta04.00=&i05.00=&ta05.00=&i06.00=&ta06.00=&i07.00=&ta07.00=&i08.00=&ta08.00=&i09.00=&ta09.00=&i10.00=&ta10.00=&i11.00=&ta11.00=&i12.00=&ta12.00=&i13.00=&ta13.00=&i14.00=&ta14.00=&i15.00=&ta15.00=&i16.00=&ta16.00=&i17.00=&ta17.00=&i18.00=&ta18.00=&i19.00=&ta19.00=&i20.00=&ta20.00=&i21.00=&ta21.00=&i22.00=&ta22.00=&i23.00=&ta23.00=&i24.00=&ta24.00=&i25.00=&ta25.00=&i26.00=&ta26.00=&i27.00=&ta27.00=&i28.00=&ta28.00=&i29.00=&ta29.00=&i30.00=&ta30.00=&i31.00=&ta31.00=
?>
Yes, the parent needed tochange for our events_in_monthhtm parent of Events in Month web application role.
Previous relevant Event Calendar New Window Tutorial is shown below.
Onto yesterdayโs Event Calendar Remembered Tutorialโs โMystery Dilemmaโ โฆ
But, thereโs an inherent weakness with the design, weโll go into more into the future.
โฆ well โฆ itโs a perennial for us, regarding how if you stick with clientside thinking, only, web applications, when the amount of data to remember starts adding up, the โget arguments approachโ ( ie. use ? and & arguments at the address bar ) is restricted by length restrictions regarding URL lengths.
Rather than jump to PHP serverside ideas just yet, we wanted to show some more ideas, staying with โclientside only thinkingโ, today, as well as improving the UX (user experience) and small steps forward regarding styling.
Okay then, regarding the idea to remember an Event in Month form, when there is a lot of data, and staying โjust clientsideโ, weโve coded for a โNew Windowโ idea, albeit not as memorable as the default โRemember in Bookmarkโ possible for your smaller datasets. However, in saying that, we found that within this new window, with our Google Chrome web browser, we could โฆ
- bring up Context Menu with a right click or two finger gesture within the popup window webpage content โฆ
- pick Inspect option โฆ
- be in Elements tab of your Web Inspector โฆ and โฆ
- highlight top <html> tag โฆ
- Context Menu with a right click or two finger gesture โฆ
- pick Copy -> Copy outerHTML โฆ so that โฆ
- your Event Calendar for your Events in Month choice is in a text buffer โฆ ready for you to โฆ
- Paste into a Text Editor that Events in Month webpage to store (perhaps in a MAMP local Apache/PHP/mySql web server environment, where you can further look at and develop your own ideas)
The user is told when the switch to โNew Windowโ compromise becomes active, decided upon by reconstructing the proposed address bar URL regularly and when too long โฆ
function formanalyze() {
var fio=document.getElementsByTagName('form')[0];
var delm='?';
var fioih=fio.innerHTML;
var fions=fioih.split(' name="');
var testurl=documentURL.split('?')[0].split('#')[0];
for (var ijk=1; ijk<fions.length; ijk++) {
testurl+=delm + fions[ijk].split('"')[0] + '=' + encodeURIComponent(document.getElementById(fions[ijk].split('"')[0]).value);
delm='&';
}
setTimeout(formanalyze, 3000);
if (eval('' + testurl.length) >= 750) {
if (document.getElementById('remember')) { document.getElementById('remember').value='New window'; }
if (document.getElementById('rememberme')) { document.getElementById('rememberme').value='New window'; }
if (document.getElementById('remembermoi')) { document.getElementById('remembermoi').value='New window'; }
} else {
if (document.getElementById('remember')) { document.getElementById('remember').value=document.getElementById('remember').value.replace(/^Remember$/g, 'Remember via Bookmark'); }
if (document.getElementById('rememberme')) { document.getElementById('rememberme').value=document.getElementById('rememberme').value.replace(/^Remember$/g, 'Remember via Bookmark'); }
if (document.getElementById('remembermoi')) { document.getElementById('remembermoi').value=document.getElementById('remembermoi').value.replace(/^Remember$/g, 'Remember via Bookmark'); }
}
return eval('' + testurl.length);
}
โฆ the form submit buttons are reworded accordingly.
Another idea from this blog threadโs inspiration โฆ
โฆ weโve now addressed in todayโs โsecond draftโ is allowing for an optional bold Event Day Blurb Title, available to the user via a new dropdown โBold Titleโ option.
And, how can we do more with colour, to help the right bits stand out, and be consistent? We thought โฆ
- text shadow means by which the text of Event Calendar can be more impactive โฆ
<div style="text-shadow:-1px 1px 1px #ff2d95;" id=eventcalendar></div> - dropdown element conditional styling โฆ
<style>
.dayb {
color: white;
background-color: red;
padding: 5 5 5 5;
}
.dow {
color: purple;
font-style: bold;
}
.selday {
margin-left: 8px;
background-color: rgba(255,0,0,0.7);
display: inline-block;
width: 50px;
}
</style>
โฆ
if (thislabel.substring(0,1) == 'i') {
if (thisval.trim() != '') {
document.getElementById(thislabel.replace('i', 'sel')).style.color='white';
document.getElementById(thislabel.replace('i', 'sel')).style.backgroundColor='red';
}
document.getElementById(thislabel.replace('i', 'opt')).innerText=thisval.replace(/\+/g, ' ').replace(/\ \ \ /g, ' + '); //.replace(/\+$/g, ' ');
document.getElementById(thislabel).value=thisval.replace(/\+$/g, ' ');
} else {
document.getElementById(thislabel).value=thisval.replace(/\+/g, ' ').replace(/\ \ \ /g, ' + ');
}
} - placeholder on Blurb conditional existence โฆ
var ourdata='';
// ...
if (documentURL.indexOf('?') != -1) {
if (documentURL.indexOf('?caltitle=') != -1) { ourdata='data-'; }
// ...
trtemplate='<tr id=tr01.00><td style=width:22%;><span id=sone01.00 class=dow>' + dotw[adate.getDay()].toUpperCase().substring(0,3) + '</span><br><br><span id=stwo01.00 class=dayb>1<span onblur=sepit(this); contenteditable=true id=sp01.00></span><input type=hidden id=i01.00 name=i01.00 value=""></input><select data-dow=' + dotw[adate.getDay()].toUpperCase().substring(0,3) + ' class=selday onchange="selit(this);" id=sel01.00><option id=opt01.00 value=""></option><option title="All such in month (ie. weekly)" value="...">...</option><option title="And ..." value="&...">&</option><option value=Bold>Bold Title</option><option value=Clone>Clone</option></select></span></td><td class=blurb title="What is on?" id=tb01.00><span title="Event title" style="font-style:bold;color:blue;" id=bd01.00></span><textarea name=ta01.00 id=ta01.00 style="width:100%;height=100%;" ' + ourdata + 'placeholder="Blurb ..." class=tablurb></textarea></td></tr>';
// ...
}
// ...
}
โฆ for our โseconddraftโ events_in_monthhtm Events in Month web application.
Previous relevant Event Calendar Remembered Tutorial is shown below.
We were inspired by an Event Calendar pamplette we saw the other day โฆ
โฆ to write a new โproofof conceptโ Events in Month web application, whose content can be recalled via the web browserโs Bookmark methodologies.
We liked the ideas for day of week and/or date of month grouping arrangements we included, being, the way we interpreted it โฆ
- just on this day in this month โฆ default
- on this day of the week throughout the month in question โฆ โโฆโ
- on this day and some others in that month in question โฆ โ&โ โฆ to start with and further amendments available via contenteditable=true span element
- โCloneโ value allows for multiple separated โblurbsโ for the one signature day
But, thereโs an inherent weakness with the design, weโll go into more into the future. For now, you can try it yourself below โฆ
Stop Press
This is where we get to for a โsecond draftโ weโll get into, further, tomorrow โฆ
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.