0

The context behind my question is quite complex, so I'll try to simplify it as much as I can.

I'm making an application where the user selects an option from a select2 and based on that selection, an AJAX call is made to fill another select and based on that selection another select appears. I did this in the "Create" view and it works fine, but in the Edit view, all the selects must already be selected, so in this case I don't make an AJAX call; I just put the data from the database since I already know what option was selected and I just add the property selected to the option that was selected. This works fine. The problem is that this select has a change function (that is getting called properly), but for some reason, the selected option doesn't return anything when prompted for the data attributes it has. I made a manual test in the Chrome Console and this was the output:

enter image description here

As you can see in the picture, when I query for the element with the selected option, I get it whithout a problem, and I can even see that the data tags are there, but if I try to get it with the data function, it returns undefined. Also, if I try to assign the first line to a variable, it assigns a value of undefined.

Any ideas on why this is happening?

EDIT:

HTML Rendering:

<div class="row">
    <label for="objeto-relacionado" class="control-label"> Asociar a otro objeto</label>
    <select id="seleccion-objeto" class="select2" name="objeto-relacionado"
            style='background-color: #fff;'>
        <option value=''></option>
        <option value="sangria" ${(tipo == 'sangria') ? "selected" : ""}>
            Sangría
        </option>
    </select>
</div>
<c:choose>
    <c:when test="${accion == 'Create'}">

        <div id="fila-select-sangria" class="row" hidden="true">
            <label for="sangria" class="control-label"> Sangría por asociar</label>
            <select id="seleccion-sangria" name="sangria"
                    style='background-color: #fff;'>
                <option value=''></option>
            </select>
        </div>

        <div id="fila-select-dia" class="row" hidden="true">
            <label for="sangria" class="control-label"> Día por asignar</label>
            <select id="seleccion-dia" name="dia"
                    style='background-color: #fff;'>
                <option value=''></option>
            </select>
        </div>

    </c:when>
    <c:otherwise>
        <div id="fila-select-sangria" class="row">
            <label for="sangria" class="control-label"> Sangría por asociar</label>
            <select id="seleccion-sangria" name="sangria"
                    style='background-color: #fff;'>
                <option value=''></option>
                <c:forEach items="${sangrias}" var="sangria">
                    <c:if test="${sangria.getId_sangria() == id_sangria}">
                        <c:set var="sangria_seleccionada" value="${sangria}" /> 
                    </c:if>

                    <option value="${sangria.getId_sangria()}"
                            data-fecha-1="${sangria.getFecha_dia1()}"
                            data-fecha-2="${sangria.getFecha_dia2()}"
                            data-fecha-3="${sangria.getFecha_dia3()}"
                            ${(sangria.getId_sangria() == id_sangria) ? "selected" : ""}>
                        ${sangria.getId_sangria_especial()}
                    </option>
                </c:forEach>
            </select>
        </div>
        <div id="fila-select-dia" class="row">
            <label for="sangria" class="control-label"> Día por asignar</label>
            <select id="seleccion-dia" name="dia"
                    style='background-color: #fff;'>
                <c:if test="${sangria_seleccionada.getFecha_dia1() != null}">
                    <option value="1" ${(dia == 1 ? "selected" : "")}>Día 1</option>
                </c:if>
                <c:if test="${sangria_seleccionada.getFecha_dia2() != null}">
                    <option value="1" ${(dia == 2 ? "selected" : "")}>Día 2</option>
                </c:if>
                <c:if test="${sangria_seleccionada.getFecha_dia3() != null}">
                    <option value="1" ${(dia == 3 ? "selected" : "")}>Día 3</option>
                </c:if>
            </select>
        </div>
    </c:otherwise>
</c:choose>

Javascript code:

/*
 * Funciones de eventos
 */

