Wizard Record Saves

  • 1
  • Question
  • Updated 5 years ago
  • Answered
I haven't had a chance to test this out, but before I go about writing a trigger I wanted to run a scenario by you folks. I'm looking to create a job application that (hopefully) will be customer facing and allow us to put our existing job application (which is a pain to make any changes to) out to pasture and bypass the convoluted process of getting into Salesforce.

My issue is, I don't want duplicate contacts. JavaScript isn't my forte, and what I'm hoping to do is have a trigger running before the record is inserted into Salesforce. It will look for existing contacts based on the data passed. If a contact exists, I want to pass that existing ID back to Skuid for the next page if it's possible. Any ideas folks? I think it should be as simple as "return idofExiting", but I've never done anything with a trigger along these lines.

Thoughts, other ideas?
Photo of Jason Hardy

Jason Hardy

  • 240 Points 100 badge 2x thumb

Posted 5 years ago

  • 1
Photo of Jason Hardy

Jason Hardy

  • 240 Points 100 badge 2x thumb
Ok, I've been playing with the javascript API a bit, but I'm not getting the behavior I expect (well maybe hope is a better descriptor).

I'm "creating a new record", but the I'm attempting to override the save button so it will look for an existing record first. I have a snippet running, and it looks something like this:

var params = arguments[0],
$ = skuid.$;
var contactModel = skuid.model.getModel('Contact');
var firstContact = contactModel.getFirstRow();
alert(firstContact);
alert(contactModel);

I have filled in data into the first row...but when I run the alert, I get [object Object]. Is it possible to grab the data dynamically before doing a commit? Or do I need to write a function that will override the information here:

http://help.skuidify.com/s/tutorials/...

All I want to do is grab the email address input into the "New contact" screen, then load that into another model and see if there are any results. If there are, in the next screen I want to pass in the ID from that model, or do I need a second model?
Photo of Glenn Elliott

Glenn Elliott, Champion

  • 7,738 Points 5k badge 2x thumb
The Skuid guys will no doubt have a better answer on this, but here's a dump from my limited brain.

In wizard step 1, user enters contact name into a text box and clicks Next. A custom snippet on the Next button takes the input text and plugs it into a condition on the ExistingContacts model, then gets the first row. If there's a row, navigate the user to Step 2, which shows a table built on ExistingContacts with a template above it with text saying "Uh oh, we already have people of that name". If there's no row, navigate to Step 3 which shows a field editor on the NewContact model to capture details of the new contact.

Is that the sort of thing you're after? If so, I may have some code you can reuse.
Photo of J.

J., Official Rep

  • 7,470 Points 5k badge 2x thumb
Jason,

J. from Skuid here. Glenn has you on the right track (thanks Glenn!), but there are a couple small adjustments that I would recommend. I would use two Models (both on Contact, neither loading data on page load) and our Wizard component. The first model (call it "SearchContact") would only be used in wizard step #1, which would only ask for whatever information you want to search on in model #2 (call it "NewContact"). SearchContact should also have "Create Default Row if Model Has None" checked.



NewContact would have a condition for each of these inputs, so if your duplicate check criteria is just checking for an existing email address, you would have one Condition (Filterable Default Off) on NewContact named "EmailAddress" or something similar.



Every Wizard step from 2 on and your Save button would use the NewContact model. When you click the Next button to get to Step #2, I would have it run a snippet which does the following:

1. Set the condition(s) on the NewContact model with the value(s) provided to the SearchContact model on Step #1 (using our skuid.model.setCondition method)
2. Load the NewContact model (using our skuid.model.updateData method)
3. In the callback for the model load, check to see if a row was returned and if not, use our skuid.model.createRow method to create one.
4. Navigate to step 2 using our wizard step.navigate method

The model methods I mentioned in 1-3 are documented in our skuid.model documentation. A good example of inserting a snippet into the button to get from Wizard step 1 to step 2 and how to use the step.navigate method is covered in this community post.

Lastly, just a small debugging tip: try opening up your browser's Javascript console and using console.log() instead of alert() to get debugging info. Depending on your browser, of course, you should get more detail and be able to interact with the output a lot more, and it won't disappear when you click OK.

I hope that all this helps!
Photo of Jason Hardy

Jason Hardy

  • 240 Points 100 badge 2x thumb
Sorry it's taken me so long to get back on this. I think I've got most of this solved; however, I am still having one point of difficulty.

Here is my code so far

var params = arguments[0];
var step = params.step;
var $ = skuid.$;
// Get references to the Models
var models = skuid.model.map();

//This model has the initial search data defined
var SearchContact = skuid.model.getModel('ContactLookup');

//This model will attempt to find the existing or create a new
var NewExistingContact = skuid.model.getModel('NewExistingContact');

//Getting the intial search results
var searchContactRow = SearchContact.getFirstRow();

//Getting the conditions
var emailAddress = NewExistingContact.getConditionByName('EmailAddress');

