I am trying to prefill the values of an external widget that it is inserted in the page.
According to the widget's documentation, one can create manually a specific widget with prefilled values, but since I can have hundreds of possible values, that would be very time-consuming and not scalable.
Therefore, I am trying to make it with Javascript or jQuery.
Once the external widget is inserted, its html looks like this:
<ins class="bookingaff" ...>
<iframe src="...>
#document
<!doctype html>
<html>
...
<form id="..." ...>
...
<input class="searchbox__inp ..." type="search" id="b_destination" name="ss" value="" ...">
</form>
</html>
</iframe>
</ins>
I tried several things, but nothing works. Here is an example:
<script>
var widgetDOMs = document.getElementsByClassName('bookingaff');
var widgetDOM = widgetDOMs[0]
console.log('widgetDOM:', widgetDOM); //until here OK, element found. Console is showing the tree structure written above
//with javascript
var innerDoc = widgetDOM.getElementsByClassName('searchbox__inp');
console.log('innerDoc:', innerDoc); // innerDoc: HTMLCollection []
//with jQuery
var innerDoc = $(widgetDOM).find('.searchbox__inp');
console.log('innerDoc:', innerDoc); // length of innerDoc element is 0
//once the elements inside the document widgetDOM can be accessed, I guess adding the value to the form would be straightforward...
</script>
No matter what I try, I do not manage to access any element inside the document inserted with the iframe. How can I do that?
Related
I am experimenting with XForms and trying to dynamically load javascript, but cannot figure it out.
I am presenting a simple example - that is just an input field and button that loads the javascript:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events" >
<head>
<title>Hello World in XForms</title>
<xf:model>
<xf:instance xmlns="">
<data>
<firstName/>
</data>
</xf:instance>
</xf:model>
<script type="text/javascript">
var myFunction = function(){
var name = document.getElementById("firstName").value;
alert("Hello " + name + "!");
}
</script>
</head>
<body>
<xf:label>Please enter your first name: </xf:label>
<xf:input ref="firstName" id="firstName">
</xf:input>
<br />
<xf:trigger>
<xf:label>Click me!</xf:label>
<xf:action ev:event="DOMActivate">
<xf:load resource="javascript:myFunction()" />
</xf:action>
</xf:trigger>
</body>
</html>
So in my script I am trying to get the value from the input box and then show an alert box with concatenated string. Currently, I get "Hello undefined!"
Do you have an idea how to get the value from the firstName xf:input with Javascript?
I know how to do it with XForms only, but this is sort of a proof of concept.
On a side note - I am using XSLTForms, so the XForms runs on the client.
Another hint might be in the fact that XSLTForms transforms the xf:input into several nested span elements with a <input type="text"> element, but that input element does not have a name or id.
With XSLTForms, there are different possibilities...
If you want to access the value of the corresponding HTML input, I would suggest document.getElementById("firstName").xfElement.input.value.
You could also use the node property to get the value stored in the bound node.
Don't hesitate to browse DOM with a debugger to find how to get things from XSLTForms!
--Alain
couldn't find a specfic answer elsewhere. I'm totally new to JS and trying to pull a value out of a form and write it to the page. The result when I try to write ProductName is undefined, and when I try to write ProductNameElement is null. I'm sure it's to do with the form values being empty when the page loads but not sure after that...
<script>
var ProductNameElement = document.getElementById("ProductName");
var ProductName = ProductNameElement.value;
function showname(){
document.write(ProductName);
}
</script>
<h2>Revenues</h2>
<div class="number">Product Name: <input type="text" id="ProductName" value=""></input></div>
<input type="button" value"showname" onclick="showname();"></input>
You are running the first two lines of your script too early BEFORE the elements in your page have been parsed and placed into the DOM. Because of that, the ProductName element doesn't exist yet when you're trying to find it with document.getElementById("ProductName");.
Place your script right before the </body> tag and then all your page elements will be available when you run your script. Or, just put all your code in the showname function that isn't called until the click event.
function showname(){
var ProductNameElement = document.getElementById("ProductName");
var ProductName = ProductNameElement.value;
document.write(ProductName);
}
And, as others have said, using document.write() after the documented has been loaded will cause the existing document to be cleared and a new empty document will be created. This is pretty much never what you want. If you're just doing this for debugging, use console.log(ProductName) and look at the debug console.
You'll have to get the element and the value inside the function, otherwise they aren't available, and the change of the value isn't caught
<script>
function showname(){
var ProductNameElement = document.getElementById("ProductName");
var ProductName = ProductNameElement.value;
document.write(ProductName);
}
</script>
<h2>Revenues</h2>
<div class="number">
Product Name: <input type="text" id="ProductName" value="" />
</div>
<input type="button" value"showname" onclick="showname();" />
FIDDLE
And inputs are self closing, and you should stop using document.write, it will overwrite the entire document and remove everything that is currently there !
I was wondering if its possible to override existing HTML Element attribute and property accessors (getters and setters) with Javascript so that when html is rendered by browser all the assignments to certain attributes in the html code are preprocessed with custom functionality.
Here is an example :
<html>
<head>
<script>
// JS code would go here which would override default behavior
// for example if I wanted to reformat id="name" so its actually
// registered as id="pre_name" once browser renders the html
</script>
</head>
<body>
<!-- here we are assigning the 'name' to id , but behind the scene we really want it to be 'pre_name' -->
<div id="name"></div>
<script>
// when we try to access the id it would actually match the overwritten one
console.log(document.body.children[0].id) // would output pre_name
</script>
</body>
</html>
Is something like that possible and how?
I know that I can traverse the dom after it's rendered and change all of the ids, but I am wondering if its possible to intercept the assignment of properties and attributes and do it at that level before browser even renders the html.
Example I presented is just made up one to present the problem and make is simple to understand.
Thanks
Unfortunately this is not possible, you can only modify the name element after it is loaded.
So it would be something like this:
<body>
<!-- here we are assigning the 'name' to id , but behind the scene we really want it to be 'pre_name' -->
<div id="name"></div>
<script>
// right after
document.getElementById('name').id = 'pre_name';
</script>
<script>
// when we try to access the id it would actually match the overwritten one
console.log(document.body.children[0].id) // would output pre_name
</script>
</body>
or even
<body>
<!-- here we are assigning the 'name' to id , but behind the scene we really want it to be 'pre_name' -->
<div id="name"></div>
<script>
// or here
document.getElementById('name').id = 'pre_name';
// when we try to access the id it would actually match the overwritten one
console.log(document.body.children[0].id) // would output pre_name
</script>
</body>
You can use html data-* attributes for second value like;
<div id="name" data-second="pre_name"></div>
And then you can use,
var div = document.getElementById('name');
div.getAttribute("data-second");
I'd like to refer to a variable ("special") in field later in the same script. I've gotten the variable to display with alert boxes and document.write, but don't now how to make to apply its value to the value field in
var special=(10000-health);
var health=(100);
<input style="background:#FF7777;" readonly="readonly" type="text" value="special" id="special" />
this just writes "special" to the box, when I would like the value instead.
You have to set the value explicitly:
document.getElementById('special').value = special;
Note: You can only access the element after it was parsed in the DOM. To be sure, you can insert this part of the script after the element in the HTML. Often JavaScript code is added just before the closing body tag or is only executed when the load event fires. For more information, see Where to place JavaScript in a HTML file.
Update: Here is an example:
<body>
<input style="background:#FF7777;" readonly="readonly" type="text" value="special" id="special" />
<script type="text/javascript">
var health = 100;
var special = 10000 - health;
document.getElementById('special').value = special;
</script>
</body>
References: getElementById, DOM
MDC's JavaScript Guide is also worth reading.
document.getElementById('special').value = special;
you have to use some kind of DOM manipulation. One of the more popular libraries is JQuery.
using jQuery you'd write something like
$('#special').val(special);
var input = document.getElementById('special');
input.value = special;
I have apex tag that generate input text field.
<apex:page id="my_page">
<apex:inputText id="foo" id="c_txt"></apex:inputText>
</apex:page>
When someone clicks this field, I want to execute javascript.
But when I check the HTML source, this apex tag which becomes input tag has (I think) dynamically generated part.
<input type="text" size="50" value="Tue Nov 16 00:00:00 GMT 2010"
name="j_id0:j_id3:j_id4:c_txt" id="j_id0:j_id3:j_id4:c_txt">
As you can see id has junk part :(
id="j_id0:j_id3:j_id4:c_txt"
In my Javascript I'm trying to getElementById('c_txt') but this does not work of course. How to deal with this???
UPDATE
Seems like I can do this but not working...
<apex:includeScript value="{!URLFOR($Resource.datepickerjs)}"></apex:includeScript>
<apex:inputText id="foo" id="c_txt" onclick="javascript:displayDatePicker()" />
datepickerjs
var elem = getElementById('c_txt');
alert(elem);
The alert shows 'null' so something must be wrong.
Even this alert returns null...
var targetDateField = document.getElementById('{!$Component.my_page:c_txt}');
alert(targetDateField);
You can use the $Component notation in javascript, you use it like so:
var e = document.getElementById("{!$Component.ComponentId}");
One thing to be wary of though, is if your element is contained within several levels of Visualforce tags which have IDs:
<apex:pageBlock id="theBlock">
<apex:pageBlockSection id="theBlockSection">
<apex:commandLink action="{!someAction}" value="LINK!" id="theLink"/>
// snip
// in javascript you would reference this component using:
document.getElementById("{!$Component.theBlock.theSection.theLink}");
I got solution to my problem.
$Compoent global visualforce expression can only be used in visualforce code not inside of
Javascript as far as my search.
Below code works fine. It outputs the value in the inputText field to js alert message Now you can pass id attribute to the Javascript and process whatever the task needed.
Created Date: <apex:inputText id="dah" value="{!created}" size="50"
onclick="javascript:go('{!$Component.dah}')"></apex:inputText>
<script>
function go(field) {
var huh = document.getElementById(field).value;
alert(huh); //returns the string u put inside of input text field
}
</script>