$("#seleccion-objeto").change(function () {
    if ($(this).find("option:selected").val() === "sangria") {
        $.ajax({
            url: "/App/Module/Model",
            type: "GET",
            data: {"accion": "sangriasajax"},
            dataType: "json",
            success: function (datos) {
                generar_select_sangria(datos);
            }
        });
    }
});

function generar_select_sangria(datos) {

    $("#fila-select-sangria").show();

    var select_sangria = $("#seleccion-sangria");
    select_sangria.select2();

    select_sangria.change(evento_seleccionar_sangria);

    for (i = 0; i < datos.length; i++) {
        var elemento = datos[i];
        var opcion = $("<option>");
        opcion.val(elemento.id_sangria);
        opcion.text(elemento.identificador);
        opcion.data("indice", i);
        opcion.data("fecha-1", elemento.fecha_dia1);
        opcion.data("fecha-2", elemento.fecha_dia2);
        opcion.data("fecha-3", elemento.fecha_dia3);

        select_sangria.append(opcion);
    }
}

function evento_seleccionar_sangria() {
    $("#fila-select-dia").show();

    var select_dia = $("#seleccion-dia");
    select_dia.find("option").remove();
    select_dia.append($("<option>"));
    select_dia.change(evento_seleccionar_dia);

    var opcion_seleccionada = $(this).find("option:selected");
    alert(opcion_seleccionada.val());

    /* Here is where I am getting undefined while on the Edit option if using .data("fecha-x") or in the Create option if using .attr("data-fecha-x") so none of this ifs enter */

    if (opcion_seleccionada.attr("data-fecha-1") !== undefined) {
        var opcion = $("<option>");
        opcion.text("Día 1");
        opcion.val("1");
        select_dia.append(opcion);
    }
    if (opcion_seleccionada.attr("data-fecha-2") !== undefined) {
        var opcion = $("<option>");
        opcion.text("Día 2");
        opcion.val("2");
        select_dia.append(opcion);
    }
    if (opcion_seleccionada.attr("data-fecha-3") !== undefined) {
        var opcion = $("<option>");
        opcion.text("Día 3");
        opcion.val("3");
        select_dia.append(opcion);
    }

    select_dia.select2();
}

function evento_seleccionar_dia() {

    var dia = $(this).find("option:selected").val();
    var id_sangria = $("#seleccion-sangria").find("option:selected").val();

    $.ajax({
        url: "/App/Module/Model",
        type: "GET",
        data: {"accion": "caballossangriaajax", "dia": dia, "id_sangria": id_sangria},
        dataType: "json",
        success: function (datos) {
            agregar_muestra_caballos(datos);
        }
    });
}

function agregar_muestra_caballos(datos) {
    var lista_caballos = [];

    for (i = 0; i < datos.length; i++) {
        var elemento = datos[i];
        lista_caballos.push(elemento.numero);
    }

    agregarMuestra();
    $("#identificadores_" + (contador - 1)).select2("val", lista_caballos);
}

