Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Fill one form field from another...

  1. #1
    Join Date
    Apr 2007
    Posts
    31
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Fill one form field from another...

    On to the next problem.
    On my form I have a text box to type a number into. I also have a hidden box that stores a value from a database.

    What I want to do is take those two values, perform a calculation and fill out a new text box on screen for entry into a database.

    <td>
    <input name="userinput" type="text" id="userinput">
    </td>
    <td><input name="dbvalue" type="hidden" id="dbvalue"></td>
    <td>
    <input name="calculated" type="text" id="calculated">
    </td>

    Take the value from 'userinput' and the value from 'dbvalue', do the calculation, and show the result in 'calculated'

    'calculated' will then be inputed into a database.

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Without knowing more about this, but assuming that it is in a valid form, I would just do:

    HTML Code:
    <td>
    <input name="userinput" type="text" id="userinput" onchange="this.form.elements['calculated'].value=this.form.elements['dbvalue'].value*1+this.value*1;">
    </td>
    <td><input name="dbvalue" type="hidden" id="dbvalue"></td>
    <td>
    <input name="calculated" type="text" id="calculated">
    </td>
    The onchange event could (should probably) include something to ensure that the entry(s) is a number. There could be a button to click to calculate the result but, it would need no name, id or event, and wouldn't even need to be in the form:

    HTML Code:
    <input type="button" value="Calculate">
    Important: Since this does involve, as you say, writing the result to a database, there should be a server side fall back unless you can be guaranteed that the user could never view this content without javascript enabled.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Apr 2007
    Posts
    31
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thanks for the suggestion. I'll work on it and see what I get.


    I have already got it working in PHP perfectly, it's just that I want to allow the user to see the result immediatly before it gets inputed into the DB.
    It is for an Intranet so Javascript will be running, but as you say I will probably leave the PHP method in as well just to make sure.

    Thanks again and I'll be back if there's a problem.

  4. #4
    Join Date
    Apr 2007
    Posts
    31
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Okay I admit defeat, the best I an get is NaN to appear.
    The suggestion works perfectly but when I adapted it for my code it don't work.
    This is what I have tried


    HTML Code:
    <td>
          <input name="userinput" type="text" id="userinput" onchange="this.form.elements['calculated'].value=Math.abs(parseInt((this.value = (this.value.split('.'))[0], 10) * 12 + parseInt(this.value[1], 10)) - this.form.elements['dbvalue']);
    	  ">
        </td>
        <td><input name="dbvalue" type="hidden" id="dbvalue" value="5"></td>
        <td>
          <input name="calculated" type="text" id="calculated">
        </td>
    User input is a decimal type number (eg. 8.1 age in year.month to be converted to age in months) which is why it needs splitting.
    Ideally the calculation would be a function (I have several pages that will use it).

    As I said the best I can get is NaN to appear in the 'caculated' box.
    Hope someone can help.
    Last edited by mhodgson; 05-08-2007 at 12:22 PM.

  5. #5
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    I don't know what you're calculating so I can't verify correctness, but consider the following function:

    Code:
    function calculateValue(form) {
        var controls = form.elements,
            age = controls.userinput.value.split('.'),
            months = (age[0] * 12) + (+age[1]);
    
        controls.userinput.value = age[0];
        controls.calculated.value = Math.abs(months - controls.dbvalue.value);
    }
    Mike
    Last edited by mwinter; 05-08-2007 at 08:53 PM.

  6. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    At this point it might be better to break it out into a separate function, but this works:

    Code:
    <form action="">
    
    <table>
    <tr>
    <td>
          <input name="userinput" type="text" id="userinput" onchange="this.form.elements['calculated'].value=this.value.split('.')[0]*12 + this.value.split('.')[1]*1 - this.form.elements['dbvalue'].value*1;">
        </td>
        <td><input name="dbvalue" type="hidden" id="dbvalue" value="5"></td>
        <td>
          <input name="calculated" type="text" id="calculated">
    </td>
    </tr>
    </table>
    
    
    </form>
    Here's one way to break it out into a function:

    Code:
    <script type="text/javascript">
    function calcFrm(el){
    var frm=el.form.elements;
    for (var i = 0, vals=el.value.split('.'); i < 2; i++)
    vals[i]=vals[i]? vals[i]*(i? 1 : 12) : 0;
    vals[2]=frm['dbvalue'].value*1;
    frm['calculated'].value=isNaN(i=vals[0] + vals[1] - vals[2])? '' : i;
    }
    </script>
    
    <form action="">
    
    <table>
    <tr>
    <td>
          <input name="userinput" type="text" id="userinput" onchange="calcFrm(this)">
        </td>
        <td><input name="dbvalue" type="hidden" id="dbvalue" value="5"></td>
        <td>
          <input name="calculated" type="text" id="calculated">
    </td>
    </tr>
    </table>
    
    
    </form>
    Either way, it could still use some error/validation checking, which I threw in with the function to at least make sure that the result is a number.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. #7
    Join Date
    Apr 2007
    Posts
    31
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    jscheuer1, many thanks, the function seems to be doing just what I need.
    you have been most helpfull
    However I would like to understand it a little more.
    I get some of it but other bits are unclear

    function calcFrm(el){ This obviously sets the function (does (el) mean this element-userinput ?)

    var frm=el.form.elements; This sets a string variable frm to save code typing

    for (var i = 0, vals=el.value.split('.'); i < 2; i++) This sets splits the variable vals and puts it into an array with two values

    vals[i]=vals[i]? vals[i]*(i? 1 : 12) : 0; I Know what this does but don't understand the process

    vals[2]=frm['dbvalue'].value*1; This gets the value from the db field (but why *1??)

    frm['calculated'].value=isNaN(i=vals[0] + vals[1] - vals[2])? '' : i; This calculates the 'calculated' value but I'm not too sure of the process - why isNan?
    }

    Hope I am on the right track as the function is good. The only value that needs validating is the user input, the one from the db is already validated.

  8. #8
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    function calcFrm(el){ This obviously sets the function (does (el) mean this element-userinput ?)
    Yes, in this case.
    var frm=el.form.elements; This sets a string variable frm to save code typing
    Not only that, it also saves lookups -- people often forget that . is an operator. Long strings of repeated lookups slow down code no end.
    vals[i]=vals[i]? vals[i]*(i? 1 : 12) : 0; I Know what this does but don't understand the process
    It's equivalent to:
    Code:
    if(vals[i]) {
      if(i) {
        vals[i] *= 1;
      } else {
        vals[i] *= 12;
      }
    } else {
      vals[i] = 0;
    }
    vals[2]=frm['dbvalue'].value*1; This gets the value from the db field (but why *1??)
    Quick way of converting to a number.
    frm['calculated'].value=isNaN(i=vals[0] + vals[1] - vals[2])? '' : i; This calculates the 'calculated' value but I'm not too sure of the process - why isNan?
    Sets it to blank if there's a non-numerical value involved, rather than displaying "NaN."
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  9. #9
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Code:
    function calculateValue(form) {
        var controls = form.elements,
            match = /^(\d+)\.(\d+)$/.exec(controls.userinput.value),
            months;
    
        if (!match) {
            /* Validation failed */
            return;
        }
        months = (match[1] * 12) + Number(match[2]);
        controls.calculated.value = months - controls.dbvalue.value;
    }
    A validating form of my earlier function.

    Quote Originally Posted by mhodgson View Post
    function calcFrm(el){ This obviously sets the function (does (el) mean this element-userinput ?)
    It will be whatever is passed when the function is called, but in John's previous post, yes, it's the userinput form control.

    var frm=el.form.elements; This sets a string variable frm to save code typing
    No, it assigns an object reference to the variable, frm. The elements property is a collection (think array) of controls within a form. You got the reason partially right, though: not only does it save typing, it's quicker as the script interpreter doesn't have to perform so many property accessor operations.

    for (var i = 0, vals=el.value.split('.'); i < 2; i++) This sets splits the variable vals and puts it into an array with two values

    vals[i]=vals[i]? vals[i]*(i? 1 : 12) : 0; I Know what this does but don't understand the process
    This is a rather convoluted way of writing:

    Code:
    var vals = el.value.split('.');
    
    if (vals[0]) vals[0] = vals[0] * 12;
    else vals[0] = 0;
    if (vals[1]) vals[1] = vals[1] * 1;
    else vals[1] = 0;
    The conditional operator (? :&#41; is somewhat like an expression form of an if statement.

    &#160;&#160;cond ? expr1 : expr2

    The first expression, cond, is evaluated as a boolean. If true, the entire expression evaluates to expr1. If false, the expression evaluates to expr2.

    vals[2]=frm['dbvalue'].value*1; This gets the value from the db field (but why *1??)
    The value property of form controls is always a string. There are many ways to convert a string to number, including multiplying by one (1). However, it's not the best way. Either use unary plus:

    Code:
    vals[2] = +frm.dbvalue.value;
    or the Number constructor function:

    Code:
    vals[2] = Number(frm.dbvalue.value);
    frm['calculated'].value=isNaN(i=vals[0] + vals[1] - vals[2])? '' : i; This calculates the 'calculated' value but I'm not too sure of the process - why isNan?
    }
    Simplified, this is equivalent to:

    Code:
    var value = vals[0] + vals[1] - vals[2];
    
    if (isNaN(value)) frm.calculated.value = '';
    else frm.calculated.value = value;
    
    /* or:
     *     frm.calculated.value = isNaN(value) ? '' : value;
     */
    If one of the string-to-number conversions fails, it will yield the special number value, NaN. Therefore, using the isNaN function is a simple form of error detection. However, using regular expressions to validate input before beginning work on it (as in my code above) is generally a better approach.

    Hope that helps,
    Mike
    Last edited by mwinter; 05-08-2007 at 09:20 PM. Reason: Presentation

  10. #10
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Thanks, Twey and mwinter. I don't think I could have done better myself in explaining the code. I especially enjoyed Twey's explanation as, it seemed to follow my thought process very closely. About Mike's (mwinter's) idea of validating earlier in the process - it is a good idea and one I considered, but figured it wasn't crucial. If I follow Mike's suggested code utilizing the exec method correctly however, it would reject 9 months or 8 years (values representing only years or only months). I could be mistaken though as, I am not intimately familiar with the exec method.

    Just to be clear though, my code would accept:

    8.1

    or:

    .9

    or:

    8

    of those three, I believe Mike's would only accept 8.1.

    If I've got that wrong, I would be happy to learn in what way.

    Thanks again guys.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •