martes, 19 de julio de 2016

Diálogo modal con Bootstrap, Javascript y jQuery

En el archivo *.js:

function Notas_Evaluciones_jQuery(NumNota) {
    var Contenedor = '#ContentPlaceHolder1_';

    $('.css' + NumNota).on('click', function (e) {
        $('#dlgEval').modal({
            keyboard: true,          //Puede cerrar el diálogo con ESC
            backdrop: 'static'      //Se cierra el diálogo sólo con los botones o ESC
        });

        $('#dlgEval').modal('show');


        return false;
    });

    return false;
}

En el archivo *.aspx:

<div class="modal fade" id="dlgEval" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
<div class="modal-content">
 <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Ficha de evaluación del participante</h4>
 </div>
 <div runat="server" id="divDlgEval" class="modal-body">          
 </div>
 <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
<button type="button" class="btn btn-primary">Guardar</button>
 </div>
</div>
  </div>
</div>

martes, 14 de junio de 2016

Crystal Reports 2008 - Servidor ocupado

Al iniciar Crystal Reports 2008, aparece un pequeño diálogo que dice: "No se puede completar esta acción porque el otro programa esta ocupado. Elija Cambiar a... para activar el programa ocupado y corregir el problema."


La solución es la siguiente:

1) Abrir el Administrador de tareas (CTRL + ALT + SUPR).
2) Ubicar la tarea Agent.exe y finalizarla.


3) En el pequeño diálogo que dice Servidor ocupado, hacer clic en el botón Reintentar.


4) Ahora que ya se pudo abrir Crystal Reports, en el menú Ayuda, desmarcar la opción Comprobar actualizaciones al iniciar.


5) Salir y volver a entrar para comprobar que ya se solucionó.

miércoles, 1 de junio de 2016

SP_HELPTEXT en MySQL

En MySql, el equivalente de sp_helptext de SQL Server se escribe así:

show create procedure Nombre_Procedimiento_Almacenado;

Por ejemplo: show create procedure pa_Encuestas_Sesion_Respuesta_INS;

El código del sp está en la columna Create Procedure de la tabla resultado.

lunes, 2 de mayo de 2016

Desactivar Ir a página anterior con tecla Retroceder (Backspace)

Hasta ahora, es el único código que funciona en los tres navegadores principales.

Javascript
=========
$(document).ready(function () {
    $(document).on("keydown", function (e) {
        if (e.which === 8 && !$(e.target).is("input:not([textarea]), [contentEditable], [contentEditable=true]")) {
            e.preventDefault();
        }

        if (e.which === 8 && !$(e.target).is("input:not([readonly]):not([type=radio]):not([type=checkbox])")) {

            e.preventDefault();
        }
    });
});

Quitar funcionalidad a un textbox DatePicker jQuery UI

Javascript / jQuery
==============

// boolEstado: true, false 

if (boolEstado) {
    $(Contenedor + 'txtFecSesion').datepicker('disable');
}
else {
    $(Contenedor + 'txtFecSesion').datepicker('enable');
}

Cruce de horarios

Como la validación del lado del servidor era demasiado lenta, implementé esta solución del lado del cliente, más sencilla.


Javascript
========

//Horario: 'MAR 11:44-19:15'
//HorarioList: 'MAR 09:15-11:45 - JUE 08:30-10:00 - SAB 09:15-1145'

function Cruce_De_Horario(Horario, HorarioList) {
    var Dias = Horario.split(' - ');
    var DiasList = HorarioList.split(' - ');
    var i = 0, k = 0;

    var Dia_Hora_I, Dia_Hora_K;
    var Dia_I, H1_I, H2_I, Dia_K, H1_K, H2_K;

    for (i = 1; i <= Dias.length; i++) {
        Dia_Hora_I = Dias[i - 1].split(' ');

        Dia_I = Dia_Hora_I[0];
        H1_I = new Date('2016/01/01 ' + Dia_Hora_I[1].split('-')[0]);
        H2_I = new Date('2016/01/01 ' + Dia_Hora_I[1].split('-')[1]);

        for (k = 1; k <= DiasList.length; k++) {
            Dia_Hora_K = DiasList[k - 1].split(' ');

            Dia_K = Dia_Hora_K[0];
            H1_K = new Date('2016/01/01 ' + Dia_Hora_K[1].split('-')[0]);
            H2_K = new Date('2016/01/01 ' + Dia_Hora_K[1].split('-')[1]);

            if (Dia_I == Dia_K) {
                if (H1_I >= H1_K && H1_I <= H2_K) {
                    if (H1_I.getHours() != H2_K.getHours() || H1_I.getMinutes() != H2_K.getMinutes()) {

                        return Dia_Hora_I[0] + ' ' + Dia_Hora_I[1] + '|' + Dia_Hora_K[0] + ' ' + Dia_Hora_K[1];
                    }
                }

                if (H2_I >= H1_K && H2_I <= H2_K) {
                    if (H2_I.getHours() != H1_K.getHours() || H2_I.getMinutes() != H1_K.getMinutes()) {

                        return Dia_Hora_I[0] + ' ' + Dia_Hora_I[1] + '|' + Dia_Hora_K[0] + ' ' + Dia_Hora_K[1];
                    }
                }
            }
        }
    }

    return '';
}

