0
votes

I've got a listbox of items where I allow multi select. I am trying to get the latest most recent item selected, not the order value, but what the user selected last.

If I try to print out .val() I get a list of the selected values, but I want the most recent (the last one in val()).

I tried using :last like so:

$("#MainContent_lbTeams option:selected:last").val();

But last works on order of ID's from ascending to descending, doesnt work on time when someone selects a value.

For instance if I have a list box of 4 items. If I select them in ascending order what I posted above prints correctly. But if I click the 1st, then the 4th, and back to the 2nd what I posted above prints the 4th item (even though I most recently selected the 2nd one).

//when a team is selected
//tell the user what this does to the record
$("#MainContent_lbTeams").on('change', function () {
    //was a value selected?
    var latest_value = $("#MainContent_lbTeams option:selected:last").val();
    var latest_text = $("#MainContent_lbTeams option:selected:last").text();
    alert(latest_value);
    alert(latest_text);
    if ($("#MainContent_lbTeams :selected").length > 0) {
        $("#MainContent_lblTeamMembers").text("Members of '" + latest_text + "':");
        // act only when the returned promise is resolved
        PopulateMembers(latest_value).then(function () {
            $("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
        });
    }
});

Is there something else I can use to pick up the latest selected value of my multiselect listbox?

2

2 Answers

0
votes

Not sure if there is a better way but because it's multi you can find an array of objects for all the added ones in added and removed ones in removed.

$('select').on('change', function () {
    var latest_value = $(this).data('value') || {},
        latest_text = $(this).data('text') || {},
        new_value = {},
        new_text = {},
        added = [],
        removed = [];

    $("option:selected", this).each(function(){
        new_value[$(this).val()] = true;
        new_text[$(this).text()] = true;
        if($(this).val() in latest_value){
            delete latest_value[$(this).val()];
            delete latest_text[$(this).text()];
        }else{
            added.push({value: $(this).val(), text: $(this).text()});
        }
    });

    for(v in latest_value){
        removed.push({value: latest_value[v], text: latest_text[v]});
    }

    console.log('added', added);
    console.log('removed', removed);

    $(this).data({value: new_value, text: new_text});
});

DEMO

0
votes

I ended up doing something a bit different. Given that the .val() for a multi select is stored as an array, I took the difference between the two arrays. Here is what I ended up with:

            var myTeam = [];
        $("#trMembers").hide();
        $("#MainContent_lbTeams").on('change', function () {
            //was a value selected?
            //store the difference of what teams are selected vs myTeam[]
            var diff = [];
            jQuery.grep($("#MainContent_lbTeams").val(), function (el) {
                if (jQuery.inArray(el, myTeam) == -1) diff.push(el);
            });

            if (diff.length > 0) {
                var latest_value = diff; //has the latest selected value
                var latest_text = $("#MainContent_lbTeams option[value='" + diff + "']").text(); //stores the text
                if ($("#MainContent_lbTeams :selected").length > 0) {
                    $("#dTeamNotice").show();
                    $("#MainContent_lblTeamMembers").text("Members of '" + latest_text + "':");
                    // act only when the returned promise is resolved
                    PopulateMembers(latest_value).then(function () {
                        $("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
                        $("#trMembers").fadeIn();
                    });
                } else {
                    //hide it...
                    $("#dTeamNotice").css("display", "none");
                    $("#trMembers").hide();
                }
            }
            myTeam = $("#MainContent_lbTeams").val();
        });