The following is sample code I wanted to introduce to you. The intent here is not to give you a quick solution, but to show you some underline patterns and practices for your consideration.
It is more robust/complex then is required to answer your question (or fix your issue - in regards to the button inputs)... I'm sure it will raise questions, and (again) it isn't intended to be a quick solution for you.
This code is demonstrating how you can use JSON (Javascript object notation) to construct two objects:
One uses a strategy pattern and is coupled to your form controls. Note that it uses querySelectorAll, not getElementById.
The other is an abstract json framework, composed of function-delegate handlers that you'll bind to event listeners: in a decoupling manner. You'll note in the init function of the JSON instance we put together, that these functions are assigned..
The Run method of the instance JSON, calls on the validate method, followed by the execute method.. which it doesn't (can't) account for.
Sample Code (Mix - HTML & Inline Javascript)
<html>
<head>
<script type="text/Javascript">
var controlHandlers = {
"OnExecuteFirstTask" : function(args) {
args = args || {"a":"", "b":"", "uri":""};
args.a = args.a || "";
args.b = args.b || "";
args.uri = args.uri || (args.a.length > 0 && args.b.length > 0) ? args.a + "+" + args.b : "";
console.log("Executing... [OnExecuteFirstTask] - EventArgs: %o", args);
window.open('http://internal.website.com/' + args.uri, 'awindow');
},
"OnExecuteSecondTask" : function(args) {
args = args || {"a":"", "b":"", "uri":""};
args.a = args.a || "";
args.b = args.b || "";
args.uri = args.uri || (args.a.length > 0 && args.b.length > 0) ? args.a + "+" + args.b : "";
console.log("Executing... [OnExecuteSecondTask] - EventArgs: %o", args);
window.open('http://internal.website.com/' + args.uri, 'awindow');
},
"OnValidateTask" : function(arr) {
console.log("Validating... [OnValidateTask]");
if (!(arr)) {return false;}
if (!(arr.length > 0)) { return false;}
var isValid = true;
for (var i = 0; i < arr.length; i++)
{
if (!(typeof(arr[i]["IsValid"]) == "function")) {
console.log("NullException: %o - 'IsValid' Method doesn't exist", arr[i]);
return false;
}
if (arr[i].IsValid())
{
arr[i].ctrl.className = "valid";
isValid = true && isValid;
} else {
arr[i].ctrl.className = "invalid";
isValid = false;
}
}
return isValid;
},
"OnTextBoxFocus" : function(ev) {
ev = ev || {"target" : null};
target = ev.target || {"className" : ""};
target.className = "focus";
}
};
var formControl = {
"Task" : {
"First" : {
"Run" : function(ev) {
var task = formControl.Task.First;
task.Validate = task.Validate || function (ev) {return false;};
if (task.Validate(formControl.elms))
{
task.Execute({"a": formControl.FirstNameTextBox.value, "b": formControl.LastNameTextBox.value});
}
},
"Execute" : null,
"Validate" : null
},
"Second" : {
"Run" : function(ev) {
var task = formControl.Task.Second;
task.Validate = task.Validate || function (ev) {return false;};
if (task.Validate(formControl.elms))
{
task.Execute({"a": formControl.FirstNameTextBox.value, "b": formControl.LastNameTextBox.value});
}
},
"Execute" : null,
"Validate" : null
}
},
"elms" : [],
"FirstTaskButton" : null,
"SecondTaskButton" : null,
"FirstNameTextBox" : null,
"LastNameTextBox" : null,
"init" : function() {
formControl.FirstTaskButton = document.querySelectorAll("input#btnFirstTask")[0];
formControl.SecondTaskButton = document.querySelectorAll("input#btnSecondTask")[0];
formControl.FirstNameTextBox = document.querySelectorAll("input#tbFirst")[0];
formControl.LastNameTextBox = document.querySelectorAll("input#tbLast")[0];
formControl.Task.First.Validate = controlHandlers.OnValidateTask;
formControl.Task.First.Execute = controlHandlers.OnExecuteFirstTask;
formControl.Task.Second.Validate = controlHandlers.OnValidateTask;
formControl.Task.Second.Execute = controlHandlers.OnExecuteSecondTask;
formControl.FirstTaskButton.addEventListener("click", formControl.Task.First.Run);
formControl.SecondTaskButton.addEventListener("click", formControl.Task.Second.Run);
formControl.FirstNameTextBox.addEventListener("focus", controlHandlers.OnTextBoxFocus);
formControl.LastNameTextBox.addEventListener("focus", controlHandlers.OnTextBoxFocus);
formControl.elms.push( { "ctrl" : formControl.FirstNameTextBox, "IsValid" : function () { return formControl.FirstNameTextBox.value.length > 0;}});
formControl.elms.push( { "ctrl" : formControl.LastNameTextBox, "IsValid" : function () { return formControl.LastNameTextBox.value.length > 0;}});
}
};
</script>
<style>
input[type="text"].valid {background-color:green;color:white;font-weight:700;text-shadow:0em 0em 0.1em black;}
input[type="text"].invalid {background-color:red;color:white;font-weight:700;text-shadow:0em 0em 0.1em black;}
.invalid::-webkit-input-placeholder {
color: white;
font-weight:700;
text-shadow:0em 0em 0.1em black;
}
.invalid:-moz-placeholder {
/* FF 4-18 */
color: white;
font-weight:700;
text-shadow:0em 0em 0.1em black;
}
.invalid::-moz-placeholder {
/* FF 19+ */
color: white;
font-weight:700;
text-shadow:0em 0em 0.1em black;
}
.invalid:-ms-input-placeholder {
/* IE 10+ */
color: white;
font-weight:700;
text-shadow:0em 0em 0.1em black;
}
</style>
</head>
<body>
<div id="msgBox" style="display:none;">Invalid Entry</div>
<form id="mainForm" name="mainForm">
<div>
<label for="tbFirst">First Name:</label>
<input type="text" id="tbFirst" name="first" placeholder="First" value="" />
</div>
<div>
<label for="tbLast">Last Name:</label>
<input type="text" id="tbLast" name="last" placeholder="Last" value="" />
</div>
<div>
<input type="button" id="btnFirstTask" value="First Task" />
<input type="button" id="btnSecondTask" value="Second Task" />
</div>
</form>
<script>
formControl.init();
</script>
</body>
</html>
that's the strategy. assigning a new function to formControl.Task.First.Execute at some point after it has been initiated (formControl.init) means it will execute that function after validating..
of course, the new method assigned to the Task.First.Execute
will receive the 'argument' parameter {"a": firstname, "b": lastname}
.. which may or may not be useful, right?
so, a more robust argument would likely become more desirable..
in turn, you can modify/grow your 'validation bag' by working with the formControls.elms array (which may need a more suitable name then the one I gave it)..