Fazer partial postback em eventos de jquery
Desde ontem que ando "a lutar" com o JQuery e o Microsoft Ajax. Não é que os dois não se dêem bem, mas por vezes eu acho que a Microsoft "esconde" muita coisa.
Pois bem eu estou a criar uma página que basicamente tem uma lista num lado e podemos pegar num item e arrasta-lo para a lista ao lado. Como pretendo manter guardado no viewstate em qual das listas está o elemento, quero fazer um postback para o servidor sem ter que recorrer a botões ou outros controlos asp.net.
O meu primeiro problema foi com o drag & drop pois ao criar os objectos draggable, apesar de poder especificar qual o containment (área onde o objecto pode ser arrastado) e o appendTo (elemento HTML onde o clone do meu objecto vai ser recriado enquanto está a ser arrastado), não consegui passar uma referência ao parent do parent do objecto draggable pois apenas podemos passar um objecto de JQuery, um elemento ou uma string predeterminada (embora parent fosse uma delas).
Baseado apenas em blind luck consegui atingir o efeito desejado simplesmente colocando assim:
appendTo: 'parent',
containment: $(this)
Ainda não sei o porquê de funcionar para ser sincero. Mas funciona. A razão de eu precisar de conseguir obter uma referência ao parent do parent é o facto de eu ter 2 listas exactamente iguais e não queria ter de repetir código. Mas para ter uma ideia melhor do que quero dizer, as listas eram as duas iguais a essa:
<div class="items_drag_area">
<asp:UpdatePanel ID="upUserItems" EnableViewState="false" UpdateMode="Conditional" runat="server"><ContentTemplate>
<div class="contentBlock offeredItemsBlock">
<div class="contentBlock blockTitle">Tu dás</div>
</div>
<div class="contentBlock userItemsBlock">
<div class="contentBlock blockTitle">Os teus jogos</div>
<div class="user_games">
<asp:Repeater ID="rptUserItems" runat="server">
<ItemTemplate>
<div class="user_item rounded_corners5">
[...]
O último problema foi mesmo o postback parcial, que ainda andei um bom tempo à procura de uma solução elegante. Até que finalmente me deparei com um post do Luis Abreu, onde por fim conseguiu perceber como fazer um postback parcial por javascript (mesmo não sendo a solução elegante que procurava). De qualquer forma um problema mantinha-se, sempre que fazia postback, este não era parcial. O problema é que eu estava a tentar "inventar" um controlo que não existia. O mais certo é o ScriptManager procurar o elemento pelo ID e caso não encontre dá erro. Assim a solução foi mesmo colocar um input para satisfazer os caprichos do AJAX.NET: <input type="hidden" id="changedTradeItem" />
A verdade é que passei algumas horas a tentar perceber algumas coisas para tentar fazer as coisas da forma correcta. Mas ás vezes parece que não há uma forma correcta de o fazer assim sendo temos que nos basear no: "se funciona não mexas" ;) De qualquer forma para quem estiver a passar pelo mesmo aqui fica o pouco que já fiz do javascript para lidar com o drag & drop e os postbacks parciais.
/// <reference path="../../scripts/jquery-1.3.2-vsdoc2.js" />
/// <reference path="../../scripts/jquery-ui-vsdoc_1.js" />
/// <reference path="../../scripts/trokas.js" />
/// <reference name="MicrosoftAjax.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />
$(document).ready(function() {
$('.items_drag_area').each(function() {
$(this).find('.user_item').draggable({
revert: 'invalid',
zIndex: 2700,
helper: 'clone',
appendTo: 'parent',
containment: $(this)
});
});
$('.offeredItemsBlock').droppable({
drop: function(event, ui) { __doPostBack("changedTradeItem", $(ui.draggable).children('.droppable_tradeItemId').val()); }
});
});
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function() {
Sys.WebForms.PageRequestManager.getInstance()._asyncPostBackControlClientIDs.push("changedTradeItem");
});