przeładowanie div-a, widok się nieładnie przesuwa

0

Witam,
Strona wyświetla użytkowników których można zaprosić do znajomych klikając w przycisk. Po kliknięciu wykonuje się kod ajax i metoda w kontrolerze, po zaproszeniu zamiast przycisku pojawia się napis "Wysłano zaproszenie". Widok dla każdego takiego użytkownika którego można zaprosić jest wyświetlany za pomocą takiego widoku częściowego:

@using System.Security.Claims;
@using Domain.Entities.User;
@model ApplicationUser

<div class="singleUserinformation">
    @if (Model.HasProfilePicture())
    {
        <img class="img-rounded" src="@Model.ProfilPicture.Picture.PhotoString" />
    }
    else
    {
        <img class="img-rounded" src="~/images/anonim_men.jpg" />
    }
    <br />

    <span>@Model.UserName</span> <br />
    <span>@Model.FirstName</span> <br />
    <span>@Model.LastName</span> <br />

        @{
            RelationshipBetweenUsers relationshipBetweenUsers = Model.GetRelationshipWithUser(User.GetUserId());

            if (relationshipBetweenUsers == RelationshipBetweenUsers.NoRelationship)
            {
                <button type="button" onclick="SendInvitationToFriends('@Model.Id', '@Model.UserName')">Zaproś do znajomych</button>
            }
            else if (relationshipBetweenUsers == RelationshipBetweenUsers.SendedInvitationToFriends)
            {
                <p>Wysłano zaproszenie</p>
            }
            else if (relationshipBetweenUsers == RelationshipBetweenUsers.ReceivedInvitationToFriends)
            {
                <p>Zaakceptuj zaproszenie</p>
            }
            else if (relationshipBetweenUsers == RelationshipBetweenUsers.Friends)
            {
                <p>Już jesteście znajomymi</p>
            }
        }
</div>
 

Funkcja js:

 function SendInvitationToFriends(userId, userName) {
    $.ajax({
        url: '/Friends/SendInvitationToFriends',
        method: 'GET',
        contentType: "application/json; charset=utf-8",
        data: { userId: userId },
        context: document.body,
        success: function () {           
            var element = $(".singleUserinformation > span:contains(" + userName + ")").parent();
            if (element != null) {
                element.load("/User/DisplayUserPartial", { userId: userId });
            }
        }
    });
}

Div się przeładowuje z poprawną treścią, jednak wartości marginesów, paddingu i obramowania się sumują ze starymi wartościami przez co wszystko się nieładnie przesuwa.
Jak temu zaradzić?

Jeszcze kod css:

.singleUserinformation {
    padding:10px;
    margin:10px;
    background-color:aliceblue;
    border:1px solid black;
    height:auto;
    text-align:center;
    width:250px;
    float:left;
}

.singleUserinformation img {

    width:100px;
    height:100px;
    border:1px solid black;
}
 
0

Twój "partial" zwraca html z rootem w <div class="singleUserinformation">. Twój js z kolei przeładowuje zawartość tego .singleUserinformation, ale zauważ, że nie podmienia samego rodzica, tylko ładuje jego zawartość. W efekcie do środka .singleUserinformation ładujesz .singleUserinformation. Musisz albo zastąpić ten istniejący element zaciągniętym, albo dodać do istniejącego tylko dzieci zaciągniętego.
Zresztą zobacz drzewko html pod jakimś narzędziem webdeveloperskim w przeglądarce (np. FireBug w FF).

A tak przy okazji - dużo rzeczy bym zrefaktorował. Masz złe nazewnictwo i nawyki. Po kolei:

  1. Skoro view jest używane jako osobna strona, to nie jest partialem, dlatego nie powinno mieć "partial" w nazwie.
  2. singleUserinformation -> camel case się kłania, singleUserInformation, a najlepiej user-info-container, albo user-info. Poza tym w html i css przyjęła się składnia z oddzielaniem członów nazwy myślnikami, którą zresztą stosujesz w img-rounded - nie mieszaj składni.
  3. img-rounded - nazwy klas css nie powinny w sobie zawierać określenia wyglądu, bo co jeśli kiedyś zmienisz styl na kanciasty? Nazwy powinny odzwierciedlać to, do czego służą, np. profile-image, a nie to, co w środku robią (przykład złej nazwy - floated-to-right, top-left-button).
  4. Model.ProfilPicture.Picture.PhotoString - literówka w ProfilePicture. Ponadto nie PhotoString, bo to nie string ze zdjęciem (?), tylko url do zdjęcia, więc PhotoUrl, a że znajduje się już w klasie opisującej zdjęcie, to wystarczy samo Url. Ponadto nie za dużo tam tych Picture/Photo? Model.Profile.Photo.Url albo jeśli model to profil to Model.Photo.Url.
  5. Zamiast tych spanów z br użyj albo div, albo spanom nadaj styl display:block (to drugie jest słabsze, bo nieintuicyjne). Br nie służy do budowania layoutu.
  6. Gromadkę if'ów zastąp jednym switch z kilkoma case, a jeszcze lepiej - treść do wyświetlenia generuj nie w widoku, tylko w ViewModelu. View w idealnym świecie nie powinno zawierać żadnej logiki, żadnych if, co najwyżej pętle. Miejscem na logikę jest ViewModel. Ale to dość upierdliwe, bo restrykcyjne wymaganie, więc tylko zadbaj o to, żeby model był czytelny, a osiągniesz to w tym punkcie przez zastąpienie if'ów switch'em.
  7. Twój ajax nie obsługuje przypadku błędu.
0

Jeszcze 8 - ajax jest asynchroniczny, a Ty sobie zakładasz, że userId się nie zmieni pomiędzy rozpoczęciem wywołania SendInvitationToFriends a DisplayUserPartial. Wykonywanie zapytania do serwera może trwać nawet kilka-kilkanaście sekund - zastanów się, co się stanie, jeśli ktoś będzie chciał zaprosić pięć osób i będzie klikał po kolei nie czekając, aż serwer odpowie.

I jeszcze raz te DisplayUserPartial - to nie nazwa View, jak napisałem wcześniej, tylko nazwa akcji. Jak akcja może być partialem? Akcja sama z siebie też nic nie pokazuje, więc żadne tam "Display". GetUserTile albo GetUserShortProfile, a jeśli działasz w kontrolerze o nazwie User, to GetShortProfile, jeśli zaś kontrolerem jest Profile, to wtedy akcja np. GetTile. DisplayUserTile to może się nazywać funkcja js wyświetlająca kafelek z informacjami o użytkowniku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1