You are viewing limited content. For full access, please sign in.

Question

Question

Autofill script with Forms 9.2

asked on October 27, 2014 Show version history

Hi,

I have a few forms that have been designed with the autofill script mentioned in this post.

It worked great until I upgraded to Forms 9.2. I had a look at this article: https://support.laserfiche.com/KB/1013538 to see how I can fix the problem, however, I'm not sure I'm implementing this fix correctly.

I'm not sure if my forms were always doing this, but it seems that my function I'm calling on my table change event is looping infinitely.

Could really use some guidance on how to implement the KB fix.

The form itself is used to pass credit on a stock item that was ordered. To pull the details of the stock item, the Sales Order Number must be entered for a lookup to take place. Then a 2nd lookup takes place when the user selects the specific Stock Code value in the table. This 2nd lookup populates the row with stock description, qty and price. These values are used to perform the subtotal calculation. What I find now is the following:

1. Autofill doesn't seem to work automatically when the stock code field is populated

2. If I then manually click on the Autofill button itself and there seems to be an infinite loop of the (sumtotalcredit) function afterwards.

Here is my code:

$(document).ready(function () {
  
  //Automatically trigger autofill button
 // $('.lookupCondition input').lookup(autofill);

  $('.tblstock').change(tableAutofill);
  
  function tableAutofill() {

  $('.tblstock tbody tr').each(function () {

  $(this).find('button.autofill').trigger('click');

});

}

function autofill() {

$('.autofill').trigger('click');  

}


  //trigger for updating stock table values

$('.tblstock').on('change', sumtotalcredit);

  function sumtotalcredit() 
  {
    var totalcredit = 0;
    var totalVAT = 0;
    var subtotalcredit = 0;
    
    $('.tblstock tbody tr').each(function ()
                                    {
                                      alert('SumTotalcredit');
                                      var uom = $(this).find('.uom input').val() * 1;
                                      var subtotal = 0;
                                      var listPrice = $(this).find('.listPrice input').val() * 1;
                                      var qtyOrdered = $(this).find('.qtyOrdered input').val() * 1;
                                      qtyOrdered = Math.round(qtyOrdered);
                                      var qtyReturned = $(this).find('.qtyReturned input').val() * 1;
                                      qtyReturned = qtyReturned.toFixed(0);
                                      $(this).find('.qtyReturned input').val(qtyReturned);
                                      //Remove decimals from QTY ordered
                                      $(this).find('.qtyOrdered input').val(qtyOrdered);

                                      var disc = $(this).find('.disc input').val()/100*1;
                                      var totalPrice =0;
                                      //Calculate total price
                                       
                                      //Calculate Discount if more than 0%
                                      if (disc > 0)
                                      {
                                        disc = 1 - disc;
                                        if(uom == 100)
                                      	{
                                        	totalPrice = listPrice/100*qtyOrdered*disc;                       
                                      	}
                                        else{totalPrice = listPrice * disc;}
                                      }
                                      else{totalPrice = listPrice/100;}                                   
                                      
                                      var totalPriceRounded = totalPrice.toFixed(2);
                                      $(this).find('.totalPrice input').val(totalPriceRounded);
                                      
                                      subtotal += totalPrice / qtyOrdered * qtyReturned;
                                      subtotal = subtotal.toFixed(2);
                                      
                                      subtotalcredit += subtotal *1;
                                      //subtotalcredit = subtotalcredit.toFixed(2);
                                      $(this).find('.stock_subtotal input').val(subtotal);                                      
                                    });//end for each tblstock function
    
    subtotalcredit = subtotalcredit.toFixed(2);
    $('.credit_subtotal input').val(subtotalcredit);
    $('.vat input').val(totalVAT);
    totalcredit += subtotalcredit *1; 
    totalcredit = totalcredit.toFixed(2);
    //totalcredit = totalcredit.toFixed(2);
    $('.totalCredit input').val(totalcredit);
  }//end sumtotalcredit function

  
});//end ready and end function

Thanks

Sheldon

0 0

Answer

SELECTED ANSWER
replied on October 30, 2014 Show version history

Hey Sheldon:

 

Glad it can work now, and thanks for sharing the code! 

According to your update, we double check it and find that you can make some updates based on your current code to make it works better.

1.  You could combine line 07-09 together into: 

$('.tblstock').on('change','.stockCode, .listPrice, .qtyReturned',sumtotalcredit);

 

