Regiões Vivas (Live Region)

Regiões vivas são regiões percebíveis de uma página web que são normalmente atualizadas como resultados de um eventos externos, enquanto o foco do usuário pode estar em outro lugar. As atualizações em tais regiões não são sempre resultado de uma interação direta do usuário. Este tipo de evento é bastante comum em aplicações que usam AJAX.

Exemplos de Regiões Vivas são: histórico de conversas em um chat, atualização de mensagens em um placar ao vivo de um evento esportivo. Como essas atualizações assíncronas ocorrem em regiões diferentes de onde está o foco do usuário, TA não são informadas sobre os novos conteúdos e, consequentemente, não informam os usuários. As Regiões Vivas provêem condições para que tais regiões possam ser identificadas e monitoradas. Assim atualizações assíncronas podem ser notificadas aos usuários, por meio das TA.

Exemplo de região viva: Código com WAI-ARIA

Dica: Veja como testar o exemplo em Como testar o seu código.


Documento: liveregion.html.

<!DOCTYPE html>
<html lang="pt-br">
    <head>
		<title>Regiões vivas (Live Regions)</title>
		<link rel="stylesheet" type="text/css" href="estilo.css">
		<script type="text/javascript" src="../libs/jquery.js"></script>
        <script type="text/javascript" src="script.js"></script>
        <meta charset="utf-8" />        
    </head>
	
    <body aria-hidden="true">
	
		<h1>Regiões vivas (<span lang="en">Live Regions</span>)</h1>
	
	    <fieldset id="area">
			<legend lang="en">Chat</legend>
			<div class="messageLog">
				<ul id="LiveRegion1" aria-live="polite" aria-relevant="additions" 
					aria-atomic="false" aria-busy="false"></ul>        
			</div>
	    </fieldset>
        
        <div id="configuracoes">
            
			<fieldset>
				<legend lang="en">Aria Live</legend>
                <label for="polite" lang="en">
					<input type="radio" name="live" value="polite" id="polite" checked>
						polite</label><br>
                <label for="off" lang="en"><
					input type="radio" name="live" value="off" id="off">
						off</label><br>
                <label for="assertive" lang="en">
					<input type="radio" name="live" value="assertive" id="assertive">
						assertive</label>
			</fieldset>
			
			<fieldset>	
				<legend lang="en">Aria Relevant</legend>
                <label for="additions" lang="en">
					<input type="radio" name="relevant" value="additions" id="additions" checked>
						additions</label><br>
                <label for="text" lang="en">
					<input type="radio" name="relevant" value="text" id="text">
						text</label><br>
                <label for="additiontext" lang="en">
					<input type="radio" name="relevant" value="addition text" id="additiontext">
						addition text</label><br>
                <label for="all" lang="en">
					<input type="radio" name="relevant" value="all" id="all">
						all</label>
			</fieldset>
				
			<fieldset>
				<legend>Intervalo entre mensagens</legend>
				<label for="intervalo">
					<input type="number" name="intervalo" id="intervalo" min="1" max="30" 
						step="1" value="5">segundos</label>
			</fieldset>
			
			<input type="button" value="iniciar exemplo" id="botao"><br>
        </div>
    </body>
</html>

Folha de estilo: estilo.css.

body {
    font-family: "Segoe UI", "Arial", "Helvetica", "sans-serif";
	font-size: 18px;
} 
#area {
    position:relative;
    left:37%;
    top:29%;
    width:320px;
    height:270px;
}
fieldset {
    width:320px;
    padding: 0;
    margin: 0;
}
.messageLog  {
	width: 98%;
	height: 220px;
	margin-left: 0.1em;
	overflow: auto;
}
#area legend {font-size: 2em;}
#LiveRegion1 {
	list-style-type:none;
	margin: 0;
	padding: 0.3em;
}
.chat li{list-style-type: none;}
#texto{
	position: relative;
	left: 37%;
	top: 29%;
	width: 318px;
	height: 50px;
	resize: none;
	overflow: auto;
}
#enviar{
    position: relative;
	left: 37%;
}
#configuracoes{
	position: relative;
	left: 37%;
	top: 29%;
	width: 320px;
}

