Repeat control refresh - xpages

Is there a easiest way to update repeat control data , What I want to do is facebook like activity stream (news feed) in a repeat control.
Any suggestions are appreciated.

Add the following CSJS code to your XPage. Set the interval value in milliseconds you'd like to refresh your repeat control (instead of 5000 = 5 seconds in example):
<xp:scriptBlock
id="scriptBlockRefresh">
<xp:this.value>
<![CDATA[
setInterval(function() {
XSP.partialRefreshPost("#{id:repeatControlId}", {})
}, 5000)
]]>
</xp:this.value>
</xp:scriptBlock>

Related

infiniteScroll with pagerAddRows but Timeago only work for the repeat limit not more

I use the Timeago for Xpages and the inifinite scrolling Custom Control.
If I use ones of them it is good. But if use both not good. The timeago only works on the entries in the repeatlimit. If I scrolling down the other one dont have a Timeago date.
The Timeago called by a dojo.addOnLoad function. For the first time okay. What event or function must I use?
You could use the script when the infinity scroll button is clicked to add the scripts for the Timeago custom control.
I added the Timeago script inside the infinite scroll script and after 500ms (the time until the server responds and fetches more rows) it will re-parse all timeago classes.
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[$(window).scroll(function(){
if($(window).scrollTop() == $(document).height() - $(window).height()) {
$(".infiniteScroll ul li a").click();
setTimeout(function(){
dojo.query(".timeago").forEach( function(el) {
var timeagoWidget= dijit.getEnclosingWidget(el);
if(!timeagoWidget){
timeagoWidget = new timeago.Timeago({}, el);
}
//refresh timeago
timeagoWidget.refresh();
});
},500);
}
});]]></xp:this.value>
</xp:scriptBlock>
Another option is hijack the partial refresh and always re-rerender the timeago scripts. How you can hijack it is explained here.

Is it the natural behavior of an Acumatica grid checkbox column to auto-refresh?

I have a grid that contains thousands of records. That grid contains a check box column, and every time I tick the box, it posts back, causing it to reload and go through the delegate each and every time. This means that every time you tick a check box on this grid, you have to wait a couple seconds. This is a problem for users who want to select several records because, they have to wait a couple seconds between every click. I tried setting CommitChanges="False," and that didn't really help. Is this the native behavior of the PXCheckBox control? Is there any way to turn that off?
Below grid declaration of PXGrid I wrote the following:
</px:PXGrid>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
function checkDOMChange() {
disableGridCheck();
setTimeout(checkDOMChange, 100);
}
$(function () {
checkDOMChange();
});
function disableGridCheck() {
$("[icon='GridUncheck']").on("click", function (elem) {
$(this).attr("check", "1");
$(this).attr("icon", "GridCheck");
$($(this).children()[0]).attr("class", "control-icon-img control-GridCheck");
return false;
});
$("[icon='GridCheck']").on("click", function (elem) {
$(this).attr("check", "0");
$(this).attr("icon", "GridUncheck");
$($(this).children()[0]).attr("class", "control-icon-img control-GridUncheck");
return false;
});
}
</script>
I had the same behaviour. In order to avoid it I had to write javascript which blocked postback.

Using JQuery to mask input fields. When I refresh a panel that contains those fields the masking stops working

I have several phone number fields that use jquery masking to format the input. See the code below. The fields work great until a combo box change above refreshes a panel that contains those fields. Once the refresh happens my masking stops working.
Any idea why and how to prevent this from happening?
<xp:scriptBlock id="scriptBlock7">
<xp:this.value><![CDATA[
jQuery(function($){
x$("#{id:dayPhone1}").mask("(999) 999-9999? x 9999999", {placeholder : " " } );
x$("#{id:eveningPhone1}").mask("(999) 999-9999? x 9999999", {placeholder : " " } );
x$("#{id:cellular1}").mask("(999) 999-9999? x 9999999", {placeholder : " " } );
});
]]></xp:this.value>
</xp:scriptBlock>
The jQuery is only run one time. It manipulates the DOM to give the mask effect. Once you run a partial refresh the original DOM is returned to the user and the mask is no longer in effect.
When the partial refresh happens the jQuery code does not know to apply itself back to the mask again. You have a number of choices, but the best is probably:
In the onComplete event of the partial refresh you can call the mask code again to reapply the "Mask". What I don't know is if the mask code will reset the fields or honor the values therein. I that is the case then take a look at the plugin code and see what options you have.
<xp:button value="Label" id="button1" styleClass="startLoginProcess" style="display:none">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="somethingHere"
onComplete="applyMaskCodeAgainHere">
</xp:eventHandler>
</xp:button>
To improve the code above because it looks like you are applying the same mask I suggest using a class selector and simplifying your code to look more like this:
<xp:scriptBlock id="scriptBlock7">
<xp:this.value><![CDATA[
jQuery(function($){
$('.phoneMask').mask("(999) 999-9999? x 9999999", {placeholder : " " } );
});
]]></xp:this.value>
</xp:scriptBlock>
put a styleClass="phoneMask" on your field :)
Is your scriptBlock also on the panel that is being refreshed? It needs to be in order for the the mask to be reapplied to the fields after the refresh.
You can remove the mask and reset it...
$(`#${id:dayPhone1}`).val(newPhoneValue).unmask().mask('(00) 00000-0000', {clearIfNotMatch: true});
This worked for me and should solve your problem!
TLDR: .unmask() before .mask()

ComboBox onBlur to refresh the values of other ComboBoxes using a function

