passing a parameter using JSP include directive - javascript

I need to pass a parameter to a page using JSP include directive find my code below:
<script>
var gTIID
function showPlayerList(pTIID)
{
gTIID=pTIID;
$("#IdtournamentMessageMain").hide();
$("#userListFrame").show();
}
</script>
<%# include file="players_list.jsp" %>
How can I pass gTIID to players_list.jsp in the players_list.jsp page gTTID is named tiID (/player_list.htm?tiID=gTIID) ?
Thanks in advance!

since you are using the <include> directive, gTIID should already be available.
Alternately, you could set them in one of the scopes (request, session, application) and then fetch from the same scope in your other JSP.
Or, you could also use <jsp:include> and <jsp:param> to achieve this.

You'll be able to acces gTIID in players_list.jsp. There's no need to pass it as a parameter, as it's a global-scope defined variable. However, take into account that the variable is only defined and initialized in the including page, not players.jsp. If that page is referenced somewhere else, it may be undeclared.

I solved the issue using an hidden input box(id="tidhide") in the "players_list.jsp page initialized to -1 and I set it in the showplayer function, find my snippet code below:
Parent page:
function showPlayerList(pTIID)
{
gTIID=pTIID;
$("#IdtournamentMessageMain").hide();
$("#tidhide").val(pTIID);
oTable.fnDraw();
$("#userListFrame").show();
}
bye!

Related

userFlow with AngularJS?

