01273 264503 info@mootpoint.org

Gravity Forms offers an excellent multi-file upload field to attach multiple files such as images to a form submission. I have used the WooCommerce Gravity Forms Add-on to add complex functionality to WooCommerce products, for example allowing customers to upload images for printing. But what happens if you want to count the number of uploaded files? Say you want to price your product based on the number of uploaded files to be processed. Normally you will need to calculate the price based on a quantity field entered by the customer since Gravity Forms does not make the number of files uploaded to a multi-file upload field available to the form. This creates a margin for error since the customer may enter the incorrect number in the quantity field.

So how do we count the number of files programmatically? With the help of Gravity Forms support team, here is a solution which makes use of the gform_pre_render hook. The hook places some Javascript on the relevant form which fires when the number of uploaded files changes, for example as files are uploaded, or if your remove uploaded files. The script updates the value of a count field (which you specify by setting the ID in the script) with the number of uploaded files. It also makes the count field read-only, to prevent manual changes to the value.

Note:

  • The code should be placed in your theme’s functions.php.
  • You will need to set the form ID of your form in line 6.
  • You will need to set the field ID of your uploaded files count field in line 50.
  • You will need to add a custom CSS class of ‘gf_readonly’ to your uploaded files count field in the form editor.
add_action( 'gform_pre_render', 'set_number_of_uploaded_images' );

// Set the uploaded images count field and make it readonly
function set_number_of_uploaded_images( $form ) {
    // only run hook for form_id = 1
    if ( $form['id'] != 1 ) {
       return $form;
    }
    // make any input field with the class gf_readonly to be read-only 
    ?>
    <script type="text/javascript">
	jQuery(document).ready(function(){
		jQuery("li.gf_readonly input").attr("readonly","readonly");
	});
    </script>
    <script type="text/javascript">

        gwCountFiles = function (fieldID, formID) {

            function getAllFiles(formID) {
                var selector = '#gform_uploaded_files_' + formID,
                    $uploadedFiles = jQuery(selector), files;
                files = $uploadedFiles.val();
                files = '' === files ? {} : jQuery.parseJSON(files);
                return files;
            }

            function getFiles(fieldID, formID) {
                var allFiles = getAllFiles(formID);
                var inputName = getInputName(fieldID);

                if (typeof allFiles[inputName] == 'undefined')
                    allFiles[inputName] = [];
                return allFiles[inputName];
            }

            function getInputName(fieldID) {
                return "input_" + fieldID;
            }

            var files = getFiles(fieldID, formID);

            return files.length;

        };

        gform.addFilter('gform_file_upload_markup', function (html, file, up, strings, imagesUrl) {
            var formId = up.settings.multipart_params.form_id,
                fieldId = up.settings.multipart_params.field_id,
                targetId = 6; // set this to the field_id of your uploaded files count field

            html = '<strong>' + file.name + "</strong> <img class='gform_delete' "
            + "src='" + imagesUrl + "/delete.png' "
            + "onclick='gformDeleteUploadedFile(" + formId + "," + fieldId + ", this);countThemFiles(" + formId + ", " + fieldId + ", 0, " + targetId + ");' "
            + "alt='" + strings.delete_file + "' title='" + strings.delete_file + "' />";
            countThemFiles(formId, fieldId, 1, targetId);
            return html;
        });

        function countThemFiles(formId, fieldId, offset, targetId) {
            var count = gwCountFiles(fieldId, formId);
            jQuery('#input_' + formId + '_' + targetId).val(count + offset).change();
        }

    </script>

    <?php
    return $form;
}