CSJS XSP.partialRefreshGet does not seem to do the refresh - javascript

I have a xe:navigator (called navigator1) on an application layout in the Left Column. In the Right Column I have a dynamicContent control. in the onClick event of the navigator I do a partial refresh on navigator1 which works but the dynamicContent1 is not refreshed. I can do a full refresh and both will refresh, but at a performance price. I put this in the Client side of the onClick:
XSP.partialRefreshGet('#{id:dynamicContent1}');
return true
but when I do the dynamicContent1 is not refreshed. I think my syntax is correct. If on the server side I do a partial refresh on dynamicContent1 it refreshes it correctly but navigator1 is not refreshed. So the issue is can one do two partial refreshes on the same onClick event?

If I'm reading your question correctly, this is just a timing issue: when you define client-side code and server code in the same event, the client-side code is always executed first. So it's refreshing your dynamicContent control before it executes the navigator event.
Move the CSJS code to the onComplete property of the eventHandler. This property isn't surfaced in the "pretty panels" for events, so you'll need to navigate directly to the <xp:eventHandler /> tag (either in the Source XML or via the Outline), and you'll find onComplete listed under All Properties.
Placing the refresh code in onComplete will ensure that the second refresh doesn't occur until after the first one is completed, which will allow the second target to reflect any changes triggered by the event.
Bonus tip: you can also chain refreshes:
XSP.partialRefreshGet("#{id:div1}", {
onComplete: function() {
XSP.partialRefreshGet("#{id:div2}", {
onComplete: function() {
XSP.partialRefreshGet("#{id:div3}", {
onComplete: function() {
XSP.partialRefreshGet("#{id:div4}");
}
});
}
});
}
});
This allows you to refresh as many targets as you want, but the same rule applies: if you need any of the targets to be "aware" of changes to data or components made within an event, you'll need to trigger the start of the chain in the onComplete attribute of that event, not as the client-side code of the event itself.

Related

Session can't be updated when trigger button used jquery and ajax

when i click on a button that tries to modify the session's value on serverside, it runs very well:
$('#btn1').click(function() {
update_session('session.php?session=1');
});
But when i tried to trigger this button from another button:
$('#btn2').click(function() {
$('#btn1').click();
});
At that moment, the session isn't changed. I really don't understand because i saw in firebug that there was a POST to server by ajax with the correct arguments.
The problem may be caused by the fact that .click() does not execute the href attribute of an anchor tag.
Having it this way should work:
var clicked = function() {
update_session('session.php?session=1');
};
$('#btn1').click(clicked);
$('#btn2').click(clicked);
If it didn't work it is very likely a server side problem (as suggested by Oriol).

Run action on load and stay on same page