La idea es validar que no haya cruce de horario entre el curso seleccionado arriba, y los ya seleccionados abajo.




SweetAlert no muestra diálogo de confirmación después de grabar

Mi error fue no haber establecido a false la propiedad closeOnConfirm de la primera alerta, que desencadena en la segunda.

Debe ser así:

Javascript
=========

$(Contenedor + 'btnGuardar').click(function () {
Controles_Validar_Reiniciar();

if (!Controles_Validar()) {
return false;
}

Dialogo_ConfirmarRegistro();   //1° Alerta

return false;
});

function Dialogo_ConfirmarRegistro() {
    swal({
        title: "Confirmar registro de notas",
        text: "Las notas ingresadas van a ser registradas. ¿Desea continuar?",
        type: "warning",
        showCancelButton: true,
        confirmButtonClass: "btn-danger",
        confirmButtonText: "Sí",
        cancelButtonText: "No",
        closeOnConfirm: false,
        allowEscapeKey: true
    },
        function () {
            Registrar_Notas();            
        }
    );

    return false;
}

function Registrar_Notas() {
    var Contenedor = '#ContentPlaceHolder1_';
    var CodSemestre = $(Contenedor + 'ddlSemestre').val();
    var CodCompetencia = $(Contenedor + 'ddlCompetencia').val();
    var CodCarga = $(Contenedor + 'hdnCodCarga').val();
    var CodCurso = $(Contenedor + 'hdnCodCurso').val();  
    var CodNota = $(Contenedor + 'hdnNota').val();
    var CodFecha = $(Contenedor + 'txtFecSesion').val();
    var IdControl = '_txt' + CodNota + '_';
    var IdCheck = '_chkSinNota_';
    var arrNotas = new Array();
 
    $(Contenedor + 'dtgNotas .css' + CodNota).each(function (index) {
        var objNotas = {
            CodAlumno: '',
            CodNota: 0.00
        };

        objNotas.CodAlumno = $('#' + this.id.replace(IdControl, '_lblCodAlumno_')).text();

        if ($('#' + this.id.replace(IdControl, IdCheck)).is(':checked')) {          
            objNotas.CodNota = -1.00;
        }
        else {
            objNotas.CodNota = parseFloat(this.value);
        }

        arrNotas.push(objNotas);
    });

    var objParams = {
        Semestre: CodSemestre,
        CodCarga: CodCarga,
        CodCurso: CodCurso,
        CodCompetencia: CodCompetencia,
        NumNota: CodNota,
        FecSesion: CodFecha,
        arrNotas: arrNotas      
    };  

    var arg = Sys.Serialization.JavaScriptSerializer.serialize(objParams);

    MostrarEspera(true);

    Registrar_Notas_Call(arg, function (result) {
        var Entity = Sys.Serialization.JavaScriptSerializer.deserialize(result.split('~')[0]);

        MostrarEspera(false);

        if (Entity.Resultado == "1") {
            //2° Alerta: Success
            swal({
                title: 'Operación completada',
                text: 'Las notas ingresadas han sido registradas correctamente.',
                type: 'success',
                showCancelButton: false,
                confirmButtonClass: 'btn-info',
                confirmButtonText: 'Aceptar',
                closeOnConfirm: false,
                allowEscapeKey: false
            },
                function () {
                    Reiniciar_Formulario();   
                }
            );
        }
        else {
            Dialogo_Error(Entity.MsgError);   //2° Alerta: Error
        }

        $(Contenedor + 'hdnMsgError').val(Entity.MsgError);
        $(Contenedor + 'hdnMsgErrorBD').val(Entity.MsgBD);

        return false;
    });

    return false;
}

function Dialogo_Error(MsgError) {
    swal({
        title: 'Operación no completada',
        text: MsgError,
        type: "warning",
        showConfirmButton: false,
        showCancelButton: true,
        cancelButtonText: "Aceptar",
        closeOnConfirm: false,
        allowEscapeKey: true
    });

    return false;
}