Shared To-Do List Widget
Adds a team to-do list to the dashboard where editors can add tasks, tick them off and clear finished ones, shared by everyone who can edit content.
Opens WPIDE on
Code
add_action( 'wp_dashboard_setup', function () {
if ( ! current_user_can( 'edit_others_posts' ) ) {
return;
}
wp_add_dashboard_widget( 'wpide_todo', 'Team to-do list', function () {
$items = (array) get_option( 'wpide_todo_items', array() );
?>
<ul id="wpide-todo-list" style="margin-top:0">
<?php foreach ( $items as $i => $item ) : ?>
<li><label><input type="checkbox" data-index="<?php echo (int) $i; ?>" <?php checked( ! empty( $item['done'] ) ); ?>>
<span style="<?php echo ! empty( $item['done'] ) ? 'text-decoration:line-through;color:#787c82' : ''; ?>"><?php echo esc_html( $item['text'] ); ?></span></label></li>
<?php endforeach; ?>
<?php if ( ! $items ) : ?><li><em>Nothing to do.</em></li><?php endif; ?>
</ul>
<form id="wpide-todo-form" style="display:flex;gap:6px">
<label for="wpide-todo-text" class="screen-reader-text">New task</label>
<input id="wpide-todo-text" type="text" class="widefat" maxlength="200" placeholder="New task" required>
<button class="button">Add</button>
<button type="button" class="button-link" id="wpide-todo-clear">Clear done</button>
</form>
<script>
( function () {
var nonce = <?php echo wp_json_encode( wp_create_nonce( 'wpide_todo' ) ); ?>;
var send = function ( data ) {
var body = new FormData();
body.append( 'action', 'wpide_todo' );
body.append( 'nonce', nonce );
Object.keys( data ).forEach( function ( key ) { body.append( key, data[ key ] ); } );
return fetch( ajaxurl, { method: 'POST', credentials: 'same-origin', body: body } ).then( function () { window.location.reload(); } );
};
document.getElementById( 'wpide-todo-form' ).addEventListener( 'submit', function ( event ) {
event.preventDefault();
send( { op: 'add', text: document.getElementById( 'wpide-todo-text' ).value } );
} );
document.getElementById( 'wpide-todo-list' ).addEventListener( 'change', function ( event ) {
if ( event.target.dataset.index !== undefined ) { send( { op: 'toggle', index: event.target.dataset.index } ); }
} );
document.getElementById( 'wpide-todo-clear' ).addEventListener( 'click', function () { send( { op: 'clear' } ); } );
} )();
</script>
<?php
} );
} );
add_action( 'wp_ajax_wpide_todo', function () {
check_ajax_referer( 'wpide_todo', 'nonce' );
if ( ! current_user_can( 'edit_others_posts' ) ) {
wp_send_json_error( null, 403 );
}
$items = (array) get_option( 'wpide_todo_items', array() );
$op = isset( $_POST['op'] ) ? sanitize_key( $_POST['op'] ) : '';
if ( 'add' === $op && ! empty( $_POST['text'] ) ) {
$items[] = array( 'text' => mb_substr( sanitize_text_field( wp_unslash( $_POST['text'] ) ), 0, 200 ), 'done' => false );
} elseif ( 'toggle' === $op && isset( $_POST['index'], $items[ absint( $_POST['index'] ) ] ) ) {
$items[ absint( $_POST['index'] ) ]['done'] = empty( $items[ absint( $_POST['index'] ) ]['done'] );
} elseif ( 'clear' === $op ) {
$items = array_filter( $items, function ( $item ) {
return empty( $item['done'] );
} );
}
update_option( 'wpide_todo_items', array_values( $items ), false );
wp_send_json_success();
} );
Notes
Tasks are stored in one option; finished tasks stay listed until someone clicks "Clear done".
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.