List control in new form - on change

Hi, I've got a form with a list control in it, and I want to update the total of the lines (in the main form) when an entry is added or changed in the list control. I've tried a few things from here but nothing seems to work in the New form.

fd.rendered(function() {

	// disable the field
	fd.field('Total').disabled = true;
	fd.field('Order_x0020_Number').disabled = true;
	
	fd.field('Order_x0020_Number').value = getOrdVar();

	//refreshing the  total
	var myVar = setInterval(calcTotal, 2000);

	fd.control('SPDataTable1').$on('change', function() {   
        fd.control('SPDataTable1').widget.bind("dataBound",function(){
            calcTotal();
        })
    });
}); 

The calcTotal function updates the Total in the main form.

Could you show me where I'm going wrong?

NB the child form is in non-dialog view

Hello

Currently, change event only works for dialog mode. Inline editing is not yet supported.

As an option, you can either change the settings to open child items in the dialog or use the below code which will refresh total value periodically and on form submit.

Please do the following changes in the code:

  • Replace {SPDataTable0} with the List or Library Control internal Name.
  • Change Value in the code (in places like value[i].Value and value[i].Value.replace(/$/g,'')) with the InternalName of the column in the related items.
 function calcTotal() {

var value = fd.control('{SPDataTable0}').widget.dataItems();
var total = 0;
if(value){
    for (var i = 0; i < value.length; i++){
        if(value[i].Value)
          total += parseInt(value[i].Value.replace(/[^0-9.]/g, ""));
    }
}
fd.field('Total').value = total;
}
var myVar = 0;

fd.spRendered(function() {

// disable the field
fd.field('Total').disabled = true;

//refreshing the  total
var myVar = setInterval(calcTotal, 2000);

}); 

fd.spBeforeSave(function(spForm) {
    var myVar = setInterval(calcTotal, 2000);
    calcTotal();
    clearInterval(myVar);
});
1 Like

Does this work with calculated columns as well?

My setup is

Parent (SP List)

Child (SP List)

Code

//Form Calculation - total from items

function calcTotal() {

var value = fd.control('SPDataTable1').widget.dataItems();
var total = 0;
if(value){
for (var i = 0; i < value.length; i++){
if(value[i].Total)
total += parseInt(value[i].Total.replace(/[^0-9.]/g, ""));
}
}
fd.field('Total_Amount').value = total;
}
var myVar = 0;

fd.spRendered(function() {

// disable the field
fd.field('Total_Amount').disabled = true;

//refreshing the total
var myVar = setInterval(calcTotal, 2000);

});

fd.spBeforeSave(function(spForm) {
var myVar = setInterval(calcTotal, 2000);
calcTotal();
clearInterval(myVar);
});

Hello @cameron_stewart,

Welcome to Plumsail Community!

Yes, the code works for calculated columns as well, but you might need to update it.

Could you please share the screenshot of the form opened in the browser. I need to see the format of the calculated column value in List or Libary control to help you with the code.

Thanks @mnikitina - is this enough?

and child list. I made them numbers instead of currency

Hello @cameron_stewart,

Please see the code below.

As your column contains not whole numbers, I've replaced parseFloat function with Number function.

Please make sure that you are using the internal field names in the code.

function calcTotal() {

var value = fd.control('SPDataTable1').widget.dataItems();
var total = 0;
if(value){
    for (var i = 0; i < value.length; i++){
        if(value[i].Total)
          total += Number(value[i].Total.replace(/[^0-9.]/g, ""));
    }
}
fd.field('Total_Amount').value = total;
}
var myVar = 0;

fd.spRendered(function() {

// disable the field
fd.field('Total_Amount').disabled = true;

//refreshing the  total
var myVar = setInterval(calcTotal, 2000);

}); 

fd.spBeforeSave(function(spForm) {
    var myVar = setInterval(calcTotal, 2000);
    calcTotal();
    clearInterval(myVar);
});

Doesn't seem to do anything :frowning:

@cameron_stewart,

Are you getting any errors in the browser console (F12)? Could you please share the screenshot.

I guess I have a similar issue but I don't quite understand how to implement the fix.
In my case, multiple Fields need to be manipulatable when a User selects other fields. Sadly I can't use the existing code of the previous dialog list, because I open this new Form from it which and always results in the following Console Error:
TypeError: Cannot read property '$on' of undefined

fd.spRendered(function() {

localStorage.clear()

    function hideOrShowFields() {
    
    
        // Status < Started (<2)
        if (fd.field("field0").widget.select() >= 2) {
            // Show the field0
            $('.fd-field-to-show').hide();
            $('.fd-field-to-hide').show();
            fd.field("field0a").disabled = true;
            fd.field("field0b").disabled = true;
        } else {
             // Hide the field0
            $('.fd-field-to-hide').hide();
            $('.fd-field-to-show').show();
            fd.field("field0a").disabled = false;
            fd.field("field0b").disabled = false;
        }
        
            // STATUS >= field1
    
        // Status < Started (<2)
        if (fd.field("field1").widget.select() >= 4) {
            // Show the field1 field
            $('.fd-button-to-show').show();
        } else {
             // Hide the field1 field 
            $('.fd-button-to-show').hide();
        }
        
        
            // STATUS >= field2
    
        // Status field2 = Yes (1) No (0)
        if (fd.field("field2").value == "1" ) {
            // Show the field2 fields
            $(fd.field("field2a").$parent.$el).show();
        } else {
             // Hide the field2 fields 
            $(fd.field("field2a").$parent.$el).hide();
        }
        
        
        }
        
    // ....


    // Calling hideOrShowFields when the user changes the checkboxes/dropdowns
    fd.field("field0").$on('change',hideOrShowFields);
    fd.field("field1").$on('change',hideOrShowFields);
    fd.field("field2").$on('change',hideOrShowFields);
    //...

    // Calling hideOrShowFields on form loading
    hideOrShowFields();
    
    
});