//Getting the data provided in the previous records
var contactEmail = SearchContact.getFieldValue(searchContactRow,'Email');
var contactFn = SearchContact.getFieldValue(searchContactRow,'FirstName');
var contactLn = SearchContact.getFieldValue(searchContactRow,'LastName');
var mobilePhone = SearchContact.getFieldValue(searchContactRow,'MobilePhone');

//Setting the condition for existing lookup with the email address defined previously
NewExistingContact.setCondition(emailAddress,contactEmail);

var existingContact = null;
var newContactRow = null;
//attempting to update the model
NewExistingContact.updateData(
function()
{
//Trying to get a row
existingContact = NewExistingContact.getFirstRow();

//If there isn't a row, then we need to create one
if(!existingContact)
{
window.newContactRow = NewExistingContact.createRow
(
{
additionalConditions:
[
{field: 'email', operator:'=', value:contactEmail},
{field: 'FirstName', operator:'=', value:contactFn},
{field: 'FirstName', operator:'=', value:contactLn},
{field: 'mobilePhone', operator:'=', value:mobilePhone}
]
}
);
}
searchContact.deleteRow(searchContactRow);
});

step.navigate('step2');


Now my problem none of the fields are actually populated other than email address when I'm attempting to create a new row. I was originally attempting to just use the updatedata function by itself without the function, then doing the get row in the next line; however, it kept saying "undefined" in the log regardless of whether or not there should have been a value.

Ideas?

Thanjks!
Photo of J.

J., Official Rep

  • 7,470 Points 5k badge 2x thumb
Jason,

The field names in the "additionalConditions" array are case sensitive (i.e. "email" and "mobilePhone" should be "Email" and "MobilePhone"). It looks like "FirstName" is listed twice too. Also, I don't think that you need to do that last deleteRow call.

None of that explains why you aren't getting field values to populate, however. Would you mind posting your page XML here so I can take a look at the stuff around this snippet? Thanks.
Photo of Jason Hardy

Jason Hardy

  • 240 Points 100 badge 2x thumb
Well your suggestion worked; however, the last part isn't working as I would expect. I've setup a step to save a record; however, the other modules aren't getting the new ID when I'm loading them in another step. Any ideas? https://amnhealthcare.box.com/s/laxr28d16d1oe9wrgfrr
(Edited)
Photo of Jason Hardy

Jason Hardy

  • 240 Points 100 badge 2x thumb
Hi J, I think I may have figured out a work around using page include. My problem appears to be the query string. It's not passing the data from model.

I'm using cid={{$Model.NewExistingContact.data.Id}}&aid={{$Model.AccountBrand.data.Id}}

Do I have this formatted incorrectly?

Thanks, appreciate the assistance! :)
Photo of J.

J., Official Rep

  • 7,470 Points 5k badge 2x thumb
Jason,

I'm sorry for the delayed reply, but I'm glad that you've been able to make progress! There's just one slight change to your merge syntax that's needed:
cid={{$Model.NewExistingContact.data.n.Id}}&aid={{$Model.AccountBrand.data.n.Id}}
...where n is the number of the row in the model that you want, in this case, 0. If the page include solution is working for you and you want to keep going that route, great! Here's another idea about how you could approach the problem though without having to create distinct pages.

For each additional model that has a reference back to the NewExistingContact record (let's say "EmergencyContact" which I see in your XML), you could set the models to not "Create Default Row if Model Has None" and not "Load Model Data on Page Load." Then, in the callback of your NewExistingContact.updateData(), just outside the closing curly brace of your "if (!existingContact)" above, call a createRow on the EmergencyContact model with an additionalCondition of the NewExistingContact record Id:
//  First get the Contact Id for reference
var conRow = NewExistingContact.getFirstRow(),
    conId = NewExistingContact.getFieldValue(conRow,'Id');

//  Create a row with the Contact Id set for each dependent model
EmergencyContact.createRow({
    additionalConditions : [{field : 'Contact__c', value : conId}]
});
From your XML, it looks like you already added each of these models to your Save button, so you should be good there. I hope that this helps!
Photo of Jason Hardy

Jason Hardy

  • 240 Points 100 badge 2x thumb
Thanks for that! I want to take one more go at using the page references if I can. It still does't appear to be working. I've attached the XML from both pages:
https://amnhealthcare.box.com/s/mgmkvvishrc2t8ll1ur2
https://amnhealthcare.box.com/s/y6ytn9xkh8szhy9lap0z

If that doesn't work, then I'll go ahead and give the the javascript option a whirl. I'm trying to avoid custom code whenever possible though. If I do need to use JavaScript, where would I put the snippet?

Thanks!
Photo of J.

J., Official Rep

  • 7,470 Points 5k badge 2x thumb
You would just add it to your existing snippet, just above the...
searchContact.deleteRow(searchContactRow);
...part (line 463 in the second link you posted above).

It looks like the reason your Page Includes aren't working you need to replace those n characters with a 0 in your merges (e.g. line 303 in the first link you posted). Sorry, I may have confused things with my earlier comment. By n, I just meant "the number of the row you want." By the way, here's a link to our Merge Syntax documentation. It's pretty handy, and I reference it myself all the time.
(Edited)