How binding attribute of inputText can effect javascript method? - javascript

I am using jsf and liferay. I am very new to it. For any javascript method which select any element of jsf for some javascript or jquery method I need to set it like.
<h:inputText id="abc" binding="#{abc}"/>
Please note that I have set binding same as id, somebody has told me to do like that. Without setting binding like that I was not able to select any element in my javascript method. I really dont know the reason. Since this was working for me so I have used it, without going in detail
But now for some functionality I really need actual use of binding, bind UIInput to managed bean. So I have changed my tag like.
<h:inputText id="abc" binding="#{mybean.uiAbc}"/>
In this case my javascript method like
function doSomething(){
$("##{abc.clientId}").val("hello everyone");
}
its not working. Its giving me exception like... # is undefined..
In javascript I have nothing to do with binding so why it stops working now? And why it was working earlier with same value of binding as id have?

If you replace binding="#{abc}" by binding="#{myBean.uiAbc}", then you should obviously also change #{abc.clientId} elsewhere in the view by #{myBean.uiAbc.clientId}.
function doSomething(){
$("##{myBean.uiAbc.clientId}").val("hello everyone");
}
That the id and binding need have to be the same name is complete nonsense.
The only problem which you may face is that the default JSF naming container separator character, :, is a special character in CSS selectors, like as used in jQuery, and thus this construct would possibly fail. This construct would only work if you've manually reconfigured your JSF webapp to use a different, CSS-safe, character like - or _. If you indeed use the default of :, then you should use
function doSomething(){
$("[id='#{myBean.uiAbc.clientId}']").val("hello everyone");
}
See also:
How to use JSF generated HTML element ID with colon ":" in CSS selectors?

Your myth for following is wrong, i.e. to have same id and binding attribute.
id="abc" binding="#{abc}"
JSF renders component with id which provided by us with preceding by form id. e.g. in your case it will be,
:formId:abc
to avoid prepending form id just set prependId attribute to false. it will render the component with id "abc" only.
Also if your component is naming container e.g. dataTable. Then you the method accessing client id is different.
In short just right click in your browser and check the element's id and you can find the id to the jQuery.

Related

How can I add a disable class to a single select, not all of that I have

I want to put a disabled class into my select, but when I do this:
$("input").attr("disabled",true);
//I tried to to this but it didn't work too:
$("#myId").attr("disabled",true);
It disable all of my selects and not one.
How can I disable only "myId"?
Without seeing your HTML (which at the time of writing has not been supplied) it's very difficult for us to tell you why it's not working.
However, if $("#myId").attr("disabled",true); isn't working, then it suggests to me that you do not have an element in your HTML with id='myId'.
Things to check in the rendered HTML (as seen by the browser, not your code)...
Is there an element with an id of myId
Is the id exactly myId, and not myID for instance (as the case is important)
Are you using something like ASP.Net where naming containers could be changing the id of the rendered control to something like ctl00_myId
Do you have 2 elements with an id of myId... in which case, this is invalid HTML, as each element must have a unique id, and would result in jQuery only setting the disabled on the first item
It disables them all because $("input").attr("disabled",true); adds the attribute disabled to all input elements. Without seeing your HTML it's hard to tell what the reason is for it not disabling when you try using #myId
Here are some mistakes I've made in the past for similar problems:
1) I did not actually have the id on the element that I thought I had. Whether it was a misspelling, or capitalization difference, or underscore vs dash...the point is the id I was trying to reference on the page simply did not match the one I was looking for with jQuery
2) I referenced it as an id but really it was a class or vice versa. . for classes, and # for id's is second nature, but sometimes if you're tired or exhausted you can very easily make that mistake
3) I had given an id that existed in multiple elements. id is supposed to be unique by convention. Duplicate id's will produce unexpected behavior
Hopefully one of these simple reasons is the cause for your issue and you can quickly resolve it. Maybe take a 30 minute break and come back to it.

jQuery caches elements selected?

