Yesterday’s ComboBox Form Tutorial progress combined with today’s involvement of …
- Wikipedia … thanks … via …
- Inhouse PHP
… and can open up our ComboBox Form Table web application to the idea that the user can decide the table column names. How, pray tell? Have you noticed how great Wikipedia is at lists? There are lists of a huge number of concepts. So, think of plural words and use the new “dot” link in the header label of our web application to define your comma separated list of column names, and we’ll use the new PHP combobox.php to see “whether it flies” with a list distilled back to the user in the dropdown within the table data row cell’s ComboBox’s div/select element’s dropdown (ie. select) part.
Along the way we’ve started down the road of some mappings to those option elements of those ComboBox dropdown parts, that being …
<option value="[WikipediaBasedURL]">[WikipediaBasedLabel]</option>
… and in turn that has given us a pretty “static” (but none the less useful) “onchange” event logic idea to start using on ComboBox select (dropdown) element parts, as per …
function woit(sthis) {
if (sthis.value.indexOf(String.fromCharCode(104) + String.fromCharCode(116) + String.fromCharCode(116) + String.fromCharCode(112)) == 0) { // absolute URL value
window.open(sthis.value,'_blank','top=100,left=100,width=600,height=600');
}
}
And on the recall analysis of form (ie. user interactions) report we can use (good ‘ol) document.referrer to glean precise “name” in “name=value” paradigm alert box reporting, those being those user defined column headings to the ComboxBox Form Table …
<script type='text/javascript'>
var selc=" ", seli=0, selcombov=[], retrep='';
while (selc != '') {
selc = location.search.split('selcombo' + seli + '=')[1] ? decodeURIComponent(location.search.split('selcombo' + seli + '=')[1].split('&')[0]) : '';
if (selc != '') { selcombov.push('' + selc); retrep+='Value' + eval(1 + seli) + ' (set by user)=' + selc + String.fromCharCode(10); }
seli++;
}
if (retrep != '') {
if (('' + document.referrer).indexOf('?topics=') != -1) {
var cols=decodeURIComponent(('' + document.referrer).split('?topics=')[1]).split(',');
for (var iiu=1; iiu<=cols.length; iiu++) {
retrep=retrep.replace('Value' + iiu + ' ', cols[eval(-1 + iiu)] + ' ');
}
}
alert(retrep);
}
</script>
That being so, our changed external Javascript combobox.js called by our changed parent HTML combobox.htm web application might be worth your re-analysis.
Previous relevant ComboBox Form Tutorial is shown below.
Yesterday’s ComboBox Primer Tutorial got us working with new ComboBox div/select elements, but that was just a display mechanism, and not a “collection of data” mechanism. We could code for dynamic select “onchange” event and div “onblur” event logics, which we may allow for into the future, but today’s work is to have our external Javascript work with a parent HTML that has a …
- form method=GET action=[“here’s looking at you kid”]
- table with a header (ie. th cells) row … and
- row with empty data cells (ie. td cells) …
<table border=20>
<tr><th>Integer</th><th>Lowercase</th><th>Uppercase</th></tr>
<tr><td></td><td></td><td></td></tr>
</table>
- form submit button
… that can parrot back what a user selected for their ComboBox(es). The external Javascript changes ensure …
- a mechanism now exists for multiple calls of the external Javascript from the parent HTML … exemplified by …
<script type='text/javascript' src='combobox.js?ddlist=1,2,3,4' defer></script>
<script type='text/javascript' src='combobox.js?ddlist=a,b,c,d' defer></script>
<script type='text/javascript' src='combobox.js?ddlist=A,B,C,D' defer></script>
- and the default place to hold those resultant ComboBox div/select elements is to empty innerHTML elements (such as those td data cells above) … and …
- ComboBox div/select elements now get created with a “name” attribute (meaning selections are passed back to [here’s looking at you kid”]
- ComboBox div/select elements now get class “combobox” applied to them to aid with parent HTML styling CSS such as …
<style>
div.combobox { background-color:yellow; }
select.combobox { background-color:pink; width:95%; }
</style>
… means they slot into place into the parent HTML form and be self-returnable (ie. action=[“here’s looking at you kid”])
… so that there can be better practical use made of these ComboBox div/select elements used by our changed external Javascript combobox.js called by our changed parent HTML combobox.htm web application …
Previous relevant ComboBox Primer Tutorial is shown below.
Do you remember a blog posting a couple of days ago called Favourites Poll Email Moderation Contenteditable Tutorial featuring …
contenteditable global attribute magic
? Well, that started me rethinking on a very long-running personal desire with our web application work. In the Windows early GUI desktop applications going back to VB.Net and C++ in the latter 1900 years there was a GUI control called “ComboBox” (class) that never failed to impress me. It matches a lot of needs to be presented with a static list of choices in mind, but then want to extend that list as time and situation changes over time. A “ComboBox” can handle it, it being that combination of …
- dropdown (static) list … and …
- textbox “extender”
… all manageable sounding in today’s web application wooooorrrrrlllllld, especially, in our minds, having defer
and contenteditable as useful concepts for the latter item above. And so a …
- dropdown (select) element … nested within a …
- div contenteditable=true
… paradigm is the basis for our combobox.js external Javascript to feature an Object Oriented looking Javascript Class …
// combobox.js
// External Javascript to extend some HTML like combobox.html allowing for a dynamically created HTML div element "combobox" (ie. dropdown + div contenteditable=true)
// November, 2020
// Called via ...
// <script type='text/javascript' src='combobox.js' defer></script>
// ... or dropdown populated example as per ...
// <script type='text/javascript' src='combobox.js?ddlist=Asia,Africa,Europe,North%20America,South%20America,Australia,Antarctica' defer></script>
class Droptext {
constructor(combobox) {
this.ele = document.createElement('div');
this.ele.id = ('' + combobox).split(';')[0];
if (('' + combobox).indexOf(';') != -1) {
this.ele.setAttribute('data-dropinnards', ('' + combobox).split(';')[1]);
this.ele.setAttribute('data-optionval', "<option value=''></option>");
this.ele.setAttribute('data-focusaway', "<input style=position:absolute;top:-200px;left:-200px; type=text value=></input>");
this.ele.setAttribute('contenteditable', true);
this.ele.innerHTML = ('' + combobox).split(';')[1]; // + "<input style=position:absolute;top:-200px;left:-200px; type=text value=></input>";
}
}
present() {
return this.ele.outerHTML.replace('><select', ' onblur=" var odiv=event.target; var optval=event.target.getAttribute(' + "'" + 'data-optionval' + "'" + '); var fway=event.target.getAttribute(' + "'" + 'data-focusaway' + "'" + '); var umytype=event.target.innerHTML; var alltogether=event.target.getAttribute(' + "'" + 'data-dropinnards' + "'" + ').split(String.fromCharCode(60) + ' + "'" + '/select' + "'" + ')[0]; if (umytype.trim().length == 0) { odiv.innerHTML = event.target.getAttribute(' + "'" + 'data-dropinnards' + "'" + '); } else if (alltogether.indexOf(String.fromCharCode(62) + umytype + String.fromCharCode(60)) != -1) { odiv.innerHTML = alltogether.replace(String.fromCharCode(62) + umytype + String.fromCharCode(60), ' + "' selected'" + ' + String.fromCharCode(62) + umytype + String.fromCharCode(60)) + event.target.getAttribute(' + "'" + 'data-focusaway' + "'" + '); } else { alltogether+=optval.replace(String.fromCharCode(39), String.fromCharCode(39) + umytype).replace(String.fromCharCode(62), String.fromCharCode(62) + umytype); alltogether+=String.fromCharCode(60) + ' + "'" + '/select' + "'" + ' + String.fromCharCode(62); odiv.innerHTML = fway; odiv.innerHTML = alltogether.replace(String.fromCharCode(62) + umytype + String.fromCharCode(60), ' + "' selected'" + ' + String.fromCharCode(62) + umytype + String.fromCharCode(60)) + event.target.getAttribute(' + "'" + 'data-focusaway' + "'" + '); odiv.setAttribute(' + "'" + 'data-dropinnards' + "'" + ',alltogether); } " onkeypress=" event.target.setAttribute(' + "'" + 'data-sofar' + "'" + ', event.target.innerHTML); " onkeydown=" if (event.target.innerHTML.indexOf(String.fromCharCode(60)) != -1) { event.target.innerHTML=' + "''" + '; } "><select');
}
}
class Contents extends Droptext {
constructor(combobox, mod) {
if (('' + combobox) == '') {
var iinn=0;
while (document.getElementById('combobox' + iinn)) {
iinn++;
}
combobox = 'combobox' + iinn;
}
super((combobox + ';' + mod));
this.dropinnards = mod;
}
show() {
return this.present() + "<input style=position:absolute;top:-200px;left:-200px; type=text value=></input>"; // + ', it is a ' + this.dropinnards;
}
}
… and middlemanperson external Javascript …
var ihs = "";
var selconts = location.search.split('ddlist=')[1] ? (ihs + decodeURIComponent(location.search.split('ddlist=')[1].split('&')[0])).split(',') : (ihs + "<select><option value=''></option><option value='Red'>Red</option><option value='Blue'>Blue</option><option value='Yellow'>Yellow</option></select>").split(',');
if (document.head.innerHTML.replace('&ddlist=','?ddlist=').indexOf('?ddlist=') != -1) {
ihs = decodeURIComponent(document.head.replace('&ddlist=','?ddlist=').innerHTML.split('?ddlist=')[1].split('&')[0].split('"')[0].split("'")[0]); // + ',';
if (ihs.trim() != '') { selconts = ihs.split(','); }
}
if (selconts[0].indexOf('<select') != 0) {
var selcont = "<select>";
for (var jiip=0; jiip<selconts.length; jiip++) {
if (selconts[jiip].indexOf('<select') != 0) {
selcont += '<option value="' + selconts[jiip] + '">' + selconts[jiip] + '</option>';
}
}
selcont += "</select>";
mycombobox = new Contents("", selcont);
} else {
mycombobox = new Contents("", selconts[0]);
}
var obody = document.body;
if (document.getElementById('demo')) {
obody = document.getElementById('demo');
} else {
var ofound = false;
var obs = document.getElementsByTagName('div');
for (var iip=0; iip<obs.length; iip++) {
if (obs[iip].innerHTML == '') {
obody = obs[iip];
ofound = true;
}
}
if (!ofound) {
obody.innerHTML += '<div id=demo></div>';
obody = document.getElementById('demo');
}
}
obody.innerHTML += mycombobox.show();
… that suits the need of our proof of concept calling HTML combobox.html live run code …
<!doctype html>
<html>
<head>
<script type='text/javascript' src='combobox.js' defer></script>
</head>
<body>
<div id='demo'></div>
</body>
</html>
Intervening at the “onkeydown” event of the hosting HTML div contenteditable=true is the essence of why the “ComboBox” can be (quite a bit, but not totally) like that forerunner “ComboBox” VB.Net GUI control.
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.