Firebreath - NPAPI - getElementsByName not working - javascript

I'm trying to call javascript native method getElementsByName to retrieve the list of all elements with the same name (name="").
Here is the code I'm using with Internet Explorer:
std::vector<FB::JSObjectPtr> nameList = DOMdoc->callMethod<std::vector<FB::JSObjectPtr> >("getElementsByName", FB::variant_list_of("name1");
No result is returned. By executing directly the method in javascript, I have the right number of items:
document.getElementsByName("name1")
I also tried to use directly the getElementById which works but returns only one element:
DOMdoc->getElementById("name1")->getJSObject();
Unfortunately I need to retrieve the list of elements for a radiobutton for exemple:
<input type="radio" name="name1" value="value1">Radio 1<br/>
<input type="radio" name="name1" value="value2">Radio 2<br/>
<input type="radio" name="name1" value="value3">Radio 3<br/>
Any help would be greatly appreciated,
Thanks.
UPDATE
Just tried with getElementsByTagName without more success:
nameList = DOMdoc->callMethod<std::vector<FB::JSObjectPtr> >("getElementsByTagName", FB::variant_list_of("name1"));

You didn't specify which browser you're using; I'm guessing you're probably using IE. If not this may not help.
There are some methods like that that can't be called directly from a plugin in IE, you have to use the correct interface. That's why there is a special method on FB::DOM::Element for calling that method.
Try something like:
std::vector<FB::DOM::ElementPtr> nameList = DOMdoc->getElementsByTagName("name1");
I'm assuming, though you didn't specify, that you got DOMdoc by calling m_host->getDOMDocument()
Good luck

Related

why doesn't element.attribute doesn't work in Edge?

I'm creating a small quiz type application in javascript. My html structure looks like this.
<div class="btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary btn-insight" data-target="#myCarousel" data-responseID="1">
<input type="radio" name="options" id="option1" autocomplete="off">
<h5>1</h5>
<p class="mb-0">label for 1</p>
<div class="line-bottom gradient-purple"></div>
</label>
...
</div>
I'm trying to use the custom data attribute data-responseID to determine what answer was provided by the user.
When the program starts, loop through the labels using querySelectorAll and attaching a click listener to each one.
const responseLables = document.querySelectorAll('div.btn-group-toggle > label');
responseLables.forEach(element => {
element.addEventListener('click', function(e){
const clickedResponse = element.attributes[2].value;
determineWhereToSlide(clickedResponse);
});
});
This works well in Firefox and Chrome, but doesn't in Edge. (I'm not concerned with IE 11)
determineWhereToSlide is just a function that gives an alert for now. Eventually it'll be used to push the carousel forward.
I've made a working example and you can see the issue if you open it up in different browser.
https://codepen.io/anon/pen/dLmQKZ?editors=1010
I don't get why this is happening.
*EDIT 1
I just realized that the order of the attributes are different. If you change the index value to ...attributes[1]... then it works just fine. Is there a better way to do this rather than providing an index?
Don't refer to attributes by index (even if it seems it should work, attributes were unordered at least until DOM3). Use any of:
element.getAttributeNode("data-responseID").value
element.attributes["data-responseID"].value
element.getAttribute("data-responseID")
element.dataset.responseID
You can use the getAttribute() method.
replace this
const clickedResponse = element.attributes[2].value;
to this
const clickedResponse = element.getAttribute('data-responseID')

Struts 2 Form Bind Parameters To Collection Without Using Index