2. Update

$('.tblstock').on('lookup','.stockCode',tableAutofill);

into

$('.tblstock').on('change lookup','.stockCode',tableAutofill);

The lookup event only works when you first load the page and it deals with the default value. After the first load, the lookup event is never triggered again. So we still need the change event to hear the change of the page after the first load. 

 

3. Based on the second suggestion, we still suggest you to use 

$('.tblstock').on('change',sumtotalcredit);

to execute the function sumtotalcredit().

The reason is: jQuery trigger change event synchronously. That is, in this case, function tableAutofill() and sumtotalcredit() are executed at the same time. Function sum() will do the calculation while fill() is filling data into table.

You could update the code into:

$('.tblstock').on('change','.stockCode, .listPrice, .qtyOrdered, .qtyReturned, .disc, .uom',sumtotalcredit);

It listens to all the changes involved in the function sum(). But it is easier to just listen to the change of the table instead of certain targets.

 

To sum up, you can update  

$('.tblstock').on('change','.stockCode',sumtotalcredit);
$('.tblstock').on('change','.listPrice',sumtotalcredit);
$('.tblstock').on('change','.qtyReturned',sumtotalcredit);
$('.tblstock').on('lookup','.stockCode',tableAutofill);

into

$('.tblstock').on('change',sumtotalcredit);
$('.tblstock').on('change lookup','.stockCode',tableAutofill);

 

Hope it can work better.  Let me know if you have any problem :)

 

*Update: 

It is improper to listen change to a wider range of scope, which may run the risk of infinity loop and redundant calculation. The better code is:

$('.tblstock').on('change','.stockCode, .listPrice, .qtyReturned',sumtotalcredit);
$('.tblstock').on('change lookup','.stockCode',tableAutofill);

 

0 0

Replies

replied on October 28, 2014

Hi Sheldon,  

We may need more information for trouble shooting. Could you open a support case and upload your business process there, as well as screen shot of the "lookup rules" page and "field rules"  page (if any) ? 

Thanks!

0 0
replied on October 29, 2014 Show version history

Hi Sheldon:

 

Sorry for replying late. After checking the business process and screen shot you uploaded in support case, we figured out that you may need to update two places to make it work:

1: In LookupRules, Rule1, section 3, swift the conditions. That is, make "Stock Code" in front of "Sales Order Number".

The reason is: "Auto fill" button will be added behind the last condition.

If we put "Stock Code" first and "Sales Order Number" second, the "Auto fill" button will actually appear behind "Sales Order Number" line. Then function tableAutofill() will not be triggered because there is no button.autofill within ".tblstock" scope. 

 

2. Update

$('.tblstock').change(tableAutofill);

into

$('.tblstock').on('change','.stockCode',tableAutofill);

The reason is: when we run the autofill, the function will look up and change every target which is within the ".tblstock" scope. Then the ".tblstock" hear the change and run function tableAutofill() again. Finally it becomes an infinity loop. 

Here we add the ".stockCode" to the change, which means that we only run the function tableAutofill() if the change happens within ".stockCode" scope. Then all the changes caused by targets will not trigger the function tableAutofill().

 

Hope it can work now. Let me know if you have any problem :)

 

 

 

 

 

 

0 0
replied on October 30, 2014

Hi Li,

 

Thank you for the feedback. I have implemented your suggestions and have managed to get it working. I rebuilt all my lookup rules, since it seems the conversion from 9.1 to 9.2 may have mixed them up a bit. Originally, my Autofill was attached to the correct field.

 

Once the lookups were working properly, I then used your script for monitoring a change event. I did not know you could monitor the table field change in this way and it offers alot more flexibility.

 

Once that was done, I also had to fiddle with the automatic trigger for the Autofill Button. I used the new "lookup" event attached to the StockCode field in the table, and it worked great. I will post my updated coded here for others to see as well.

Thanks for your help.

 