Script: script.js.

$(function () {

    var mensagens = ["oi", "oi, como vai?", "vou bem, e você?", "vou bem também, obrigado!", 
					 "você foi bem na prova de física?", "acho que sim, o resultado sai na terça!", 
					"humm, tomara que sim,", "Vamos torcer :)"];
    var i = 0;

    function exibirMensagem() {
        $("#LiveRegion1").append('<li class="chat"><b>Fulano: </b>' + mensagens[2 * i] + '</li>');
        $("#LiveRegion1").append('<li class="chat-b"><b>Beltrano: </b>' + mensagens[2 * i + 1] + '</li>');
        i++;
        
        if (i == 4) //zerar o contador
            i = 0;
    }

    var myTimer;
    $('#botao').click(function () {
        if ($(this).val() == "iniciar exemplo") {		
			$('input:radio[name=live]').attr("disabled","disabled");
			$('input:radio[name=relevant]').attr("disabled","disabled");
			$('#intervalo').attr("disabled","disabled");

			$(this).val("parar");
            $('body').attr('aria-hidden', 'false');
            myTimer = window.setInterval(exibirMensagem, $('#intervalo').val()*1000);
        } else {
			$('input:radio[name=live]').removeAttr("disabled");
			$('input:radio[name=relevant]').removeAttr("disabled");
			$('#intervalo').removeAttr("disabled");	
			
            $(this).val("iniciar exemplo");
            $('body').attr('aria-hidden', 'true');
            clearInterval(myTimer);
        }
    });

    $('input:radio[name=live]').click(function () {
        $('#LiveRegion1').attr("aria-live", $(this).attr("value"));
    });

    $('input:radio[name=relevant]').click(function () {
        $('#LiveRegion1').attr("aria-relevant", $(this).attr("value"));
    });
});

Alertas (Alert e AlertDialog)

Alertas são um tipo de região viva que contém informações importantes e, geralmente, sensíveis ao tempo (eventos). Os alertas são usados para avisar o usuário de algo que ocorreu ou está ocorrendo em um certo momento.

Há dois tipos de alertas, o papel alert e a sua especialização alertdialog.

As alerts são regiões vivas assertivas, dessa maneira criadores de RIA e navegadores Web não necessitam gerenciar o foco para os alertas. Consequentemente, usuários não devem ter que fechar um alerta. A Figura 1 ilustra a aparência comum de alert.

Ilustração de formulário com campos para nome, idade e um botão enviar. Logo abaixo do botão há uma mensagem de alerta que diz: Você deve informar o seu nome. A mensagem tem uma borda vermelha.
Figura 1. Exemplo de mensagem de alerta usando o papel alert.

Já o alertdialog requer que o foco seja alterado para um elemento dentro do alertdialog (geralmente um dos botões do diálogo). A apresentação deve ser no estilo modal, ou seja, a navegação deve ficar somente no alertdialog até que ele seja fechado. Um alertdialog é composto pela mensagem de alerta e o demais elementos para o diálogo. A Figura 2 ilustra a aparência comum de alertdialog.

Ilustração de formulário com campos para nome, idade e um botão enviar. O formulário está em cores de tom cinza, indicando que está desabilitado. Sobre o formulário está a caixa de diálogo do alerta, com borda vermelha. Nela há uma mensagem de alerta que diz: Você deve informar o seu nome. Logo abaixo, ainda dentro da caixa há uma pergunta: Deseja tentar novamente? Em seguida há dois botões: sim e não.
Figura 2. Exemplo de mensagem de alerta usando o papel alertdialog.

Propriedades para os papeis alert e alertdialog: aria-atomic, aria-controls, aria-describedat, aria-describedby, aria-dropeffect, aria-flowto, aria-haspopup, aria-label, aria-labelledby, aria-live, aria-owns, aria-relevant.

Para o papel alertdialog há ainda uma propriedade adicional: aria-modal.

Estados para os papeis alert e alertdialog: aria-busy, aria-disabled, aria-expanded, aria-grabbed, aria-hidden, aria-invalid.

Exemplo de papel alert: Código com WAI-ARIA

Dica: Veja como testar o exemplo em Como testar o seu código.