Struts Version: 2.3.16.3
Is there a way to populate a list of objects without having to specify the index? Currently I have to reference the collection like so:
<input name="myCollection[0].myProperty" value="some value" />
I really want to be able to do something like this:
<input name="myCollection[].myProperty" value="some value" />
I am dynamically adding and removing elements on the page with JavaScript and it has been a pain to get the indexing right with the JavaScript. Rather just have the backend add to the end of the collection in the order the elements come across from the form. Similar to how PHP processes it.
The docs for the parameters interceptor say that it is really just a ognl expression that the input name is binding to. I went to the ognl docs and it says you can reference array's like this:
array["length"]
which would be the next element in the array. The parameter interceptor is spitting out a message that it is rejecting this parameter name. I would really like to find a way to make this happen, even if it means extending the parameters interceptor.
Well, since
you are manipulating the page with Javascript
you are having troubles detecting / updating the index of elements when adding / removing them
the simplest solution is:
use the syntax you prefer when manipulating them, for example myCollection[].myProperty, and
convert them into the form desired by Struts in a pre-submit function.
This way you don't have to bother with the indexes while manipulating the elements, but only once, at the end, when you can simply loop them by name or something, and change their name with javascript by assigning the right index.
A kick-off example with jQuery:
$(function() {
$('#myform').submit(function() {
$('[name^="myCollection[]"]').each(function(index) {
var oldV = this.name;
var newV = oldV.replace("myCollection[]", "myCollection[" + index + "]");
console.log("was: " + oldV + " - now is: " + newV);
this.name = newV;
});
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="myform">
Open Javascript Console, then press submit, then inspect input elements
<br>
<input name="myCollection[].myProperty" />
<br>
<input name="myCollection[].myProperty" />
<br>
<input name="myCollection[].myProperty" />
<br>
<input name="myCollection[].myProperty" />
<br>
<input name="myCollection[].myProperty" />
<br>
<button>submit</button>
</form>
You need somehow to identify which object some property belongs to. Indexes are simplest way to do that, so you cannot just remove them.
There are many ways to achieve what you want. Look at Andrea's answer for one possible solution using javascript.
You can also pull object properties to simple lists and later set them to object.
E.g.
private List<String> myProperty;
can be referenced in JSP w/o indexes:
<input name="myProperty" value="first value" />
<input name="myProperty" value="second value" />
Of course you if you have many properties you need to somehow sync them in JSP in such way that order and size of the properties in list is consistent for every property.

xml() function in jQuery

There is already the html() function in jQuery.
The problem I am having with this function is that, in its returned html string, all the self-closing / are stripped off from the elements. For example,
<div>
<input type="text" name="textbox1" value="" />
</div>
Becomes:
<div>
<input type="text" name="textbox1" value="">
</div>
I know this is normal for this function since this is valid in html.
But I would like to have a function that returns valid xml so that the / is still there in the returned string.
It seems jQuery itself does not provide such a function, so I wonder if anyone knows of any plugin that can make this possible.
Thanks in advance.
I think you are misconceiving how browsers interpret HTML. They don't keep a copy of your source file and modify it according to your Javascript. Rather, a browser reads your HTML and parses it into a DOM representation. This corrects any mistakes you may have made in your HTML. When you try to get the HTML of an element, the element is converted to a string according to the current DOCTYPE. Since you probably have an HTML doctype (it's quite hard to get a browser to genuinely treat your document as XHTML), you get HTML returned to you.
Doing this in Javascript is almost certainly not the way to go.
I think this is what I need.
Thank you very much for everyone's reply.
http://code.google.com/p/jquery-clean/
UPDATE 1: I thought this plugin would work but actually it does not. The way I use it is that, I pass it the html string returned by html() and let it fix the tags which do not properly self-close.
However, the way it corrects the tags is not what I need (seems like a bug).
For example, passing it the following html:
<div><input type="text" id="txt1" name="txt1"><label for="txt1">TextBox1</label></div>
It gives:
<div><input type="text" id="txt1" name="txt1"><label for="txt1">TextBox1</label></input></div>
Rather than:
<div><input type="text" id="txt1" name="txt1" /><label for="txt1">TextBox1</label></div>
UPDATE 2: The bug I mention above is already fixed. This plugin works now. If you want to test it out, feel free to paste your html in this page and see if it works for you:
http://www.antix.co.uk/Content/Demos/jQuery-htmlClean/Test.htm
You could try using the native .innerHTML property (you cen get the native element using .get() in jQuery).

ASP: Get the value from javascript using getElementbyId

I am trying to get value from javascript using getElementbyId but i am not getting it.
If i put,
<input type="text" id="disprice<% =pID %>" value="<%=disprice%>" name="Price" />
like this then i am getting value from java script in my text box.
But if i try to get that same thing like this,
<span class="productListPrice" id="disprice<% =pID %>">
then i am not getting the value..
Please help me if possible.
Mitesh
Your texbox needs an id.
More details http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_doc_getelementbyid
#mitesh: Here's some sample code that should help --
JavaScript:
var price = document.getElementById('Price');
ASP:
Dim iPrice
iPrice = Request.Form("Price")
HTML:
<input type="text" id="Price" name="Price" value="<%=iPrice %>">
Only input values are transmitted back to the server on a postback and the name is used (not the id). The id is primarily for doing things in JavaScript client-side.
Also, in both cases, getElementById will return the element with the given id. However, the element itself is different (a span as no inherent value). This step may require some more troubleshooting to determine "what" isn't working.

Accessing an array of HTML input text boxes using jQuery or plain Javascript

I'm looking to create a form which contains a dynamic number of input text boxes. I would like each text box to form part of an array (this would in theory make it easier for me to loop through them, especially as I won't know the number of text fields that will eventually exist). The HTML code would like something like:
<p>Field 1: <input type="text" name="field[1]" id="field[1]"></p>
<p>Field 2: <input type="text" name="field[2]" id="field[2]"></p>
<p>Field 3: <input type="text" name="field[3]" id="field[3]"></p>
<p>Field 4: <input type="text" name="field[4]" id="field[4]"></p>
<p>Field 5: <input type="text" name="field[5]" id="field[5]"></p>
This data would then be sent to a PHP script and would be represented as an array - or at least, that's the theory.
So my first question is, is this achievable using HTML? Are forms designed to work that way?
If the answer to that is "yes", how would I then go about accessing each of those using jQuery or failing that, plain old JavaScript?
I've attempted to achieve this using the following jQuery code:
someval = $('#field[1]').val();
and
someval = $('#field')[1].val();
and the following JavaScript:
someval = document.getElementById('related_link_url')[1].value;
But I've not had any luck.
Thanks in advance.
Edit:
I should note that from a Javascript point of view, I've had it working where the ID of each element is something like field_1, field_2 etc. However, I feel that if I can achieve it by placing each text box into an array, it would make for tidier and easier to manage code.
Give each element a class and access the group using jQuery:
<p>Field 1: <input type="text" name="field[1]" class="fields"></p>
<p>Field 2: <input type="text" name="field[2]" class="fields"></p>
<!-- etc... -->
jQuery:
$("input.fields").each(function (index)
{
// Your code here
});
This will run the anonymous function on each input element with a classname of "fields", with the this keyword pointing to the current element. See http://api.jquery.com/each/ for more info.
First of all, id attribute cannot contains [ or ] character.
There is lots of ways to get jQuery/plain JavaScript references to these elements. You can use descendant selector:
<fieldset id="list-of-fields">
<!-- your inputs here -->
</fieldset>
$("#list-of-fields input");
document.getElementById("list....").getElementsByTagName("input");
You can also use attribute selector:
$("input[name^=field]");
I'm not sure whether that's the only way but I think in plain JavaScript you'll have to fetch all input elements (document.getElementsByTagName) and then loop through array of these elements and check each element (whether it has name attribute which value starts with field).

Categories

Resources