Problem
I'm building an order form that has the ability to add new items. Each item row consist of something like quantity, unit price, description, and total. Everytime you want to add a new item, you click an action and a new row is inserted below the original with a set of blank fields. The problem I'm facing is when the browser contains a scroll bar and the items are near the bottom of the screen. When you add a new item, the new item appears below the view requiring the user to have to manually scroll the page.
What I'm looking for.
I'm looking for a jquery solution that will,
- 1) detect the location of the previous item in the view.
- 2) after a new item has been inserted into the page via ajax, do a nice animated scroll of the page bringing the newly created item back to the exact position of the previous item.
What I've tried.
<div id="lineItemContainer">
<div class="tapestry-forminjector">
<div><input type="text" name="quantity"/></div>
<div><input type="text" name="unit price"/></div>
<div><input type="text" name="description"/></div>
<div><input type="text" name="total"/></div>
</div>
</div>
<div id="buttonContainer"><input type="submit" value="Add New Item"/></div>
//This event handler listens for new rows and is fired once the new row has been added.
$("#lineItemContainer div.tapestry-forminjector").live(Tapestry.AJAXFORMLOOP_ROW_ADDED, function(event){
// This provides zero animation and currently does not work.
var y = $(window).scrollTop();
$(window).scrollTop(y+176);
}
Thoughts I'm assuming the best solution would be to get the y view coordinate of the previous to last item once the new item has been added and then scroll the page until the last item is at the same y view coordinate. I'm just not sure how to accomplish this task.
Thanks in advance. Tapestry.AJAXFORMLOOP_ROW_ADDED event handler
UPDATE Requested by simon, the
$.widget("ui.tapestryFormInjector", {
options : {
show : "highlight"
},
_create : function() {
this.element.addClass("tapestry-forminjector")
},
destroy : function() {
this.element.removeClass("tapestry-forminjector");
$.Widget.prototype.destroy.apply(this, arguments);
},
trigger : function() {
var that = this, el = $("#" + this.options.element);
var successHandler = function(data) {
$(data).log("data");
$.tapestry.utils.loadScriptsInReply(data, function() {
// Clone the FormInjector element (usually a div)
// to create the new element, that gets inserted
// before or after the FormInjector's element.
var newElement = el.clone(false);
newElement.attr("id", data.elementId);
newElement.html(data.content);
newElement = that.options.below ? el.after(newElement) : el
.before(newElement);
newElement.effect(that.options.show);
newElement.trigger(Tapestry.AJAXFORMLOOP_ROW_ADDED);
});
};
$(this.options).log("this.options.url" + this.options.url)
$.tapestry.utils.ajaxRequest({
type : "POST",
url : this.options.url,
success : successHandler
});
}
});