I would like to implement a kind of information for my users about the progress status. I have found several components like:
Richfaces status or IceFaces onnection Status
So, I would like to add something like that to my page especially for ajax requests. What's the easiest way to implement it? I would not like to use one of those components, rather programming my own one but I can't imagine how and how much effort it takes :-)
I am thankfull for ideas...
The standard JSF implementation doesn't provide a ready-to-use component for this. The JSF 2.0 specification however outlines the following in chapter 13.3.5.2:
13.3.5.2 Monitoring Events For All Ajax Requests
The JavaScript API provides the jsf.ajax.addOnEvent function that can be used to register a JavaScript function
that will be notified when any Ajax request/response event occurs. Refer to Section 14.4 “Registering Callback
Functions” for more details. The jsf.ajax.addOnEvent function accepts a JavaScript function argument that will be
notified when events occur during any Ajax request/response event cycle. The implementation must
ensure the JavaScript function that is registered must be called in accordance with the events outlined in
Section TABLE 14-3 “Events”.
You can find here a blog of one of the Mojarra developers which contains basic examples. Here's an extract of relevance:
<h3> Status:</h3>
<textarea id="statusArea" cols="40" rows="10" readonly="readonly" />
A simple textarea, not even hooked
into the backend server data model.
Then in our javascript (for the demo,
in a separately loaded file, though it
could just as easily be in page) we
have:
var statusUpdate = function statusUpdate(data) {
var statusArea = document.getElementById("statusArea");
var text = statusArea.value;
text = text + "Name: "+data.source.id;
if (data.type === "event") {
text = text +" Event: "+data.name+"\n";
} else { // otherwise, it's an error
text = text + " Error: "+data.name+"\n";
}
statusArea.value = text;
};
// Setup the statusUpdate function to hear all events on the page
jsf.ajax.addOnEvent(statusUpdate);
jsf.ajax.addOnError(statusUpdate);
Related
I have disabled autosave functionality on my crm form using the below code. However it still triggers the save function in my html webresource.
//Javascript on the Form onsave
let eventArgs = context.getEventArgs();
if (eventArgs.getSaveMode() == 70)
{
eventArgs.preventDefault();
}
I am using Vue.js as backend for the html webresource. below is the code i have written:
//Javascript File behind the html
async created: function ()
{
window.parent.Xrm.Page.data.entity.addOnSave(async () => { await saveData(this) });
}
saveData : function()
{
let results = await window.parent.Xrm.WebApi.online.executeMultiple(modifiedrecords);
for (let resultsub in results)
{
const result = results[resultsub];
if (result.ok) {}
}
}
Any help would be appreciated.
You are accessing the web resource's parent form using the window.parent.Xrm.Page construct. This indeed works, but it is not supported and not reliable. (Besides, in Dynamics CRM 2016 accessing the parent page is not possible anymore.)
Entity forms are pretty complex objects that need some heavy processing before the form onload can be called. Contrary, HTML web resources that are integrated on entity forms in iFrames are often lightweight and therefore load quickly. As a result your web resource attaches itself to the onSave handler before the form is able to do that. But, this may vary, depending on the caching behaviour of the browser and other factors. Anyway, when the web resource attaches itself before the form, it is not affected by the preventDefault() down the event pipeline.
You can solve this by giving the onLoad function on the entity form the initiative to load and/or initialize the web resource.
My query is that I have a link that redirects to another page. In webkit browsers, how to force the sitecatalyst server call (script execution) to finish before the redirect happens?
I am using sitecatalyst for a portal. I have
configured the custom link call to include the doneAction parameter for
successful call completion on webkit browsers (As mentioned in Adobe guide).
The custom link code for onClick event of button is as below:
<script language="javascript" >
function search(keyword)
{
var s=s_gi('testing');
s.linkTrackVars="prop11,events";
s.linkTrackEvents="event6";
s.prop11=keyword;
s.events="event6";
s.tl(this,'o','Search',navigate());
window.location=searchresults.html;
}
</script>
<script language="javascript" >
function navigate()
{
return false;
/*To induce a delay to ensure that image request is sent to Adobe before the
user leaves the page.(As given in Adobe guide - code release H.25))
Code version H.25 (released July 2012) includes an overloaded
track link method ( s.tl ) that forces WebKit
browsers to wait for the track link call to complete.)*/
}
</script>
However, even after this, I am getting error in custom link tracking. The redirect happens before the call can complete.
Please help on the same. Thanks in Advance.
Regards,
Harshil
Okay so firstly there are a number of issues with how you implemented it. Here is an example of how it should look like:
search
<script type='text/javascript'>
function search(keyword) {
var s=s_gi('testing');
s.linkTrackVars="prop11,events";
s.linkTrackEvents="event6";
s.prop11=keyword;
s.events="event6";
s.tl(this,'o','Search',null,navigate);
return false;
}
function navigate(){
window.location="searchresults.html";
}
</script>
Some points
You didn't actually post the link or whatever you are using that calls the search function so I have a link shown as an example.
You passed the navigate function as the 4th argument when it should be the 5th (with a null or blank string as a placeholder for the 4th)
It should be navigate not navigate(). The way you did it, you are making a call to the function and passing the result of the function as an argument. s.tl requires the actual function or reference to a function, and it will make the call to the function. In fairness, the Adobe document is typoed: it shows the example wrapped in quotes which doesn't work.
The redirect should be placed in navigate, not in search.
Replace the link href with javascript function
function trackLink(e) {
nextUrl = e.href;
e.href = "javascript:sendData('" + nextUrl + "')";
}
function sendData(url) {
s.tl(this, "o", "Link Name", null, function() {
window.location.href = url;
});
}
or try out the following
function sendData(obj) {
s.tl(obj, "o", "Link Name", null, "navigate");
return false;
}
Link
Link tracking is a dinosaur form of tracking as the numbers are barely accurate these days if you are not putting analytics before user experience. What I don't understand is that why don't you measure this on the next page instead of the link, unless you have no control over the next step?
As for your question: Previous examples on how to prevent link following before event is executed are quite solid, but remember if you have other JS code binded, be sure not to break it. As for the syntax, you can pass all variables to s.tl function as an object without setting linkTrackVars and linkTrackEvents for the s-object, which might have negative effects on events if case you use the code on dynamic pages.
E.g.
...
var data = {
linkTrackVars="prop11,events",
linkTrackEvents="event6",
prop11=keyword,
events="event6"
};
s.tl(this, "o", "Search", data, "navigate");
...
Note: You can't actually use props and events together in standard reporting. As per the code you pasted in comments to Crayon I can see that you are using eVars, so I assume that the example was not that accurate.
I'm working on a web application project using Scala / Lift. I would like to make my application support drag and drop to improve the user experience.
But I'm not quite sure how to bridge jQuery part with Lift.
Currently I've a working UI part, an div block has class named listRow is dragable with an HTML5 attribute data-stuffid which has an ID from database.
It can be dragged to an block named nextAction, and I could print out the data-stuffid field correctly in JavaScript.
Here is my JavaScript code block:
<script type="text/javascript">
$('.listRow').draggable({
revert: true
});
$("#nextAction").droppable({
accept: ".listRow",
tolerance: "pointer",
activeClass: "dropActive",
hoverClass: "dropHover",
drop: function(event, ui) {
var stuffID = ui.draggable.data("stuffid")
console.log(stuffID)
}
})
But I don't know how to call to a Lift AJAX handler, and pass stuffID to Lift in the case.
What I would like to do is have an Scala function likes the following:
def showDialog(stuffID: String): JsCmds
{
// Do some server side work, ex: querying database
// Return a javascript cmds likes SHtml.ajaxButton...etc.
Alert("SutffID:" + stuffID)
}
And when user drag a .listRow to "#nextAction", showDialog would be called, and return the javascript to browser and let browser execute it.
You probably looking for one of these two functions. I'd take a look at :
JsCmds.Function and SHtml.ajaxCall
JsCmds.Function will allow you to create a JavaScript function, and SHtml.ajaxCall will allow you to execute code via ajax. You'd create a function in your Lift CSS Selector and then you'd be able to call that functions directly from your jQuery code.
There are a lot of discussions on using both those, some relevant info might be:
https://groups.google.com/forum/?fromgroups=#!topic/liftweb/4EyE1EbcDDM
https://groups.google.com/forum/?fromgroups=#!topic/liftweb/aAmvSjPxcyI
When initializing jquery from lift, just send lift ajax callback as parameter
I would like to have a central place where I monitor ajax requests and in certain situations abort them.
The only thing I don't know to do is to actually abort the ajax request from one central function.
I Imagine that the solution would look something like this:
jsf.ajax.addOnEvent(function(data) {
if (data.status === 'begin') {
// abort the ajax request
}
});
But I might be mistaken.
Thanks!
This is not possible by the standard JSF JS API. Your best bet is to add an onclick or onchange handler on the calling JSF component which returns false if the desired condition is met to abort the ajax request.
<h:commandButton onclick="return mayFireAjax(this)">
<f:ajax />
</h:commandButton>
You can if necessary abstract this away with jQuery.on() (or jQuery.delegate() or jQuery.live() depending on the jQuery version used) on a common selector so that you don't need to repeat it on every desired component.
$(someSelector).on("click", function() {
return mayFireAjax(this);
});
If you have control the source, you can always attach a onClick to the UICommand component. But in some situation, you do not have access to source. For example, the ajax is provided by some third-party component. You do not want to mess up with their components.
First, I have a small js library.
var FxJSFBegin = "JSFBegin";
if (jsf) {
var originalRequest = jsf.ajax.request;
jsf.ajax.request = function(source, oevent, options) {
var event = $.Event(FxJSFBegin);
event.options = options;
event.originalEvent = oevent;
$(source).trigger(event);
if (event.isDefaultPrevented()) {
return;
} else {
originalRequest.apply(null, arguments);
}
};
}
This piece code proxies original JSF ajax call. It uses jQuery to fire a "JSFBegin" event. Integration code can listen this event using jQuery mechanism. Listener can cancel the jsf call using event.preventDefault().
Requirement:
jQuery
This piece code should be placed after jsf.js is loaded.
Using global="false" will help you prevent calling the ajax status for an ajax call. Please refer to the following link.
Different Ajax statuses for different components in PrimeFaces
How can I show some loading message when making request using <f:ajax>?
If you're not already using a 3rd party component library which could already have a ready-made component for that, such as PrimeFaces with <p:ajaxStatus>, then you can use the JSF-provided JavaScript jsf.ajax.addOnEvent() function (and eventually also jsf.ajax.addOnError()) to hook a function on ajax events.
Here's a basic kickoff example:
<script>
jsf.ajax.addOnEvent(function(data) {
var ajaxstatus = data.status; // Can be "begin", "complete" and "success"
var ajaxloader = document.getElementById("ajaxloader");
switch (ajaxstatus) {
case "begin": // This is called right before ajax request is been sent.
ajaxloader.style.display = 'block';
break;
case "complete": // This is called right after ajax response is received.
ajaxloader.style.display = 'none';
break;
case "success": // This is called when ajax response is successfully processed.
// NOOP.
break;
}
});
</script>
<img id="ajaxloader" src="ajaxloader.gif" style="display: none;" />
See also chapter 13.3.5.2 of the JSF 2.0 specification:
13.3.5.2 Monitoring Events For All Ajax Requests
The JavaScript API provides the jsf.ajax.addOnEvent function that can be used to register a JavaScript function
that will be notified when any Ajax request/response event occurs. Refer to Section 14.4 “Registering Callback
Functions” for more details. The jsf.ajax.addOnEvent function accepts a JavaScript function argument that will be
notified when events occur during any Ajax request/response event cycle. The implementation must
ensure the JavaScript function that is registered must be called in accordance with the events outlined in
Section TABLE 14-3 “Events”.
You can grab some cool ajax loader gifs for free from http://www.ajaxload.info, by the way.
richfaces has a very easy to use component that I use like this:
<a4j:status startText="" stopText="" onstart="showAjaxActive();" onstop="hideAjaxActive();"/>