I can't get UserFlow to work for our AngularJS app.
The product runs on old AngularJS (1.8) and we love the concept of UserFlow , but the typical injection and init model runs in the core JS scope which AngularJS does not have access to... so, even after following the onboarding instructions, every user that registers is appearing to UserFlow as the same {{userId}}
We believe this is happening (UserFlow is not able to receive the user ID in userflow.identify as described here) because the user ID is not known outside of the AngularJS digest. i.e. - the method was called in a place where angularJS is not taking effect, so the handlebars never get rewritten.
Got it fixed. An overview of how we fixed it is below:
Simply split UserFlow's initialization into two distinct steps:
userflow.init() - this can be directly in your index.html or otherwise injected into the <body>
userflow.identify() - this has to be done within your AngularJS controller
.
DETAILED STEPS---------------
1. init() normally, but use a build variable and don't identify yet
In index.html, at the bottom of the <body> tag, add the following script:
<!-- UserFlow -->
<script ng-if="customization.features.userflow">
!function(){var e="undefined"==typeof window?{}:window,t=e.userflow;if(!t){var r="https://js.userflow.com/";t=e.userflow={_stubbed:!0};var n=e.USERFLOWJS_QUEUE=e.USERFLOWJS_QUEUE||[],o=function(e){t[e]=function(){var t=Array.prototype.slice.call(arguments);i(),n.push([e,null,t])}},s=function(e){t[e]=function(){var t,r=Array.prototype.slice.call(arguments);i();var o=new Promise((function(e,r){t={resolve:e,reject:r}}));return n.push([e,t,r]),o}},a=function(e,r){t[e]=function(){return r}},u=!1,i=function(){if(!u){u=!0;var t=document.createElement("script");t.async=!0;var n=e.USERFLOWJS_ENV_VARS||{};"es2020"===(n.USERFLOWJS_BROWSER_TARGET||function(e){for(var t=[[/Edg\//,/Edg\/(\d+)/,80],[/OPR\//,/OPR\/(\d+)/,67],[/Chrome\//,/Chrome\/(\d+)/,80],[/Safari\//,/Version\/(\d+)/,14],[/Firefox\//,/Firefox\/(\d+)/,74]],r=0;r<t.length;r++){var n=t[r],o=n[0],s=n[1],a=n[2];if(e.match(o)){var u=e.match(new RegExp(s));if(u&&parseInt(u[1],10)>=a)return"es2020";break}}return"legacy"}(navigator.userAgent))?(t.type="module",t.src=n.USERFLOWJS_ES2020_URL||r+"es2020/userflow.js"):t.src=n.USERFLOWJS_LEGACY_URL||r+"legacy/userflow.js",t.onerror=function(){u=!1,console.error("Could not load Userflow.js")},document.head.appendChild(t)}};o("_setTargetEnv"),o("closeResourceCenter"),o("init"),o("off"),o("on"),o("prepareAudio"),o("registerCustomInput"),o("remount"),o("reset"),o("setCustomInputSelector"),o("setCustomNavigate"),o("setCustomScrollIntoView"),o("setInferenceAttributeFilter"),o("setInferenceAttributeNames"),o("setInferenceClassNameFilter"),o("setResourceCenterLauncherHidden"),o("setScrollPadding"),o("setShadowDomEnabled"),o("setPageTrackingDisabled"),o("setUrlFilter"),o("openResourceCenter"),o("toggleResourceCenter"),s("endAll"),s("endAllFlows"),s("endChecklist"),s("group"),s("identify"),s("identifyAnonymous"),s("start"),s("startFlow"),s("startWalk"),s("track"),s("updateGroup"),s("updateUser"),a("getResourceCenterState",null),a("isIdentified",!1)}}();
userflow.init('##grunt_userflow')
</script>
Since we use Grunt as a build tool (which I don't recommend, but you can replicate the same pattern with different technologies), we put the environment-specific token, ##grunt_userflow, into our build script which replaces the individual token to match the respective environment.
You'll notice here we're not calling userflow.identify() yet...
2. Execute the UserFlow identify() directly within the controller
When the user first logs in, now you need to execute the userflow.identify() function and pass in the right IDs. Personally, I like putting AngularJS-agnostic functions like this outside of the controller and then inherit them in:
const startUserFlow = function(userId, login) {
userflow.identify(userId, {
email: login
});
};
And, now calling that function from within AJS:
$scope.processCredentials($scope.username, response.data.access_token).then(function (result) {
trackEvent('signIn', $rootScope.userProfile.id);
startUserFlow($rootScope.userProfile.id, $scope.username);
3. Finally, to reinitialize your Content, use ng-click=() on any HTML you'd like
That's right - since we're scoping it in and doing this the AngularJS way, use ng-click like any other function and bind it directly. Example below.
$scope.launchUserFlowChecklist = function () {
userflow.start('[insert content ID here]');
};
I hope this helps! Cheers.

Function Undefined: Must a javascript function be defined within the same file?

I've got a file notifications.js containing one event bound to an element, and a function updateNotification(). This function uses jQuery to update certain elements on the page when a JSON object is passed as a parameter.
The problem:
I'm attempting to call this function within the page (via <script> tags), however rather than calling it, it breaks the page. I did some digging around within the Chrome Developer Console (not sure of the name), and an error is flagged:
/pleaseshare/views/install/:50 Uncaught ReferenceError:updateNotification is not defined
However, when I pan within the console, I can clearly see the file notifications.js listed under scripts, and the function is defined there. If I define the function within the current scope (e.g. the line above the call), it works fine.
What I've tried
The function contains some javascript that requires jQuery, so I've attempted both with and without encasing it in $(document).ready( function() {});, with neither seeming to have any affect.
I'm pretty stumped.
For good measure, here's a link to show the structure of my javascript and html: http://snippi.com/s/znk6xe9
Any help in figuring out why this is happening, or explanations of why javascript functions cannot be called cross-file (although I'd hope this isn't the case), would be greatly appreciated ;)!!
A function cannot be called unless it was defined in the same file or one loaded before the attempt to call it.
A function cannot be called unless it is in the same or greater scope then the one trying to call it.
You code looks like the structure should work, but is clearly a reduced test case that has been reduced to the point where it won't.
Got it working. The issue was definitely multi-faceted, but I figured it out.
First off the use of RequireJS had an impact on updateNotification(), in that it couldn't be called cross-file, and was therefore considered undefined. I assume this because of how RequireJS loads files, and I'll look into the documentation later (and post an edit if I find anything relevant).
Secondly, updateNotification() would again be considered undefined when encased within jQuery's DOM ready loader $(document).ready(function(){}). However updateNotification() contains executions which require jQuery, so I had to encase the contents of the function in $(document).ready(function(){}).
This is an issue very unique to RequireJS/jQuery, hence why in most use cases this wouldn't occur.
Side note: The tags are edited to reflect this.
you need to import your script into your page:
<script type="text/javascript" language="javascript" src="path/to/notifications.js"></script>
This needs to be added above the <script> tag that calls updateNotification()
Functions do not need to be declared in the same file. In fact, avoiding having every declaration dumped into the global namespace is usually a concern in JavaScript.
In the sample code in the link you provided, updateNotification is declared as a global, so there should not be a scoping problem.
However, in the same sample, you don't show notifications.js being included. You need to import it using a <script></script> element and that element must come before the script element that includes the call to updateNotification. You also must include jQuery before notifications.js, since it uses jQuery. So you need something like:
<body>
// One or two elements
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="notifications.js"></script>
<script type="text/javascript">
$(document).ready( function() {
var json = {status : 'ok', message: 'Hello'};
updateNotification(json);
});
</script>
// All other elements
</body>

Grails 2.0: Use Service in javascript function in GSP

I am just wondering how I can call a method of a service from within a function within a GSP. I tried the following but it does not seem to work:
<%# page import="com.company.MyService" %>
<%
def myService =grailsApplication.classLoader.loadClass('com.company.MyService').newInstance()
%>
<html>
<head>
[...]
<script language="javascript">
function myFunction() {
if (${myservice.isSomethingAvailable()}) {
[...]
}
}
</script>
I am pretty new to javascript and Grails. Not sure how to achieve that or if it's even possible. Any help appreciated.
Thanks a lot
Jonas
loadClass().newInstance() creates new instance of object, not spring bean (i mean it's not tied to grails infrastructure), i'm sure it's not what you want
You can pass service from your controller, like render(model: [myService: myService]) (you have to declare it at controller lever)
It's much more correct way is to pass result of this call, not service itself. I mean: render(model: [isSomethingAvailable: myService.isSomethingAvailable]) and test it as if ($(isSomethingAvailable)) {
Notice that gsp is processed in server-side, not client-size. So it doesn't matter where you use your variable - on javascript code, or html code. And also, you can use gsp if tag: <g:if test="${isSomethingAvailable}"> instead of preparing javascript to check value on client-side (because you already know the result)

Executing a salesforce controller through javascript?

I know it's easily possible to execute javascript through a controller, but is it possible to do it the other way around?
Use case scenario:
I have a list of products on the left side of a page. When I click one of these products, I have a CSS highlight appearing. I'd then like the javascript to rerender my search results function, "showtheresults".
It would allow users to drill down the product whose data they are searching through. The only way I can think of doing it is through javascript. Other suggestions welcome.
You can try using the Ajax toolkit. In JavaScript:
// Include Ajax toolkit
{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/22.0/apex.js")}
// Get selected Lead Ids
var leadIds = {!GETRECORDIDS($ObjectType.Lead)};
// Call your class method
var result = sforce.apex.execute('CalledFromJavaScript', 'theMethod', {arg: leadIds});
Then in Apex:
// Make your class global and method a webservice:
global class CalledFromJavaScript
{
webService static Integer theMethod(List<Id> sObjectIds)
{
...
}
}
You can do this with an output panel that you rendered selectively based on a boolean in your controller. In this example set 'renderScriptPanel' when you'd like the showResults function to run. If you're doing a partial page refresh make sure to refresh the id of the output panel.
<apex:outputPanel id="scriptPanel" rendered="{!renderScriptPanel}">
<script type="text/javascript">
showTheResults();
</script>
</apex:outputPanel>
You may want to look at JavaScript Remoting for Apex Controllers

Get the name of the HTML document that called a JS function

I'm a beginner with JS.
I am working with some JavaScript on a site, and I just want to use only 1 file of JS for determine the actions off the pages. Something like this:
function registerEvents(){
NameOfHTMLDocument = //?? Get the name of the document that called registerEvents function.
switch(NameOfHTMLDocument)
{
case:"homepage":
hmp_btn = document.getElementById("hmp_btn");
hmp_btn.onclick=otherFunction;
break;
case:"otherPage":
elem = document.getElementById("elemID");
elem.onclick=fooFunction;
break;
//etc...
}
}
This function is called with a <body onload="registerEvents()"> that is "inherited" by all the pages.
The question is, How can I get the "NameOfHTMLDocument"?. Because I don't want that JS begin doing weird things when trying to get elements that don't exist.
I found that I can get the URL of the DOM and then play a little with it to get the string that i want, but i'm not sure if this is the better way of doing it.
It Would be nice if you have a better suggestion.
Firstly I would really suggest that you create separate script tags in html documents for functionality that is used only on that page and common functionality in separate file for several reasons:
No code pollution
Ease of change
Smaller download
Secondly, you can use switch on window.location.pathname DOM variable which is everything after domain
instead of homepage, etc..
i.e.
url = vader.samplesite.com/light/saber/
window.location.pathname = /light/saber/
(look at http://www.developertutorials.com/questions/question/q-242.php )
window.location.pathname
All you need to do is some parsing, but I'm sure you'll figure that out :) If not, leave a comment.
In your <body onload="registerEvents()"> pass the object this (the BODY in the DOM) through your event function such as : <body onload="registerEvents( THIS )">.
In your function itself, call the object you passed like object.ownerDocument.URL to get the URL including the HMTL document name or object.ownerDocument.title to get the page title.

Categories

Resources