Create records in a table based on selected records in another table.

  • 1
  • Question
  • Updated 4 years ago
  • Answered
I haven't quite seen this in the discussions, so I apologize it there is an existing thread. My problem is this. I have an object (Object A) that contains hundreds of thousands of records in it. Object A acts as a lookup object only and is not associated with accounts, opportunities, cases, or anything like that. I have another object (Object B) that that references Object A through a lookup. Object B is associated with Accounts, cases...all that jazz. The purpose of this structure is for easy record creation for Object B. When someone calls in, we find their information in Object A and create a record in Object B that will tie the account we are creating. I would like to search for a record in Object A table and add a mass action to create a record in Object B with the lookup already populated (lookup that references Object A). How do I go about doing this with a javascript inline snippet?
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb

Posted 5 years ago

  • 1
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
Hi Glenn, check out this tutorial : http://help.skuidify.com/s/tutorials/m/components/l/109496-mass-create-records pay close attention to the JavaScript at the end of the tutorial. Specifically you want to focus on this part :
  1. $.each(contacts.data,function(){
  2. var row = newStatements.createRow({
  3. additionalConditions: [
  4. { field: 'Contact__c', value: this.Id, operator: '=', nameFieldValue: this.Name }
  5. ]
  6. });
  7. });
You can create a row and pass in values as "Additional Conditions".
(Edited)
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
Thank you for the quick response! I have used this code in other areas of our deployment (works great!), but I did not think I could use for this case because of the $.each section of the code. I simply want to select records in Object A and create rows in Object B with the lookup Id of Object A already populated in Object B. I can use getFirstRow() to populate the account and contact we just created. Each account/contact could have multiple records I want associated with it. What object would I reference in the $.each section if I use this method. I'm afraid if I used 'Object A' in this section it would create hundreds of thousands of records, when I only need to create x number of rows for x number selected in the table & pass the Id of the selected records to the new rows. Is there a way to create a row for $.each 'selected row in Object A'
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
You can use something like this from the mass action, to get the ids of all the Object A records:

var Ids = skuid.$.map(arguments[0].list.getSelectedItems(),function(item){    
return item.row.Id;
});

You can then use a for loop to create a row for each Id in Ids, and populate the lookup with that Id field. I'm not sure if a "$.each" loop will work for this, although I think it can. You might be able to use a "for in" loop as well. 
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
thank you...I think that gets me on the right path. I'll post back later with any success or modifications to get me further. 
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
Moshe - thanks for your participation in these posts.  Its great to see the community working together.  You are making a serious bid to become our next community champion! 
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
I have the script below created as a mass action in a table that references a model called 'property'. 'clientProperty' is the model where I want a record to be created for every 'property' record that is selected. When I click on the dropdown for the mass action nothing happens. What I want to happen is all the records that are selected in the 'property' model to create a record in the 'clientProperty' model and autopopulate the 'Property__c' (lookup field between 'clientProperty' and 'property' ) filed with the selected record's Id.

Script:

var params = arguments[0];var step = params.step;
var $ = skuid.$;
var models = skuid.model.map();

var Ids = skuid.$.map(arguments[0].list.getSelectedItems(),function(item){     
return item.row.Id;
});

var clientproperty = skuid.model.getModel('clientProperty');


$.each(Ids.data,function(){
    var ClientProprow = clientproperty.createRow({
        additionalConditions: [
            { field: 'Property__c', value: this.Id, operator: '='},



        ]
    });
});
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
Ok let's get the dumb questions out of the way.  You have the mass action set to type "Custom" and have made the calling the right snippet name?   If you console log "hello world" in the snippet - does it show?  Is somthing happening at all? 
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
yes, with alert('Hello World'); on mass action I get the alert in the browser. Name of snippet and mass action type seem to working just fine.
Photo of JD Bell

JD Bell, Senior Product Engineer

  • 2,996 Points 2k badge 2x thumb
Hi Glenn,

I see a couple possible issues with the Javascript you've posted.

First, your 'Ids' variable is an array of strings. There is no "data" property, so you are attempting to iterate over an undefined value. Try removing ".data" from your "$.each" function.

Second, I see a stray comma after the condition object literal. Try removing that as well.