Documento: alert.html.

<!DOCTYPE html>
<html lang="pt-br">
    <head>
        <meta charset="UTF-8">
        <title>Exemplo do Papel Alert</title> 

        <link rel="stylesheet" type="text/css" href="estilo.css">
        <script type="text/javascript" src="../libs/jquery.js"> </script>
        <script type="text/javascript" src="script.js"> </script>
    </head>

    <body>

<h1>Papel <span lang= "en">Alert</span></h1>

<fieldset id="area">
    <legend>Formulário</legend>

	    <p>Campos obrigatórios marcados com *.</p>
		
		<p role="alert" id="alerta">Falha ao enviar!</p>
		
	    <label id="descNome">Nome* 
			<input type="text" name="nome" id="nome" placeholder="nome" 
				class="nome" required></label>

	    <label for="sobrenome">Sobrenome* 
			<input type="text" name="sobrenome" id="sobrenome" placeholder="sobrenome" 
				class="sobrenome" required></label>
	
	    <label for="email">E-mail* 
			<input type="text" name="email" id="email" placeholder="e-mail" 
				class="email" required></label>
	
	    <label for="senha">Senha* 
			<input type="password" name="senha" id="senha" placeholder="senha" 
				class="senha" required></label>
	
	    <input id="enviar" type="button" name="submit" value="enviar dados" 
			onkeypress="this.onclick();">

        </fieldset>
    </body>
</html>

Folha de estilo: estilo.css.

body {
	font-family: "Segoe UI", "Arial", "Helvetica", "sans-serif";
	font-size: 18px;
} 

#area{
    position:relative;
    left:37%;
    top:29%;
    width:320px;
    height:370px;
}

fieldset{
    width:300px;
    height:300px;
}
 
legend{
	font-size: 28px;
	text-align: center;
}

label {display: block; margin-bottom: 1em;}

input {
	border: solid rgb(170, 170, 170) 0.1em;
} 
 
input.nome{
    position:absolute;
    left:115px;
    width:200px;
}
input.sobrenome{
    position:absolute;
    left:115px;
    width:200px;
}
input.email{
    position:absolute;
    left:115px;
    width:200px;
}

input.senha{
    position:absolute;
    left:115px;
    width:200px;
}

#descNome{
    margin-top: 102px;
}

#alerta{
    position: absolute;
	display: none;
	color: red;
}

Script: script.js.

/*arquivo JavaScrip do Alert Role*/
$(function() {
    function isEmail(email) {
        var regex = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        return regex.test(email);
    }

	function setInputStyle(element, type) {
		if (type == "alert")
			$(element).css("border","solid #F00 0.1em");
		else if (type == "normal")
			$(element).css("border","solid rgb(170, 170, 170) 0.1em");			
	}
	
    $("#enviar").click(function() {
			
        var camposInvalidos = "";

        if($("#nome").val() == '') {
			setInputStyle("#nome","alert");
            camposInvalidos = "Por favor insira um nome";
		} else
			setInputStyle("#nome","normal");
		
        if($("#sobrenome").val() == '') {
			setInputStyle("#sobrenome","alert");
            camposInvalidos += camposInvalidos.length == 0 ? 
				"Por favor insira um sobrenome" : ", um sobrenome";
		} else
			setInputStyle("#sobrenome","normal");

        if(isEmail($("#email").val()) == false) {
			setInputStyle("#email","alert");
            camposInvalidos += camposInvalidos.length == 0 ? 
				"Por favor insira um email válido" : ", um email válido";
		} else
			setInputStyle("#email","normal");

        if($("#senha").val() == '') {
			setInputStyle("#senha","alert");
            camposInvalidos += camposInvalidos.length == 0 ? 
				"Por favor insira uma senha" : ", uma senha";
		} else
			setInputStyle("#senha","normal");
		
		$("#alerta").css("display","block");
		if (camposInvalidos.length > 0) {
			$("#alerta").css("color","#F00");
			camposInvalidos += ".";			
			$("#alerta").text(camposInvalidos);
		} else {
			$("#alerta").css("color","#0A0");
			$("#alerta").text("Dados enviados com sucesso.");
		}
    });
});