I have an infopath form that I want to modify via jQuery. The only problem is that it loads after the pages DOM loads, so jQuery's standard $(document).ready(handler);
won't work here. My question is is there any way to pull a $(infopath).read开发者_StackOverflow中文版y(handler);
of some sort, or a way to maybe wait for the infopath form to get done loading, without just using a standard setTimeout()
.
EDIT 1: So you have more information, the jQuery is within a Content Editor Web Part (CEWP), and the Infopath form is within an Infopath Form Viewer Web Part.
I know using jQuery or javascript with infopath isn't a standard practice, it unfortunately is a necessary one in this situation due to non-ideal functionality from infopath repeated option controls, discussed further in this question.
EDIT 2: From what I can tell, and I may very well be wrong, sharepoint has a js file called core.js, this seems to have functionality for loading, via AJAX, an infopath form into the page. Is there any way I can set a jQuery function to act after a remote javascript file finishes execution?
Try like this: In FormServer.aspx, just above </body>, put this:
<script type="text/javascript">
_InfoPath.OnLoad2 = function() {
_InfoPath.OnLoad();
//Here I will put my custom javascript code, which will be invoked after loading InfoPath form
}
window.onload = _InfoPath.OnLoad2;
</script>
My answer also here: How to check if InfoPath form was loaded (in javascript)
There is a better way, depending on your context. My requirement is to intercept the click
handler on my InfoPath form Save button and do some additional validation that is difficult to do in InfoPath. As the question states, it is not possible to use the normal jQuery $()
function directly because the form isn't loaded at that point.
There is a workaround. SharePoint provides a JavaScript array _spBodyOnLoadFunctionNames
and initialisation functions can be added to this array. By pushing a function onto the array, it will be called after the InfoPath form is loaded:
$(function(){
if (window.location.pathname.match(/Item\/(new|edit)ifs\.aspx/i)){
_spBodyOnLoadFunctionNames.push('CustomInfoPathInit');
}
});
function CustomInfoPathInit(){
$(document).on('focusin', 'input[value="Save"]', function(event){
$(this).attr('onclick', null); // remove standard handler
$(this).off('click').on('click', function(){
alert('click');
});
return (Button.OnClick(this, event)); // original click handler
});
}
The reason I'm using $(document).on('focusin', function(event){...
is because any postbacks from the form (e.g. when the form displays Sending data to the server...) will result in a refresh of the form and any bound handlers will be removed. Using the jQuery $(document).on('focusin',...)
method resolves this issue and using the focusin
event allows the button's original click handler to be removed and the new one re-attached.
I ended up using a timer that checks to see if a label on the InfoPath form has shown up in the DOM:
var InfoPathCheck;
$(document).ready(function(){
InfoPathCheck = setInterval(function() { //Wait for InfoPath to finish loading
HasInfoPathLoaded();
}, 200);
});
function HasInfoPathLoaded() {
var testDiv = $('h4 span:contains("Photo")').html();
if (testDiv) {
clearInterval(InfoPathCheck);
// Do stuff with the InfoPath form here....
}
}
I don't know if this is your problem or not, but if things are still loading after the $(document).ready function, try the $(window).load function. This one fires after all of your libraries, pictures, styles, and other things have finished loading.
Have you looked at XDocument.Onload Event?
According to the API docs, this occurs "after a Microsoft Office InfoPath 2007 form has been loaded, but before any views have been initialized".
Also, take a look at this post that talks about adding your onLoad
handler to SharePoint's onLoad
process.
If finding a hook in infopath (whatever it is) code fails, you can brute force generate an event yourself. Write a function which checks for the done condition somehow using jQuery, and either triggers the event or reschedules itself to run again in 200 ms.
Then write your event handler the usual way. If you ever find a better way you just need to replace the first part.
I have an idea but no time to try it. How about detecting XDocument.OnLoad in jscript and jscript puts a value in hidden input. And then javascript detects the event. I think it will work in IE but maybe not in the other browsers.
精彩评论