Your code should like like this:
$.each(Ids,function(){
    var ClientProprow = clientproperty.createRow({
        additionalConditions: [
            { field: 'Property__c', value: this.Id, operator: '='}
        ]
    });
I also have one more suggestion. It's generally a good idea to explicitly set the name field in your condition. If Skuid has any trouble looking up the name field in your model, then you'll just end up with a fairly unreadable Id in place of a name in your relationship. You can explicitly set the name field like so:

       additionalConditions: [
            { field: 'Property__c', value: this.Id, operator: '=', nameFieldValue: 'Name' }
        ]
(Edited)
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
Thank you JD! That got me ALMOST there. The correct number of rows are being created now, but the 'Property__c' filed is not being populated. If I use { field: 'Property__c', value: Ids, operator: '='}, I get the array to display in the Propery__c field. How can I it to create a row and populate only 1 record from the Ids array?
Photo of Ben Hubbard

Ben Hubbard, Employee

  • 12,490 Points 10k badge 2x thumb
I think the scope of the "this" keyword is no longer pointing to the id that you're iterating over.  The "this" now has scope within the createrow function.  I would try explicitly setting
var currentId = this.Id;
outside the createRow function and then referencing it inside the createRow function like this...

$.each(Ids,function(){   
   var currentId = this.Id; 
   var ClientProprow = clientproperty.createRow({
        additionalConditions: [
            { field: 'Property__c', value: currentId, operator: '='}
        ]
});

(Edited)
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
just to clarity. I did use { field: 'Property__c', value: this.Id, operator: '=', nameFieldValue: 'Name' }, but only the actual text "Name" appeared in the Property__c field. I also tried { field: 'Property__c', value: this.Id, operator: '='} which returned no result in the Property__c field.
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
Ben, thank you for chiming in, but I am getting the same result as if I used this.Id...Property__c is not being populated at all.
Photo of Ben Hubbard

Ben Hubbard, Employee

  • 12,490 Points 10k badge 2x thumb
Sorry Glenn, I came in this late and didn't have all my ducks in a row.  When you're creating your array of ids using the skuid.$.map function, you're not setting any properties on that object.  So I think the code below should be correct.  You just need to remove the .Id after "this".

$.each(Ids,function(){      
   var currentId = this; 
   var ClientProprow = clientproperty.createRow({
        additionalConditions: [
            { field: 'Property__c', value: currentId, operator: '='}
        ]
});

Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
Ben thanks so much. That did the trick! Thank you ALL. What a team effort! I cannot express how grateful I am to the community. When I learn more I will give back for sure.
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
Glenn,  we do appreciate the community.  We look forward to seeing what you can come up with.  In the mean time,  a really cool expression of gratitude would be a app exchange review.  (And here I'm shamelessly asking.... )   Here is the link:   https://appexchange.salesforce.com/listingDetail?listingId=a0N30000009wyDjEAI

Thanks. 
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
done! you guys deserve it.
Photo of Glenn Goodrich

Glenn Goodrich

  • 190 Points 100 badge 2x thumb
here is the code that works. 

var params = arguments[0];var step = params.step;
var $ = skuid.$;
var models = skuid.model.map();

var Ids = skuid.$.map(arguments[0].list.getSelectedItems(),function(item){     
return item.row.Id;
});

var clientproperty = skuid.model.getModel('clientProperty');


$.each(Ids,function(){ 
var currentId = this;
var ClientProprow = clientproperty.createRow({ 
        additionalConditions: [
{ field: 'Property__c', value: currentId, operator: '='}

        ]
    });
});
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
Hi guys, just came across this thread and it has been VERY useful. Great thread. I have one additional problem I can't get my head around though, I'm trying to pull in the id property of an additional (related) field in the row that is being selected - this is the Account ID to which the object belongs. How could this be done? My snippet is pasted below, along with a screenshot:

var params = arguments[0];var step = params.step;
var $ = skuid.$;
var models = skuid.model.map();

var Ids = skuid.$.map(arguments[0].list.getSelectedItems(),function(item){    
return item.row.Id;
});

var addingQuotes = skuid.model.getModel('BrokerQuote');
var aircraftdata = skuid.model.getModel('database');


$.each(Ids,function(){
var currentId = this;

var quoteRow = addingQuotes.createRow({
        additionalConditions: [
{ field: 'stack__Aircraft__c', value: currentId, operator: '=', nameFieldValue: this.Name}

//need to add another field update here which says
//{ field: 'stack__Operator__c', value: ??????, operator: '=', nameFieldValue: this.Name}

        ]
    });
});

addingQuotes.save({

    callback: function(result){
       
        if (result.totalsuccess) {

        var aircraftData = skuid.model.getModel('database');
        aircraftData.updateData();
        }
    }
});


(trying to pull in the id of the 'Operator Name' field below, 'Tail Number' is the record id which works fine.)
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
Hope this helps...

var params = arguments[0];var step = params.step;var $ = skuid.$;
var models = skuid.model.map();

var Ids = skuid.$.map(arguments[0].list.getSelectedItems(),function(item){     
return item.row.Id;
});

var addingQuotes = skuid.model.getModel('BrokerQuote');
var aircraftdata = skuid.model.getModel('database');

// see if you can access the row your operating on 
$.each(Ids,function(){ 
var currentId = this;
// I don't know if this will work but it might...
//var currentRow = this.row;
//console.log(currentRow); //check it out in the console
// or maybe this 
//var actualrow = YOURMODEL.getRowById(this);
//either way you get the row, set a variable to the value of operator name 
var operatorName = YOURMODEL.getFieldValue(currentRow,'stack__Operator__c'); 
var quoteRow = addingQuotes.createRow({ 
        additionalConditions: [
{ field: 'stack__Aircraft__c', value: currentId, operator: '=', nameFieldValue: this.Name},

//then populate your operator name field with the right value 
{ field: 'stack__Operator__c', value: operatorName}

        ]
    });
});

addingQuotes.save({

    callback: function(result){
        
        if (result.totalsuccess) {

        var aircraftData = skuid.model.getModel('database');
        aircraftData.updateData();
        }
    }
});
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
Moshe, you could have given me a fish, but instead you taught me how to fish! Thank you. Here is the final snippet, although I am still having trouble refreshing one of the models. Any idea how to do an updateData(); based on the model's condition? (given that none of the values in any of the rows have changed)

var params = arguments[0];var step = params.step;var $ = skuid.$;
var models = skuid.model.map();

var Ids = skuid.$.map(arguments[0].list.getSelectedItems(),function(item){    
return item.row.Id;
});


var addingQuotes = skuid.model.getModel('BrokerQuote');
var aircraftdata = skuid.model.getModel('database');

$.each(Ids,function(){
var currentId = this;
var actualrow = aircraftdata.getRowById(this);
//console.log(actualrow);
var operatorId = aircraftdata.getFieldValue(actualrow,'stack__Op_Name__c');
//console.log(operatorId);
var quoteRow = addingQuotes.createRow({
        additionalConditions: [
{ field: 'stack__Aircraft__c', value: currentId, operator: '=', nameFieldValue: this.Name},
{ field: 'stack__Operator__c', value: operatorId, operator: '=' }

        ]
    });
});

addingQuotes.save();
console.log('saving quotes');
aircraftdata.updateData();
console.log('updating aircraft model');


//The statement: aircraftdata.UpdateData(); actually works, but doesn't change the rows which are rendered on the page. I can only think this is because none of the 'values' in any of these rows have changed. However the selected rows should be removed based on a condition which has been set on the model.

Any idea how to do an updateData(); based on the model's condition?
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
You might be having the issue because update Data happens before the save finishes. To fix that replace this section:

addingQuotes.save();
console.log('saving quotes');
aircraftdata.updateData();
console.log('updating aircraft model');

With this...

addingQuotes.save({callback:function(result){
if(result.totalsuccess){
aircraftdata.updateData();
}
}});

This causes the updateData call to wait until the save has finished.
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
Still not working unfortunately. I thought perhaps maybe the save wasn't a 'totalSuccess' but the console is still saying it's successful and updating the table:

addingQuotes.save({callback:function(result){
if(result.totalsuccess){
aircraftdata.updateData();
    console.log('updated aircraft list');
} else { console.log('not working') }
}});


Could it be related to the condition on the model I'm trying to refresh?:

Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
You might have to update brokerQuote together with database. Replace 

aircraftdata.updateData();

with....

skuid.model.updateData([aircraftdata,addingQuotes]);
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
same result unfortunately. Could it have something to do with the model sitting in a nested tab?


I've had a previous issue with a page include component which required a different jquery function, but the models in this case are all inside the same page.
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb
I've actually had problems before with update Data on a model condition that uses the in operator. I think this might be a bug, here is a thread with a similar situation I had.

https://community.skuidify.com/skuid/topics/in_operator_bug_in_model_condition
Photo of Ben Hubbard

Ben Hubbard, Employee

  • 12,490 Points 10k badge 2x thumb
Hi Greg, Try one quick thing.  Do what Moshe said about combining the two models into one updateData call, but switch the order of the models.

skuid.model.updateData([addingQuotes,aircraftdata]);

I'm not 100% sure this will fix your issue, but it's worth a try.  Order is important in updateData calls, just as it is important when you're building out your models in the page composer.  You need the source model to be before the dependent model in the list.