Undefined index

To com um script e queria fazer uma adaptação nele, como acrescentar mais input. Só que coloquei mais um input dnascimento, mas somente ele não é enviado via post. Colquei o comando var_dump($_POST); e somente o campo dnascimento não é enviado via post.

html:

Admin
<div id="msg-php" class="no-display"></div>

<form method="POST" enctype="multipart/form-data" onSubmit="salvarForm(); return false;" id="frmCrud">
<fieldset>
    <legend>Nome:</legend>
    <input id="nome" type=text class=input-text required placeholder="Digite seu nome aqui" size=20 name=nome onFocus="inputOn(this)" onBlur="inputOff(this)"/>
    <legend>Nascimento:</legend>
    <input id="dnascimento" type=text class=input-text required placeholder="Digite sua data aqui" size=20 name=dnascimento onFocus="inputOn(this)" onBlur="inputOff(this)"/>
    <legend>Email:</legend>
    <input id="email" type=email class=input-text required placeholder="Informe seu email" size=30 name=email onFocus="inputOn(this)" onBlur="inputOff(this)"/>
    <legend>Telefone:</legend>
    <input id="telefone" type=text class=input-text required pattern="\d*" placeholder="Seu telefone? (apenas números)" size=10 name=telefone onFocus="inputOn(this)" onBlur="inputOff(this)"/>
</fieldset>
<fieldset>
    <legend>Foto:</legend>
    <input type=file id="foto" name=foto class=input-text accept="image/png, image/jpeg"/>
    <img id="image" class=thumb />
</fieldset>
<input id="id" type=hidden value="-1" />
<input id="nomeFoto" type=hidden value="" />
<input type=reset class=button id="btnLimpar" value="Limpar" />
<input type=submit class=button id="btnSalvar" value="Salvar" />
</form>

php:

<?php

//dados de conexao com banco de dados do sistema
$host   = "localhost";
$user   = "root";
$pass   = "";
$db     = "crud";

//captura acao que deve ser executada
$a = $_REQUEST["action"];

//identifica acao e invoca metodo a ser executado
switch ( $a ) {
    case "lista":
        carregarLista(); break;
    case "salvar":
        salvarForm(); break;
    case "excluir":
        excluirForm(); break;
    case "buscar":
        carregarCliente(); break;
}

//*****************************************************************************
// Metodo que carrega lista de clientes cadastrados
//
function carregarLista() {
    //abre conexao com banco de dados
    global $host, $user, $pass, $db;
    $mysqli = new mysqli( $host, $user, $pass, $db );
    if ( $mysqli->connect_errno ) { printf("Connect failed: %s\n", $mysqli->connect_error); exit(); }
    //preara e executa consulta de lista de clientes
    $sql = "SELECT * FROM cliente ORDER BY id DESC";
    if (!$res = $mysqli->query( $sql )) {
        echo "Erro ao executar SQL<br>";
        echo "Query: ".$sql."<br>";
        echo "Errno: ".$mysqli->errno."<br>";
        echo "Error: ".$mysqli->error."<br>";
        $res->close();
        exit;
    }
    //verifica se existe retorno de dados
    if ($res->num_rows === 0) {
        echo "Nenhum cadastro realizado até o momento.";
        $res->close();
        exit;
    }
    //monta tabela de resultados na pagina
    $saida = "<table>";
    while ($d = mysqli_fetch_array($res, MYSQLI_BOTH)) {
        $saida  = $saida. "<tr>"
                . "  <td style='width:25%'><img class=thumb src='/crud/imagens/".$d['foto']."' /></td>"
                . "  <td>"
                . "      <td class=plus style='padding-top:30px'>".$d['nome']."</td>"
                . "      <td class=plus style='padding-top:30px'>".$d['dnascimento']."</td>"
                . "      <td style='padding-top:30px'>".$d['email']."</td>"
                . "      <td style='padding-top:30px'>".$d['telefone']."</td>"
                . "  </td>"
                . "  <td style='width:25%; padding-top:10px'><input type=button class=button value=Editar onClick='carregarCliente(\"".$d['id']."\");'></td>"
                . "  <td style='width:10%; padding-top:10px''><input type=button class='button delete' value=X onClick='excluirRegistro(\"".$d['id']."\");'></td>"
                . "</tr>";
    }
    $saida = $saida. "</table>";

    echo $saida;
    $res->close();
    $mysqli->close();
}