I would be happy if you can help fixing this.

I now also tried to open the Form like described "change the settings to open child items in the dialog"
with the following code in the Form Button
//?PageType=8 - will open a New Form
Dialog.open("https://domain.sharepoint.com/sites/AnotherGroupSite/_layouts/15/listform.aspx?PageType=8&ListId={3b3c9b7b-41ec-43aa-9607-6d5c993bcfd2}")

The new Form now also opens in a small window, but I still get the same Error in the Consol

(upload://msgoS0U34W7vJe5zNubnwimr1Dq.jpeg)

Hello @andy,

Welcome to Plumsail Community!

What SharePoint version are you using?

How do you open the New Form? Form the List or Library control?
Where do you use the code?

Hi @minikitina
I use SharePoint Online, and I open the form through a button in another (Default (New)) form.

The open button code is in the click field of the button. The field modification code mentioned in the previous post is in the JS of both (Form 2 (New)) and (Default(New)) but only works in the (Default(New)).

Thanks for your help.

Here a picture explaining in more detail how I Open the "New Form" and when the error occurs.
I hope that helps to explain my problem.

Basically what I want to do is to have selected a "New Form" (specific for a department) with different presets but uses the same List. In Both forms, I want to manipulate the list depending on the selections the user does. (example when field 0 has a specific entry (higher than the first two options) it should disable Field0a &Field 0b)

The following Code only works on Default, in the "New Form" I get the Conole Error: "TypeError: Cannot read property '$on' of undefined..."

    fd.spRendered(function() {


    localStorage.clear()

        function hideOrShowFields() {
        
        
            // Status < Started (<2)
            if (fd.field("field0").widget.select() >= 2) {
                // Show the field0
                $('.fd-field-to-show').hide();
                $('.fd-field-to-hide').show();
                fd.field("field0a").disabled = true;
                fd.field("field0b").disabled = true;
            } else {
                 // Hide the field0
                $('.fd-field-to-hide').hide();
                $('.fd-field-to-show').show();
                fd.field("field0a").disabled = false;
                fd.field("field0b").disabled = false;
            }
            
                // STATUS >= field1
        
            // Status < Started (<2)
            if (fd.field("field1").widget.select() >= 4) {
                // Show the field1 field
                $('.fd-button-to-show').show();
            } else {
                 // Hide the field1 field 
                $('.fd-button-to-show').hide();
            }
            
            
                // STATUS >= field2
        
            // Status field2 = Yes (1) No (0)
            if (fd.field("field2").value == "1" ) {
                // Show the field2 fields
                $(fd.field("field2a").$parent.$el).show();
            } else {
                 // Hide the field2 fields 
                $(fd.field("field2a").$parent.$el).hide();
            }
            
            
            }
            
        // ....


        // Calling hideOrShowFields when the user changes the checkboxes/dropdowns
        fd.field("field0").$on('change',hideOrShowFields);
        fd.field("field1").$on('change',hideOrShowFields);
        fd.field("field2").$on('change',hideOrShowFields);
        //...

        // Calling hideOrShowFields on form loading
        hideOrShowFields();
        
        
    });

I filnaly figured it out, the adapted code can be found below.

fd.spRendered(function() {


localStorage.clear()
var myVar = 0;

    function hideOrShowFields() {
    
    
        // Status < Started (<2)
        if (fd.field("field0").widget.select() >= 2) {
            // Show the field0
            $('.fd-field-to-show').hide();
            $('.fd-field-to-hide').show();
            fd.field("field0a").disabled = true;
            fd.field("field0b").disabled = true;
        } else {
             // Hide the field0
            $('.fd-field-to-hide').hide();
            $('.fd-field-to-show').show();
            fd.field("field0a").disabled = false;
            fd.field("field0b").disabled = false;
        }
       
        
            // STATUS >= field2
    
        // Status field2 = Yes (1) No (0)
        if (fd.field("field2").value == "1" ) {
            // Show the field2 fields
            $(fd.field("field2a").$parent.$el).show();
        } else {
             // Hide the field2 fields 
            $(fd.field("field2a").$parent.$el).hide();
        }
        
        
        }
        


   //refreshing the  HideOrShow after 3sec
var myVar = setInterval(hideOrShowFields, 3000);
    
    
});

 fd.spBeforeSave(function(spForm) {
        var myVar = setInterval(hideOrShowFields, 3000);
        hideOrShowFields();
        clearInterval(myVar);
    });
1 Like