xpages - how to set a scope variable from client side javascript? - javascript

I'm trying to set an XPages scope variable from Client side JavaScript. I have an XPage which contains several sections which are shown or hidden using Dojo. On this XPage I have a button which executes some server side JavaScript. Once the SSJS behind the button executes, the section of the XPage which is visible by default is again visible, rather than the section which was visible immediately prior to the button being clicked. I would like the section which was visible prior to the button being clicked to also be visible after the SSJS behind the button has executed.
To do this I have thought of using a scope variable - use client side JavaScript to calculate which section of the XPage which is currently visible, set this value in a scope variable and read the scope variable in the onClientLoad event of the XPage to again make this section visible (and hide all other sections).
However, I have found no way of setting a scope variable from client side JavaScript. I have tried adding
var xyz = "#{javascript:viewScope.put('sectionDisplay','Section')}"
to the onClick client event of the button but this sets the scope variable regardless of whether the button is clicked or not.
Before XPages, I would have used the querystring to pass variable from one page to another. How can I now do this?

You cannot set the CSJS variable this way: If you add this code to your CSJS, it will be calculated before sent to the browser. That is why the variable is set regardless of a click onto the button.
But you can add some SSJS code to your button which sets the viewScope variable. You can send the value from the browser with a parameter as described here: http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_events_and_partial_or_full_refresh#Run+a+partial+update+from+client+javascript
EDIT:
You can access different parameters with the param object in SSJS. F.e. if you add the parameter value in your CSJS...
XSP.partialRefreshGet( id, {
params: { 'value': 'some string'}
});
... you can access the parameter in SSJS like this:
param.get("value");

Depends on your use case. If you want to set it with partial/full refresh, you can simply put Hidden edit into XP, bind it to anyScope.variable_name and set its value with CSJS:
var field = document.getElementById("#{id:hiddenInput1}");
field.value = "new Value";
Every refresh will submit its value to model and will be available in scoped variable.
Another option is to use event handler anywhere with SSJS to set scoped variable based on hidden input value or submitted value, as stated in Sven's answer.

One other approach: perhaps you don't need the scope variable at all, if you just want to hide something, you can set it's style property to "display:none".
For example, you have this div: <xp:div id="mydiv">...</xp:div>
Then you can use the following CSJS in a button:
dojo.byId("#{id:mydiv}").style.display="none"