So I'm using this code to:
$('.something').on('click', function () {
console.log($(this).data('id'));
}
And for some reason, if I modify the data-id using the inspector, jQuery still sees the id that was there in the beginning. However, I tried the same thing using JS and it does see the changes. This makes me wondering if jQuery caches in some way the elements selected and uses them instead of the actual DOM.
Can someone please explain what happens and how jQuery does the event binding in the background?
Later edit: I want to specify that I'm talking about the "data-" attribute that I put in the HTML, not about the '.data()' provided by jQuery. Not sure if it's the same thing.
jQuery caches elements selected?
No. But the data managed by data is stored in an object cache maintained by jQuery, keyed by a unique identifier jQuery adds to the element (so it can look up the data). data is only initialized from data-* attributes, it is not an accessor for them. It's both more and less than that.
If you're interested, you can see that as an "expando" property on the element instance, it'll start with "jquery" and have a long number attached to it (currently; it's undocumented — for good reason — so this may change):
var foo = $("#foo");
console.log(foo.data("info")); // hi there
console.log("Expando name: " + Object.getOwnPropertyNames(foo[0]).find(name => name.startsWith("jQuery")));
<div id="foo" data-info="hi there"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Is it bad form to use html class attribute as a variable

I am wondering if the html class attribute should only be used for styling. Is there any drawback to using the class attribute as a variable. The W3 spec http://www.w3.org/TR/html5/dom.html#classes does not specify one way or another but, all examples and training point in the direction of styling only for multiple objects.
In my case I want to use the class attribute as variable that matches the key value in a object array. For example in my Javascript code I have an object that has a number of key/value pairs. On my web app I have a number of save buttons. When a save button is clicked I grab the parents class attribute value and use it as the key for the object to know which value to change. The class attribute on the parent has not other value than to let me know which key value pair to change in my object
While I'm sure it's possible to use classes that way, it's certainly not their intended purpose. html has data attributes that provide the functionality you want, for example
<button data-key="some value" name="" id="">click me</button>
You can then get that value (onClick if you like) and use it as a key for your object/data structure. Theres a good overview here
While it is not bad, it neither is best practice.
You can, instead of using the class attribute, define explicit data attributes. Using the class attribute would mean that you could not use several classes (because that would be a weird key to search for in an object, right?).
For instance:
<div class="any classes you like" data-mykey="searchforthiskey">
<button></button>
</div>
In jQuery:
$('button').click(function() {
var key = $(this).closest('div').attr('data-mykey');
});
From a functional perspective, there's no reason to NOT use the class attribute to store information about that element. You can access a class attribute as easily as you can a data attribute.
From a standards perspective, it is probably better to use a data attribute. Why? Well, if you are the only person working on your front-end, no big deal. If you are one of many on a team of front-end developers, who works specifically on the javascript side of things, you may run into a conflict with another front-end developer who works on the HTML/CSS side of things. They may remove a class from the element, not realizing that its also being used as your javascript hook into that element. In that case, you're better off creating your own data attribute, which then makes it clear that this attribute is probably data related and won't be molested by someone just trying to fix the styling of that element.

Get Forms (Jquery vs Javascript)

What would the equivalent of
document.forms[0].submit();
...be in jquery format? I know it would look like something similar to:
$("form").submit()
But i'm not sure how to just send a general form without knowing it's id
Since your javascript code is trying to submit first form in the page, in jQuery you've multiple ways to achieve it, one way is to use .first():
Reduce the set of matched elements to the first in the set.
$("form").first().submit()
$("form").eq(0).submit()
Given a jQuery object that represents a set of DOM elements, the .eq()
method constructs a new jQuery object from one element within that
set. The supplied index identifies the position of this element in the
set.
The first submits the first form on the page.
The jQuery equivalent would be:
$("form:eq(0)").submit();
But if it works in plain JavaScript, you shouldn't change it to jQuery! If it isn't broken, don't "fix" it!

Accessing html field values in JSF framework

By default JSF renders the HTML field id name dynamically. ID name is generated randomly in the format formname:id_some_random_number.
Because of this i cannot use document.getElementById("").
Is there any solution for this problem?
If all else fails, you can try giving the elements unique css classes and then accessing them via getElementsByClassName(). Or try browsing the childNodes() of an element with known id. Or you can add a node with known id inside your target element and then use .parentNode :)
You just need to specify the ID of the input.
However, note that the ID will be prefixed by the ID of the form that contains the input field.
For example:
<h:form id="myForm">
...
<h:inputText id="myInput" .../>
the real ID of the inputText is myForm:myInput.
Thus, this Javascript code will work:
var obj = document.getElementById("myForm:myInput");
Edit (for precision)
To be more precise, if a component implements the NamingContainer interface in Java, then all the nested components will have their ID prefixed by the ID of this component. This is the case for the <h:form/> component, but also for <h:datatable/>.
You can get the generated ID by using UIComponent.getClientId (JSF 2, if you can use it, adds a no-arg version that makes this more useful with EL expressions). See this blog post for tips on working with JSF component identifiers (though note the caveats).

Categories