0

The value of previousDiv when i run the jQuery shown below is always: [ ]. I have tried several variations of the .prev() function including .prev('div'), and .prev() all with the same result.

Here is the jQuery:

$('.AddToRole').click(function(evt) {
var path = document.URL;
var thisUser = this.value;
var previousControl = $(this).prev('.AvailableRoles');
var newUserRole = previousControl[0].options[previousControl[0].selectedIndex].text;
var newHTML = "<button id='button_DeleteRole_" + newUserRole +"' class='DeleteRole' value=" + newUserRole + ">X</button>&nbsp;<label id='label_DeleteRole_" + newUserRole + "'>" + newUserRole + "</label><br />";
var previousDiv = $(this).prev('#DisplayUserRoles');
$(previousDiv).append(newHTML);

Here is the html/razor code in the page:

<div>
                    @* Display user email. *@
                    <h3>@user.Email</h3>
                    <div>
                        <div id="DisplayUserRoles">
                            @{
                                @* Display roles user belongs to. *@
                                foreach (var role in userRoles)
                                {
                                    @* Remove user from role button. *@
                                    <button id="button_RemoveFromRole_@user.Email" value="@role.RoleName" onclick="RemoveUserFromRole(this);">X</button>
                                    <label id="label_RemoveFromRole_@role.RoleName">@role.RoleName</label>
                                    <br />
                                }
                            }
                        </div>
                        <br />                            
                    @{                                                    
                        @* Create ListBox with roles user does not belong to. *@
                        var items = rolesUserDoesNotBelongTo.Select(i => new SelectListItem
                        {
                            Value = i.RoleName,
                            Text = i.RoleName
                        });

                        string listBoxId = "listboxRoles_";
                        listBoxId = listBoxId + user.Email;

                    }                            
                        @Html.ListBox(listBoxId, items, new { @class = "AvailableRoles" })
                        @* Add user to role button. *@
                        <button id="button_AddToRole_@user.Email" class="AddToRole" value="@user.Email">Add To Role</button>
                    </div>
                </div>

For the end result I am trying to add another button and label just before the closing div tag for #DisplayUserRoles.

Darren
  • 793
  • 5
  • 17
  • 30
  • probably just a typo: you're not closing the `click` event. `})` – RASG Oct 15 '12 at 02:11
  • 1
    We would need to see your actual HTML (from View/Source in the browser), not the template language to know how to traverse your HTML. – jfriend00 Oct 15 '12 at 02:18
  • I think the problem is that .prev() only selects the siblings of the same element type. In your case $(this) is a button so it has no other sibling and .prev() returns []. – nix Oct 15 '12 at 02:22

2 Answers2

1

.prev() does not work how you are using it. It gets the previous sibling element and then filters that by the selector you pass. It does NOT look for any previous sibling that matches the selector.

Thus, when you do both of these:

$(this).prev('.AvailableRoles');
$(this).prev('#DisplayUserRoles');

At least one of them will return no object unless the previous sibling is both .AvailableRoles and #DisplayUserRoles which I doubt is what you're looking for.


I'm not exactly sure I know what you're trying to do with these, but you could do this instead:

$(this).prevAll('.AvailableRoles').first();

And for the DisplayUserRoles, since there can only ever be one object with a given ID in the document, you can just do this:

$('#DisplayUserRoles');

These would get all previous siblings that match the selector and then get just the first one.


As I said in my comment, we could help a lot better if you posted the generated HTML (what a browser sees with View/Source) rather than you template code which we don't necessarily know what HTML it generates.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

As stated before, if there are no sibling elements of the selected element, .prev() returns an empty array. If this is the case, then check the closest parent element.

var previousControl = $(this).prev();

if (!previousControl.length) {
    previousControl = $(this).parent();
}

previousControl.toggleClass('bestClass'); // This is just an example function 
                                          // call on the element
CalMlynarczyk
  • 705
  • 2
  • 7
  • 12