Calling JS function automatically after image is loaded by java backing bean - javascript

I need my JS resizing function to be called automatically after image is returned by java backing bean. This is xhtml part responsible for image loading. It is part of dataGrid.
<p:panel id="panel1" >
<p:graphicImage id="image1" value="#{imageService.image}" width="100%" height="100%">
<f:param name="id" value="#{kprod.id}" />
</p:graphicImage>
</p:panel>
This is bean method:
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
}
else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
return findImage(Long.valueOf(id));
}
}
After completing the rendering phase, it goes to else branch which returns actual image.
I have working JS function resizeImage(). I tested it by adding attribute onclick="resizeImage()" to <p:graphicImage> and then clicked on image and it resized correctly. What I need now is automatic calling of this function.
<p:graphicImage> doesnt have any attributes that I can use. I also tried <p:ajax oncomplete="resizeImage()" /> to involve into <p:graphicImage> node but every time I use ajax this error is returned:
Event attribute could not be determined: null
I also have one sub question. Actual image id in final HTML is contentForm:kprods:7:image1 where number is variable according to order. Is there a way how to pass to JS id of the element as a parameter?
Thanks a lot.

Well I found solution. Basically all I needed was to run my function on load event. But primefaces element <p:graphicImage> doesnt have onload attribute.
So I added to my xhtml new namespace for passthrough attributes:
xmlns:x="http://xmlns.jcp.org/jsf/passthrough".
And added x:onload attribute to graphicImage element:
<p:panel id="panel1" >
<p:graphicImage id="image1" value="#{imageService.image}" x:onload="resizeImage(this.id)" width="100%" height="100%">
<f:param name="id" value="#{kprod.id}" />
</p:graphicImage>
</p:panel>
Then I inspected final HTML and there was onload attribute with my function added to <img> element.

Related

How to use jQuery .find() to retrieve a value from an embedded object

The following code is embedded in a multiview, all I want to do is access the Doc1Amount1 TextBox value, that is part of the BodyCode div, which is loaded into the DocBody div.
<asp:View ID="Tab2" runat="server">
<div class="HeaderLine">02: Documentation</div>
<br />
<asp:HiddenField ID="HiddenField1" runat="server" />
//a<asp:Label ID="Label1" runat="server" Text ="Label1"></asp:Label>b
<div id="DocBody" />
<script>
$("#DocBody").load('LabReportContent/DocumentationSub.aspx #BodyCode');
$(window).load(function () {
var current = $('#DocBody');
$("#HiddenField1").val(current.contents().find("#Doc1Amount1").val());
});
</script>
</asp:View>
The div is overwritten successfully, and all the loaded objects are showing as expected, but the find command is bringing back a blank value.
I initially wrote this without the $(window).load, and thought the contents of Doc1Amount1 weren’t showing because the page wasn’t loaded properly.
But the same thing is still happening after adding the window load to this.
Any help would be appreciated, as I'm relatively new to jQuery.
You don' need contents(). And you should execute the code simple after the load, because window load may be to early. You can use the callback of the .load() function.
$("#DocBody").load('LabReportContent/DocumentationSub.aspx #BodyCode', function() {
var current = $('#DocBody');
$("#HiddenField1").val(current.find("#Doc1Amount1").val());
$("#Label1").text(current.find("#Label1").text());
});
And you can select the child elements directly by context too, without using find.
var current = $('#DocBody');
$("#HiddenField1").val($("#Doc1Amount1", current).val());
$("#Label1").text($("#Label1", current).text());

Converting aspx page to WebUserControl

I am running into an issue when converting an ASPX page to a controller (ASCX). My JavaScript isn't finding a textbox in a hidden div and its not firing an onclick event either. However it works perfectly fine in the ASPX page.
My JavaScript is..
function FireEditClickButton() {
document.getElementById("btnFireEdit").click();
}
Its supposed to fire this button that is in a hidden div along with the next piece)
<asp:Button ID="btnFireEdit" runat="server" OnClick="btnFireEdit_Click" />
Then with this JavaScript
function GetSelection() {
var c = document.getElementById("tbRA");
c.innerText = checkListBox.GetSelectedValues();
UpdateText();
}
gets called everytime the checklistbox has values.
Both errors are saying that they are null but they are right here in a hidden div
<div style="visibility: hidden">
<asp:TextBox ID="tbRA" runat="server"></asp:TextBox>
<asp:Button ID="btnFireEdit" runat="server" OnClick="btnFireEdit_Click" />
</div>
So why would this be happening since it works completely fine in the ASPX page? would it have to do with the WebUserControl not using a form tag?
Thanks
Your javascript cannot find the button because in the rendered HTML it no longer has id="btnFireEdit" but instead an id based on the name of the usercontrol (e.g. id="myctrlname_btnFireEdit").
You have two choices... either update the javascript to include the name of the usercontrol...
document.getElementById("myctrlname_btnFireEdit").click();
document.getElementById("<%=btnFireEdit.ClientID%>").click();
(Note, the 2nd of these two lines will only work if the javascript is part of the usercontrol itself. It will not work if the javascript is in an external .js file or the parent page)
Or use the ClientIDMode attribute of the <asp:Button> and set the value to Static. This will make the rendered HTML use id="btnFireEdit"...
<asp:Button ID="btnFireEdit" runat="server" OnClick="btnFireEdit_Click"
ClientIDMode="Static" />
When using nested controls (or pages nested in a master page), by default the ID on the client side will be different than on the server. ASP.NET does this by default to help ensure that all ID's on the client are unique. However, you can prevent this using one of two ways.
The first option is to change the ClientIDMode to static. You can do this at the control, page, web.config, or machine.config levels. The web.config technique is shown below. The ID on the client will then match the ID on the server.
<configuration>
<system.web>
<pages clientIDMode="static" />
</system.Web>
</configuration>
The second option is to use inline C# code to embed the ID into your JavaScript, but this only works if the JavaScript is embedded on an ASP.NET page or control and not in a separate script file. The C# expression will be evaluated and therefore the ID on the client will be embedded into the JavaScript.
document.getElementById('<%= btnFireEdit.ClientId %>');
There is a third option, and that is to figure out what the ID will be on the client and then manually put that in the JavaScript, like this:
document.getElementById("myctrlname_btnFireEdit").click();
However, that is a bad idea. If you ever rename either myctrlname or btnFireEdit then your client side code will fail at runtime. And it's always better to fail at compile time than runtime.