//*****************************************************************************
// Metodo que carrega dados do cliente selecionado para alteracao
//
function carregarCliente() {
    //var_dump($_POST);
    if ( ! isset( $_POST ) || empty( $_POST ) ) {
        echo "Dados do formulário não chegaram no PHP.";
        exit;
    }
    //recupera ID a ser buscado
    if ( isset( $_POST["id"] ) && is_numeric( $_POST["id"] ) ) {
        $id = (int) $_POST["id"];

        //abre conexao com banco
        global $host, $user, $pass, $db;
        $mysqli = new mysqli( $host, $user, $pass, $db );
        if ( $mysqli->connect_errno ) { printf("Connect failed: %s\n", $mysqli->connect_error); exit(); }
        //prepara e executa sql para buscar registro
        $stmt = $mysqli->prepare("SELECT * FROM cliente WHERE id=?");
        $stmt->bind_param('i', $id);
        $stmt->execute();

        $meta = $stmt->result_metadata();
        while ($field = $meta->fetch_field()) {
            $parameters[] = &$row[$field->name];
        }

        call_user_func_array(array($stmt, 'bind_result'), $parameters);
        while ($stmt->fetch()) {
            foreach($row as $key => $val) {
                $x[$key] = $val;
            }
            $results[] = $x;
        }
        //retorna array em formato JSON para leitura via ajax
        echo json_encode( $results );

        $mysqli->close();
    } else {
        echo "ID nao encontrado.";
    }
}

//*****************************************************************************
// Metodo que salva ou atualiza form de cadastro do cliente
//
function salvarForm() {
    var_dump($_POST);
    if ( ! isset( $_POST ) || empty( $_POST ) ) {
        echo "Dados do formulário não chegaram no PHP.";
        exit;
    }
    //recupera dados do formulario html
    $id         = (int) $_POST["id"];
    $nome       = $_POST["nome"];
    $dnascimento       = $_POST["dnascimento"];
    $email      = $_POST["email"];
    $telefone   = $_POST["telefone"];
    $foto       = isset( $_FILES['foto'] ) ? $_FILES['foto'] : null;
    $nome_imagem= $_POST["nomeFoto"];
    //verifica dados do form
    $v = validarForm( $id, $nome, $dnascimento, $email, $telefone, $foto );
    if ($v != null) {
        echo "Problema encontrado:<br>".$v;
        exit;
    }
    //envia a imagem para o diretorio
    if (! empty( $foto ) ) {
        $imagem_tmp   = $foto['tmp_name'];
        $nome_imagem  = $foto['name']; //basename($foto['name']);
        $diretorio    = $_SERVER['DOCUMENT_ROOT'].'/crud/imagens/';
        $envia_imagem = $diretorio.$nome_imagem;

        if (! move_uploaded_file( $imagem_tmp, $envia_imagem ) ) {
            echo 'Erro ao enviar arquivo de imagem.';
            //echo "<br>Nome temporario do arquivo: ".$imagem_tmp."<br>Nome da Imagem: ".$nome_imagem."<br>Diretorio armazenamento: ".$diretorio."<br>envia: ".$envia_imagem;
            exit;
        }
    }
    //abre conexao com banco
    global $host, $user, $pass, $db;
    $mysqli = new mysqli( $host, $user, $pass, $db );
    if ( $mysqli->connect_errno ) { printf("Connect failed: %s\n", $mysqli->connect_error); exit(); }
    //prepara SQL para insert ou update dependendo do ID do form
    $sql = null;
    if ( $id > 1 ) {
        $sql = "UPDATE cliente SET nome=?, dnascimento=? email=?, telefone=?, foto=? WHERE id=".$id;
    } else {
        $sql = "INSERT INTO cliente (nome, dnascimento, email, telefone, foto) VALUES (?, ?, ?, ?)";
    }
    //prepara e executa sql para insert dos dados
    $stmt = $mysqli->prepare( $sql );
    $stmt->bind_param('ssis', $nome, $dnascimento, $email, $telefone, $nome_imagem);
    $stmt->execute();
    //verifica se SQL de update foi executado
    if ( $id > 1 ) {
        if ( $stmt->affected_rows > 0 ) {
            echo "Cliente atualizado com sucesso!";
        } else {
            echo "Não houve necessidade de atualizar os dados, nenhum valor foi modificado.";
        }
    //verifica se SQL de insert foi executado
    } else {
        if ( $stmt->affected_rows > 0 ) {
            echo "Cliente cadastrado com sucesso!";
        } else {
            echo "Error: ".$stmt;
            exit;
        }
    }

    $mysqli->close();
}

