May 2007 - Posts
Object-oriented language is characterized by this three concepts:
1. Encapsulation
2. Inheritance
3. Polymorphism
If you are familiar with VB.Net and C# then you are most certainly know how to implement those concepts in your language.
But......What if I say that JavaScript is also an object-oriented language???
"Hahaha...!!!!". You will must certainly laugh at me, don't ya?? :)
OK! Here is my reasons:
Creating an Object
JavaScript can create objects. To create an object in JavaScript is simple:
function ObjectA(InitialValue){
this.X = InitialValue;
}
var a = new ObjectA(10);
alert(a.X); //this will display '10'
"OK! I can instantiate an object in JavaScript, but how to add a method to the object? Can JavaScript do that??"
Off course! There are two ways to do that. You can do it in the simple way or in a more longer way. Here is the simple way:
function ObjectA(InitialValue){
this.X = InitialValue;
this.SomeMethod = function(){
alert("Message from SomeMethod()");
}
}
var a = new ObjectA(10);
a.SomeMethod(); //this will show the alert box.
And this is the more longer way:
function ObjectA(InitialValue){
this.X = InitialValue;
}
ObjectA.prototype.SomeMethod = function(){
alert("Message from SomeMethod()");
}
var a = new ObjectA(10);
a.SomeMethod(); //this will show the alert box.
"Ya, I see now that JavaScript can instantiate an object. But how about Encapsulation? Can JavaScript hide private member variable?"
Encapsulation
The JavaScript way to private member is by using closure:
function ObjectA(InitialValue){
var X = InitialValue;
this.GetX = function(){
return X;
}
this.SetX = function(value){
X = value;
}
}
var a = new ObjectA(10);
a.SetX(20);
alert(a.GetX()); //this will display '20'
Hey, its a getter and setter property ya?
"Naa...Many language can create object and do some encapsulation but not many language can do inheritance. So how to do that in JavaScript?"
Inheritance
JavaScript is a prototype-based language. Not like VB.Net or C# that is a class-based language where there is a distinction between a class definition and the class instance. In JavaScript, it uses prototype. A prototype is an object that is used as a template for every new object. Confuse?? Sure!!! But the point is, to do inheritance in JavaScript is different with VB.Net and C# is. Here is why:
function Animal(AnimalName){
this.Name = AnimalName;
}
Animal.prototype.Walk = function(){
alert("The animal is walking.");
}
function Dog(DogName){
Animal.call(this, DogName);
}
Dog.prototype = new Animal();
var d = new Dog("You :)");
d.Walk();
alert(d.Name);
"What a weirdo way of to inherit?". Yeah...Its the JavaScript way! :)
"I see! I am courius to see how to do polymorphism."
Polymorphism
Just like VB.Net and C#. JavaScript can do polymorphism and the subclass can call the overriden method in the base class. Here is how:
function Animal(AnimalName){
this.Name = AnimalName;
}
Animal.prototype.Walk = function(){
alert("The animal is walking.");
}
function Dog(DogName){
Animal.call(this, DogName);
}
Dog.prototype = new Animal();
Dog.prototype.Walk = function(){
Animal.prototype.Walk.call(this);
alert("The dog is walking");
}
var d = new Dog("You :)");
d.Walk();
alert(d.Name);
Conclusion
Because JavaScript can do all of OOP concepts then JavaScript is an object-oriented language. Do you agree with me?
See ya!!
Why so many people like property much than public field even though inside the property there is no other code beside the simple get and set? What is the common sense reason to use it? Why don't they use public field instead? Its faster to type and faster to run. Is it because Microsoft does it? Do they realize the reasons why Microsoft recommending to use properties instead of public fields??
As a developer, I am hoping that one day I can be a project manager (PM). Many people will think that my hope is based on the money that received by a PM in Indonesia is MORE...MORE bigger than received by a developer. Well! it's not! My concerns is power! Because I have experienced difficulties in projects because of the PM was not thinking or seeing in programmer's point of view (except Fred Brooks off course). Many PM that I have work with have so much preference with waterfall. Despite the fact they use RUP (Rational Unified Process) based process but the project always executed with waterfall style.
Its okay to do waterfall if you have done the same project in the past and there are nothing new to you, for example on the technology being used or the domain problem faced. But if you are using a new technology, an unfamiliar problem domain then you have to get the feel with them by doing some coding up-front. But, most PM will reject the idea to code first. They fear the project will be fail because of that. That's why what is commonly done first is requirements gathering and no coding to trying an unfamiliar problem. Even though the project methodology is using RUP and on the schedule is mentioning about inception and elaboration phase but still no code at all. Why?? Is it I that have a wrong understanding of what inception and elaboration phase is?? Please, tell me!
Also, the system analyst is the person responsible to gather the requirements from the domain expert. And they are responsible to jot down the requirements into documents. So, in the end the programmer just read the documents and voila!!! They can understand the domain. That is just a theory. Because in my experience the analyst is not complete in jotting down the requirements. Many important informations is missing. So what the is meaning of producing the documents if it can not be count on to understand the domain? Why is this happening? Is the analyst is lacking the writing skill?? Is the time taken to produce a complete requirements documents is longer than the time allocated? This makes me wants to be an analyst too so I can produce a more complete documents for programmers. As long the software used is not a word processor :P
In the end...Just like many Indonesian movies...The ending is predictable. Me!!! As a developer that must work hard to understand and solve the problem in the remaining short time. Is it must be done like this? Or there is another way?? A better way?!
When I am being a PM the way will be better than :P Hahaha...!!! :D Lol.
Damn!!! I wish C# has
this.
This is one reason why I love JavaScript more than C# and what makes it better than C#
<html>
<body>
<script language="javascript">
window.NewMethod = function(){
alert("This is a dynamically added method!");
}
window.NewMethod();
</script>
</body>
</html>
I use this JavaScript feature to implement my document no textbox. Although I can use closure for that.
In every business application there is a need to display and getting input for a document number. The most convenient way for that is using a single textbox control but part--usually the prefix--of it is not editable like shown in the picture below:

I have made a javascript function to create that kind of textbox. All that you have to do just use it like this:
<html>
<body>
<input type="text" id="txt1"><br>
<!--
<input type="text" id="txt2">
<input type="text" id="txtNumber">
-->
<script language="javascript">
var txt = document.all.txt1;
var NonDeletableString = "SO-2007-A1-";
txt.value = NonDeletableString;
ApplyDocumentNoControl(txt, NonDeletableString);
</script>
</body>
Here is the complete javascript functions:
function ApplyDocumentNoControl(TextBoxControl, PrefixString){
TextBoxControl.NonDeletableString = PrefixString;
TextBoxControl.onselect = function(){
var selectionRange = this.createTextRange();
if(selectionRange.text.length > this.NonDeletableString.length){
if(selectionRange.text.substring(0, this.NonDeletableString.length)
== this.NonDeletableString){
selectionRange.moveStart('character', this.NonDeletableString.length);
selectionRange.select();
}
}
}
TextBoxControl.onkeydown = function(){
//alert(this.NonDeletableString);
if((event.keyCode == 8)
|| (event.keyCode == 37)
|| (event.keyCode == 33)){
if(doGetCaretPosition(this) <= this.NonDeletableString.length){
event.returnValue = false;
}
}
//home key
if((event.keyCode == 36) && !(event.shiftKey)){
setCaretPosition(this, this.NonDeletableString.length);
event.returnValue = false;
}
}
TextBoxControl.onfocus = function(){
setCaretPosition(this, this.NonDeletableString.length);
}
TextBoxControl.onkeypress = function(){
var selectionRange = document.selection.createRange();
if(selectionRange.text == this.NonDeletableString){
event.returnValue = false;
}
}
TextBoxControl.onkeyup = function(){
if(doGetCaretPosition(this) < this.NonDeletableString.length){
setCaretPosition(this, this.NonDeletableString.length);
}
if(this.value.substring(0, this.NonDeletableString.length) != this.NonDeletableString){
var remaining = this.value.substring(this.NonDeletableString.length, this.value.length)
this.value = this.NonDeletableString + remaining;
}
}
}
function doGetCaretPosition (ctrl) {
var CaretPos = 0;
// IE Support
if (document.selection) {
ctrl.focus ();
var Sel = document.selection.createRange ();
Sel.moveStart ('character', -ctrl.value.length);
CaretPos = Sel.text.length;
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0')
CaretPos = ctrl.selectionStart;
return (CaretPos);
}
function getCaretPosition (el)
{
var iCaretPos = 0;
if (document.selection){
if (el.type == 'text') {
var selectionRange = document.selection.createRange();
selectionRange.moveStart ('word', -el.value.length);
iCaretPos = selectionRange.text.length;
}
else {
iCaretPos = Math.abs(document.selection.createRange().moveStart("character", -1000000)) - 193;
}
}
else if (el.selectionStart || el.selectionStart == '0') {
iCaretPos = el.selectionStart
}
return iCaretPos;
}
function setCaretPosition(el, iCaretPos)
{
if (document.selection) {
var range = document.selection.createRange();
if (el.type == 'text') {
range.moveStart ('character', -el.value.length)
range.moveEnd ('character', -el.value.length)
range.moveStart ('character', iCaretPos)
range.select()
}
else {
range.collapse(false)
range.move ('character', iCaretPos - el.value.length + el.value.split('\n').length - 1)
range.select()
}
}
else if (el.selectionStart || el.selectionStart == '0') {
el.setSelectionRange(iCaretPos, iCaretPos)
}
}
Bagi yang butuh source code AjaxGrid (GridView bisa tambah row baru diclient) bisa dilihat dibawah. Sorry, belum sempet buat tutorialnya.
/*** AjaxGridColumnType Enum ***/
function AjaxGridColumnTypeEnum(){
this.REGULAR_CHECKBOX = 0;
this.REGULAR_TEXTBOX = 1;
this.UC_DATELOOKUP = 2;
this.REGULAR_DROPDOWNLIST = 3;
this.REGULAR_RADIOBUTTON = 4;
this.UC_TEXTBOXWITHIDLOOKUP = 5;
this.COMBINATION_CHECKBOXDROPDOWNLIST = 6;
this.UC_TEXTBOXLOOKUP = 7;
this.UC_DROPDOWNLISTMODEL1 = 8;
this.UC_DROPDOWNLISTMODEL3 = 9;
this.UC_TEXTBOXWITHID = 10;
}var AjaxGridColumnType = new AjaxGridColumnTypeEnum();
/*** CreateAjaxColumn ***/
function CreateAjaxColumn(ColumnType, HTMLElement){
switch(ColumnType){
case AjaxGridColumnType.REGULAR_CHECKBOX:
{
return new RegularCheckBoxColumn(HTMLElement);
}
break;
case AjaxGridColumnType.REGULAR_TEXTBOX:
{
return new RegularTextBoxColumn(HTMLElement);
}
break;
case AjaxGridColumnType.UC_DATELOOKUP:
{
return new UCDateLookupColumn(HTMLElement);
}
break;
case AjaxGridColumnType.REGULAR_DROPDOWNLIST:
{
return new RegularDropDownListColumn(HTMLElement);
}
break;
case AjaxGridColumnType.COMBINATION_CHECKBOXDROPDOWNLIST:
{
return new CombinationCheckboxDropDownListColumn(HTMLElement);
}
break;
case AjaxGridColumnType.UC_TEXTBOXLOOKUP:
{
return new UCTextBoxLookup(HTMLElement);
}
case AjaxGridColumnType.UC_DROPDOWNLISTMODEL1:
{
return new UCDropDownListModel1(HTMLElement);
}
case AjaxGridColumnType.UC_DROPDOWNLISTMODEL3:
{
return new UCDropDownListModel3(HTMLElement);
}
case AjaxGridColumnType.UC_TEXTBOXWITHID:
{
return new UCTextBoxWithID(HTMLElement);
}
default:
alert('Unknown ColumnType in CreateAjaxColumn: ' + ColumnType);
break;
}
return null;
}
/*** GridViewAdapter class ***/
function GridViewAdapter(GridViewClientIDString){
this.GridView = eval('document.all.' + GridViewClientIDString);
if(!this.GridView){
alert('GridViewClientIDString: ' + GridViewClientIDString + ' is not valid in GridViewAdapter');
}
this.GetRow = function(RowIndex){
var rows = this.GetRows();
if(!rows){
alert('Failed to get rows in GridViewAdapter.GetRow() function.');
return null;
}
if(RowIndex >= rows.length){
alert('Index out of bound in GridViewAdapter.GetRow() Grid: ' + this.GridView.id);
}
return rows[RowIndex];
}
this.GetRows = function(){
return this.GridView.tBodies[0].rows;
}
this.AddRow = function(NewRow){
this.GridView.tBodies[0].appendChild(NewRow);
}
this.RemoveRow = function(RowIndex){
this.GridView.deleteRow(RowIndex);
}
}
/*** AjaxGridColumn class ***/
function AjaxGridColumn(ColumnName, ColumnType){
this.ColumnName = ColumnName;
this.ColumnType = ColumnType;
}
/*** AutoAddRowInfo class ***/
function AutoAddRowInfo(ColIndexToAddAutoAddRowHandler, AutoAddRowEventName, ControlTag){
}
/*** AjaxGridRow class ***/
function AjaxGridRow(AjaxGridObject, RowIndex){
this.AjaxGridObject = AjaxGridObject;
this.GridViewAdapter = AjaxGridObject.GridView;
this.RowIndex = RowIndex;
this.GetCell = function(ColumnIndex){
var CellRow = this.GridViewAdapter.GetRow(this.RowIndex);
if(!this.AjaxGridObject.Columns[ColumnIndex]){
alert('Invalid ColumnIndex : ' + ColumnIndex + ' in AjaxGridRow.GetCell()');
}
var CellColumnType = this.AjaxGridObject.Columns[ColumnIndex].ColumnType;
var HTMLElement = CellRow.cells[ColumnIndex].children[0];
return CreateAjaxColumn(CellColumnType, HTMLElement);
}
}
/*** AjaxGrid class ***/
function AjaxGrid(GridViewClientID, IsContainsHeader, InstanceName, AutoAddRowInfoInstance){
this.OriginalRow = null;
this.Columns = new Array();
this.GridView = new GridViewAdapter(GridViewClientID);
this.DataSource = "";
this.IsContainsHeader = IsContainsHeader;
this.InstanceName = InstanceName;
this.beginRequestHandlerAdded = false;
this.Binding = false;
this.GetRow = function(RowIndex){
//Plus 1 to RowIndex, because the grid contains header.
var theRowIndex = this.GetDataRowIndex(RowIndex);
// return this.GridView.GetRow(theRowIndex);
return new AjaxGridRow(this, theRowIndex);
}
this.GetRows = function(){
return this.GridView.GetRows();
}
this.DataBind = function(){
this.Binding = true;
this.OriginalRow = this.GridView.GetRow(1).cloneNode(true);
this.DataSource = eval(this.DataSource);
if(this.ColIndexOfTabKeyDown == -1){
this.ColIndexOfTabKeyDown = this.Columns.length - 1;
}
//this.addAutoNewRowEvent(this.ColIndexOfTabKeyDown, this.GridView.GetRow(1), this.GridView.GetRows().length);
if(this.OnRowCreated){
this.OnRowCreated(this.GetRow(1));
}
var rowsMinus = this.DataSource.length - (this.GetRows().length - 1);
for(i = 1; i <= rowsMinus; i++){
this.AddNewRow();
}
for(dsRowIndex = 0; dsRowIndex < this.DataSource.length; dsRowIndex++){
if(this.OnRowDataBound){
var rowIndex = dsRowIndex+1;
var currentGridRow = this.GetRow(rowIndex);
var currentDataSourceRow = this.DataSource[dsRowIndex];
this.OnRowDataBound(currentGridRow, currentDataSourceRow);
}
}
this.Binding = false;
}
}
AjaxGrid.prototype.ColIndexOfTabKeyDown = -1;
AjaxGrid.prototype.OnSaveState = function(){}
AjaxGrid.prototype.SaveGridState = function(){
this.OnSaveState();
//this.ClearRows();
}
AjaxGrid.prototype.ClearRows = function(){
while(this.GridView.GetRows().length > 1){
this.RemoveRow(this.GridView.GetRows().length - 1);
}
}
AjaxGrid.prototype.OnInsertEventForAutoAddRow = function(PreviousRow, TargetRow){
}
AjaxGrid.prototype.GetDataRowIndex = function(RowIndex){
var theRowIndex = RowIndex;
// if(this.IsContainsHeader){
// theRowIndex += 1;
// }
return theRowIndex;
}
AjaxGrid.prototype.OnRowCreated = function(NewRow){
}
AjaxGrid.prototype.CreateNewRow = function(){
var newRow = this.OriginalRow.cloneNode(true);
var rowCountBeforeAdded = this.GridView.GetRows().length;
this.GridView.AddRow(newRow);
var rowIndex = rowCountBeforeAdded;
for(colIndex = 0; colIndex < this.Columns.length; colIndex++){
var columnName = this.Columns[colIndex].ColumnName;
switch(this.Columns[colIndex].ColumnType){
case AjaxGridColumnType.UC_DATELOOKUP:
{
var inputs = newRow.cells[colIndex].getElementsByTagName("INPUT");
var txt = null;
var btn = null;
if(inputs[0].type.toLowerCase() == "text".toLowerCase()){
txt = inputs[0];
btn = inputs[1];
}
else{
txt = inputs[1];
btn = inputs[0];
}
txt.setAttribute("id", "txt_r" + rowIndex + "_c_" + colIndex + "_" + columnName);
btn.setAttribute("id", "btn_r" + rowIndex + "_c_" + colIndex + "_" + columnName);
Calendar.setup({inputField: txt.id, ifFormat: "%d.%m.%Y", button: btn.id});
}
break;
case AjaxGridColumnType.UC_DROPDOWNLISTMODEL1:
{
this.GetRow(rowIndex).GetCell(colIndex).TextBoxID.TextBoxElement.setAttribute("id", "txt_r" + rowIndex + "_c_" + colIndex + "_" + columnName);
this.GetRow(rowIndex).GetCell(colIndex).Button.ButtonElement.setAttribute("id", "btn_r" + rowIndex + "_c_" + colIndex + "_" + columnName);
this.GetRow(rowIndex).GetCell(colIndex).TextBoxDescription.TextBoxElement.setAttribute("id", "txt_d" + rowIndex + "_c_" + colIndex + "_" + columnName);
this.GetRow(rowIndex).GetCell(colIndex).TextBoxID.TextBoxElement.setAttribute("name", "txt_r" + rowIndex + "_c_" + colIndex + "_" + columnName);
this.GetRow(rowIndex).GetCell(colIndex).Button.ButtonElement.setAttribute("name", "btn_r" + rowIndex + "_c_" + colIndex + "_" + columnName);
this.GetRow(rowIndex).GetCell(colIndex).TextBoxDescription.TextBoxElement.setAttribute("name", "txt_d" + rowIndex + "_c_" + colIndex + "_" + columnName);
}
break;
}
}
if(this.OnRowCreated){
this.OnRowCreated(this.GetRow(rowIndex));
}
return newRow;
}
function displayHourglassCursor(){
document.body.style.cursor = 'wait';
}
function resetCursor(){
document.body.style.cursor = 'default';
}
AjaxGrid.prototype.OnValidateRow = function(RowIndex, Row){
return true;
}
AjaxGrid.prototype.RemoveRow = function(RowIndex){
displayHourglassCursor();
var theRowIndex = RowIndex;//this.GetDataRowIndex(RowIndex);
this.GridView.RemoveRow(theRowIndex);
resetCursor();
}
AjaxGrid.prototype.OnRowDataBound = function(CurrentGridRow, CurrentDataSourceRow)
{
}
AjaxGrid.prototype.IsRowValid = function(){
return false;
}
AjaxGrid.prototype.AddNewRow = function(){
//var newRow = this.CreateNewRow();//this.OriginalRow.cloneNode(true);
this.CreateNewRow();
//this.GridView.AddRow(newRow);
}
Array.prototype.Counter = 0;
Array.prototype.Add = function(AjaxGridColumnInstance){
this[AjaxGridColumnInstance.ColumnName] = AjaxGridColumnInstance;
this[this.Counter] = AjaxGridColumnInstance;
this.Counter++;
this.length = this.Counter;
}
/*** End of AjaxGrid class ***/
/*** AjaxGridColumns ****/
function ValidateINPUTElement(ColumnTypeString, InputElement, HTMLElement, InputType){
if(!InputElement){
alert('Invalid HTMLElement for ' + ColumnTypeString + ' : ' + HTMLElement);
}
if(!InputElement.type){
alert('InputElement.type is invalid for ColumnTypeString: ' + ColumnTypeString +
', InputElement.tagName: ' + InputElement.tagName + ', HTMLElement.tagName: ' + HTMLElement.tagName +
', InputType : ' + InputType);
}
if(InputElement.type.toLowerCase() != InputType.toLowerCase()){
alert('HTMLElement for ' + ColumnTypeString + ' is not a ' + InputType + ' : ' + HTMLElement.type);
}
}
function UCDropDownListModel3(HTMLElement){
this.TextBoxID = new RegularTextBoxColumn(HTMLElement.childNodes[0].childNodes[0].childNodes[0].rows[0].cells[0].childNodes[0]);
this.Button = new RegularButtonColumn(HTMLElement.childNodes[0].childNodes[0].childNodes[0].rows[0].cells[1].childNodes[0]);
this.ListBox = new RegularListBoxColumn(HTMLElement.childNodes[0].childNodes[0].childNodes[0].rows[1].cells[0].childNodes[0].childNodes[0]);
}
function UCDropDownListModel1(HTMLElement){
this.Elements = new Array();
this.DropDownListModel3 = new UCDropDownListModel3(HTMLElement);
this.TextBoxID = this.DropDownListModel3.TextBoxID;
this.Button = this.DropDownListModel3.Button;
this.ListBox = this.DropDownListModel3.ListBox;
this.TextBoxDescription = new RegularTextBoxColumn(HTMLElement.childNodes[0].childNodes[0].childNodes[0].rows[0].cells[3].childNodes[0]);
this.SetSelectedIndex = function(value){
this.ListBox.SetSelectedIndex(value);
this.Button.SetText("5");
try{
this.Button.ButtonElement.click();
}catch(ex){
alert("SetSelectedIndex Error: " + ex);
}
}
this.GetSelectedIndex = function(value){
return this.ListBox.GetSelectedIndex();
}
}
function UCTextBoxWithID(HTMLElement){
this.TextBoxID = new RegularTextBoxColumn(HTMLElement.tBodies[0].rows[0].cells[0].childNodes[0]);
this.TextBoxDescription = new RegularTextBoxColumn(HTMLElement.tBodies[0].rows[0].cells[2].childNodes[0]);
this.SetID = function(value){
this.TextBoxID.SetText(value);
}
this.GetID = function(){
return this.TextBoxID.GetText();
}
this.SetDescription = function(value){
this.TextBoxDescription.SetText(value);
}
this.GetDescription = function(){
return this.TextBoxDescription.GetText();
}
}
function RegularCheckBoxColumn(HTMLElement){
if(HTMLElement.tagName != "INPUT") HTMLElement = HTMLElement.childNodes[0];
this.CheckBoxElement = HTMLElement;
ValidateINPUTElement("RegularCheckBoxColumn", this.CheckBoxElement, HTMLElement, "checkbox");
this.GetChecked = function(){
return this.CheckBoxElement.checked;
}
this.SetChecked = function(value){
this.CheckBoxElement.checked = value;
}
}
function RegularTextBoxColumn(HTMLElement){
this.TextBoxElement = HTMLElement;
ValidateINPUTElement("RegularTextBoxColumn", this.TextBoxElement, HTMLElement, "text");
this.GetText = function(){
return this.TextBoxElement.value;
}
this.SetText = function(value){
this.TextBoxElement.value = value;
}
}
function RegularButtonColumn(HTMLElement){
this.ButtonElement = HTMLElement;
ValidateINPUTElement("RegularButtonColumn", this.ButtonElement, HTMLElement, "button");
this.GetText = function(){
return this.ButtonElement.value;
}
this.SetText = function(value){
this.ButtonElement.value = value;
}
this.Click = function(){
this.ButtonElement.click();
}
}
function RegularListBoxColumn(HTMLElement){
this.ListBoxElement = HTMLElement;
this.GetText = function(){
return this.ListBoxElement.value;
}
this.SetSelectedIndex = function(value){
this.ListBoxElement.selectedIndex = value;
}
this.GetSelectedIndex = function(value){
return this.ListBoxElement.selectedIndex;
}
}
function getTextBoxAndButton(HTMLElement, ObjectHolder){
var inputs = HTMLElement.getElementsByTagName("INPUT");
var txt = null;
var btn = null;
if(inputs[0].type.toLowerCase() == "text".toLowerCase()){
txt = inputs[0];
if(inputs.length >= 2){
btn = inputs[1];
}
}
else{
if(inputs.length >= 2){
txt = inputs[1];
}
btn = inputs[0];
}
ObjectHolder.TextBoxElement = txt;
ObjectHolder.ButtonElement = btn;
}
function UCDateLookupColumn(HTMLElement){
getTextBoxAndButton(HTMLElement, this);
this.SetDate = function(value){
this.TextBoxElement.value = value;
this.TextBoxElement.onblur();
}
this.GetDateString = function(){
return this.TextBoxElement.value;
}
this.focus = function(){
this.TextBoxElement.focus();
this.TextBoxElement.scrollIntoView();
}
}
function UCTextBoxLookup(HTMLElement){
getTextBoxAndButton(HTMLElement, this);
this.SetText = function(value){
this.TextBoxElement.value = value;
}
this.GetText = function(){
return this.TextBoxElement.value;
}
}
function ValidateSELECTElement(ColumnTypeString, InputElement, HTMLElement, InputType){
if(!InputElement){
alert('Invalid HTMLElement for ' + ColumnTypeString + ' : ' + HTMLElement);
}
if(InputElement.type.toLowerCase() != InputType.toLowerCase()){
alert('HTMLElement for ' + ColumnTypeString + ' with type : ' + InputElement.type + ' is not a ' + InputType + ' : ' + HTMLElement);
}
}
function RegularDropDownListColumn(HTMLElement){
this.DropDownElement = HTMLElement;
ValidateSELECTElement("RegularDropDownListColumn", this.DropDownElement, HTMLElement, "select-one");
this.GetSelectedValue = function(){
return this.DropDownElement.value;
}
this.SetSelectedValue = function(value){
var i = -1;
for(i = 0; i < this.DropDownElement.options.length; i++){
if(this.DropDownElement.options
.value.toLowerCase() = value.toLowerCase()){
break;
}
}
this.SetSelectedIndex(i);
}
this.GetSelectedIndex = function(){
return this.DropDownElement.selectedIndex;
}
this.SetSelectedIndex = function(value){
this.DropDownElement.selectedIndex = value;
}
this.GetSelectedItem = function(){
return new AjaxOptionElement(this.DropDownElement.options[this.GetSelectedIndex()]);
}
}
function AjaxOptionElement(HTMLElement){
this.OptionElement = HTMLElement;
this.GetText = function(){
return this.OptionElement.text;
}
this.GetValue = function(){
return this.OptionElement.value;
}
}
function CombinationCheckboxDropDownListColumn(HTMLElement){
this.CheckBoxElement = new RegularCheckBoxColumn(HTMLElement.parentNode.children[0]);//.parentNode.getElementsByTagName("INPUT"));
this.DropDownElement = new RegularDropDownListColumn(HTMLElement.parentNode.children[1]);//(HTMLElement.parentNode.getElementsByTagName("SELECT"));
}
/*** End of AjaxGridColumns ****/
////////////////////////////////////////////////////////////////////////////////////////////////////
Lagi megang modul finance, ada kebutuhan untuk bikin penterjemah angka menjadi terbilang dalam Bahasa Indonesia. Codenya masih butuh refactoring kalo gw sempat nanti gw beresin. Berikut code lengkapnya:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
private string[] _ZeroToEleven = {"Nol", "Satu", "Dua", "Tiga", "Empat"
, "Lima", "Enam", "Tujuh", "Delapan"
, "Sembilan", "Sepuluh", "Sebelas"};
private string[] _GroupSuffix = {"", "ribu", "juta", "milyar", "trilyun", "bilyun", "tetra bilyun"};
public string Pronounce(long Number, bool LowerCase)
{
string numberString = Number.ToString();
string result = string.Empty;
if (Number <= 11)
{
return (LowerCase ? _ZeroToEleven[Number].ToLower() : _ZeroToEleven[Number]);
}
//handle puluhan and belasan but starts from twelve up
if (numberString.Length == 2)
{
int firstDigit = Convert.ToInt32(numberString[0].ToString());
int secondDigit = Convert.ToInt32(numberString[1].ToString());
//belasan (12 - 19)
if (firstDigit == 1)
{
return Pronounce(secondDigit, LowerCase) +" belas";
}
if (secondDigit == 0)
{
return Pronounce(firstDigit, LowerCase) + " puluh";
}
else
{
return Pronounce(firstDigit, LowerCase) + " puluh " + Pronounce(secondDigit, true);
}
}
//handle 100 - 999
if (numberString.Length == 3)
{
long firstDigit = Convert.ToInt32(numberString[0].ToString());
string lastTwoDigits = numberString.Substring(1);
long lastTwoDigitNumber = Convert.ToInt64(lastTwoDigits);
if (firstDigit == 1)
{
if (lastTwoDigitNumber > 0)
{
result = "Seratus " + Pronounce(lastTwoDigitNumber, true);
}
else
{
result = "Seratus";
}
if (LowerCase)
{
result = result[0].ToString().ToLower() + result.Substring(1);
}
return result;
}
else
{
if (lastTwoDigitNumber > 0)
{
return Pronounce(firstDigit, LowerCase) + " ratus " + Pronounce(lastTwoDigitNumber, true);
}
else
{
return Pronounce(firstDigit, LowerCase) + " ratus";
}
}
}
Stack<string> groupStack = GroupNumber(numberString);
if(groupStack.Count > _GroupSuffix.Length)
{
throw new InvalidOperationException("Number is too big. I don't know how to pronounce it in Bahasa.");
}
while (groupStack.Count > 0)
{
string currentGroup = groupStack.Pop();
long currentGroupNumber = Convert.ToInt64(currentGroup);
//Print only 1000 down with 'se' e.g. Seribu
if (currentGroupNumber == 1 && groupStack.Count <= 1)
{
if (result.Length > 0)
{
result += " ";
}
result += "se" + _GroupSuffix[groupStack.Count];
}
else
{
if (currentGroupNumber > 0)
{
if (result.Length > 0)
{
result += " ";
}
result += Pronounce(currentGroupNumber, true) + " " + _GroupSuffix[groupStack.Count];
}
}
}
result = result[0].ToString().ToUpper() + result.Substring(1);
return result;
}
private Stack<string> GroupNumber(string NumberString)
{
Stack<string> groupStack = new Stack<string>();
string currentGroup = string.Empty;
int counter = 0;
for (int i = NumberString.Length - 1; i >= 0; i--)
{
currentGroup = NumberString
.ToString() + currentGroup;
counter++;
if (counter == 3)
{
groupStack.Push(currentGroup);
counter = 0;
currentGroup = string.Empty;
}
}
if (counter > 0)
{
groupStack.Push(currentGroup);
}
return groupStack;
}
}
}
Buat yang butuh silahkan pakai. Kalau ada bug please kasih tahu yaah...!.