Update a user profile via frontend

I’ve written this in a hurry and it’s untested and probably sloppy code, but it gives you an idea of how to accomplish this with AJAX.

<form id="update_user">
    <div class="form-group">
        <label for="firstname">Name</label>
        <input type="text"
               name="firstname"
               id="firstname"
               value="<?= esc_attr(wp_get_current_user()->user_firstname) ?>"
               placeholder="Vorname">
    </div>

    <div class="form-group">
        <label for="name">Name</label>
        <input type="text"
               name="name"
               id="name"
               value="<?= esc_attr(wp_get_current_user()->user_lastname) ?>"
               placeholder="Name">
    </div>

    <div class="form-group">
        <label for="username">Benutzername</label>
        <input type="text"
               name="username"
               id="username"
               value="<?= esc_attr(wp_get_current_user()->user_login) ?>"
               placeholder="Benutzername">
    </div>

    <div class="form-group">
        <label for="street">Straße</label>
        <input type="text"
               name="street"
               id="street"
               value="<?= esc_attr(get_user_meta(get_current_user_id(), 'street', true)) ?>"
               placeholder="Straße">
    </div>

    <div class="form-group">
        <div class="row">
            <div class="col-md-4">
                <label for="zip">PLZ</label>
                <input type="text"
                       name="zip"
                       id="zip"
                       value="<?=  esc_attr(get_user_meta(get_current_user_id(), 'zipcode', true)) ?>"
                       placeholder="PLZ"
                       maxlength="5">
            </div>
            <div class="col-md-8">
                <label for="location">Ort</label>
                <input type="text"
                       name="location"
                       id="location"
                       value="<?= esc_attr(get_user_meta(get_current_user_id(), 'city', true)) ?>"
                       placeholder="Ort">
            </div>
        </div>
    </div>

    <div class="form-group">
        <label for="street">Telefonnummer</label>
        <input type="text"
               name="phone"
               id="phone"
               placeholder="Telefonnummer"
               value="<?= esc_attr(get_user_meta(get_current_user_id(), 'phone', true)) ?>">
    </div>

    <div class="form-group">
        <label for="street">E-Mail-Adresse</label>
        <input type="email"
               name="email"
               id="email"
               value="<?= esc_attr(wp_get_current_user()->user_email) ?>"
               placeholder="E-Mail-Adresse">
    </div>

    <input type="submit" class="btn-mitmachen btn-small" value="Speichern" />
</form>

Create a file called

/assets/js/update-user.js

And add your AJAX function that will pass the values to your edit_user in functions.php

function updateTheUser() {

    $.ajax({
        url: ajax_params.url,
        method: 'POST',
        data: {
            action: 'update_user',
            security: ajax_params.nonce,
            user_id: ajax_params.user,
            email: $( '#email' ).val()
            first_name: $( '#firstname' ).val(),
            last_name: $( '#name' ).val(),
            username: $( '#username' ).val(),
            street: $( '#street' ).val(),
            zip: $( '#zip' ).val(),
            location: $( '#location' ).val(),
            phone: $( '#phone' ).val()
        },
        beforeSend: function( xhr ) {
            // Do something before like add loading animation
        },
        success: function( data ) {
            // Do something on success like redirect the user
        }
    })
}

$( '#update_user' ).on( 'submit', updateTheUser )

In functions.php you need to localize the JavaScript file you just created with you AJAX URL and nonce values.

wp_enqueue_script( 'update-user', get_template_directory_uri() . '/assets/js/update-user.js', array('jquery'), '', true );

wp_localize_script( 'pricebreaks-custom', 'ajax_params', array(
  'url'         => admin_url( 'admin-ajax.php' ),
  'nonce'       => wp_create_nonce( 'ajax_validation' ),
  'user'        => get_current_user_id()
));

Then you need to write the functionality to edit the user. You can’t update the user_login, so I would suggest editing the nickname or display name instead.

function edit_user_ajax_handler() {

    // Ensure we have the data we need to continue
    if( ! isset( $_POST ) || empty( $_POST ) || ! is_user_logged_in() ) {

        // If we don't - return custom error message and exit
        header( 'HTTP/1.1 400 Empty POST Values' );
        echo 'Could Not Verify POST Values.';
        exit;
    }

    check_ajax_referer( 'ajax_validation', 'security' );

    $user_id = $_POST['user_id'];

    $user_id = wp_update_user( array(
        'ID' => $user_id,
        'first_name' => $_POST['first_name'];
        'last_name' => $_POST['last_name'];
        'user_email' => $_POST['email'];
        'nickname' => $_POST['username'];
    ) );

    if ( is_wp_error( $user_id ) ) {
      // There was an error, probably that user doesn't exist.
    } else {

        update_user_meta( $user_id, 'street', $_POST['street'], get_user_meta( $user_id, 'street', true ) )
        update_user_meta( $user_id, 'zip', $_POST['zip'], get_user_meta( $user_id, 'zip', true ) )
        update_user_meta( $user_id, 'location', $_POST['location'], get_user_meta( $user_id, 'location', true ) )
        update_user_meta( $user_id, 'phone', $_POST['phone'], get_user_meta( $user_id, 'phone', true ) )

    }
}
add_action('wp_ajax_edit_user', 'edit_user_ajax_handler');
add_action('wp_ajax_nopriv_edit_user', 'edit_user_ajax_handler');