//*****************************************************************************
// Metodo que exclui registro do cliente
//
function excluirForm() {
    //var_dump($_POST);
    if ( ! isset( $_POST ) || empty( $_POST ) ) {
        echo "Dados do formulário não chegaram no PHP.";
        exit;
    }
    //recupera ID a ser deletado
    if ( isset( $_POST["id"] ) && is_numeric( $_POST["id"] ) ) {
        $id = (int) $_POST["id"];

        //abre conexao com banco
        global $host, $user, $pass, $db;
        $mysqli = new mysqli( $host, $user, $pass, $db );
        if ( $mysqli->connect_errno ) { printf("Connect failed: %s\n", $mysqli->connect_error); exit(); }
        //prepara e executa sql para delete do registro
        $stmt = $mysqli->prepare("DELETE FROM cliente WHERE id=?");
        $stmt->bind_param('i', $id); 
        $stmt->execute();
        //verifica se SQL foi executado com sucesso
        if ( $stmt->affected_rows > 0 ) {
            echo "Registro deletado com sucesso!";
        } else {
            echo "Error: ".$stmt;
            exit;
        }
        $mysqli->close();
    } else {
        echo "ID invalido para delete.";
    }
}

//*****************************************************************************
// Metodo que persiste dados do formulario em server-side
//
function validarForm( $id, $nome, $dnascimento, $email, $telefone, $foto ) {
    //validar campo nome
    if ( $nome == null || trim( $nome ) == "" ) {
        return "Campo Nome deve ser preenchido.";
    }

    if ( $dnascimento == null || trim( $dnascimento ) == "" ) {
        return "Campo Nome deve ser preenchido.";
    }
    //validar campo email
    if ( $email == null || trim( $email ) == "" ) {
        return "Campo Email deve ser preenchido.";
    }
    //validar campo telefone
    if ( $telefone == null || trim( $telefone ) == "" ) {
        return "Campo Telefone deve ser preenchido.";
    }
    //validar campo foto
    if ( empty( $foto ) ) {
        //return "Campo Foto deve ser preenchido.";
    }

    return null;
}

js:

window.onload = function() {
	//script para mostrar um preview da imagem do upload
	document.getElementById("foto").onchange = function () {
		var reader = new FileReader();

		reader.onload = function (e) {
			document.getElementById("image").src = e.target.result; //obtem info do campo foto
		};
		//carrega a imagem na tela
		reader.readAsDataURL(this.files[0]);
	};

	//prepara botao Limpar na acao de Editar cliente
	document.getElementById("btnLimpar").onclick = function () {
		restauraForm();
	};
}

function restauraForm() {
	//limpa quadro preview imagem
	document.getElementById('image').src 		= '';
	//limpa os campos id e nomeFoto usados no update
	document.getElementById('id').value  		= "-1";
	document.getElementById('nomeFoto').value  	= "";
	//retorna o label original dos botoes
	document.getElementById('btnLimpar').value 	= "Limpar";
	document.getElementById('btnSalvar').value 	= "Salvar";
}

//*****************************************************************************
// Metodo que altera a cor do input quando recebe o foco
//
function inputOn( obj ) {
	obj.style.backgroundColor = "#ffffff";
}

//*****************************************************************************
// Metodo que altera a cor do input quando perde o foco
//
function inputOff( obj ) {
	obj.style.backgroundColor = "#7e83a2";
}

//*****************************************************************************
// Metodo que carrega lista de clientes cadastrados
//
function carregarLista() {
	var xhttp;
	xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
    	if (this.readyState == 4 && this.status == 200) {
      		document.getElementById('lista').innerHTML = this.responseText;
    	} else {
    		document.getElementById('lista').innerHTML = "Erro na execucao do Ajax";
    	}
  	};
  	xhttp.open("POST", "crud.php", true);
  	xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  	xhttp.send("action=lista");
}

