I am using the Data Tables jQuery plugin on XPages to display our price list to users. The administrators of the price list search for similar items, click the item description to modify the item via a dialog box. As there are over 1000 items in the price list it is necessary to save the search and at the same time refresh the table so the user can review the changes in the list after closing before moving to the next item in their search. Due to the large number of entries refreshing the whole page is messy, so when opening the dialog I refresh only the dialog, which has always worked fine until I have introduced the stateSave on the DataTable. The problem being now when I close the dialog the page continues making POST requests to open the dialog again with a random item from the bean.
Any help would be greatly appreciated.
<xp:div style="width:30%" styleClass="mg20">
<xp:panel id="tablePanel">
<table id="keyItemsPLTable">
<thead>
<tr>
<th>Description</th>
<th>Code</th>
</tr>
</thead>
<tbody>
<xp:repeat id="repeat1" rows="10000"
var="rowData">
<xp:this.value><![CDATA[# #javascript:itemBean.getPlItems("All","Price List Sales Cat Only")}]]></xp:this.value>
<tr>
<td>
<xp:link escape="true"
text="#{rowData.description}" id="link3">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="dialog1" execMode="partial"> //Problem occurs due to this partial refresh
<xp:this.action><![CDATA[#{javascript:itemBean.setPlItem(rowData);
var dialog = getComponent("dialog1");
dialog.show()}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
</td>
<xp:text tagName="td" escape="true"
id="computedField1" value="#{rowData.code}">
</xp:text>
</tr>
</xp:repeat>
</tbody>
</table>
<xp:scriptBlock>
<xp:this.value><![CDATA[
$(document).ready(function() {
var table = $('#keyItemsPLTable').DataTable( {
stateSave: true, //https://datatables.net/reference/option/stateSave
stateDuration: -1//This doesn't seem to work. https://datatables.net/reference/option/stateDuration
});
});
]]></xp:this.value>
</xp:scriptBlock>
</xp:panel>
</xp:div>
<xe:dialog id="dialog1">
<xp:panel id="panelFullDialog" styleClass="mg20">
<xp:div styleClass="mg20">
<xp:inputText id="inputDesc"
value="#{itemBean.plItem.description}" styleClass="wd200">
</xp:inputText>
</xp:div>
<xp:div styleClass="mg20">
<xp:inputText value="#{itemBean.plItem.code}"
id="inputText2" styleClass="wd200">
</xp:inputText>
</xp:div>
<xe:dialogButtonBar id="dialogButtonBar1">
<xp:button value="Cancel" id="button4">
<xp:eventHandler event="onclick" submit="false">
<xp:this.script><![CDATA[XSP.closeDialog('#{id:dialog1}')]]></xp:this.script>
</xp:eventHandler>
</xp:button>
<xp:button id="button1">
<xp:this.value><![CDATA[Save & Close]]></xp:this.value>
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="tablePanel">
<xp:this.action><![CDATA[#{javascript:itemBean.savePLItem();
var dialog = getComponent("dialog1");
dialog.hide();
}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xe:dialogButtonBar>
</xp:panel>
</xe:dialog>
On closing the Post requests continue with the dialog reappearing until the page is closed.
200
POST
instant.abc.co.uk testing.xsp?$$ajaxid=view:_id1:tablePanel xhr html 35.47 kB 426.05 kB 2165 ms
200
POST
instant.abc.co.uk testing.xsp?$$ajaxid=view:_id1:dialog1 xhr html 574 B 650 B 1969 ms
200
GET
instant.abc.co.uk testing.xsp?$$ajaxid=view:_id1:dialog1:_content&$$showdialog=true&$$created=true&$$createdialog=false&$$viewid=!6rftmmaw860jebb294nc4ay3y! xhr html 871 B 1.94 kB
6 ms
200
POST
instant.abc.co.uk testing.xsp?$$ajaxid=view:_id1:dialog1 xhr html 574 B 650 B 2057 ms
200
GET
instant.abc.co.uk testing.xsp?$$ajaxid=view:_id1:dialog1:_content&$$showdialog=true&$$created=true&$$createdialog=false&$$viewid=!6rftmmaw860jebb294nc4ay3y! xhr html 873 B 1.94 kB
4 ms
200
POST
instant.networkconnect.co.uk testing.xsp?$$ajaxid=view:_id1:dialog1 xhr html 574 B 650 B
If you're trying to refresh tablePanel after closing the dialog, don't make that the refresh ID. The hide() method takes a parameter of the area to refresh after the dialog has closed. That's because the SSJS needs to post back to the browser to make the call to close the dialog, so it will pass a client-side JavaScript call to make a GET request to refresh whatever ID was passed as a parameter of the hide() method. See https://www.intec.co.uk/xpages-dialog-control-and-partial-refreshes/.
Related
Im using a vuetify data table and have added a td element to download a pdf on a separate browser tab. <td class="add-outline text-xs-left" style="cursor:pointer;" v-on:click.once.stop="openFile(props.item.pdfFile)" ><a target="_blank" :href="props.item.pdfFile" style="text-decoration: none; color: black;">{{ props.item.reportDate }}</a></td>
I have tried
v-on:click.once
v-on:click.stop
and
v-on:click.stop.once
my method only opens the new window
openFile (url) {
window.open(url)
},
When i click it downloads the pdf twice. what is the best way to prevent this from happening?
this is what my click event looks like using vue dev tools
I have a RESTful API web service. I'm programming a simple pure Javascript client app to interact with the APIs. I also use Knockout framework. My Javscript code:
self.movies = ko.observableArray();
$.get(self.moviessURI, function(data){
var obj = JSON.parse(data);
for (var i=0; i < obj.movies.length; i++) {
self.movies.push(obj.movies[i]);
}
}, "json");
My HTML code:
<table class="table table-striped">
<tr><td><b>Title</b></td><td><b>VideoID</b></td></tr>
<!-- ko foreach: movies -->
<tr>
<td><p><b data-bind="text: title"></b></p></td><td><p data-bind="text: videoId"></p></td>
</tr>
<!-- /ko -->
</table>
After running, I have a request status 200 on the web service, but my client app does not display anything. I also used Postman to test the API and its working.
Where did I do wrong? Thanks for any help!
I'm using the dataTables jQuery plugin with xpages and have a custom control I drop onto any page, pass in a custom property of viewName and it will display a table using REST - All based on some great examples by Oliver Busse.
Everything works perfectly if this custom control is used on a basic page, however, if it is within a tab, which is not default, when I then click on the tab containing the control, I receive an error when calling viewjson.getId()
I think the issue is because I set viewjson on beforePageLoad?
Any idea how I can get this to work in a tabbed interface?
Code below:
<xp:this.beforePageLoad><![CDATA[#{javascript:var viewjson = new org.openntf.rest.DynamicView(compositeData.viewName);}]]></xp:this.beforePageLoad>
<table
id="#{javascript:viewjson.getId()}"
class="table table-hover table-striped">
<thead>
<xp:repeat id="repeat1" rows="30" disableOutputTag="true"
var="col">
<xp:this.value><![CDATA[#{javascript:try {
viewjson.getCols()}
catch (e) {
openLogBean.addError(e,this)
}}]]></xp:this.value>
<th>
<xp:text escape="true" disableTheme="true"
value="#{col}">
</xp:text>
</th>
</xp:repeat>
</thead>
<tbody></tbody>
</table>
UPDATE
I've tried the following to try and load jQuery first
<xp:this.resources>
<xp:headTag
tagName="script">
<xp:this.attributes>
<xp:parameter
name="type"
value="text/javascript" />
<xp:parameter
name="src"
value="/xsp/.ibmxspres/.extlib/responsive/jquery/jquery.min.js" />
</xp:this.attributes>
</xp:headTag>
</xp:this.resources>
And also this in xsp properties
xsp.client.script.dojo.djConfig="dojo-amd-factory-scan": false
But I'm still getting a blank page with no dojo elements displaying
I believe the main problem is that for the XPages core controls a non active tab is not actually rendered to the browser until it becomes active. So what you called in the beforePageLoad() was looking for content that didn't exist at the time.
There's probably a CSJS thing that could re-init the data tables. Another option is to not use the tab core control but use the dojo version from the ext. library. I'm pretty sure that the dojo version renders all content and just uses CSS to hide non active tabs.
Custom control's beforePageLoad event gets executed when XPage is loaded already.
When later the tab is activated and with it the table is rendered the variable viewjson is gone.
One approach would be to put Java object into a composite data variable compositeData.viewjson in beforePageLoad and use it in table later. But, you would calculate all views for every tab before rendering page. In addition, this class is not serializable and couldn't be stored in composite data variable. You could make the class serializable though.
The better approach is to instantiate Java bean in table - without a beforePageLoad event:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<table
id="#{javascript:
var viewjson = new org.openntf.rest.DynamicView(compositeData.viewName);
return viewjson.getId();
}">
<thead>
<xp:repeat id="repeat1" rows="30" disableOutputTag="true"
var="col" value="#{javascript: viewjson.getCols()}">
<th>
<xp:text escape="true" disableTheme="true" value="#{col}">
</xp:text>
</th>
</xp:repeat>
</thead>
<tbody></tbody>
</table>
</xp:view>
I tested the custom control above (ccView with property viewName) with this XPage
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:br />
<xp:panel id="tabs">
<xe:djTabContainer id="tabContainer"
selectedTab="djTabPane1" defaultTabContent="one">
<xe:djTabPane id="djTabPaneView" title="one" closable="false"
partialRefresh="true">
tab rendered first
</xe:djTabPane>
<xe:djTabPane id="djTabPane2" title="two" closable="false"
partialRefresh="true">
<xc:ccView viewName="ByCity" />
</xe:djTabPane>
<xe:djTabPane id="djTabPane3" title="three" closable="false"
partialRefresh="true">
<xc:ccView viewName="ByName" />
</xe:djTabPane>
</xe:djTabContainer>
</xp:panel>
</xp:view>
Views in tabs "two" or "three" get loaded per REST services when user clicks the respective tab.
I have a big problem using dojo IO Pipelines in combination with ExtLib Controls (e.g. xe:namepicker) in Domino 9.0.1 FP3.
For illustration here two scenarios....
The XPage code for the first scenario (without xe:namepicker):
<xp:this.properties>
<xp:parameter name="xsp.client.script.dojo.djConfig" value="ioPublish:true"></xp:parameter>
</xp:this.properties>
<xp:button value="Partial Refresh" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="main" execMode="partial">
<xp:this.onComplete><![CDATA[doPartialRefreshOf(['tagCloud1', 'tagCloud2']); ]]></xp:this.onComplete>
</xp:eventHandler>
</xp:button>
<xp:panel id="main" style="background-color:rgb(0,255,64);">CONTENT</xp:panel>
<xp:panel id="tagCloud1" style="background-color:rgb(255,128,0)">TAGCLOUD1</xp:panel>
<xp:panel id="tagCloud2" style="background-color:rgb(128,0,255)">TAGCLOUD2</xp:panel>
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[dojo.subscribe("/dojo/io/start", function(data){
console.log("triggered on /dojo/io/start channel");
});
dojo.subscribe("/dojo/io/stop", function(data){
console.log("triggered on /dojo/io/stop channel");
});]]></xp:this.script>
</xp:eventHandler>
Click on the button “Partial Refresh” results in the following output (on Firebug console):
triggered on /dojo/io/stop channel
POST...main
GET...tagCloud1
GET...tagCloud2
triggered on /dojo/io/stop channel
All works perfect!
The XPage code for the second scenario (with xe:namepicker):
<xp:this.properties>
<xp:parameter name="xsp.client.script.dojo.djConfig" value="ioPublish:true"></xp:parameter>
</xp:this.properties>
<xp:button value="Partial Refresh" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="main" execMode="partial">
<xp:this.onComplete><![CDATA[doPartialRefreshOf(['tagCloud1', 'tagCloud2']); ]]></xp:this.onComplete>
</xp:eventHandler>
</xp:button>
<xe:namePicker id="namePicker1" for="inputText1" pickerText="NamePicker"></xe:namePicker>
<xp:panel id="main" style="background-color:rgb(0,255,64);">CONTENT</xp:panel>
<xp:panel id="tagCloud1" style="background-color:rgb(255,128,0)">TAGCLOUD1</xp:panel>
<xp:panel id="tagCloud2" style="background-color:rgb(128,0,255)">TAGCLOUD2</xp:panel>
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[dojo.subscribe("/dojo/io/start", function(data){
console.log("triggered on /dojo/io/start channel");
});
dojo.subscribe("/dojo/io/stop", function(data){
console.log("triggered on /dojo/io/stop channel");
});]]></xp:this.script>
</xp:eventHandler>
Click on the button “Partial Refresh” results in the following output (on Firebug console):
POST...main
GET...tagCloud1
GET...tagCloud2
As you can see, there is no output (/dojo/io/...) on the firebug console (dojo/io channels will not be triggered..)!
Both scenarios are working perfect in Domino 8.5.3 FP6 + Lotus Domino Upgrade Pack.
Any hints/advices how to solve this problem?
Thanks in advance
Georg
9.0.1FP3 contains Dojo v1.9.4, and dojo/io has been deprecated since dojo 1.8. This may be part of the problem. See here: http://dojotoolkit.org/reference-guide/1.9/dojo/io.html
You could try using dojo/request instead, as suggested in that link. I'm not really familiar with the old IO or the new request packages though, so you would need to do some investgiation.
I want to click the submit button of the webpage i am displaying in my Web Browser but it seems not to work at all here is my code:
WebBrowser1.Document.Forms(0).InvokeMember("image")
i was basing on the html code of the button i want to click which is:
<div class="buttonRow forward">
<input type="image" src="includes/templates/template_default/buttons/english/button_send.gif" alt="Send Now" title=" Send Now ">
</div>
did i miss something? i really need help.
Try setting this property
Webbrowser.AllowNavigation = True