I am trying to figure out how to get an address from a text field to an address field within the same table. I had made a script to import data from a paragraph field where info is pated and parsed into 62 fields. All were successful but addresses. Knack has very little guidance and I can’t afford to hire someone for this. I feel I am missing something simple. I tried standard JS w/parsing and regex format but still no go. Then just had them parse into txt fields in hopes I could put them in the structured fields post a render of a new page view. Even did api, to be wrapped in .env but still hitting a wall. Any one have the basic sample script for this?
Hello Daniel,
Maybe you can create an Excel and make some formulas to separate the text field into multiple field like
Address line 1, Line 2, City State, Zip, and then you can import. But for this, all addresses need to be in proper format …
Regards,
Sunny Singla
ssingla1985@gmail.com
+919855089359
Is there a way to automate this within the app? I’ve tried Ajax get calls using the internal API. Having an issue with the initial connection. Something about tokens which doesn’t make sense cuz when working in the developer mode under live view, I’m under a user authority through the app testing it. And the user has the authority so not sure.
I tried doing an API using the key which is successful I would then do the .env to mask the API within the code. Underdeveloper mode it showed it was successfully received but nothing is importing. I tried using standard js scripts and all sorts of ways and still nothing, parsing it out for Street, city, state. There’s only one page referencing addresses on knack.com and I can’t find anybody else that’s had an answer to their issue that was similar in the community. One negative of using this platform is there’s not a lot in the online arena to assist. And since they don’t provide support, what they do provide is very ambiguous. What seems to be a simple issue to resolve has turned into a pain in the neck and weeks of variations in script attempts. I have three addresses and three name fields that won’t parse from a text field into the name fields in the same table. I tried using regex in the call and still nothing. I’ll put my latest attempt in the community chat and see if somebody will help unless you’d like to take a look at it LOL and everybody’s busy and my issue is I’m a startup working I’m trying to get this off the ground ASAP and currently between gigs with reserves diminishing so needless to say I don’t have money to hire somebody for this and I would think it would be so simple.
If you’ve had this success with Excel, like if you have an example of how I could do that or direct me to somewhere on knack that explains it that would be much appreciated! Nonetheless, thank you so much for reaching out and trying to help! Seems like a rarity these days.
Hi @Daniel8,
While I can’t provide you with steps on how this would be done since it’s necessary for custom code to be utilized, I wanted to share that I did find it helpful to use AI for this scenario. I’m not sure if you already tried this, but I plugged your question into ChatGPT, which gave me a simplified example script with a Regex pattern. This may help lead you in the right direction.
For formatting address fields, you may find this section helpful as well: Multi-Column Fields
Best of luck and happy building!
Thank you so much. Yes I did try that and I am still working out the kinks with its help. Sometimes using AI can regress the process and you have to reprompt it. The app is successfully seeing it. It shows it being parsed but not actually connecting/inputting the data yet with the structured field. Thank you so much for reaching out. I will check this out too, looks like it has some guidance! Thanks Again!
Hello Daniel,
If you are still struggling, let me know I will check if there is any API issue. Send me email
Regards,
Sunny Singla
ssingla1985@gmail.com
+919855089359
Still working out the script on the addresses and the names. I’m having to use a direct API via JavaScript as of right now because the version using Ajax or the rest API is not functioning it keeps coming back with issues under the header and developer mode, using edge, it says essentially I’m not authorized and I know the logic was right. I’ve also had issues using the API key where sometimes it’ll put the file record and then other times it comes up blank. I noticed there the JavaScript area is finicky and sometimes I have to paste the code back in it and then it works. Makes me kind of skittish on JS and if it’ll have issues in the future just because but as of right now I managed to get one of the names working. I had somebody reach out from knack that provided me the link to one of the pages. It provided the functional language for names and addresses to which I was able to figure out the scripting for it so I managed to get a name field through. Although some names will be two names and some names will have an initial and that was my issue so I concentrated on the initial and that one’s functioning but it doesn’t show up on the details page upon redirection when I do the render view, likely because I’m not using a lazy loader or some delay to allow for it I’ll work that out. I have to add other logic to compensate for the potential of two names or three names in order for the other names to work. Also still having issues with getting the addresses to render but it is what it is it’ll get there. I’ll post it on the chats once I final this script, as a basic one without my direct connection and field stuff so they have it cuz I wouldn’t wish having for someone else to do this LOL on my worst enemy. And would have loved to have that on there when I was looking for it. I see some guys out there for a few years now that haven’t gotten a response.
But I have had issues with getting the restful API working so if there’s any intel on that and how I can do this without using the API key so I don’t have to do a .EnV set up that would be awesome and would also limit the amount of API puts. My application is going to be fairly large at the end of it and I’m anticipating having to utilize that for certain things beyond this so would be nice to limit its use. I’ll keep you updated and let me know if there’s any intel regarding that.
Hi Daniel
Have you thought of using Make or Zapier for this it works really well. In terms of using the Knack API have you looked here for info?
Sorry if these are all things you have seen or tried.
Could you post the JS you are trying to use we have had a lot of success using the view based API calls and I may be able to help.
Craig
I have been using the code below in multiple situations for a long while and it works for me.
I am copying text from several different text fields to an address field to use in Maps, I use a Drop Down for Towns and Counties so they can be selected rather than typed in thus ensuring accurate input.
You need to put the Address field in your Form (the CSS below will hide it)
Fields and Views numbers should be altered accordingly.
Unfortunately I am not a coder, I stole this from somewhere years ago.
CSS
#view_680 #kn-input-field_389
{
visibility: hidden;
height:50px;
}
Java:
$(“#view_680 .kn-submit”).live(“hover”, function () {
$(“#kn-input-field_389 #street”).val($(“#view_680 #field_1096”).val());
$(“#kn-input-field_389 #street2”).val($(“#view_680 #field_1097”).val());
$(“#kn-input-field_389 #city”).val($(“#view_680_field_1460_chzn .chzn-single span”).html());
$(“#kn-input-field_389 #state”).val($(“#view_680_field_2783_chzn .chzn-single span”).html());
$(“#kn-input-field_389 #zip”).val($(“#view_680 #field_1060”).val());
});
Hey Craig,
This one is a bit convoluted of a script. I am sure it can be done much simpler but I am new to this and knack. I tried to clean it up and provided some context to the script for help incase anyone finds any part useful. I have not had success in calling the internal API. I keep getting the Token is unauthorized thing in the headers under developer mode section.
Also, I could not get the names and emails to parse correctly when making this. I needed to make a ‘Proof of Life’ senario for a bus partner and was running out of time so converted the name fields and addresses to txt field data to be parsed. I am now working on the address and names. All emails and currency fields work fluently with this code though.
Also, for context, I am pasting first, what the copied data is that is pasted into a plain text field to remove most of the HTML structure. The code accounts for additional uncaught HTML though and there are helpful logs to view cleaned, extracted and updated fields. I would love some help in changing the fields for names and addresses. Currently still working through that. Here is the pasted data, cleaned for general use by the community. Hope I didnt confuse it by cleaning out some of the specific context to the labels etc pertaining to its specific industry use, but here it is and all fields are functional, tested and working:
PASTED INFORMATION INTO THE TEXT FIELD-SAMPLE INFO – INFO CAN CHANGE BUT LABELS REMAIN THE SAME:
Label 1
SAMPLE INFO 1
Label 2
123 SAMPLE RD PEORIA IL 61614
Label 3
4567 BAREFOOT CIR BAREFOOT BAY AL 12345-7014
Label 4
SOME COUNTY
Date Reported (LABEL)
06/05/2024 12:00 AM
Label 5
05/18/2020 12:00 AM
Label 6
05/18/2024 12:01 AM
Main Contact
Name
JOHN H DOE
Phone
555-555-3716
Email
tmh@example.com
Role
Reporter, Main Contact
Label 7 (LABEL TO BE JOINED WITH ‘\n’ TO REMOVE PARSING ERRORS-label is a primary label for the section/portion they are copying e.g. Person contacted (top label); Name(actual label))
Name (label)
JOHN H DOE
Primary Phone
555-555-3716
Business
555-555-3716
Home
555-333-2222
Addl Phone 1
555-555-2233
Addl Phone 2
555-332-2222
Fax
555-222-2074
Email
tmh@example.com
Label 8
Dugy Houser
Label 9 (LABEL TO BE JOINED WITH ‘\n’ TO REMOVE PARSING ERRORS-label is a primary label for the section/portion they are copying)
Company
Sample Company
Label 10
JOHN DANGER
Label 11
6789 US HIGHWAY 18 UNIT 2 DURAN IL 33445
Phone
555-555-3154
Email
jks@example.com
Reported By
Jerry Luis
Phone
555-444-1111
Email
rhiki@example.com
Role
Reporter
Label 12
Sample Company 2
Label 13
2
Label 14
Sample Data
Label 15
Sub Sample Data
Label 16
Long Text Sample Explanation of Sample Data
Label 17
Text Data
Label 18
Text Data
Label 19
1
Label 20
1
Label 21
1
Label 22
42
Label 23
24
Label 24
Serial Number Data
Label 25
Yes
Label 26
No
Label 27
true
Label 28
Details Data
Label 29
N
Label 30
$7300.00
Label 31
$500.00
Label 32
$4000.00
Label 33
$700.00
Label 34
$100000.00
Label 35
$2000.00
Label 36
$360.00
Label 37
$200.00
Label 38
- (numeric field. The copied data comes in as ‘-‘ if no number. Additional code employed for white spaces and allocates for this in the numeric currency fields to be parsed as ‘0.00’)
Label 39
10000 (parsed as ’10,000.00)
Label 40
30000 (30,000.00)
Label 41
DATA – LONG TEXT MULTILINED
CODE IT APPLIED FOR THIS AREA TO PARSE OUT TO THE LONG TEXT FIELD
//JS FOR PARSING THE ABOVE:
$(document).ready(function() {
// The lazyLoad function ensures that the script runs only after the entire page has loaded.
function lazyLoad(callback) {
if (document.readyState === ‘complete’) {
callback(); // If the page is already loaded, execute the callback immediately.
} else {
window.addEventListener(‘load’, callback); // Otherwise, wait for the page to finish loading.
}
}
// Calling lazyLoad to attach our main functionality to the form submit event once the page is fully loaded.
lazyLoad(function() {
// Adding an event listener to the form submission event in Knack's view.
$(document).on('knack-form-submit.view_418', function(event, view, record) {
const pastedData = record.field_A; // Replace field_A with your actual Knack field that captures the pasted data.
const extractedData = processData(pastedData); // Call processData to extract and map the data from the pasted text.
console.log('Final Extracted Data:', extractedData); // Log the extracted data for debugging purposes.
// Perform an API call to update the record in the database with the extracted data.
$.ajax({
url: `https://api.knack.com/v1/objects/object_X/records/${record.id}`, // Construct the API endpoint URL dynamically based on the record ID.
type: 'PUT', // Use the PUT method to update the existing record.
headers: {
'Content-Type': 'application/json', // Set the content type to JSON.
'X-Knack-Application-ID': Knack.application_id, // Include the Knack Application ID in the headers.
'X-Knack-REST-API-Key': 'Your API Key', // Replace with your actual API key for authentication.
},
data: JSON.stringify(extractedData), // Convert the extracted data to JSON format for the API request.
success: function(response) {
console.log('Record updated:', response); // Log the successful response from the API.
},
error: function(xhr, status, error) {
console.error('Error updating record:', error); // Log any errors encountered during the API request.
alert('An error occurred while submitting the data. Please try again.'); // Alert the user if the API request fails.
}
});
});
});
});
function processData(pastedData) {
console.log(‘Starting processData’); // Log the start of the processData function.
console.log(‘Original Data:’, pastedData); // Log the original pasted data for reference.
// Clean the pasted data by replacing HTML line breaks with new lines and trimming whitespace.
const cleanData = pastedData.replace(/<br \/>/g, '\n').trim();
const dataLines = cleanData.split('\n').map(line => line.trim()); // Split the cleaned data into individual lines and trim each line.
console.log('Cleaned Data:', cleanData); // Log the cleaned data.
console.log('Data Lines:', dataLines); // Log the array of data lines for debugging.
let extractedData = {}; // Initialize an object to store the extracted data.
let currentFieldKey = ''; // Variable to store the current field being processed.
let currentContext = ''; // Variable to store the current context (e.g., Main Contact, Reported By).
let totalSqFtCaptured = false; // Flag to ensure only one Total Sq Ft value is captured.
// Array of labels to omit from processing.
const labelsToOmit = [
'Label 22', 'Label 23', 'Label 24', 'Label 25',
'Label 26', 'Label 27', 'Label 28'
];
// Object mapping labels from the pasted data to field keys in the database.
const mappings = {
'Label 1': 'field_A',
'Label 2': 'field_B',
'Label 3': 'field_C',
'Label 4': 'field_D',
'Date Reported': 'field_E',
'Label 5': 'field_F',
'Label 6': 'field_G',
'Main Contact\nName': 'field_H',
'Main Contact\nPhone': 'field_I',
'Main Contact\nEmail': 'field_J',
'Main Contact\nRole': 'field_K',
'Label 7\nName': 'field_L',
'Label 7\nPrimary Phone': 'field_M',
'Label 7\nBusiness': 'field_N',
'Label 7\nHome': 'field_O',
'Label 7\nAddl Phone 1': 'field_P',
'Label 7\nAddl Phone 2': 'field_Q',
'Label 7\nFax': 'field_R',
'Label 7\nEmail': 'field_S',
'Label 8': 'field_T',
'Label 9\nAgency': 'field_U',
'Label 10': 'field_V',
'Label 11': 'field_W',
'Label 11\nPhone': 'field_X',
'Label 11\nEmail': 'field_Y',
'Reported By\nName': 'field_Z',
'Reported By\nPhone': 'field_AA',
'Reported By\nEmail': 'field_BB',
'Reported By\nRole': 'field_CC',
'Label 12': 'field_DD',
'Label 13': 'field_EE',
'Label 14': 'field_FF',
'Label 15': 'field_GG',
'Label 16': 'field_HH',
'Label 17': 'field_II',
'Label 18': 'field_JJ',
'Label 19': 'field_KK',
'Label 20': 'field_LL',
'Label 21': 'field_MM',
'Label 29': 'field_NN',
'Label 30': 'field_OO',
'Label 31': 'field_PP',
'Label 32': 'field_QQ',
'Label 33': 'field_RR',
'Label 34': 'field_SS',
'Label 35': 'field_TT',
'Label 36': 'field_UU',
'Label 37': 'field_VV',
'Label 38': 'field_WW',
'Label 39': 'field_XX',
'Label 40': 'field_YY',
'Label 41': 'field_ZZ',
'Label 42': 'field_AAA',
'Label 43': 'field_BBB',
'Label 44': 'field_CCC',
'Label 45': 'field_DDD',
'Label 46': 'field_EEE',
'Label 47': 'field_FFF',
'Label 48': 'field_GGG',
'Label 49': 'field_HHH',
'Label 50': 'field_III',
'Label 51': 'field_JJJ',
'Label 52': 'field_KKK'
};
// Object mapping contexts (e.g., Main Contact, Reported By) to associated sub-labels.
const contextMappings = {
'Main Contact': ['Phone', 'Email', 'Role'],
'Label 7': ['Name', 'Primary Phone', 'Business', 'Home', 'Addl Phone 1', 'Addl Phone 2', 'Fax', 'Email'],
'Label 9': ['Company', 'POSITION', 'Address', 'Phone', 'Email'],
'Reported By': ['Name', 'Phone', 'Email', 'Role'],
'Label 19': ['Building #'],
'Label 13': ['Claim Severity']
};
// Iterate over each line of data to extract and map the information.
dataLines.forEach((line, index) => {
if (labelsToOmit.includes(line)) {
return; // Skip lines with labels that should be omitted.
}
// Check if the line is a context switcher (e.g., Main Contact, Reported By).
if (contextMappings.hasOwnProperty(line)) {
currentContext = line; // Update the current context.
console.log(`Switching context to: ${currentContext}`);
} else if (mappings.hasOwnProperty(`${currentContext}\n${line}`)) {
currentFieldKey = mappings[`${currentContext}\n${line}`]; // Map the line to a field key based on the current context.
console.log(`Mapping field: ${line} to ${currentFieldKey}`);
} else if (mappings.hasOwnProperty(line)) {
currentFieldKey = mappings[line]; // Map the line to a field key directly.
console.log(`Mapping field: ${line} to ${currentFieldKey}`);
} else if (currentFieldKey) {
// Handle name fields
if (['field_H', 'field_L', 'field_T', 'field_V', 'field_Z'].includes(currentFieldKey)) {
console.log(`Processing name field at line ${index}: ${line}`);
extractedData[currentFieldKey] = line.trim(); // Trim and store the name field.
console.log(`Parsed name for ${currentFieldKey}: ${extractedData[currentFieldKey]}`);
}
// Handle phone fields
else if (['field_I', 'field_M', 'field_N', 'field_O', 'field_P', 'field_Q', 'field_R', 'field_X', 'field_AA'].includes(currentFieldKey)) {
console.log(`Processing phone field at line ${index}: ${line}`);
extractedData[currentFieldKey] = line.replace(/\D/g, ''); // Remove non-digit characters from the phone number.
console.log(`Parsed phone for ${currentFieldKey}: ${extractedData[currentFieldKey]}`);
}
// Handle email fields ensuring HTML tags are stripped
else if (['field_J', 'field_S', 'field_Y', 'field_BB'].includes(currentFieldKey)) {
if (line.includes('@')) {
console.log(`Processing email field at line ${index}: ${line}`);
extractedData[currentFieldKey] = line.replace(/<[^>]+>/g, '').trim(); // Remove any HTML tags and trim the email.
console.log(`Parsed email for ${currentFieldKey}: ${extractedData[currentFieldKey]}`);
} else if (currentContext === 'Reported By') {
// Ensure names in "Reported By" context are captured
extractedData['field_Z'] = line.trim();
console.log(`Captured Reporter Name for field_Z: ${extractedData['field_Z']}`);
} else {
console.warn(`Skipping line as it does not contain a valid email at line ${index}: ${line}`);
}
}
// Handle numeric fields like Total Sq Ft
else if (currentFieldKey === 'field_MM') {
if (!isNaN(line.trim()) && !totalSqFtCaptured) {
console.log(`Processing numeric field at line ${index}: ${line}`);
extractedData[currentFieldKey] = parseFloat(line.trim()); // Convert the numeric value to a float and store it.
totalSqFtCaptured = true; // Ensure only the first valid number is captured.
console.log(`Parsed numeric value for ${currentFieldKey}: ${extractedData[currentFieldKey]}`);
} else {
console.warn(`Skipping invalid or duplicate data for Total Sq Ft at line ${index}: ${line}`);
}
}
// Handle endorsements (multiline)
else if (currentFieldKey === 'field_KKK') {
console.log(`Processing field at line ${index}: ${line}`);
extractedData[currentFieldKey] = (extractedData[currentFieldKey] || '') + line + '\n'; // Append the line to the Label 45 'field_DDD' field.
console.log(`Parsed Label 45 for ${currentFieldKey}: ${extractedData[currentFieldKey]}`);
} else {
extractedData[currentFieldKey] = line; // Store the line in the extracted data object.
console.log(`Parsed general data for ${currentFieldKey}: ${extractedData[currentFieldKey]}`);
}
} else {
console.warn(`Unmapped label detected at line ${index}: ${line}`); // Warn if a line doesn't match any known labels or contexts.
}
});
console.log('Final Extracted Data:', extractedData); // Log the final extracted data.
return extractedData; // Return the extracted data for the API call.
}
Hi @Daniel8
Wow that’s quite a lot of info. I’ll take a look through it and get back to you with something to help if I can.
Craig
Thanks Craig,
As it is, it is fully functional. The only thing I had an issue with was properly parsing the names and addresses and I wasn’t able to get the internal API to work so I had to go with the API KEY directly. Before the app goes live, if I am stuck with doing it that way, I can set up a table for the key and app ID and do a .env so that the API cannot be retrieved under dev mode from the script. Mostly posted this to mainly help anyone else trying to get a complex copy/paste hurdle passed. This took me over 2 weeks to crack, lol. If I dont see anything on a work around in here for names and addresses, I will post mine when successful to help others.
This is the script I would actually like help on and the only thing holding this phase back. As you see I am still using the API key senario. I just found the token help page so will be tinkering with that. But I am having issues with the code parsing the data from the text fields to the name/address fields. See Below:
$(document).on(‘knack-view-render.view_XX’, function(event, view, record) {
// Defining the function to update structured fields in the Knack record
function updateStructuredFields(recordId) {
// Create the payload with parsed address and name data
const payload = {
"field_452": {
street: getAddressStreet(record.field_398),
street2: getAddressStreet2(record.field_398),
city: getAddressCity(record.field_398),
state: getAddressState(record.field_398),
zip: getAddressZip(record.field_398),
country: getAddressCountry(record.field_398)
},
"field_453": {
street: getAddressStreet(record.field_399),
street2: getAddressStreet2(record.field_399),
city: getAddressCity(record.field_399),
state: getAddressState(record.field_399),
zip: getAddressZip(record.field_399),
country: getAddressCountry(record.field_399)
},
"field_454": {
first: getNameFirst(record.field_404),
middle: getNameMiddle(record.field_404),
last: getNameLast(record.field_404),
title: getNameTitle(record.field_404)
},
"field_457": {
first: getNameFirst(record.field_408),
middle: getNameMiddle(record.field_408),
last: getNameLast(record.field_408),
title: getNameTitle(record.field_408)
},
"field_458": {
first: getNameFirst(record.field_416),
middle: getNameMiddle(record.field_416),
last: getNameLast(record.field_416),
title: getNameTitle(record.field_416)
},
"field_459": {
first: getNameFirst(record.field_418),
middle: getNameMiddle(record.field_418),
last: getNameLast(record.field_418),
title: getNameTitle(record.field_418)
},
"field_455": {
street: getAddressStreet(record.field_419),
street2: getAddressStreet2(record.field_419),
city: getAddressCity(record.field_419),
state: getAddressState(record.field_419),
zip: getAddressZip(record.field_419),
country: getAddressCountry(record.field_419)
},
"field_460": {
first: getNameFirst(record.field_422),
middle: getNameMiddle(record.field_422),
last: getNameLast(record.field_422),
title: getNameTitle(record.field_422)
}
};
// Send a PUT request to update the Knack record with the structured data
$.ajax({
url: `https://api.knack.com/v1/objects/object_xx/records/${recordId}`,
type: 'PUT',
headers: {
'Authorization': Knack.getUserToken(),
'X-Knack-Application-ID': Knack.application_id,
'X-Knack-REST-API-Key': 'Your API Key',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'https://api.knack.com'
},
data: JSON.stringify(payload),
success: function(response) {
console.log("Record updated successfully:", response);
Knack.views[view.key].model.fetch(); // Refresh the view to see the updates
},
error: function(xhr, status, error) {
console.error("Failed to update structured fields:", {
readyState: xhr.readyState,
status: xhr.status,
statusText: xhr.statusText,
responseText: xhr.responseText
});
}
});
}
// Calls the updateStructuredFields function with the record ID after a delay to ensure proper loading
setTimeout(function() {
updateStructuredFields(record.id);
}, 1000);
});
My initial reaction is that you should be using field_123_raw.
But I’ll take a proper look tomorrow.
It might be worth a try.
I’ve only glanced at the code though.
Craig
So here is the fully functioning code. Since I couldn’t find anything relating to this, thought I would put it out there for anyone else struggling. This page helped in figuring it out: Importing Records thanks to Les.
Also this page Using Regular Expressions (Regex) With Your App helped me to understand how to parse it rather than separating columns, importing files and using a 3rd party service. If you are a struggling hard knocks and working on a shoe string, this may help you. Now there is a work around w/out all the xtra baggage.
UPDATE: Revised with the GET and PUT ‘getUserToken’ so doesn’t expose the API and calls. For me, this works where a user pastes a complex amount of texts into a field that then needs to be parsed to many fields in a form. Many had like named labels associated so I took texts or sector labels(was an HTML partitioned grid they need to copy from with headers per each block area) and incorporated them to the sub labels e.g. ‘Farm Tools’; ‘Hammer’ I would script the label ‘Farm Tools\nHammer’ to reduce the amount of text to omit. This is the script above. After omitting text, white space and aforementioned grouping, all but the name and addresses were parsing correctly. Since the fields had various iterations of duplicate labels, particularly ‘name’, ‘address’, I needed a separate script to handle them. Since the parsed fields were rendered in the child form for editing, I could not parse them there as the other script was rendering so the second script could not capture the ‘name’/‘address’ field data to parse. So I made an additional child form for redirection that would work as a modal form and only show a Confirmation label e.g. “Please Confirm the Inputted Data is Correct” and the submit button relabeled as “Confirm”. If you have a duplicate need like this, you need to ensure all fields that need to be parsed and the txt fields to be parsed are in the form and set to hidden in the display rules. Take one of the mailing addresses or name fields you know will be blank and use the IF/then in Display Rules to set them all as hidden including the one you are using thats blank. Add a redirect page or to an existing one from there and the hole shebang will appear fluidic in nature. That’s about it. Only took me time and memorial as a laymen in all this and new to Knack. Just hope it saves some time of others. The below script is just to handle the names/addresses but if you need, it can be used when rendering any form view prob gridview with inline edits. Enjoy!
$(document).ready(function() {
function lazyLoad(callback) {
if (document.readyState === ‘complete’) {
callback();
} else {
window.addEventListener(‘load’, callback);
}
}
lazyLoad(function() {
$(document).on('knack-view-render.view_YYY', function(event, view, record) {
function getAddressStreet(address) {
return address ? address.match(/^(.*?),\s*/)[1] : "";
}
function getAddressCity(address) {
return address ? address.match(/,\s*(.*?),\s*\w{2}/)[1] : "";
}
function getAddressState(address) {
return address ? address.match(/\w{2}\s*/)[0] : "";
}
function getAddressZip(address) {
return address ? address.match(/\d{5}(-\d{4})?$/)[0] : "";
}
function getNameFirst(name) {
return name ? name.split(" ").slice(0, 1).join(" ") : "";
}
function getNameLast(name) {
return name ? name.split(" ").slice(-1).join(" ") : "";
}
function getNameMiddle(name) {
if (!name) return ""; // Handle null or undefined names
const nameParts = name.split(" ");
return nameParts.length > 2 ? nameParts.slice(1, -1).join(" ") : "";
}
// Fetch the current record data
$.ajax({
url: `https://api.knack.com/v1/pages/scene_XXX/views/view_YYY/records/${record.id}`,
type: 'GET',
headers: {
'Authorization': Knack.getUserToken(),
'X-Knack-Application-ID': Knack.application_id,
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'https://api.knack.com'
},
success: function(data) {
console.log("Current record data:", data);
const payload = {
"field_452": {
street: getAddressStreet(data.field_398_raw),
city: getAddressCity(data.field_398_raw),
state: getAddressState(data.field_398_raw),
zip: getAddressZip(data.field_398_raw)
},
"field_453": {
street: getAddressStreet(data.field_399_raw),
city: getAddressCity(data.field_399_raw),
state: getAddressState(data.field_399_raw),
zip: getAddressZip(data.field_399_raw)
},
"field_454": {
first: getNameFirst(data.field_404_raw),
last: getNameLast(data.field_404_raw),
middle: getNameMiddle(data.field_404_raw)
},
"field_457": {
first: getNameFirst(data.field_408_raw),
last: getNameLast(data.field_408_raw),
middle: getNameMiddle(data.field_408_raw)
},
"field_458": {
first: getNameFirst(data.field_416_raw),
last: getNameLast(data.field_416_raw),
middle: getNameMiddle(data.field_416_raw)
},
"field_459": {
first: getNameFirst(data.field_418_raw),
last: getNameLast(data.field_418_raw),
middle: getNameMiddle(data.field_418_raw)
},
"field_455": {
street: getAddressStreet(data.field_419_raw),
city: getAddressCity(data.field_419_raw),
state: getAddressState(data.field_419_raw),
zip: getAddressZip(data.field_419_raw)
},
"field_460": {
first: getNameFirst(data.field_422_raw),
last: getNameLast(data.field_422_raw),
middle: getNameMiddle(data.field_422_raw)
}
};
console.log("Payload to be sent:", JSON.stringify(payload));
// Now perform the PUT request to update the record
$.ajax({
url: `https://api.knack.com/v1/pages/scene_YYY/views/view_XXX/records/${record.id}`,
type: 'PUT',
headers: {
'Authorization': Knack.getUserToken(),
'X-Knack-Application-ID': Knack.application_id,
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'https://api.knack.com'
},
data: JSON.stringify(payload),
success: function(response) {
console.log("Record updated successfully:", response);
Knack.views[view.key].model.fetch(); // Re-fetch to render the data
},
error: function(xhr, status, error) {
console.error("Failed to update structured fields:", {
readyState: xhr.readyState,
status: xhr.status,
statusText: xhr.statusText,
responseText: xhr.responseText
});
}
});
},
error: function(xhr, status, error) {
console.error("Failed to fetch current record data:", {
readyState: xhr.readyState,
status: xhr.status,
statusText: xhr.statusText,
responseText: xhr.responseText
});
}
});
});
});
});
I’m with Sunny on this.
But question is that a once off ?
If it is export the data to excel then use text to columns to extract data for each part of the address field.
Rename the fields as appropriate then reimport
No it’s to be done consistently by our user’s, a simplification process within the program. That’s okay though it’s worked out. The scripts I laid out while there’s a few tweaks that needed to be done still, for the one with many many fields over 50 without counting them, that will need my API key and env for masking. As per the addresses to be parsed from the text. That worked out beautifully using the token API. So for anybody who needs, they’re welcome to use them. I know the first one’s a little convoluted for most people. But the primary thing is that it can be done without having to use a third party service and additional costs outside of knack. Thank you for your responding and your help though!