How George Boole helped me in JavaScript, HTML, CSS

It’s quite simple example I have experienced recently. But I think to share notes on blog, so that I remember this case and maybe someone else might use it in future.

cool-boole-700x467

Task is about Multipart form with dropdown which defines (control) which part of UI to render (show/hide) and depend on file field values submit button should be enabled/disabled. Key point, that the logic of interaction should be one single function/formula.

multipart_form

Main part of HTML:


<form id="myForm" name="myForm" enctype="multipart/form-data" method="POST"
data-bind="submit: pseudoSubmitForm">
<select data-bind="options: uiTypes,
optionsText: 'typeLabel',
optionsValue: 'typeValue',
value: selectedType,
optionsCaption: 'Choose…'">
</select>
<div id="file1" data-bind="visible: showField1">
<p>Select file 1</p>
<input type="file" name="files" data-bind="value: valueField1"/>
</div>
<div id="file2" data-bind="visible: showField2">
<p>Select file 2</p>
<input type="file" name="files" data-bind="value: valueField2"/>
</div>
<input type="submit" value="Execute" data-bind="enable: enableExecutionButton() "/>
</form>

view raw

multipart.html

hosted with ❤ by GitHub

Main part of JavaScript:


(function (){
var node = document.getElementById('myForm');
function AppViewModel() {
this.uiTypes = ko.observableArray([
{"typeValue":"A", "typeLabel": "1 field type"},
{"typeValue":"B", "typeLabel": "2 fields type"}
]);
this.selectedType = ko.observable();
this.showField1 = ko.observable(false);
this.showField2 = ko.observable(false);
this.valueField1 = ko.observable('');
this.valueField2= ko.observable('');
this.selectedType.subscribe(function (type) {
if (!type){
this.showField1(false);
this.showField2(false);
} else {
this.showField1(true);
this.showField2(type === 'B');
}
this.valueField1('');
this.valueField2('');
}, this);
this.enableExecutionButton = ko.computed(function(){
var a = this.showField1();
var b = this.showField2();
var x = this.valueField1();
var y = this.valueField2();
function AndAndXnor(a,b,x,y) {
//return (a&&b && x&&y || a&&!b && x&&!y); // WORKS
return (a&&x) && (b&&y || !b&&!y); // WORKS
//return (a&&x) && !(b^y); // "(b&&y || !b&&!y)" // DOES NOT WORK
}
return AndAndXnor(a,b,x,y);
}, this);
this.pseudoSubmitForm = function(formElement){
this.selectedType('');
}
}
var model = new AppViewModel();
ko.applyBindings(model, node);
})()

view raw

multipart.js

hosted with ❤ by GitHub

Task implementation notes

  1. By default there should be only 1 dropdown – set of types how UI will behave when u select dropdown.
    • Used Knockout data-bind="options ..."
    • Used Knockout this.uiTypes = ko.observableArray() for array/set of types.
    • Used Knockout this.selectedType = ko.observable() for selected value in dropdown
    • Used Knockout this.selectedType.subscribe() approach to receive always new value to bind.
  2. When you select “1 field type” it should show one upload filed, but “Execute” button should be disabled, until u provide real file name.
    • Used this.showField1 = ko.observable(false);
  3. When you select “2 fields type” – almost the same, but both field’s values should be provided. And if you select 1st then 2nd or 2nd then 1st, logic must be the same.
    • Used this.showField2 = ko.observable(false);
    • And very special piece of code, where Boolean logic and my experience with microelectronics helped me function AndAndXnor()
  4. Data binding between dropdown, UI containers for upload fields, uplod file values, execution button and reset values on submit should be implemented with Knockout.JS.
    • Main “watcher/observation” function but in Knockout terms it’s “computed” – this.enableExecutionButton = ko.computed(function(){...})
    • Interesting Knockout feature – data-bind="submit: pseudoSubmitForm" for FORM tag

Special note about Boolean Logic as help and fun 🙂

Initially I had issue – as soon as I selected 1 upload field, button “Execute” was enabled, which is not ok.
So I started to think on more complex logic:

enableExecutionButton if (
 (showField1 AND showField2 AND field1Value AND fieldValue2)  // This is case for 2 fields
 OR 
 (showField1 AND NOT-showField2 AND field1Value AND NOT-fieldValue2) // This is case of 1 field only
)

So far so good – logic works fine. But it’s complicated a bit. So I simplified using Boolean rules:

(A*B*X*Y) + (A*!B*X*!Y) => (A*X) * (B*Y + !B*!Y);

schemeit-project-1
And again, so far all works fine.
But have a look, last part of formula is in fact inverted XOR operation – XNOR.
Unfortunately in JavaScript we have only bitwise XOR. So my try to simplify more – failed:

(a&&x) && !(b^y);

Because ^ is bitwise but not logical operation. So if we have Logical XNOR in JavaScript, then formula would look like this:

schemeit-project-2

Having this logical formula in mind, I gave a name to the function – “AndAndXnor“, used it but I returned to previous simplified formula (without XNOR inside).

You can try/see how it works here

Resources

 

george_boole_and_his_algebra

 

 

Leave a comment