Eu passei por uma situação parecida. Para fazer essa seleção de estado e cidade acabei optando por usar um zoomField (http://tdn.totvs.com/pages/releaseview.action?pageId=75270483#DesenvolvimentodeFormulários-Zoom).
Após carregar os campos de um zoom eu deixo o outro bloqueado e na function setSelectedZoomItem(selectedItem) eu utilizei o método reloadZoomFilterValues que recarrega os valores de um zoomField criando o filtro assim no dataSet de cidade.
function setSelectedZoomItem(selectedItem) {
if(selectedItem.inputName == "estado") {
reloadZoomFilterValues("cidade", "idUf," + selectedItem.id);
}
}
O método setSelectedZoomItem é executando sempre que trocado o valor de um zoomField.
O método reloadZoomFilterValues cria uma constraint para o campo passado ("idUf," + selectedItem.id), no dataset do zoomDestino ("cidade") e atualizando os valores do zoomField.
Exemplo de zoomField para cidade consultando do dataset dsCidades trazendo o nome da cidade como resultado:
<div class="form-group">
<label class="label-fields" for="tipo">Cidade</label>
<div class="input-group">
<input type="zoom" class="form-control" name="cidade" id="cidade"
data-zoom="{'displayKey':'nome','datasetId':'dsCidades','fields':[
{'field':'nome','label':'Cidade','standard': 'true', 'search':'true'}
]}">
<div class="input-group-addon zoom-preview">
<span class="fluigicon fluigicon-zoom-in"></span>
</div>
</div>
</div>
EDIT: código DataSet: No código eu crio um SQL e monsto os filtros para esse SQL com as constraints passadas.
A constraint nome filtra quando é digitado algo no ZoomField.
A constraint idUf é o filtro de estado.
function getSQL(constraints) {
var filtro = "";
if (constraints != null) {
for (var i = 0; i < constraints.length; i++) {
if (constraints[i].fieldName == "nome") {
filtro += " and descricao like UPPER('%" +constraints[i].initialValue + "%')";
}
if (constraints[i].fieldName == "idUf" && constraints[i].initialValue && constraints[i].initialValue != "") {
filtro += " and idUnidadeFederativa = " + constraints[i].initialValue;
}
}
}
return ' select idUnidadeFederativa, idCidade, descricao'+
' from cidade'+
' where idnAtivo = 1'+
filtro +
' order by descricao';
}