A more efficient way to perform this function?

Tap Forms – Organizer Database App for Mac, iPhone, and iPad Forums Script Talk A more efficient way to perform this function?

Viewing 5 reply threads
  • Author
    Posts
  • March 9, 2023 at 6:26 AM #49118

    Kirk Williams
    Participant

    Greetings!

    I have a form that contains a database of products that are exported to a WooCommerce site. Each item has a number of “attribute” fields that are included when exporting the record data.

    The problem I was attempting to solve with the script below is that WooCommerce requires specific titles for CSV columns. I initially named my fields to correspond with the export requirements but quickly found that having to remember that “Attribute 5” equals “Model”, etc. was too cumbersome.

    My first crack at a workaround was to rename my fields with logical identifiers, then use MS Excel to rename the exported columns to the terms required by WooCommerce. This worked but still felt like an unnecessary extra task.

    I then concocted this script that essentially involves duplicate fields within TapForms itself. One column is named logically (ex: “Model”), while the duplicate is named to accommodate the WooCommerce import requirements (ex: “Attribute 5”). Obviously, the data in both fields need to be identical, so I’m using this script to automatically update certain fields whenever its corresponding field is modified:

    function wc_attributes_update() {

    var year_id = 'fld-bcf37649c9ee4332b7100a9589110f96';
    var year = record.getFieldValue(year_id);
    var manufacturer_id = 'fld-17e5cb32753f43eea332701c2587d2d6';
    var manufacturer = record.getFieldValue(manufacturer_id);
    var model_id = 'fld-81bfab5a547e4c59a46fb5c3fb795fbc';
    var model = record.getFieldValue(model_id);
    var gauge_id = 'fld-28d551114d734843a0e64680575e991e';
    var gauge = record.getFieldValue(gauge_id);
    var container_id = 'fld-b0c7a9bbb57a40a891c659346fa63ae0';
    var container = record.getFieldValue(container_id);
    var era_id = 'fld-0101387087f044ddb402ae2111b2a854';
    var era = record.getFieldValue(era_id);
    var railroad_id = 'fld-c522d3a2b0e245e69f21f8eb3553be83';
    var railroad = record.getFieldValue(railroad_id);
    var brand_id = 'fld-f2dcf5e1818a4e588863424cc70e9804';
    var brand = record.getFieldValue(brand_id);
    var collection_id = 'fld-b133cb39179f4083b5377f7f01ecb1ea';
    var collection = record.getFieldValue(collection_id);
    var tca_grade_id = 'fld-0699ee653f564342855aa82798c88a01';
    var tca_grade = record.getFieldValue(tca_grade_id);
    var attribute_1_value_s_id = 'fld-722b1a029a2e4e8bbadd9cbf481d060f';
    var attribute_2_value_s_id = 'fld-828e1965c3ce4fa88b6a12b2dba89d39';
    var attribute_3_value_s_id = 'fld-a3e517222cd143e79323d7e99641c00c';
    var attribute_4_value_s_id = 'fld-8480a45102ed499cb00008b4c38625c7';
    var attribute_5_value_s_id = 'fld-9c0b1069d7024d46a519749589fef59e';
    var attribute_6_value_s_id = 'fld-f95371e7ac824cba92cf80da77c2fd7a';
    var attribute_7_value_s_id = 'fld-8651f7fbbfe0429690a9e0175b6eeaa4';
    var attribute_8_value_s_id = 'fld-56222dff96644bd9b9b3bd6d72d39db5';
    var attribute_9_value_s_id = 'fld-f4be5cac1b5d4ce48805765a2ff47a51';
    var attribute_10_value_s_id = 'fld-da36f2e28e1d4a8f8207a8a0e7f6b24d';
    record.setFieldValue(attribute_1_value_s_id, year);
    record.setFieldValue(attribute_2_value_s_id, manufacturer);
    record.setFieldValue(attribute_3_value_s_id, model);
    record.setFieldValue(attribute_4_value_s_id, gauge);
    record.setFieldValue(attribute_5_value_s_id, container);
    record.setFieldValue(attribute_6_value_s_id, era);
    record.setFieldValue(attribute_7_value_s_id, railroad);
    record.setFieldValue(attribute_8_value_s_id, brand);
    record.setFieldValue(attribute_9_value_s_id, collection);
    record.setFieldValue(attribute_10_value_s_id, tca_grade);
    form.saveAllChanges()

    }

    wc_attributes_update();

    While this works surprisingly well with regard to producing a proper CSV export, what I’ve found is that, as it’s currently scripted, the active record is saved immediately any time one of the “paired” fields is edited. This results in a “refresh” of sorts that results in my cursor being returned to the first field of the form. It’s functional, but grossly inefficient for data entry.

    I’m convinced there is a better method to perform this function, but having limited scripting experience, I’m hoping some of you that are more agile with TF may offer some better guidance. Since the “duplicate” columns’ ONLY purpose is for exporting (they are all hidden within TF), I tried to create a “form” script that I could execute on-demand prior to export (vs. my current “field” script that executes automatically any time data is added/changed in one of these fields). Sadly, I haven’t been able to get anything even close to doing that thus far.

    If there’s a way to have this field replication execute on-demand, or even a “back to the drawing board” alternative strategy, I’d be grateful and eager to hear anyone’s suggestions.

    Thanks in advance for any suggestions!

    Cheers

    March 9, 2023 at 9:25 AM #49119

    Daniel Leu
    Participant

    To duplicate a field value I would use a calculation field. You just have to pay attention to use the correct return type.

    Another option I could imagine is creating the CSV from a form script. Once done, copy it to the clipboard with Utils.copyTextToClipboard(). I don’t know if you directly can use the copied text in WooCommerce. If you need a file, then maybe use an AppleScript that calls your TF script to get the data and then saves them to a file. But that’s getting a bit more complicated.

    March 9, 2023 at 12:13 PM #49120

    Brendan
    Keymaster

    Does WooCommerce have a REST API? Maybe as you edit your data in Tap Forms, a script can use the Utils. postContentToUrlWithContentType() or Utils.postJsonToUrl() functions.

    To avoid the refreshing issue, maybe instead of using a Field Script, use a Form Script and have it loop through your records, updating the exportable fields with the values from the regular fields. So when you’re going to export, just run the script first. Then it won’t be interrupting you while you edit the records.

    March 9, 2023 at 12:14 PM #49121

    Brendan
    Keymaster

    But I really should have an API that lets you write to a file from within Tap Forms so you could build your own custom export routines.

    March 9, 2023 at 12:28 PM #49122

    Daniel Leu
    Participant

    > But I really should have an API that lets you write to a file from within Tap Forms so you could build your own custom export routines.

    That would be nice!

    • This reply was modified 1 year, 9 months ago by Daniel Leu.
    March 10, 2023 at 8:48 AM #49125

    Kirk Williams
    Participant

    Thanks for the suggestion Daniel!

    I know WC accepts CSV and XML; I feel like I’ve seen references to text imports but I’d have to dig into the documentation to confirm. Since it’s within the WordPress environment, I imagine there’s likely some security components that would prevent text-based script imports, but I may be able to circumvent those by tweaking the php settings. It’s an interesting angle – thanks!

    March 10, 2023 at 9:03 AM #49126

    Kirk Williams
    Participant

    <p>
    Does WooCommerce have a REST API? Maybe as you edit your data in Tap Forms, a script can use the Utils. postContentToUrlWithContentType() or Utils.postJsonToUrl() functions.
    </p>

    This is an interesting question, one that I’d need to investigate. I suspect there numerous APIs for WordPress in general; that would be the most likely point of entry for any transactional functions between TapForms & WooCommerce. I won’t lie, though – it already sounds like a project that is well beyond by coding expertise!

    <p>
    To avoid the refreshing issue, maybe instead of using a Field Script, use a Form Script and have it loop through your records, updating the exportable fields with the values from the regular fields. So when you’re going to export, just run the script first. Then it won’t be interrupting you while you edit the records.
    </p>

    Yes, this is precisely what I’ve been working on, but thus far have not been able to create with any success. Your suggestion that such a function is indeed possible is more than enough motivation for me to take another crack at it.

    Thank you for the suggestions!!!

    March 10, 2023 at 9:36 AM #49127

    Daniel Leu
    Participant

    Re: Form script:

    You just need to loop over all your records and then assign the values on each one:

    
    function wc_attributes_update() {
    
      // definitions
      var year_id = 'fld-bcf37649c9ee4332b7100a9589110f96';
      ....
    
      for (rec of form.getRecords()){
        rec.setFieldValue(attribute_3_value_s_id, model);
        rec.setFieldValue(attribute_4_value_s_id, gauge);
        rec.setFieldValue(attribute_5_value_s_id, container);
        rec.setFieldValue(attribute_6_value_s_id, era);
        rec.setFieldValue(attribute_7_value_s_id, railroad);
        rec.setFieldValue(attribute_8_value_s_id, brand);
        rec.setFieldValue(attribute_9_value_s_id, collection);
        rec.setFieldValue(attribute_10_value_s_id, tca_grade);
      }
      form.saveAllChanges()
    }
    
    wc_attributes_update();    
    

    This example works on all the records. If you only want to update the ones from a saved search, you might use form.getSearchNamed('Genre: Action & Adventure').

Viewing 5 reply threads

You must be logged in to reply to this topic.