//*****************************************************************************
// Metodo que carrega lista de clientes cadastrados
//
function carregarCliente( obj ) {
	var xhttp;
	xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
    	if (this.readyState == 4 && this.status == 200) {
      		var resultado = JSON.parse( this.responseText );
      		//preenche form com dados do cliente para alteracao
      		document.getElementById('id').value 		= resultado[0].id;
      		document.getElementById('nome').value 		= resultado[0].nome;
			document.getElementById('dnascimento').value 		= resultado[0].dnascimento;
      		document.getElementById('email').value 		= resultado[0].email;
      		document.getElementById('telefone').value 	= resultado[0].telefone;
      		document.getElementById('image').src 		= "/crud/imagens/"+resultado[0].foto;
      		document.getElementById('nomeFoto').value 	= resultado[0].foto;
      		//deixa o foco no campo nome para edicao
      		document.getElementById('nome').focus();
      		//modifica acao do botao limpar para voltar
      		document.getElementById('btnLimpar').value 	 = "Voltar";
      		//modifica acao do botao salvar para atualizar
      		document.getElementById('btnSalvar').value 	 = "Atualizar";
    	} else {
    		document.getElementById('msg-php').innerHTML = "Erro na execucao do Ajax";
    	}
  	};
  	xhttp.open("POST", "crud.php", true);
  	xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  	xhttp.send("action=buscar&id="+obj);
}

//*****************************************************************************
// Metodo que carrega lista de clientes cadastrados
//
function excluirRegistro( obj ) {
	if ( confirm("Clique em OK para confirmar a operação.") ) {
		var xhttp;
		xhttp = new XMLHttpRequest();
		xhttp.onreadystatechange = function() {
	    	if (this.readyState == 4 && this.status == 200) {
	      		//exibe mensagem de sucesso na tela por alguns segundos
	      		document.getElementById('msg-php').innerHTML = this.responseText;
	      		document.getElementById('msg-php').classList.remove("no-display");
	      		document.getElementById('msg-php').classList.add("msg-php");
	      		hideMsg();
	  			//atualiza lista de clientes
	  			carregarLista();
	    	} else {
	    		document.getElementById('msg-php').innerHTML = "Erro na execucao do Ajax";
	    	}
	  	};
	  	xhttp.open("POST", "crud.php", true);
	  	xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	  	xhttp.send("action=excluir&id="+obj);
  	}
}

//*****************************************************************************
// Metodo que salva (ou atualiza) form de cadastro do cliente
//
function salvarForm() {
	var xhttp;
	xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
    	if (this.readyState == 4 && this.status == 200) {
    		//limpa o formulario
    		restauraForm();
    		document.getElementById('frmCrud').reset();
    		//exibe mensagem de sucesso na tela por alguns segundos
      		document.getElementById('msg-php').innerHTML = this.responseText;
      		document.getElementById('msg-php').classList.remove("no-display");
      		document.getElementById('msg-php').classList.add("msg-php");
      		hideMsg();
  			//atualiza lista de clientes
  			carregarLista();
    	} else {
    		document.getElementById('msg-php').innerHTML = "Erro na execucao do Ajax";
    	}
  	};
  	//recupera valores do form para enviar via ajax
  	var formData = new FormData();
  	formData.append("id", document.getElementById("id").value);
  	formData.append("nome", document.getElementById("nome").value);
	formData.append("dnascimento", document.getElementById("dnascimento").value);
  	formData.append("email", document.getElementById("email").value);
  	formData.append("telefone", document.getElementById("telefone").value);
  	formData.append("foto", document.getElementById("foto").files[0]);
  	formData.append("nomeFoto", document.getElementById("nomeFoto").value);
  	//submete para server-side
  	//xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  	xhttp.open("POST", "crud.php?action=salvar", true);
  	xhttp.send( formData );
}

//*****************************************************************************
// Metodo que oculta as mensagens de alerta na tela
//
function hideMsg() {
	setTimeout(function() {
      	document.getElementById('msg-php').classList.add("no-display"); 
    }, 5000);
}

Só é permitido um legend por fieldset. Você deve usar labels para os campos. Ademais, acredito ser melhor você usar date para o campo data, ao invés de text.
Nesta ferramenta, https://www.freeformatter.com/html-validator.html, é mostrado o seguinte erro e vários outros do mesmo tipo para os mesmos elementos legend:
Element “legend” not allowed as child of element “fieldset” in this context. (Suppressing further errors from this subtree.)

From line 7, column 5 to line 7, column 12

Code Extract:
s)"/>↩ Nasci