$(document).ready(function () {
    var tipo = $("#tipo-edicion").data("tipo");
    if (tipo === "sangria") {
        $("#seleccion-objeto").find("option[value=sangria]").prop("selected", true);
        $("#seleccion-objeto").select2();

        var select_sangria = $("#seleccion-sangria");
        select_sangria.select2();
        select_sangria.change(evento_seleccionar_sangria);

        var select_dia = $("#seleccion-dia");
        select_dia.select2();
        select_dia.change(evento_seleccionar_dia);
    }
});
  • 1
    try getting all `data` attributes and see if any data is there. call `.data()` – Cerlin Aug 20 '15 at 07:04
  • 1
    is the webpage is in iframe? – Akki619 Aug 20 '15 at 07:05
  • Looks like it is in top frame. – Praveen Kumar Purushothaman Aug 20 '15 at 07:06
  • 2
    Try calling with `attr('data-fecha-1')` once! – Guruprasad J Rao Aug 20 '15 at 07:07
  • 1
    *"if I try to assign the first line to a variable, it assigns a value of undefined."* - Assigning to the variable isn't really "returning" undefined: the console shows `undefined` because it just evaluated the `var` statement itself rather than the variable. `sangria` will not be undefined, it will refer to the jQuery object just created. – nnnnnn Aug 20 '15 at 07:16
  • @nnnnnn that's good information. – Akki619 Aug 20 '15 at 07:24
  • @nnnnnn Oh, yeah, you're right. That's a dumb mistake. I was too tired when doing those tests so I didn't notice that particular thing. – Jose Daniel Chacón Bogarín Aug 20 '15 at 17:31
  • @CerlinBoss I'm going to try that – Jose Daniel Chacón Bogarín Aug 20 '15 at 17:32
  • @CerlinBoss No, doing `.data()` return `Object {}` in Chrome's dev console – Jose Daniel Chacón Bogarín Aug 20 '15 at 17:34
  • As @guruprasad suggested try using an attrubute selector. If thats also not working then please post the entire rendered html. Both before and after initializing the select2 plugin – Cerlin Aug 20 '15 at 17:37
  • @CerlinBoss thanks for your responsiveness. As a matter of fact, `.attr("data-fecha-x")` works, but since I'm reutilizing the Create View code, now it's not working there. I stumbled upon this question: http://stackoverflow.com/questions/8707226/jquery-data-does-not-work-but-attrdata-itemname-does which says something about caching data values. In the Create view, I create the options through jQuery and in the Edit view I create them during the HTML rendering, so I guess the issue lies around there. I'm going to post the code – Jose Daniel Chacón Bogarín Aug 20 '15 at 17:44
  • The issue which is mentioned in that question is common if you use both attr and .data() at the same time. You can use either one of them. Regarding your current problem, it ill be good if we could see more html. – Cerlin Aug 20 '15 at 17:51
  • Done. The only solution I can come up with now is either changing the creation of the options after the AJAX calls in order for them to work with `attr("data-fecha-x")` or making a check if the action I'm in is either Edit or Create in the `evento_seleccionar_sangria` function which would be a horrible solution – Jose Daniel Chacón Bogarín Aug 20 '15 at 18:07
  • Or rendering the options without using AJAX, but on the long run that will affect performance, unfortunately – Jose Daniel Chacón Bogarín Aug 20 '15 at 18:09

1 Answers1

0

The only solution I could come up with was changing this:

function generar_select_sangria(datos) {

    $("#fila-select-sangria").show();

    var select_sangria = $("#seleccion-sangria");
    select_sangria.select2();

    select_sangria.change(evento_seleccionar_sangria);

    for (i = 0; i < datos.length; i++) {
        var elemento = datos[i];
        var opcion = $("<option>");
        opcion.val(elemento.id_sangria);
        opcion.text(elemento.identificador);
        opcion.data("indice", i);
        opcion.data("fecha-1", elemento.fecha_dia1);
        opcion.data("fecha-2", elemento.fecha_dia2);
        opcion.data("fecha-3", elemento.fecha_dia3);

        select_sangria.append(opcion);
    }
}

To this

function generar_select_sangria(datos) {

    $("#fila-select-sangria").show();

    var select_sangria = $("#seleccion-sangria");
    select_sangria.select2();

    select_sangria.change(evento_seleccionar_sangria);

    for (var i = 0; i < datos.length; i++) {
        var elemento = datos[i];
        var opcion = $("<option value=\""+ elemento.id_sangria + "\"" 
            + "data-fecha-1=\"" + elemento.fecha_dia1 +  "\"" 
            + "data-fecha-2=\"" + elemento.fecha_dia2 +  "\"" 
            + "data-fecha-3=\"" + elemento.fecha_dia3 +  "\"" 
            + ">");
        opcion.text(elemento.identificador);

        select_sangria.append(opcion);
    }
}

That raises me a question: Why are the data attributes from the HTML render not getting recognized by the jQuery code?