$(document).ready(function () {
  
  //Automatically trigger autofill button
 // $('.lookupCondition input').blur(autofill);

  //$('.tblstock').change(tableAutofill);
  $('.tblstock').on('change','.stockCode',sumtotalcredit);
  $('.tblstock').on('change','.listPrice',sumtotalcredit);
  $('.tblstock').on('change','.qtyReturned',sumtotalcredit);
  $('.tblstock').on('lookup','.stockCode',tableAutofill);
  //$('.PSNumber').change(tableAutofill);
  
  function tableAutofill() {

  $('.tblstock tbody tr').each(function () {

  $(this).find('.autofill').trigger('click');
   
});

}

function autofill() {

$('.autofill').trigger('click');  

}

  function sumtotalcredit() 
  {

    var totalcredit = 0;
    var totalVAT = 0;
    var subtotalcredit = 0;
   
    $('.tblstock tbody tr').each(function ()
                                    {
                                      
                                      var uom = $(this).find('.uom input').val() * 1;
                                      var subtotal = 0;
                                      var listPrice = $(this).find('.listPrice input').val() * 1;
                                      var qtyOrdered = $(this).find('.qtyOrdered input').val() * 1;
                                      qtyOrdered = Math.round(qtyOrdered);
                                      var qtyReturned = $(this).find('.qtyReturned input').val() * 1;
                                      qtyReturned = qtyReturned.toFixed(0);
                                      $(this).find('.qtyReturned input').val(qtyReturned);
                                      //Remove decimals from QTY ordered
                                      $(this).find('.qtyOrdered input').val(qtyOrdered);

                                    
                                      var disc = $(this).find('.disc input').val()/100*1;
                                      var totalPrice =0;
                                      //Calculate total price
                                      
                                      
                                      
                                      //Calculate Discount if more than 0%
                                      if (disc > 0)
                                      {
                                        disc = 1 - disc;
                                        if(uom == 100)
                                      	{
                                        	totalPrice = listPrice/100*qtyOrdered*disc;                                    
                                      	}
                                        else{totalPrice = listPrice * disc;}
                                      }
                                      else{totalPrice = listPrice/100;}                                   
                                      
                                      var totalPriceRounded = totalPrice.toFixed(2);
                                      $(this).find('.totalPrice input').val(totalPriceRounded);
                                      
                                      subtotal += totalPrice / qtyOrdered * qtyReturned;
                                      subtotal = subtotal.toFixed(2);
                                      
  
                                      subtotalcredit += subtotal *1;
                                      //subtotalcredit = subtotalcredit.toFixed(2);
                                      $(this).find('.stock_subtotal input').val(subtotal);                                      
                                    });//end for each tblstock function
    
   
    subtotalcredit = subtotalcredit.toFixed(2);
    $('.credit_subtotal input').val(subtotalcredit);
    $('.vat input').val(totalVAT);
    totalcredit += subtotalcredit *1; 
    totalcredit = totalcredit.toFixed(2);
    //totalcredit = totalcredit.toFixed(2);
    $('.totalCredit input').val(totalcredit);
    
  }//end sumtotalcredit function

  
});//end ready and end function

 

0 0
replied on October 31, 2014

Hi Li,

 

Thank you for the tips, it definitely helps to make the code shorter. However, I find it difficult to manage the order in which events take place, in order to get the right outcome. I have tried your specific suggestions, but find that the "sumtotalcredit" function wouldn't get a chance to do it's job properly and create a subtotal.

I ended up with this combination of event handlers that give me the result I need. I don't think it's the best for performance, but all my "formatting" and calculations end up the way I need it to. This is especially true when there are multiple rows in my table that need to be calculated. When adding a row, then all rows are refreshed with the Autofill and each row is recalculated again. I specifically targeted some of the fields on which the lookup is performed to try and get the order in which the the Autofill and the calculations work. Maybe it's by chance, but the order in which they work seems to give me the right results.

  //Automatically trigger autofill button
  $('.tblstock').on('change','.stockCode, .listPrice, .qtyReturned',sumtotalcredit);
  $('.tblstock').on('lookup','.stockCode, .qtyReturned',tableAutofill);
   $('.tblstock').on('lookup','.qtyReturned',sumtotalcredit);

 

0 0
replied on October 31, 2014

Hey Sheldon:

Maybe our test case is a little bit different from your business process, and that causes the different results with the same piece of code. We are sorry for any improper advice before :/

It is always better to listen to specific targets and we are glad your method can work properly.

Please let us know if you have any question :) 

 

0 0
replied on November 2, 2014

Hi Li,

Thank you very much for the advice you've offered. The way you've explained the use of the event handlers has helped my understand alot better and helped me with my solution. I didn't know it could work that way before.

Thanks

Sheldon

0 0
replied on November 3, 2014

You are always welcome laugh

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.