1
\$\begingroup\$

I have a function called FormatCurrency() which I would like to call on each of the following elements:

 TextBoxA
 TextBoxB
 TextBoxC
 ...
 TextBoxN

My current function performs the following operation

 function formatALL()
 {
      //get the value into var v. call FormatCurrency(v) and store it back
      var v = document.getElementById("TextBoxA_TextBox").value;
  document.getElementById("TextBoxA_TextBox").value = FormatCurrency(v);

      v = document.getElementById("TextBoxB_TextBox").value;
  document.getElementById("TextBoxB_TextBox").value = FormatCurrency(v);        

  v = document.getElementById("TextBoxC_TextBox").value;
  document.getElementById("TextBoxC_TextBox").value = FormatCurrency(v); 

      //etc... all the way til my last TextBox
 }

Is it possible to optimize this code? In other words, does anyone know any slick loops/operations/etc. to perform this same task?

\$\endgroup\$
2
  • 3
    \$\begingroup\$ are you familiar with jQuery? \$\endgroup\$ Commented Jul 5, 2012 at 23:59
  • 1
    \$\begingroup\$ yes, jQuery would make this infinitely slicker. \$\endgroup\$ Commented Jul 6, 2012 at 0:06

6 Answers 6

6
\$\begingroup\$

You can loop through the elements using a for loop:

for(var i = 65; i <= 78; i++) {
    var box = document.getElementById("TextBox" + String.fromCharCode(i) + "_TextBox");
    box.value = FormatCurrency(box.value); 
}
\$\endgroup\$
4
  • \$\begingroup\$ Store the fetch into a variable and you're golden. \$\endgroup\$ Commented Jul 6, 2012 at 0:01
  • \$\begingroup\$ This is JavaScript, nothing with a char type and a ++ operator on it... \$\endgroup\$ Commented Jul 6, 2012 at 0:04
  • \$\begingroup\$ @Bergi: Ah good catch. Been jumping around too many languages lately. \$\endgroup\$ Commented Jul 6, 2012 at 0:06
  • \$\begingroup\$ Well I enumerated them with Alphabets since in actuality, they actually don't have any pattern to their names. I should've been more clear in that regards. Let's say that the names are Jon, steve, mike, etc... Still this is a good suggestion \$\endgroup\$ Commented Jul 6, 2012 at 4:25
3
\$\begingroup\$

You could use a library such as jQuery, which allows you, for example, to select elemts using CSS selectors. In this case you could assign all your elements a class and use:

$('.currency-textbox').each(function() {
   $(this).val(FormatCurrency($(this).val()));
});
\$\endgroup\$
1
\$\begingroup\$

stick all the strings into an array and iterate over them?

something like

var myElems=["TextBoxA_TextBox","TextBoxB_TextBox","TextBoxC_TextBox"];
for(var i = 0; i < myElems.list; i++) {
    var v = document.getElementById(i).value;
    document.getElementById(i).value = FormatCurrency(v);
}
\$\endgroup\$
1
\$\begingroup\$

The quickest modification would be to store your elements in a variable:

var obj = document.getElementById("TextBoxA_TextBox");
obj.value = FormatCurrency(obj.value);

The next step would be to create a loop that repeats the process dynamically and not statically as it is currently configured.

\$\endgroup\$
1
\$\begingroup\$

Two strategies: loops and variables.

function formatALL() {
    // "A".charCodeAt(0) = 65
    // "N".charCodeAt(0) = 78
    for (var i=65; i<79; i++) {
        var chr = String.fromCharCode(i);
        var el = document.getElementById("TextBox"+chr+"_TextBox");
        el.value = FormatCurrency(el.value);
    }
}

It would be easier if you had enumerated your elements with decimal numbers, not alphanumerical characters. If the element ids grew more complicated (less predictable), you'd need to put them in an array and loop over them:

function formatALL() {
    var ids = ["Jon", "steve", "mike", ...];
    for (var i=0; i<ids.length; i++) {
        var el = document.getElementById(ids[i]+"_TextBox");
        el.value = FormatCurrency(el.value);
    }
}

An even better strategy would be to use a class instead of numbered ids (the elements don't seem to be such unique :-)), like "currency" in your case. Then you don't need to adjust the array every time you change something in the page. With a class name, you can use something like getElementsByClassName("currency") (or a library equivalent like jQuery(".currency"), then iterate over the returned NodeList.

\$\endgroup\$
7
  • \$\begingroup\$ In terms of optimization, I would eliminate the unnecessary container variables. \$\endgroup\$ Commented Jul 6, 2012 at 0:09
  • \$\begingroup\$ What do you mean with "container variable"? The only unnecessary var is "chr", which I've used to improve comprehensibility and readability. Nothing to micro-optimize here. \$\endgroup\$ Commented Jul 6, 2012 at 0:13
  • \$\begingroup\$ He asked what he could do to optimize the code. Even if it's "micro-optimization," creating unneccessary vars is using unnecessary memory. \$\endgroup\$ Commented Jul 6, 2012 at 0:16
  • \$\begingroup\$ The OP wanted to optimize code, not performance. As you can see in @tskuzzy's answer, the line gets too long for SO - that's not "good" code. Depending on your JS knowledge, you might write less code less readable - I might have done the same if it wasn't a answer on a newbies question. \$\endgroup\$ Commented Jul 6, 2012 at 0:27
  • \$\begingroup\$ Well I enumerated them with Alphabets since in actuality, they actually don't have any pattern to their names. I should've been more clear in that regards. Let's say that the names are Jon, steve, mike, etc... \$\endgroup\$ Commented Jul 6, 2012 at 4:20
0
\$\begingroup\$

There are a fews ways to go about it. Since your examining how to create "slicker" or DRY code, I would assume you would want succinct code, but not illegible? And you would also be willing to change code to get it.

Note: Don't Repeat Yourself (DRY).

Here are two ways in which to do it. One uses ID (current), and one uses class (perhaps more slick).

Note: We use Array.from() to create an actual Array from the document node list (ES6), or use the polyfill for legacy browsers here

// If changing the FormatCurrency function is on the table...

function FormatCurrencyWithChange(input){
  // Whatever you do in here, use input.value.
  input.value = '$ ' + (Math.random() * 100).toFixed(2);
}

Array.from(document.getElementsByClassName("currency")).forEach(FormatCurrencyWithChange);

// OR

Array.from(document.querySelectorAll('[id$="TextBox"]')).forEach(FormatCurrencyWithChange)

// If you cannot change the FormatCurrency function, then you could also wrap it up.
// Also, if it's not a class, then the function name should be camelCase.

function formatCurrency(input){
  input.value = FormatCurrencyNoChange(input.value);
}

function FormatCurrencyNoChange(value){
  // I don't know whats in your function; This one still accepts value.
  return '$ ' + (Math.random() * 100).toFixed(2);
}

Array.from(document.getElementsByClassName("currency-wrap")).forEach(formatCurrency);
input, label {
  display: block;
}

input {
  margin-bottom: 20px;
}
<label>Text Box A (ID)</label>
<input id="#TextBoxA_TextBox" type="text" />

<label>Text Box B (ID)</label>
<input id="#TextBoxB_TextBox" type="text" />

<label>Currency (CLASS)</label>
<input class="currency" type="text" />

<label>Currency (CLASS)</label>
<input class="currency" type="text" />

<label>Currency (CLASS) Using Wrapper</label>
<input class="currency-wrap" type="text" />

<label>Currency (CLASS) Using Wrapper</label>
<input class="currency-wrap" type="text" />

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.