Adding a timestamp button above a field!

I have a text area field in form. This is used for writing production updates. Every time the project is updated I have to manually add the date to the text area and then a new line and then write the update.

Here is an example:

12/12/2024
some updates

12/09/2024
some more updates.

What would be really handy for me is to be able to have a button above the field that when I press adds the date and a new line so I can just type the update.

Does anyone know how I might be able to achieve this? I’ve tried with ChatGPT but haven’t been able to code this with JQuery.

Cheers.

Have you considered capturing those updates as individual rows in a child table instead of appending to one ever-growing text field?

That way you can’t accidentally delete prior history and the date can be added automatically with a record rule.

If you wish to use current approach the automatic appending of a timestamp could be done using custom javascript but you will need a developer - its not trivial.

Hi

Try Stephen Chapman and see if he’s available as he knocked up something for us, that is similar in action, very quickly and reasonably priced. We wanted something to quickly insert common phrases into our notes.

Dean

@Dean I appreciate the mention. :slight_smile:
@GSH as the other have mentioned, it is better to have a connected table with your updates.

If you really want it all in a concatenated text field, @Callum.Boase has a good video on how to achieve this:
Knack | Record changelogs in a text field to save on records - YouTube

1 Like

Thanks all. Let me hammer chatGPT on this.

Right I managed to sort this out, looks like it took 40 minutes. Hopefully it can help others.

What you can do is take this script and ask GPT to analyze it so it understands the logic, and you can then use this to add other types of UX functions within knack.

For example I have a character counter function with a circle that goes red as people reach the character limit on a field, where I didn’t want to set hard length validations on fields and simply provide some visual feedback to the user.

The script is structured with parings so you enter the view (knack builder, page view, copy just the view value, and then the field alongside which the icon needs to appear - you get this from the knack table that contains the field - you may have to punch the icon so you can see the field names in the table view).

Test this first on your setup. If there are any real programmers what want to comment and improve please go ahead.

What this script will do is read the field first - so in my case where I have a log, it will simply add a date to the top of the field without cancelling what was there before. I even got it to put the cursor focus underneath the field ready for typing.

Have a good day.

// 1. Add your view-field pairings here
const calendarFieldPairs = [
    { view: 'view_XXX', field: 'field_XXX' },
    { view: 'view_XXX', field: 'field_XXX' }
    // Add more as needed: { view: 'view_xxx', field: 'field_yyy' }
];

function getFormattedDate() {
    const now = new Date();
    const day = String(now.getDate()).padStart(2, '0');
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const year = now.getFullYear();
    return `${day}/${month}/${year}`;
}

// Modified process to accept view and field as arguments
function insertCalendarIcon(viewId, fieldId) {
    const fieldSelector = `#${viewId} #${fieldId}`;
    const $field = $(fieldSelector);

    if (!$field.length) return;

    // Prevent adding duplicate icon if the function runs more than once
    if ($field.parent().hasClass('calendar-icon-wrapper')) return;

    const calendarIconSvg = `
        <span class="calendar-icon-btn" style="cursor:pointer; display: flex; align-items: center; margin-left: 8px;">
            <svg height="18" width="18" style="display:inline;" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
                <line x1="16" y1="2" x2="16" y2="6"></line>
                <line x1="8" y1="2" x2="8" y2="6"></line>
                <line x1="3" y1="10" x2="21" y2="10"></line>
            </svg>
        </span>
    `;

    const $wrapper = $('<div class="calendar-icon-wrapper" style="display: flex; align-items: center;"></div>');
    $field.before($wrapper);
    $wrapper.append($field).append(calendarIconSvg);

    $wrapper.find('.calendar-icon-btn').on('click', function() {
        const currentValue = $field.val();
        const todayStr = getFormattedDate();

        let newValue, cursorPos;
        if (!currentValue || currentValue.trim() === "") {
            newValue = todayStr + "\n";
            cursorPos = newValue.length;
        } else {
            newValue = todayStr + "\n";
            cursorPos = newValue.length;
            newValue += "\n" + currentValue;
        }

        $field.val(newValue).focus();
        const fieldEl = $field.get(0);
        if (fieldEl.setSelectionRange) {
            fieldEl.setSelectionRange(cursorPos, cursorPos);
        } else if (fieldEl.createTextRange) {
            var range = fieldEl.createTextRange();
            range.collapse(true);
            range.moveEnd('character', cursorPos);
            range.moveStart('character', cursorPos);
            range.select();
        }
    });
}

// Wire up our logic to each view render event for each pairing
calendarFieldPairs.forEach(pair => {
    $(document).on(`knack-view-render.${pair.view}`, function(event, view) {
        insertCalendarIcon(pair.view, pair.field);
    });
});

To be perfectly honest I think you have over complicated the whole process.

Native knack function will update a connected file where date stamped notes can be saved and retrieved /edited/deleted etc quite simply.

I have a data file with connected researchers notes on one to many basis.
Each time a note is added its automatically time date stamped.

This also adds the name of the user and allows for multiple comments on the same day without having to prompt for dates or times or researcher
Step 1

Step 2

Process added through form > record actions

Lower grid retrieves the accumulating comments for the file/record in use

Adding extra javascript is really not necessary (unless I have misunderstood what your wanting to achieve)

Hey Ray, thanks for that. I use something similar in other parts of my system, but I really only wanted to keep this within a form and not have to create a separate view.

Understand. You can combine a grid view with the form on the same scene though.
Far less complex than reading and extracting from a long text string.
Good Luck with your project

1 Like