class Example_App_Save {

	/**
	 * Function hooked early enough to generate password and pass to our save_tree method
	 */
	public function save_updated_tree_form() {

		if ( 'true' === $_POST['regenerate_key'] ) {
			$this->sharing->regenerate_key();
			$new_key = get_option( 'rusty-inc-org-chart-key' );
		} else {
			$new_key = null;
		}

		if ( isset( $_POST['tree'] ) ) {
			/**
			 * First we decode the json string passed in from our form after we strip out the slashes
			 */
			$decoded_tree_json = json_decode( stripslashes( $_POST['tree'] ) );
		} else {
			$tree = null;
		}

		if ( isset( $_POST['nonce'] ) ) {
			/**
			 * Next we clean up our nonce
			 */
			$nonce = stripslashes( $_POST['nonce'] );
			$nonce = str_replace( '"', '', $nonce );
		} else {
			$nonce = null;
		}

		/**
		 * Now if the nonce is valid, let's call our save method to save the actual data
		 * if there is a valid nonce in our $_POST data
		 */
		if ( null !== $nonce && wp_verify_nonce( $nonce ) ) {
			$example_app_save = new Example_App_Save();
			$example_app_save->save_tree( $new_key, $decoded_tree_json, $nonce );
		} else {
			$example_app_save = new Example_App_Save();
			$example_app_save->custom_save_form_redirect( 'Nonce error.' );
		}
	}

	/**
	 * Saves our new tree data after user alters the tree
	 */
	public function save_tree( $key, $tree ) {

		if ( null !== $tree ) {

			$i          = 0;
			$flat_array = array();
			$a          = $tree;
			$it         = new RecursiveIteratorIterator( new RecursiveArrayIterator( $a ) );

			/**
			 * Let's convert the multidimensional array into a flat array in the format we want
			 */
			foreach ( $it as $k => $v ) {
				$flat_array[ $i ][ $k ] = $v;

				/**
				 * Increase our index when we hit the last value, parent_id.
				 * Here is where I need to find a more reliable way to group the data
				 */
				if ( 'parent_id' === $k ) {
					$i++;
				}
			}
			/**
			 * Update our database option here
			 */
			$updated = update_option( Example_App_Plugin::OPTION_NAME, $flat_array );

			if ( $updated ) {
				$admin_notice = 'success';
			} else {
				$admin_notice = 'failed';
			}
		} else {
			/**
			 * Add a user feedback message that the $_POST tree variable is empty
			 */
			$admin_notice = 'failed';
		}

		// redirect the user to the appropriate page
		$this->custom_save_form_redirect( $admin_notice );
		exit;

	}

	/**
	 * Redirects the browser to our plugin page along with an admin message
	 */
	public function custom_save_form_redirect( $admin_notice ) {
		wp_redirect(
			esc_url_raw(
				add_query_arg(
					array(
						'example_app_admin_add_notice' => $admin_notice,
					),
					admin_url( 'admin.php?page=' . Example_App_Plugin::PLUGIN_NAME )
				)
			)
		);
	}

	/**
	 * Print custom admin notices
	 */
	public function print_plugin_admin_notices() {
		if ( isset( $_REQUEST['example_app_admin_add_notice'] ) ) {
			if ( 'success' === $_REQUEST['example_app_admin_add_notice'] ) {
				$html = '<div class="notice notice-success is-dismissible"><p><strong>Your data has been saved. If you requested a new secret key, it has been updated.</strong></p></div>';
				echo $html;
			} elseif ( 'failed' === $_REQUEST['example_app_admin_add_notice'] ) {
				$html = '<div class="notice notice-error is-dismissible"><p><strong>There was an error saving your data.</strong></p></div>';
				echo $html;
			}
		} else {
			return;
		}

	}

}

SCSS Example

.alp_admin-tools {

	&-wrap {
		max-width: 960px;
		margin: 30px auto;
	}

	header {

		h1 {
			margin: 0 0 30px;
		}

	}

	.alp-option {

		&-box-inner {
			background: #fff;
		    background-clip: border-box;
		    border: none;
		    border-radius: 3px;
		    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
		    padding: 0 30px 30px;
		    margin: 0 0 60px;

		    > h3 {
		    	font-size: 24px;
			    margin: 0 -30px 30px;
			    padding: 30px;
			    background: #4F5467;
			    color: #fff;
		    }

		}

	}

	.acf-field {

		input[type="text"], input[type="password"], input[type="number"], input[type="search"], input[type="email"], input[type="url"], textarea, .acf-field select {
			width: 99%;
			max-width: 460px;
		}

	}

}

jQuery Example

var switchToInput = function () {

    var $input = $( '<textarea>', {
        val: $( this ).text(),
        type: 'textarea'
    } );
    
    $input.css( 'height', $( this ).closest( 'li' ).height() );
    $( this ).replaceWith( $input );
    $input.on( 'blur', switchToSpan );
    $input.select();

};

var switchToSpan = function () {

    var $span = $( '<span>' , {
        text: $( this ).val()
    } );

    $span.addClass( 'alp-showcase-spec-val-editable' );
    $( this ).replaceWith( $span );
    $span.append( '<i class="icon-amalinkspro-edit" title="Edit Specification"></i>' );
    $span.on( 'click', switchToInput );

}

$( 'body' ).on( 'click', '.alp-showcase-spec-val-editable', switchToInput );