TIP: Append to running lists with the "Add to list" action


#7

Javascript’s standard Array.map can take an existing function on a single string, and apply it to a whole list of strings.

For example:

d.content = d.content + currentContent
.split('\n')
.map(x => '- [ ] ' + x)
.join('\n'),

Used in context:

Full source for an Add *All* to List variant – click to expand
(() => {
    'use strict';

    // Based on an original script by @agiletortoise

    /*
      Ask for a category, and append to a 
      tagged list for that category
    */

    // EDIT THIS
    // setup categories available
    const
        categories = ['Movies', 'TV Shows', 'Blog Ideas'],

        // EDIT TAG
        // tag to assign to list drafts
        listTag = 'lists',

        // grab text
        currentContent = draft.content.trim(),

        // A prompt for selecting an item from a list.
        p = categories.reduce(

            // Accumulator updates - a button added for 
            // each category in the list:
            (prompt, buttonName) => {
                prompt.addButton(buttonName);
                return prompt;
            },

            // Initial accumulator: a prompt with properties:
            Object.assign(
                Prompt.create(), {
                    title: 'Select list:',
                    message: 'Ask for a category, and append' +
                        ' to a tagged list for that category',
                    isCancellable: true
                }
            )
        );

    return p.show() ? (() => {
        const
            category = p.buttonPressed,

            // query for list drafts...
            drafts = Draft.query(category, 'inbox', [listTag]),

            // index of first draft that matches a condition
            iDraft = drafts.findIndex(
                draft => draft.content.startsWith('## ' + category)
            ),

            d = iDraft !== -1 ? (
                drafts[iDraft]
            ) : Object.assign(
                Draft.create(), {
                    content: '## ' + category + '\n\n'
                });

        return (
            // tag and update content
            d.addTag(listTag),

            d.content = d.content + currentContent
            .split('\n')
            .map(x => '- [ ] ' + x)
            .join('\n'),

            d.update(),
            console.log(true)
        );
    })() : (
        context.cancel(),
        console.log(false)
    );
})();

JS :: Building prompts with Array.reduce and Object.assign
#8

Is there a way to cross off [x] items e.g. from a shopping list?


#9

They are tappable task marks. Is that what you are asking?


#10

Experimenting with a version that:

  • collects the category names from the top of the list drafts
  • adds a prompt to create a new category / list draft

Not listed, so it doesn’t step on Greg’s example, but you can look at it here.


#11

Yes I have those. But to delete the ones done. I.e. in a shopping list it deletes the items you have picked up leaving the ones you need, when you next open the note.
Hope that makes sense.


#12

Great addition. Thanks.


#13

This is great, thanks!


#14

You can modify this action that I created which moves the done tasks to the bottom of the list to do what you need.


#15

Re the final lines of that action

begin = begin.slice(0,-1);
end = end.slice(0,-1);
editor.setText(begin + "\n" + end);
d.update;
editor.focus(d);
  • My understanding is that update is a method, so presumably it needs to be called with a trailing parentheses ? d.update()

(rather than just evaluating to a function value ?)


#16

Is it possible to run this script without the check boxes?


#17

You know what I’d like here? I’d like the action to turn each listed item into a tappable link to search Google or Duck Duck Go so when I later come back to the list it’s easy to look up whatever the thing is.


#18

This great thanks appreciated.


#19

Is there a way to adapt this script to prepend rather than append text to an existing draft? I keep a running list of favourite quotes with the most recent at the top. At the moment when I open the draft each time and the cursor default to the end of the text. I’ve had a look but coding isn’ t my strong point!

Thanks in advance.

Euan


#20

Yes, it’s certainly possible to alter the script to put new list items at the top. A little more complex if you want to maintain the heading, since the script would have to local the right insertion point, not just tack text on the top.

Not restoring the last cursor position is a bug in the current release which will be fixed in the next update.


#21

No heading so that’s not a problem but some idea of how to modify the script to prepend would be good.

Thanks!


#22

I updated my tweaked version of this action:

  • new Add option to append or prepend items to a list.

  • Collect list names from tagged drafts.

  • Create new lists inside the action.

Action directory: https://actions.getdrafts.com/a/1Gd


#23

Can you add in the description and code comments that to identify a list, the set tag (e.g. lists) and ## header is required?

Thanks for the fork!


#24

Hi - This worked great for me for a while - not sure what I did, but now when I try to add something to a list, it creates a NEW list whose only item is the Draft just acted upon…
Any thoughts what might be causing this? I’m suspecting it may have something to do w the fact that the old lists have been archived; so when I go to add to them, it creates a new list in the Inbox; however, I don’t want the lists sitting in my Inbox… but rather out of sight, out of mind…
Any help would be welcomed!


#25

The action is only looking for list drafts in the inbox.

I have a tweaked version of the action that has a few additional features. I updated it to look in the inbox, flagged, and archive which might work for you.

Action directory: https://actions.getdrafts.com/a/1Gd


#26

Thanks so much for your quick response - I’ll give it a try:)