I have an xpage with 5 fields on it. Each field has code in the onBlur event to refresh the values of the ComboBoxes below it. I now have to add a bunch more fields to this application and I don't want to write the refresh code for each field. Rather, I would like to create a function that takes a parameter of which field I'm in and do the refresh with a loop.
I can't seem to get this to work. Below is the code I'm using in the onBlur event. I don't know the semantics of putting this code in a script library that can access each combobox and call the refresh code in a loop.
Any ideas?
<xp:comboBox id="vendorAppAdvSkills1">
<xp:selectItem itemLabel="-Select a Category-"
itemValue="-Select a Category-"></xp:selectItem>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:getComponent( "vendorAppSkills1" ).getValue();}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onblur" submit="false">
<xp:this.script><![CDATA[
XSP.partialRefreshPost("#{id:panelVendorAppSkills2}",
{
onComplete: function()
{
XSP.partialRefreshPost("#{id:panelVendorAppSkills3}",
{
onComplete: function()
{
XSP.partialRefreshPost("#{id:panelVendorAppSkills4}",
{
onComplete: function()
{
XSP.partialRefreshPost("#{id:panelVendorAppSkills5}",
{
onComplete: function()
{
XSP.partialRefreshPost("#{id:panelNextFinish}",
{
} )
}
} )
}
} )
}
} )
}
} );]]></xp:this.script>
</xp:eventHandler>
</xp:comboBox>
Do you have validation on your XPage? If so, validation will be preventing any of the partial refreshes running.
If possible just set the refresh ID of the eventHandler to an area that encompasses all combo boxes. That would just call one partial refresh from the browser to the server.
With your current code you're calling 5 partial refreshes, each time posting the whole content of the browser across to the server, each time updating the whole page, but just pushing back an individual component. Performance is not going to be good, so the single refresh area is better practice (as well as being easier to code!).
As best practice, unless you're preventing validation, also ensure the refresh area includes a Display Errors control. Otherwise your users (including you when testing) will not know if validation has failed.

inputText onchange event not called after inactivity

I have a typeahead enabled on an inputText field which triggers an onChange event. This works fine unless the page has not been refreshed for a period of time (in testing, it stops working after 1 hour but may be less). Refreshing the page completely fixes the issue.
The code for the inputText field is as follows;
<xp:inputText id="quickSelectEntry" style="width:170px;">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="placeHolder" value="Enter name">
</xp:dojoAttribute>
</xp:this.dojoAttributes>
<xp:typeAhead mode="none" minChars="2" ignoreCase="true"
var="searchValue" valueMarkup="true">
<xp:this.valueList><![CDATA[#{javascript:return nameTypeAhead(searchValue)}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange" submit="true"
refreshMode="norefresh">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var searchVal:string = getComponent("quickSelectEntry").getValue();
if (searchVal.substr(0,1).equals("?")) {
context.redirectToPage("xCheckSecurityGroup.xsp?group=" + searchVal.substr(1));
return false;
} else {
var doc:NotesDocument = quickLookupView.getDocumentByKey(searchVal, true);
if (null != doc) {
viewScope.lookupKey = doc.getUniversalID();
viewScope.lookupForm = doc.getItemValueString("form");
return true;
} else {
viewScope.lookupKey = ""
viewScope.lookupForm = ""
return false;
}
}
]]></xp:this.script>
</xp:executeScript>
<xp:actionGroup>
<xp:this.condition><![CDATA[#{javascript:viewScope.lookupKey != ""}]]></xp:this.condition>
<xp:openPage target="openDocument"
documentId="#{javascript:return viewScope.lookupKey}">
<xp:this.name><![CDATA[#{javascript:return "x" + viewScope.lookupForm + ".xsp" }]]></xp:this.name>
</xp:openPage>
</xp:actionGroup>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
So far I've tried doing a timed partial refresh of the containing panel with no joy, I've set the typeahead mode from none to full. No difference.
Aside from refreshing the page every 10 minutes, is there anything else that couple be causing the problem. FYI The actual typeahead is working correctly consistently, its just the onchange event that stops firing.
What seems to happen is that the server web session is intact but the XPages session is lost.
Add the following to the bottom of your XPage and what it will do is refresh the DIV preiodically based on your setting (in milliseconds) (300000 = 300 seconds = 5 minutes) - the longest I have had a successful test is 3.5 hours.
You need to set a value at least one minute less than the session timeout length set in the application properties for your database.
<xp:div id="keepSessionAlive"></xp:div>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value>
<![CDATA[
XSP.addOnLoad(function(){
setInterval(function(){
XSP.partialRefreshPost("#{id:keepSessionAlive}", {});
}, 300000)
})]]>
</xp:this.value>
</xp:scriptBlock>
Do not set a short refresh time as this will needlessly waste bandwidth and also bloat IE's RAM usage which is not well managed by the browser.
Understand that this is a SECURITY ISSUE at the same time - by basically keeping an idle computer's session alive you leave it open to hijack without the user's knowledge - that is the part of the point of a timeout
The issue is that the XSP session times out (according to your server settings). See this answer for recommendations on keeping the session alive:
How do I refresh page automatically when partial refresh doesn't work?
I have seen this too. I ended up putting in a meta refresh tag to reload the page every 30 minutes. It was the only thing that seems to work.
Howard
May want to check the Application Properties(go to Xpages tab). There you can set the Application and the session timeouts for the database. If these are blank I think they will default to server which is typically 30 minutes.
V/R,
Kev

Resources