JSF execute javascript after f:ajax

In my JSF 2 web application, I use the following code to display and switch the contents of a rich:dataTable according to the selectedStatus:
<h:selectOneRadio id="statusSelection" value="#{backingBean.selectedStatus}" style="width:auto; float:left;">
<f:selectItem itemValue="AVAILABLE" itemLabel="Available" />
<f:selectItem itemValue="INACTIVE" itemLabel="Inactive" />
<f:ajax render="itemsDataTable" execute="#{backingBean.sortByTitel('ascending')}" />
<f:ajax render="itemsDataTable" event="click" />
</h:selectOneRadio>
The dataTable contains a4j:commandLink s, which unintentionally need to be double clicked in some IE versions after changing table content - I found out, that executing the following Javascript code (on IE's debugging console, after table contents have changed) solves the issue:
document.getElementById(<dataTableClientId>).focus()
My question is: How can I achieve automatic execution of the javascript code after the table contents have changed?
In order to execute JS code after the <f:ajax> is successfully completed, the following inline solution will do:
<f:ajax
render="itemsDataTable"
onevent="function(data) { if (data.status === 'success') {
// Put your JS code here.
document.getElementById('dataTableClientId').focus();
}}" />
Or the following external function solution (note: do not put parentheses in onevent, only the function name):
<f:ajax
render="itemsDataTable"
onevent="scriptFunctionName" />
function scriptFunctionName(data) {
if (data.status === 'success') {
// Put your JS code here.
document.getElementById('dataTableClientId').focus();
}
}
Also take a look at this answer: JSF and Jquery AJAX - How can I make them work together?
Also, double check the need of the event="click" in your f:ajax , because the default event in <h:selectOneRadio> is change which I think you better use... See also What values can I pass to the event attribute of the f:ajax tag?

Access javascript document in asp.net code behind

I am trying to access javascript document from ASP.net page code behind. How do I do same thing as below in c# code behind?
document.getElementById(id).src = "myurl.com"
Thank you for your help.
Add runat="server" and an ID to the element. You should then be able to access the src via the attributes collection.
<img src="http://www.google.com/img.png" id="imgGoogle" runat="server" />
Dim src as String = imgGoogle.Attributes("src")

jsf ajax call: executing javascript function in the end

I'm working with JSF 2.0 and here's my form:
<h:form id="fff" onsubmit="reloadMap();">
<h:selectOneMenu value="#{rentCarPoolBean.state}">
<f:selectItems value="#{rentCarPoolBean.stateList}" id="stateList" />
<f:ajax event="change" render="cities stateSelected" onevent="showAlert"/>
</h:selectOneMenu>
<h:selectOneMenu id="cities" value="#{rentCarPoolBean.city}">
<f:selectItems value="#{rentCarPoolBean.cityList}"/>
</h:selectOneMenu>
<h:outputText value="#{rentCarPoolBean.state}" id="stateSelected" />
</h:form>
And the javascript function:
<script type="text/javascript">
function showAlert(data){
if (data.status == "complete")
alert(document.getElementById("stateSelected"));
}
</script>
What the above code does is on selecting a state from the first dropdown, it makes the ajax call and renders the 'cities' dropdown and the 'stateSelected' outputText.
Also, it calls the showAlert() javascript function.
What I want to do is call the javascript function after all the data is returned and both the dropdown and the outputText have been rendered.
But currently the javascript function is called before the elements are rendered and the alert displays null.
How do we make the javascript function execute in the end?
You need to hook on a status of success instead. This will run after the HTML DOM tree has been updated. The status of complete runs directly after the ajax response has been returned. This is admittedly a misleading status name, but you should try to interpret it in context of "HTTP request" like as the begin status.
Another problem is that the document.getElementById() selects items by the HTML element ID, not by JSF component ID. You need to give it exactly the ID as JSF has generated to the HTML. You can figure the right HTML element ID by viewing the page source in webbrowser.
All with all, your new function should look like this:
function showAlert(data){
if (data.status == "success")
alert(document.getElementById("fff:stateSelected"));
}
Here:
alert(document.getElementById("stateSelected"));
you're specifying only JSF component id, but you need to give a full clientId. Here's a link explaining this.

Categories