I am currently trying to run an action in my grails controller upon a page load in my application that will start a thread an continue with a task. I still have yet been able to successfully implement this in. This is my code:
$(document).ready(function(){
var $form = $("#background_thread");
$form.submit(function(e){
e.preventDefault();
$.post($(this).attr("background"), $(this).serialize(), function(data){
alert("should work" + data)
});
return false;
});
});
I cannot for the life of me figure out why it's not working. Is there some simple syntax I'm overlooking or a different way I should be doing this?
Update:
My form id is #background_thread and I am trying to do it asynchronously so that the page will still stay the same and my action will be run.
My script is run but fails on $form.submit(function(e){ and will not pass through.
You need to prevent the default behaviour on the event that has been generated.
$form.submit(function(e){
e.preventDefault();
// your code
}
Update:
You will certainly need to add the above regardless, once you get the overall script working. Also, please add your markup to the question. A few basic questions to make sure:
Is #background_thread the id of your form?
In your network tab in Chrome Inspector (or similar) is the request being fired off?
Is the markup being delivered asynchronously, as if it is, you will need to use .on to attach the event permanently, rather than just a basic selector?
Update 2:
Your form is being delivered asynchronously itself, therefore your event attaqchement must change to:
$(document).ready(function(){
$("body").on("submit", "#background_thread", function(e){
e.preventDefault();
$.post($(this).attr("background"), $(this).serialize(), function(data){
alert("should work" + data)
});
return false;
});
});
So, to explain, your event attachment was happening during document ready. Document ready fires, but the form hasn't been delivered to the DOM yet, so it doesn't have an attachment to it. Therefore, you use on() to permanently attach that event to that element for the lifetime of the entire page's rendering to the browser.
N.B. I attached it to body, to begin listening for submit at that point, in practice you would not do this for many reasons, you would attach it to the outermost point of AJAX replacement for the form, essentially, the nearest parent to the form that will be known on initial page load.
I hope that this has been of some use and good luck with your application.

jQueryMobile pagebeforechange get destination page id

I got some controls which are visible on each site. To move those controls to the page currently active, I am using the pagebeforechange event.
$(document).bind('pagebeforechange',function(e,data) {
var topageid=$(data.toPage).attr('id'); //MY QUESTION IS ON THIS LINE
console.log("Changing page to "+topageid);
$header = $('#myheader');
$footer = $('#myfooter');
$header.detach();
$footer.detach();
$header.prependTo(topageid);
$footer.appendTo(topageid);
});
The source code shown above works sometimes, sometimes not. That's because from time to time data.toPage contains only an url like ...index.html#mypage.
How to detect the id of the toPage in any case?
You could use the pagebeforeshow event rather than the pagebeforechange event. The difference is that the former fires after external pages have been added to the DOM and the latter fires before that occurs.
There are other page-events that could work for you: http://jquerymobile.com/demos/1.2.0/docs/api/events.html
From the documentation (linked-to above):
pagebeforechange
This event is triggered prior to any page loading or
transition.
.
pagebeforeshow
Triggered on the "toPage" we are transitioning to,
before the actual transition animation is kicked off.
The pagebeforechange event is fired twice, the first time it is fired before the destination page is loaded, that's when you get data.toPage containing an URL.
The second time the event is fired the destination page is loaded, in that case you will get a query object containing the page DOM in data.toPage.
If you want to stick to the pagebeforechange event then you can do something like :
if (typeof data.toPage != "string") {
... Do your stuff ...
}
If you are flexible about the event you want to use then follow Jasper advice and use pagebeforeshow which will allow you to modify your detination page DOM before the page is transitioned to.

How to bind to submit event in jQuery Mobile pages

Tried to bind submit event (or click or whatever) to an element within a jQuery mobile page. What I wanted to do is get the value from an input within an form element within a jQuery page and store it in cookies/localStorage. Every time I come back to this page I want to restore the input field.
Currently I ended up in using this script:
$('.pageClassSelector').live('pageinit', function (e) {
$('.classSelector').submit(function () {
var q = $('.inputClassSelector').val();
// store to localStorage ...
});
// load from localStorage ...
$('.q').val(lastSearchString);
});
This approach is documented there http://jquerymobile.com/test/docs/api/events.html
Since it seems possible that identical pages are hold in the DOM, ID selectors are not quite useful. My problem now is that everytime I navigate to this page the submit event is bound again and thus results in storing DIFFERENT (!) values. The submit event seems to be fired multiple times and much more interesting with the value before last.
Am I doing anything completly wrong? Any hints how to do scripting in jquery mobile properly?
TRY1:
I placed now the submit event binding within the pagebeforeshow event like so:
$('#PageId').on('pagebeforeshow', function (e) {
$('.classSelector').on('submit', function () {
var q = $('.q').val();
alert('stored: ' + q);
}
$('.q').val(lastSearchString);
}
But the value going to be stored is still the value before last, when I was navigating the page before. The first time it works as it should.
TRY2:
This is what I have now and it looks like it does that what I want. I select now the current page and select only the form which is a child of this page.
Is this good practice?
$('div:jqmData(id="PageId")').on('pagebeforeshow', function (e) {
$(this).find('#form').on('submit', function () {
var q = $(this).find('#input').val();
localStorage.setItem("key", q);
return true;
});
lastSearchString = localStorage.getItem("key");
$(this).find('#input').val(lastSearchString);
});
Your requirement to load from local storage and store on the page needs to be done by binding to the pagebeforeshow event (look at the section "Page transition events") and not the pageinit event like you are currently doing.
$('.pageClassSelector').on('pagebeforeshow', function (e) {
// load from localStorage ...
$('.q').val(lastSearchString);
});
Furthermore generally each page element (where you have data-role='page') should have a unique ID so you can use that instead of the CSS selector.
Multiple events firing when navigating pages sounds like multiple bindings to me, which is a known problem with jQuery Mobile. Bindings are not unbound when navigating pages, because everything is loaded through AJAX. See for example this StackOverflow Question: Jquery mobile .click firing multiple times on new page visit or my solution.
$('.classSelector').on('submit', function(){})
Try to use the constraction to bind your event to element.
Look likes some data was loaded through ajax request

Javascript for when AjaxControlToolkit TabContainer is ready?

I have a page with a TabContainer control (from the Ajax Control Toolkit), and I toggle the visibility of some elements on the page depending on the currently-selected tab. I'd been doing this in an event handler for OnClientActiveTabChanged (which works fine), but I discovered that it leaves the page in the wrong state after a postback. I tried adding some code to the document.ready event handler to get the index, but when I do the following:
$(document).ready(function () {
var index = $('#<%= TabContainer1.ClientID %>').[0].control.get_activeTabIndex();
// Do some stuff with the index
});
...I get a null reference exception on the .control property. Is there a way to hook a client-side "ready" event for the TabContainer?
I’m not familiar with the event lifecycle with normal DOM elements (it seems like there ought to be a general onload event, but I don’t see one). If there isn’t an event that can be easily handled, it seemed like it might work to add an UpdatePanel with UpdateMode=Conditional and an AsyncPostBackTrigger that pointed to a hidden button with an onclick event handler that would get the active tab index – but that seems like a lot of moving pieces for something that I’d expect the DOM to expose already.
Too late to be helpful, but I've had the same issue and found a workaround.
Change you code
$(document).ready(function () {
var index = $('#<%= TabContainer1.ClientID %>').[0].control.get_activeTabIndex();
// Do some stuff with the index
});
to
function pageLoad() {
var index = $('#<%= TabContainer1.ClientID %>').[0].control.get_activeTabIndex();
// Do some stuff with the index
};
Explanation here:
http://encosia.com/document-ready-and-pageload-are-not-the-same/
Basically, jQuery's ready event is "a bit early" and the TabContainer is not initialized yet, whereas the client side ASP.Net's pageLoad is late enough and the TabContainer has been initialized by then.
Check this post to save tab selection during postbacks. It works for normal post backs by saving the active tab index in hidden variable. Though its written for a JQuery plugin in the posted link, concept should be the same i.e., persisting the index of the selected tab.

Categories