XSP.partialRefreshGet( id, {
params: { 'value': 'some string'}
});
... you can access the parameter in SSJS like this:
param.get("value");
I am passing a UNID from a grid to a dialog box. I can get param.get('unid') but I can't get it set to the document datasource unid. So that the fields would populate with values from backend document. There are many fields so I'd like to somehow populate that datasource without having to write values in each field.
How can I get the document datasource to recognize the param.unid? I am trying with a hidden input as you described but the value is not submitted either.
Is that possible?
XSP.partialRefreshGet(dialogId,
{
params: xspParams,
onStart: function(){
//dojo.style(loadingGifId,'display','block');
XSP.getElementById("#{id:inputText1}").innerHTML = unid; //not working
XSP.getElementById("#{id:inputText1}").value = unid; //not working either
},
onComplete: function(){
dijit.byId(dialogId).show();
//dojo.style(loadingGifId,'display','none');
}});
<xp:panel id="dialog">
<input id="inputText1"
value="#{javascript:sessionScope.personUNID;}">
</input>
<xp:this.data>
<xp:dominoDocument var="docPerson" action="editDocument"
formName="fUserName">
<xp:this.documentId><![CDATA[#{javascript:sessionScope.personUNID ;}]]></xp:this.documentId>
</xp:dominoDocument>
</xp:this.data>
<xp:inputText id="cfParams"
value="#{javascript:param.get('unid');}">
</xp:inputText>
</xp:panel>

Related

Oracle APEX - passing IG column value to javascript

I have an IG with a link column where the target is set to URL and I use it to call javascript.
What I want to accomplish is whenever a link column is clicked, grab a value of another - hidden column and set a page item to that value:
javascript:$s('P1_ITEM',#COLUMN2#);alert($v('P1_ITEM'));
but what happens, if I reference COLUMN2 value using just #COLUMN#, I get a javascript error and if I wrap it in single quotes, the value of P1_ITEM literally gets set to #COLUMN2#.
The first thing I would recommend is that you move to a Dynamic Action rather than trying to put all the code in the link. Also, I think buttons are a better than links (and they can be styled to look like links).
Start by going to https://apex.oracle.com/ut. Navigate to Reference > Button Builder and build the button you want. Then copy the value from the Entire Markup field.
Change the Type of the Link column to HTML Expression and paste the HTML from the Button Builder in the HTML Expression field. I styled my button to look like a link (as you had it), added a custom class to the class property named my-button, and added a data-attribute for the primary key value (my table was EMP, so the PK was EMPNO). It looked like this in the end:
<button type="button" class="t-Button t-Button--link my-custom-button" data-id="&EMPNO.">Click me!</button>
Give the Interactive Grid a Static ID value of my-ig.
With that done, create a new Dynamic Action. Set Name to .my-button clicked, Event to Click, Selection Type to jQuery Selector, and jQuery Selector to .my-button. Finally, set Event Scope to Dynamic, which will use event delegation to keep the event binding working if the report refreshes (see this for details).
In the action, set Action to Execute JavaScript Code. Enter the following code in the Code field:
var id = $(this.triggeringElement).data('id');
var model = apex.region('my-ig').call('getViews').grid.model;
var record = model.getRecord(id);
var job = model.getValue(record, 'JOB');
$s('P1_ITEM', job);
alert($v('P1_ITEM'));
This code starts by obtaining the value of the primary key from the data- attribute on the button using jQuery's data method. Next, a reference to the model that is used by the IG is obtained. Then the model's getRecord method is invoked and the primary key value is passed in. Finally, the model's getValue method is used to get the 'JOB' value from the record. I went after the JOB column since I was using the EMP table, but you would go after whatever column you need.
You can learn more about the model methods here:
https://apex.oracle.com/js > Interfaces > Model.

How to change only part of the query in url

I have this url
http://www.test.com/home-package/?location=locationA&bed=3&bath=4
and a variable (e.g. $location = "locationB") which holds the value user has selected when they land on the website. They can also change this location from any page they want and the variable will be updated with that location.
What I'm trying to achieve is,
If user is browsing http://www.test.com/home-package/?location=locationA&bed=3&bath=4 and then change the location to 'locationB', I want the url to update to http://www.test.com/home-package/?location=locationB
Hope I have made this clear.
Edit 1: User is selecting location from a dropdown list. <select> is wrapped inside <form> and upon hitting save, the value of location is saved in a session variable.
Thanks.
As I understand the locationB is in HTML input element? Add a onchange listener to the element and redirect user with javascript.
let locationB = getValueFromElement();
window.location.replace("http://www.test.com/home-package/?location="+locationB);
//or
window.location.href = "http://www.test.com/home-package/?location="+locationB;
Read differences between JS redirects.
If the locationB value comes from backend and redirecting in backend is not possible you can also add a hidden element that holds the value and read it with JS.

How to get function parameter values from an HTML Page using bookmarklet?

The code below saves data entered in textarea using saveFieldData().I want to use a Delete Button as a bookmarklet which will make this field blank and save the same in the server.
<textarea rows="4" cols="49" name="Synonym" id="Synonym" onchange="saveFieldData(85261, this, 'docProductInfo', 'Synonym', 84796);"></textarea>
So here is my bookmarklet
javascript:(function(){var sy=document.getElementById("Synonym");sy.value="";saveFieldData(85261,sy, 'docProductInfo', 'Synonym', 84796);})();
It deletes the data perfectly but the problem is whenever the page reloads it assigns some new values as function parameters as a result my code fails to work.For example after page reloads the function parameter changes like this
saveFieldData(85261, this, 'docProductInfo', 'Synonym', 84789);
basically the last parameter changes.So,Is there any way so that my bookmarklet will detect that parameter automatically and delete that field successfully?
If you just need to invoke the onchange handler you don't need to know it's parameters:
var sy=document.getElementById("Synonym");
var fn=sy.onchange;
sy.value="";
fn.call(sy);
Or more simply, since the onchange handler doesn't use any this within it:
fn();
Without knowing more about your page, I can't give you an ideal answer. There could easily be a better way, but based only on what you have shown, the only answer I see is to use a regular expression something like this:
sy = document.getElementById("Synonym");
id = sy.onchange.toString().match(/saveFieldData\(.+?,.+?,.+?,.+?,\s*(\d+)\)/)[1];

Javascript dynamic conditional onclick event

I have an ASP.NET gridview, with the code below (modified from another stackoverflow question) to make the row clickable.
e.Row.Attributes("onclick") = Me.Page.ClientScript.GetPostBackClientHyperlink(Me.gvPricingGrid, "Select$" & e.Row.RowIndex)
I also have a button that, when clicked, flips a boolean held in the session (accessed through a code-behind property), and makes visible some textboxes in each row for updating the row. The property is called IsEditingProperty
What I want is for the onclick to work as it does now when IsEditingProperty = False, but do nothing when the property = True. I have tried the below, but the property is evaluated at render, rather than when the click actually occurs.
e.Row.Attributes("onclick") = "if (""<% IsEditingProperty() %>"") " & Me.Page.ClientScript.GetPostBackClientHyperlink(Me.gvPricingGrid, "Select$" & e.Row.RowIndex)
Is there a way to make this happen?
I ended up dealing with this by realizing that rowCreated happens on postback simply adding the check against the property there.

RoR + How to refresh Javascript value when Ajax refreshes the textbox value

In my web page, I am using ajax + RoR to refresh the contents of the textbox using searchtool. All the value I am accessing, such like superset value for the current page. Means for example there is headquarter and it has many stations. When I am trying to access the value of headquarter at station then corresponding values changes at textbox.
Here, we are displaying the global value of head-quarter, due to less space I am showing telephone number and its quality on Tool-Tip. When page changes the value of station then whole contents changes but the tooltip remains same.
Sample of code:
<div class="divFloat" id="populate_phone1" onmouseout="UnTip()"
onmouseover='Tip("<%=GlobalPartnersHq.globally_phone_type(#station_hq.is_global_phone1, #station_hq.phone1_type_id) %>")' >
<%=GlobalPartnersHq.global_phone(#station_hq.is_global_phone1, #station_hq.phone1)%>
</div>
How can I refresh the JavaScript onmouseover value when ajax updates the value of textboxes?
I'm not following your code entirely, but it sounds like Ajax is updating the DOM and you want to trigger some additional code. What I recommend is that you emit a custom event and write separate handlers. If you are using jQuery check out trigger docs. You can do something like $.trigger('myEvent') then bind multiple handlers to it (e.g. $('selector').bind('myEvent', function() {});) to update various parts of the page.

Categories

Resources