Render view on form submission

Hello,

I am having some trouble with updating the view of data within a Knack system when a form has been submitted.

Instead of using the following code:
$(document).on(‘knack-form-submit.any’, function(event, view, record) {
Knack.views[“view_XX”].model.fetch();
Knack.views.view_XX.render();
});

I would like to automate the process of rendering each view on each scene from each form submission.

$(document).on('knack-form-submit.any', async function(event, view, record) {
      $('.kn-scene .view-group').each(async function() {
        var viewGroup = $(this);
        var sceneId = viewGroup.closest('.kn-scene').attr('id');

        if (sceneId) {
          var sceneMatches = sceneId.match(/^kn-scene_(\d+)$/);
          if (sceneMatches && sceneMatches.length === 2) {
            var sceneNumber = sceneMatches[1];

            viewGroup.find("[id^='view_']").each(async function() {
              var viewId = $(this).attr('id');

              if (viewId) {
                var matches = viewId.match(/^view_(\d+)$/);
                if (matches && matches.length === 2) {
                  var viewNumber = matches[1];

                  console.log('Form submitted');
                  console.log('Scene Number:', sceneNumber);
                  console.log('View Number:', viewNumber);

                  var dataSourceUrl = 'https://api.knack.com/v1/pages/scene_' + sceneNumber + '/views/view_' + viewNumber + '/records';
            var recordId = $('.kn-modal form .kn-submit input[name="id"]').val();

                  if (recordId) {
                    try {
                      const response = await fetch(dataSourceUrl + '/' + recordId, {
                        method: 'PUT',
                        headers: {
                          'X-Knack-Application-ID': '62b36e2e0a7cc5001f9283cd',
                          'X-Knack-REST-API-Key': '818e87c9-903a-4cf9-aa00-363cf75f2ad1',
                          'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(record)
                      });

                      if (response.ok) {
                        console.log('Record updated successfully:', response);

                        // Fetch and render each view
                        const viewResponse = await fetch(dataSourceUrl, {
                          headers: {
                            'X-Knack-Application-ID': '62b36e2e0a7cc5001f9283cd',
                            'X-Knack-REST-API-Key': '818e87c9-903a-4cf9-aa00-363cf75f2ad1',
                            'Content-Type': 'application/json'
                          }
                        });

                        if (viewResponse.ok) {
                          const viewData = await viewResponse.json();
                          console.log('View data fetched successfully:', viewData);

                          Knack.views['view_' + viewNumber].model.set(viewData);
                          Knack.views['view_' + viewNumber].render();
                          console.log('View rendered');
                        } else {
                          throw new Error('Failed to fetch view data');
                        }
                      } else {
                        throw new Error('Failed to update record');
                      }
                    } catch (error) {
                      console.log('Error:', error);
                    }
                  } else {
                    console.log('Unable to find the record ID.');
                  }
                } else {
                  console.log('Unable to find the view number.');
                }
              }
            });
          } else {
            console.log('Unable to find the scene number.');
          }
        }
      });
    });

This code keep yielding the XHR console log:
Status
400
Bad Request
VersionHTTP/2
Transferred1.21 kB (227 B size)
Referrer Policystrict-origin-when-cross-origin

How can I render each view without specifically defining “view_XX”?

P.S. I have also tried this version:

$(document).on('knack-form-submit.any', function(event, view, record) {
  $('.kn-scene .view-group').each(function() {
    var viewGroup = $(this);
    var sceneId = viewGroup.closest('.kn-scene').attr('id');

    if (sceneId) {
      var sceneMatches = sceneId.match(/^kn-scene_(\d+)$/);
      if (sceneMatches && sceneMatches.length === 2) {
        var sceneNumber = sceneMatches[1];

        viewGroup.find("[id^='view_']").each(function() {
          var viewId = $(this).attr('id');

          if (viewId) {
            var matches = viewId.match(/^view_(\d+)$/);
            if (matches && matches.length === 2) {
              var viewNumber = matches[1];

              console.log('Form submitted');
              console.log('Scene Number:', sceneNumber);
              console.log('View Number:', viewNumber);

              var dataSourceUrl = 'https://api.knack.com/v1/pages/scene_' + sceneNumber + '/views/view_' + viewNumber + '/records';
        var recordId = $('.kn-modal form .kn-submit input[name="id"]').val();


              if (recordId) {
                $.ajax({
                  type: 'PUT',
                  url: dataSourceUrl + '/' + recordId,
                  headers: {
                    'X-Knack-Application-ID': '62b36e2e0a7cc5001f9283cd',
                    'X-Knack-REST-API-Key': '818e87c9-903a-4cf9-aa00-363cf75f2ad1'
                  },
                  data: record,
                  success: function(response) {
                    console.log('Record updated successfully:', response);

                    // Fetch and render each view
                    Knack.views['view_' + viewNumber].model.fetch({
                      url: dataSourceUrl,
                      headers: {
                        'X-Knack-Application-ID': '62b36e2e0a7cc5001f9283cd',
                        'X-Knack-REST-API-Key': '818e87c9-903a-4cf9-aa00-363cf75f2ad1'
                      },
                      success: function(response) {
                        console.log('View data fetched successfully:', response);

                        Knack.views['view_' + viewNumber].render();
                        console.log('View rendered');
                      },
                      error: function(error) {
                        console.log('Error fetching view data:', error);
                      }
                    });
                  },
                  error: function(xhr, status, error) {
                    console.log('Error updating record:', error);
                    console.log('XHR status:', status);
                    console.log('XHR response:', xhr.responseText);
                  }
                });
              } else {
                console.log('Unable to find the record ID.');
              }
            } else {
              console.log('Unable to find the view number.');
            }
          }
        });
      } else {
        console.log('Unable to find the scene number.');
      }
    }
  });
});

Hey @LukeAHoughton
You will probably have more luck getting an answer to this question over on the Ask Developers section of our forum! Sorry I couldn’t help here - custom code is unfortunately out of our scope.

Good luck!

1 Like

If you mean your form is on the same page as the grid view you want to have updated after the form is submitted you should look into using the KTL-Toolkit Introducing the Knack Toolkit Library (KTL) in pre-relase - by Cortex R&D Inc

Loading up the Toolkit is pretty easy, and there is a code you add to the View in Settings > Title that looks like this:

_rvs=vTitle1,vTitle2

Refresh Views after a Submit. Add this to a form’s title and when it is submitted successfully, will refresh any other views specified. Use the exact full title text, separated by commas, spaces are allowed.

Ex: Customer Sale _rvs=Client Sales, Store Sales

Here, the form’s visible title will be “Customer Sales”, and when submitted successfully, the two views with the title “Client Sales” and “Store Sales” will be refreshed. @Normand_Morbern

2 Likes

Thanks Dean for your answer.

As a courtesy, here’s the direct link to that _rvs keyword in the KTL documentation:

Keywords · cortexrd/Knack-Toolkit-Library Wiki (github.com)

@LukeAHoughton
Luke, if you have questions or need assistance let me know.
You can also reach me directly at nd@ctrnd.com

Best regards,
Normand D.

2 Likes

@LukeAHoughton

Luke,

Here’s the video from my channel, that shows how the _rvs keyword works, at 1:14.

I invite you to watch all other videos to better understand how the KTL works.
(994) Cortex R&D Inc. - YouTube

Cheers,
Norm

Hello all,

Thank you for the responses.

Coincidentally, I have been observing the Knack Toolkit Library (KLT) and only started using it since the beginning of last week (prior to the posting of my question). I did not check out all of the features and only started briefly using the toolkit. I have also checked out the videos. Good job @NormandDefayette_CortexRD .

I managed to solve my issue. But, it is definitely good to know that this toolkit provides the solution.

I have encountered a severe issue when using the toolkit. This is most definitely a unique issue to me because I have a load of custom code within my Knack app that perform specific tasks and automations. After performing research I have discovered the clash. I had to force the toolkit to only enact in #knack-dist_1 as my embedded apps where experiencing the clash on my website www.projektid.co.

@NormandDefayette_CortexRD If possible, would you like to have a Whatsapp/FaceTime meeting to go through this?

1 Like

Hi Luke,

Sure, I will gladly help you with your issue(s).

Send me an email with your time zone and availability.
I’m in Montreal, Eastern Daylight Saving Time (GMT-4).

For the video call, I’m on Windows, so I use Teams, Zoom, WhatsApp, Google Meet and Facebook’s Messenger. I think I can receive a Facetime invite and run it from the browser - I can try that if you prefer ft.

Normand D.