Photo filenames in Calculated Field?

Viewing 7 reply threads
  • Author
    Posts
  • February 18, 2019 at 8:41 AM #33783

    Kirk Williams
    Participant

    Hello all,

    New user here – a bit of a learning curve for me as a relatively new Mac user, but I definitely appreciate the potential of this app. I’m still a bit stumped with one form in particular (that was the primary reason for me purchasing TF).

    I am currently using AirTable for inventorying my late father’s model train collection. In the interest of efficiency, I am using that same AirTable data to export my data into a WordPress website (Woocommerce shop via CSV). I am rapidly approaching the limit threshold of my free AirTable account, so I’d like to migrate this data into tap forms.

    The field with which I am hitting a roadblock is the “Product Images”. I’ll try to describe this field without being too verbose:

    Each record in this collection includes one or more photos. These photos are added to my Airtable, and also (as a completely separate process) uploaded to the WordPress site. Once uploaded, the photo(s) can be referenced using their original filename, preceded by the site’s URL and directory structure. The end result resembles “http://mywebsite.com/wp-content/uploads/2019/02/filename.jpg”.

    Using Airtable, I have created a formula field (the equivalent to Tap Form’s calculation field afaik) that assembles the URL by combining the URL prefix (which I enter as static text in a separate field) and the filename of the photo. I have multiple photo fields, so none have more than one single image attached. “IF” arguments are used in the formula field to prevent blank cells from returning just the URL prefix. The end result is a calculated field containing a comma-separated list of each photo’s filename preceded with the URL.

    I feel that this mechanism could be replicated using Tap Forms, however, the hurdle I’ve yet to overcome is how to extract the photo filename into a calculation. It seems it can be done AFTER an export using the CSV data, but I’d prefer to be able to process this field within the app so that my exported file can be immediately used to import data to the website.

    If anyone can offer guidance as to if/how I can accomplish this task within Tap Forms, I would be extremely grateful! Please note I have virtually zero JS scripting knowledge, but I’d be willing to take a crack at it if scripting is the only option. For reference, the arguments from my AirTable calculation are:

    {WC Featured Image}&IF({WC Gallery Image 2}=BLANK(),BLANK(),”, “&{WC Gallery Image 2})&IF({WC Gallery Image 3}=BLANK(),BLANK(),”, “&{WC Gallery Image 3})

    Thanks in advance for any insight!

    Best,

    Kirk

    February 18, 2019 at 9:54 AM #33784

    Kirk Williams
    Participant

    Update: I attempted to use a file attachment field in place of the photo field… Sadly, filenames from the file attachments are also unavailable as calculation arguments.

    February 18, 2019 at 11:49 AM #33785

    Brendan
    Keymaster

    Hi Kirk,

    You can accomplish what you want by using a Script field instead of a Calculation field.

    In Tap Forms, a Photo field is represented by an array of dictionaries that looks like this:

    [
          {
            "dimensions" : "{2048, 1536}",
            "filename" : "terminator-jugement-day.jpeg",
            "mimetype" : "image/jpeg"
          },
          {
            "mimetype" : "image/jpeg",
            "dimensions" : "{1280, 960}",
            "filename" : "hunger-games.jpeg"
          },
          {
            "mimetype" : "image/jpeg",
            "dimensions" : "{4032, 3024}",
            "filename" : "the-martian.jpeg"
          }
    ]

    Each of the things above are a dictionary that contains the mime type, the dimensions of the original image stored in Tap Forms, and the original filename.

    In a Script field you could have Tap Forms return a list of these images prefixed by a specific URL if you like.

    You would need to first get the value for the Photo field — which will be in the format like the above sample, then loop through the array picking out the filename from each Dictionary. A Dictionary is just like what you see above where there’s a key and a value. The key you want is filename and the value will be whatever the value is (e.g. the-martian.jpeg).

    Here’s some Script Field code which will do exactly what you need:

    function Photo_Links() {
    
    	var photo_field_id = 'fld-e2cf02f376864a7cb9f090e4a597f3e4';
    	var photos = record.getFieldValue(photo_field_id);
    	var links = "";
    	var link_prefix = 'http://mywebsite.com/wp-content/uploads/2019/02/';
    	
    	for (var index = 0, count = photos.length; index < count; index++){
    		var photo_data = photos[index];
    		var filename = photo_data['filename'];
    		links = links + link_prefix + filename;
    
                    // append a comma at the end of the link only if this is not the last link
    		if (index < photos.length - 1) {
    			links = links + ",";
    		}	
    	}
    	return links;
    
    }
    
    Photo_Links();

    You could just copy and paste the above into a Script Field in your form and then just modify the photo_field_id to match the ID of your own Photo field and the link_prefix to use the correct URL.

    Let me know if that works for you.

    Thanks!

    Brendan

    February 18, 2019 at 12:11 PM #33786

    Kirk Williams
    Participant

    Thanks so much, Bendan – this is super helpful! One thing I neglected to mention is that the URL prefix is actually entered into a field on the form (since WordPress insists on creating monthly directories for uploaded images, I change the default value of this field at the beginning of the month). With that in mind, I replaced the static text in your code with a reference to the ID of the “image_prefix” field.

    The prefix seems to be working, but I’m still not getting the filename. It’s referencing a TypeError on line 9; I am going to continue to tinker and see if I can determine where I’ve thrown off the script.

    Once I get this working, my next challenge will be to include data from the other photo fields (“photo1”, “photo2”, “photo3” and “photo4”). Your code to append the comma for all but the last item is very cool!… I guess it’s time to start brushing up on my Java lol!

    Thanks again for your time – I will keep you posted on my progress.

    Attachments:
    You must be logged in to view attached files.
    February 18, 2019 at 4:09 PM #33789

    Brendan
    Keymaster

    Is there a photo on the selected record for your Photo field? If not, then you may just need to add an extra check to make sure that photos exists.

    if (photos) {
    
      // do your stuff
    
    }
    February 19, 2019 at 9:06 AM #33796

    Kirk Williams
    Participant

    Thanks again for your help Brendan! I was able to make this work, although I likely did it in the most bone-headed manner possible (I hope to clean it up as I learn more about scripting).

    Just in case the reference may be useful to others, here’s the “solution” that produced the desired output:

    Each record in my form has four photo fields (“Photo1” – “Photo4”). How many of those fields are used varies by record, but every item must have at least one, and the photo fields are entered sequentially (meaning that, in theory, “Photo1” will never be blank).

    I also use an “Image Prefix” text field in which the URL is entered. This value only changes monthly, so I update the default value for new records at the beginning of each new month.

    With that in mind, I only altered the code you provided by updating the field ID’s and references and changing the URL reference from the static text to my “Image Prefix” field ID.

    function Photo_Links() {
    
    	var photo1_id = 'fld-b83135f083fe44b98835538c57a94834';
    	var photos = record.getFieldValue(photo1_id);
    	var links = "";
    	var image_prefix_id = 'fld-dea58cfd801f4e75882f397fc37a5df2';
    	var image_prefix = record.getFieldValue('fld-dea58cfd801f4e75882f397fc37a5df2');
    	
    	for (var index = 0, count = photos.length; index < count; index++){
    		var photo_data = photos[index];
    		var filename = photo_data['filename'];
    		links = links + image_prefix + filename;
    
                    // append a comma at the end of the link only if this is not the last link
    		if (index < photos.length - 1) {
    			links = links + ",";
    		}	
    	}
    	return links;
    
    }
    
    Photo_Links();

    The code above is used to populate a field titled “Photo1 Name”. I then replicated the same code to create fields referencing the remaining three photo fields (“Photo2 Name”, “Photo3 Name, “Photo4 Name”). For photos 3-4, I changed line 5 to insert a comma followed by a space instead of the original null value:

    function Photo_Links() {
    
    	var photo2_id = 'fld-e0aac08a96714b6390443627e49e73c1';
    	var photos = record.getFieldValue(photo2_id);
    	var links = ", ";
    	var image_prefix_id = 'fld-dea58cfd801f4e75882f397fc37a5df2';
    	var image_prefix = record.getFieldValue('fld-dea58cfd801f4e75882f397fc37a5df2');
    	
    	for (var index = 0, count = photos.length; index < count; index++){
    		var photo_data = photos[index];
    		var filename = photo_data['filename'];
    		links = links + image_prefix + filename;
    
                    // append a comma at the end of the link only if this is not the last link
    		if (index < photos.length - 1) {
    			links = links + ",";
    		}	
    	}
    	return links;
    
    }
    
    Photo_Links();

    With all four photo fields now populating exactly what I need, I just added a calculated field that returns the values of all “PhotoX Name” fields sequentially. Since the photo name fields return null values when there is no image, I’ve got a comma-separated list of each item’s photos that plays nicely with the Woocommerce import (essentially, I’m just prepending the comma rather than appending it based on logical conditions).

    I’m sure experienced scripters will cringe reading this lol… I’m always up for learning, so I’ll happily entertain any suggestions on how to clean this up.

    THANKS SO MUCH again for your help!!!

    K

    February 19, 2019 at 11:11 AM #33802

    Brendan
    Keymaster

    I noticed you defined image_prefix_id, but you never used it:

    var image_prefix_id = 'fld-dea58cfd801f4e75882f397fc37a5df2';
    var image_prefix = record.getFieldValue('fld-dea58cfd801f4e75882f397fc37a5df2');

    You would want to change it to this:

    var image_prefix_id = 'fld-dea58cfd801f4e75882f397fc37a5df2';
    var image_prefix = record.getFieldValue(image_prefix_id);
    February 21, 2019 at 6:57 AM #33828

    Kirk Williams
    Participant

    Interesting. I’ll have another look at it; there may be an unnecessary statement since it is populating properly (including the prefix).

Viewing 7 reply threads

You must be logged in to reply to this topic.