Saving data from a smarty template to a custom database

suiteCRM v7.11.23

I am trying to emulate the behaviour of the Line item groups using smartyTemplate. I made function vardef inside my custom module’s vardefs:

$dictionary['test_testModule']['fields']['custom_line'] = array(
  'name' => 'custom_line',
  'vname' => 'LBL_CUSTOM_LINE',
  'type' => 'function',
  'source' => 'non-db',
  'massupdate' => 0,
  'importable' => 'false',
  'duplicate_merge' => 'disabled',
  'duplicate_merge_dom_value' => 0,
  'audited' => false,
  'reportable' => false,
  'inline_edit' => false,
  'function' =>
    array(
      'name' => 'display_custom_line',
      'returns' => 'html',
      'include' => 'custom/modules/test_testModule/Line_Items.php',
    ),
);

That vardef calls a php file with this function inside that file via include:

function display_custom_line($focus, $field, $value, $view)
{
  global $sugar_config, $locale, $app_list_strings, $mod_strings;

  $smarty = new Sugar_Smarty();

  $smarty->assign('itemName', 'Item Name');

  $html = $smarty->fetch('custom/modules/test_testModule/templates/line.tpl');
}

And here’s is that template:

<div class="p-3">
    <table id="to-buy-list" class="table table-bordered">
        <thead class="bg-light">
        <tr>
            <th class="text-center">{$itemName}</th>
            <th class="text-center">Quantity</th>
            <th class="text-center">Status</th>
            <th></th>
        </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
{*    <button id="add-row" ><span class='start-btn'>Add Item</span></button>*}
    <button id="add-row" class="add-item-btn" role="button">ADD ITEM</button>
</div>

{literal}
    <style>
        /* Add Button Below */
        .add-item-btn {
            /*appearance: button;*/
            background-color: #000;
            background-image: none;
            border: 1px solid #000;
            border-radius: 4px;
            box-shadow: #fff 4px 4px 0 0,#000 4px 4px 0 1px;
            box-sizing: border-box;
            color: #fff;
            cursor: pointer;
            display: inline-block;
            font-family: ITCAvantGardeStd-Bk,Arial,sans-serif;
            font-size: 9px;
            font-weight: 400;
            line-height: 20px;
            margin: 0 5px 10px 0;
            overflow: visible;
            padding: 12px 40px;
            text-align: center;
            text-transform: none;
            touch-action: manipulation;
            user-select: none;
            -webkit-user-select: none;
            vertical-align: middle;
            white-space: nowrap;
        }

        .add-item-btn:focus {
            text-decoration: none;
        }

        .add-item-btn:hover {
            text-decoration: none;
        }

        .add-item-btn:active {
            box-shadow: rgba(0, 0, 0, .125) 0 3px 5px inset;
            outline: 0;
        }

        .add-item-btn:not([disabled]):active {
            box-shadow: #fff 2px 2px 0 0, #000 2px 2px 0 1px;
            transform: translate(2px, 2px);
        }
        /* Remove Button Below */
        .remove-item-btn {
            font-family: "Open Sans", sans-serif;
            font-size: 10px;
            letter-spacing: 2px;
            text-decoration: none;
            text-transform: uppercase;
            color: #9E1A1A;
            cursor: pointer;
            border: 2px solid #9E1A1A;
            padding: 0.15em 0.25em;
            box-shadow: 1px 1px 0px 0px #9E1A1A, 1px 1px 0px 0px #9E1A1A, 2px 2px 0px 0px #9E1A1A, 3px 3px 0px 0px #9E1A1A, 4px 4px 0px 0px #9E1A1A;
            position: relative;
            user-select: none;
            -webkit-user-select: none;
            touch-action: manipulation;
        }

        .remove-item-btn:hover{
            background-color: #9E1A1A;
            color: #ffffff;
        }

        .remove-item-btn:active {
            box-shadow: 0px 0px 0px 0px;
            top: 5px;
            left: 5px;
        }

        @media (min-width: 768px) {
            .add-item-btn, .remove-item-btn {
                padding: 12px 50px;
            }
        }
    </style>
<script type="text/javascript">
    $(document).ready(function(){
    let counter = 0;
    function addItem(ev){
        ev.preventDefault();

        let table = $('#to-buy-list tbody')[0];

        let row = $('<tr/>');
        $(table).append(row);

        let col1 = "<td><input style='width: 100%;' type='hidden' class=' custom-input' name='products_id[" + counter + "]' id='products_id" + counter + "' /><input style='width: 100%;' type='text' class=' custom-input' name='products[" + counter + "]' id='products" + counter + "' /></td>";
        $(row).append(col1);

        let col2 = "<td><input style='width: 100%;' type='hidden' class=' custom-input' name='quantity_id[" + counter + "]' id='quantity_id" + counter + "' /><input style='width: 100%;' type='number' class=' custom-input' name='quantity[" + counter + "]' id='quantity" + counter + "' /></td>";
        $(row).append(col2);

        let col3 = "<td> <select style='width: 100%;' type='hidden' class='select custom-input' name='status_id[" + counter + "]' id='status_id" + counter + "'> <option value='Pending'>Pending</option> <option value='Done'>Done</option> </select> </td>";
        $(row).append(col3);

        // let col4 = "<td><a href='#' class='btn btn-danger remove-btn'>Remove</a></td>";
        let col4 = "<td> <button id='remove-btn' class='remove-item-btn' role='button'>Remove</button> </td>"
        $(row).append(col4);


        addToValidate('EditView', 'products'+counter, 'id', true, 'Product Name');
        addToValidate('EditView', 'quantity'+counter, 'id', true, 'Product Quantity');

        counter++;
    }

    function removeItem(ev){
    ev.preventDefault();
    let btn = ev.currentTarget;
    $(btn).closest('tr').remove();
    }

    $(document).on('click', '#add-row', addItem);
    $(document).on('click', '#remove-btn', removeItem);

    });
</script>
{/literal}

I already made a custom module(lineItems) to save the product name, quantity, and status to that module(lineItems) and I was suggested that I would be using an after save hook to save the data from the smarty template to the custom module(lineItems).
However, I am at a loss on how to do that. Any pointers for those that do? :sob:

That part about the logic hook doesn’t seem right to me… first, you’d have to get the data back from the browser (and at this point, the smarty template doesn’t have much to do, it’s role is in building up the page).

So your fields would have to be part of an HTML form, and you’d get them in the controller Save action. Or you could also do it with Javascript sending the data as Ajax requests.