quick add

  • 1
  • Question
  • Updated 4 years ago
  • Answered
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

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?
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb

Posted 4 years ago

  • 1
Photo of Ben Hubbard

Ben Hubbard, Employee

  • 12,550 Points 10k badge 2x thumb
1. model.data.length;
2. model.data[model.data.length-1];
3. capital "If" isn't valid javascript. Use lowercase "if".
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
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.
Photo of Irvin Waldman

Irvin Waldman, Champion

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

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.

Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
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?
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
I have everything working except for when the table is in a drawer and in context of it's parent row.

Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 43,156 Points 20k badge 2x thumb
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.