quick add

I’d like to create a button that creates a new row using another as it’s template. All fields except the name field would duplicate. The name field would be incremented by number or letter. ie. “Room 101” would be “Room 102”, or “Section A” would be “Section B”.



I certainly have to use javascript, but not too sure how get there. Here is the function I have so far. 

function CreateIncRow(modelid){ var model = skuid.model.getModel(modelid); var lastrow = ; //(will need to know how many rows there are in order to get the last row. Not sure how to select row by index though) var lastrowlocationname = model.getFieldValue(lastrow,'Location_Name__c'); var lastword = lastrowlocationname.split(" ").pop(); If (!IsNan(lastword)){ updatedlastword = lastword++; } else { var lastwordlastchar = lastword.slice(-1); var lastwordlastcharIncrement = String.fromCharCode(lastwordlastchar.charCodeAt() + 1); var updatedlastword = lastword.substring(0,lastword.length - 1).concat(lastwordlastcharIncrement); } var newrow = model.createRow({ additionalConditions: [ { field: 'Location_Name__c', value: updatedlastword } //Other fields and values here ], doAppend: true }); }<br>


Need help with a few things.

  1. How do get the row count of a model?
  2. How do get the last row using an index?
  3. Why am I getting this error below?


  1. model.data.length;
    2. model.data[model.data.length-1];
    3. capital “If” isn’t valid javascript. Use lowercase “if”.

coding analogy … you just turned me 180 at my first at bat in tball. :S

Ok. So I’m still learning the ropes in javascript. First time really programming anything significant. So, I guess the reason I didn’t get what was available until not was that the documentation specifies the properties in your api and not the properties available to javascript. ie. array properties such as model.data.length

Each property then has it’s own set of properties based on which type of property it is. This is where I was not making the connection. These properties are documented already a hundred times over, which is why it’s not provided. For a newby, and others coming after me, this escaped me entirely.

Hi Pat,

I took the liberty of enhancing the cloneRecord snippet to check for a custom Location_Name__c field and update the value per your requirements.  Note that this is implemented as a Row action that invokes a custom snippet.  

Give this a shot and then you can adjust accordingly.

// Snippet for cloning a record in a table and setting a custom name skuid.snippet.registerSnippet('cloneRecordWithCustomName', function() {<br>&nbsp; &nbsp; var params = arguments[0],<br>&nbsp; &nbsp; &nbsp; &nbsp; item = params.item,<br>&nbsp; &nbsp; &nbsp; &nbsp; row = item.row,<br>&nbsp; &nbsp; &nbsp; &nbsp; model = params.model,<br>&nbsp; &nbsp; &nbsp; &nbsp; $ = skuid.$;<br>&nbsp; &nbsp; // Create a new row in our table<br>&nbsp; &nbsp; var newRow = model.createRow();<br>&nbsp; &nbsp; // Put in default values from the fields in our current row<br>&nbsp; &nbsp; if (row) {<br>&nbsp; &nbsp; &nbsp; &nbsp; $.each(row, function(fieldId, val) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Only allow fields that are Objects or that are Createable<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((fieldId !== 'attributes') &amp;&amp; (val !== null) &amp;&amp; (fieldId !== 'Id') &amp;&amp; (fieldId !== 'Location_Name__c')) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var modelField = model.getField(fieldId);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((typeof val === 'object') || (modelField &amp;&amp; modelField.createable)) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; model.updateRow(newRow, fieldId, val);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if (fieldId === 'Location_Name__c') {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Custom logic to populate the custom Location_Name__c field&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // e.g Room 101 -&gt; Room 102 or Building A -&gt; Building B, etc.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var valArray = val.split(' ');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (valArray.length &gt; 1) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastWord = valArray.pop();<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Increment count if last bit is a number<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var updatedLastWord;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isNaN(lastWord)) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; updatedLastWord = ++lastWord;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Otherwise increment character<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastWordLastChar = lastWord.slice(-1);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastWordLastCharIncr = String.fromCharCode(lastWordLastChar.charCodeAt() + 1);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; updatedLastWord = lastWord.substring(0, lastWord.length - 1).concat(lastWordLastCharIncr);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; valArray.push(updatedLastWord);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Updated custom field<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; model.updateRow(newRow, fieldId, valArray.join(' '));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; });<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; // Force all registered lists to put our row into edit mode<br>&nbsp; &nbsp; $.each(model.registeredLists, function() {<br>&nbsp; &nbsp; &nbsp; &nbsp; // See if this item has been rendered in this list yet<br>&nbsp; &nbsp; &nbsp; &nbsp; var newItem = this.renderedItems[newRow.Id];<br>&nbsp; &nbsp; &nbsp; &nbsp; if (newItem) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newItem.mode = 'edit';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newItem.refreshFields();<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; });<br>}); 



Note that I do not claim that the Javascript used to manipulate the name is optimized. Just a quick hack to get it working.  There are probably edge cases and of course other data considerations that you will need to account for.

Enjoy!

I have everything working except for when the table is in a drawer and in context of it’s parent row.


I like the part about the looping in the snippet you provided. Before I use it though, I’d like to understand it better. Where do they fieldId & val variables get their values? Is there documentation for it?

Woot Woot!!!

My snippet is working! Some tweaking and tidying needs to happen in order to say it’s a well formed snippet.

  1. Used the List.visibleItems property to get the right row. This will only work if there are multiple pages for the table. Any idea on how to make this work on the last row in context regardless of page? Assuming no, so I’ll make the table and model show all rows. Shouldn’t be an issue as there won’t be that many rows most of the time.
  2. Loop through fields for copying values as opposed to selectively declaring them.
  3. Comment
  4. Anything else recommended for best practices.
I can now say that I’m crossing the threshold into the darkside. I can create snippets at the level of “research and code one line at a time”. Great documentation once you start to understand what you will and what you find in it.