JSP, Javascript, getting ElementId within another Id - javascript

my question today revolves arround the world of javascript in a Websphere JSP environment...
I have a code that is somewhat like this:
<div id="randomDynamicId">
<input id="whatIwantToGetTo">
</div>
I know that I could just look for that id directly, but this is in a Websphere portal, I "should" be able to link to it directly by document.getElementById(), but I always need to acquire the id of the prior div.
(it ends up being the portlet id with the namespace and since sometimes these portlets might be replicated I want to target just one specifically)
Any way that I might be able to do this?
Thanks in advance.

As per your request I post my earlier comment as an answer, a little more elaborated: If the issue is that whatIwantToGetTo is not namespace-prefixed so that you end up with multiple elements with the same id on your page, you should rewrite your JSP to namespace all id attributes as well. This should probably be done anyway (if you can modify the HTML, that is), at the very least if there is a possibility of the portlet occurring more than once on any page!
However, seeing as you're on a WebSphere Portal 7, you most likely have Dojo around and you could leverage its CSS-style selector mechanism like so:
var inputElement = dojo.query('#randomId > input');

What you want is
document.getElementById ('whatIwantToGetTo').parentNode

If you can use jQuery, you can accomplish this like so:
var parent = $('#whatIwantToGetTo').parent();
See Here
The pure javascript alternative is something like this:
alert(document.getElementById('objectIWant').parentNode.id);
See here

Related

Is there a better way to do innerHTML?

I want to know if there is a better way to be doing innerHTML than what I do here. The way I am doing it is causing problems because of the fact that I can't have triple nested quotes. along side that, it is really hard to look at and manage. Thanks!
function buttonClicked(buttonValue)
{
switch (buttonValue)
{
case 1:
soundFolders.innerHTML = "<li onClick='buttonClicked(11);'>Thunder 1</li> <li onClick='buttonClicked(13);'>Light Rain 1</li> <li onClick='buttonClicked(0);'>Back</li>";
break;
case 11:
if(!thunder1Control)
{
thunder1.play();
var thunder1Control = document.createElement("li");
soundList.appendChild(thunder1Control);
thunder1Control.innerHTML = "<h3>Thunder 1</h3> <button class='stopSound' onClick='thunder1.pause(); thunder1.currentTime=0; thunder1Control.parentNode.removeChild(thunder1Control); '>X</button> <button class='volDown' onClick='thunder1.volume -= 0.25;'>-</button> <button class='volUp' onClick='thunder1.volume += 0.25;'>+</button>";
thunder1Control.setAttribute("class", "playingSound");
}
P.S. Do you guys know why the thunder1Control.parentNode.removeChild(thunder1Control) is not working?
To your first question about another way to approach this type of code, "best" is a matter of opinion so I won't really try to address what is best. But, I will give you some alternatives:
Avoid putting code into strings in your HTML. There are all sorts of limitations with that and you generally want to separate code from presentation anyway.
Install event handlers in your code with obj.addEventListener() instead of putting event handlers and code in your HTML.
Use classes and IDs or DOM queries from a particular point in the hierarchy to retrieve specific objects in your page rather than trying to save references to them in global variables. In plain javascript, element.querySelectorAll() is pretty powerful.
In many cases, it's much simpler to just hide and show blocks of HTML using obj.style.display = "none" and obj.style.display = "block" than it is to dynamically create and destroy HTML and this has the added advantage of the HTML is all specified in the page and doesn't have to be shoehorned into a javascript string.
For large blocks of dynamic HTML that wouldn't work well with hide/show for whatever reason, you can dynamically load snippets/templates of HTML from your server using ajax or you dynamically create the HTML using javascript. My first preference is generally hide/show and then if that isn't practical for some reason, it depends upon how much the HTML I want to insert varies based on the state for whether I'd rather load a template or create it dynamically using javascript. If you have large blocks of HTML you have to fit in your javascript, it is messy with quoting, etc... - no way around that if you go that route other than using one quoting scheme for the JS string delimiter and the other in your HTML.
In your particular case, it sure looks like the hide/show method would be simple.
To your second question, this line of code:
thunder1Control.parentNode.removeChild(thunder1Control)
does not work because the thunder1Control variable is long, long out of scope when your click handler is executed because it's a local variable in your buttonClicked() clicked function.
When you put code into a string as part of HTML, it is evaluated in the global scope only so any variables that it tries to reference, must themselves be global in scope.
I'd suggest that you NOT put code into strings in your HTML like that. Use references to actual javascript functions. In that particular case, I'd have to see your HTML to know how to best advise you. If there is only ever one thunder1Control, then I'd suggest you just put an id value on it and retrieve it with document.getElementBtId() when you need it rather than trying to save a reference to it in a variable.
There are essentially two other ways that I can see:
Use a framework that helps with this kind of things. Others have
mentioned jQuery. A commenter is arguing that it might be overkill
to include a framework for just this. I would argue that if you're
doing any javascript at all, you should be using a framework to
make it less terrible. But continue onto suggestion 2 if you
disagree!
You can create each of the elements via plain old javascript and append it to the elements that you need, instead of inserting it directly into innerHTML. ex.
var li = document.createElement("li");
soundFolders.appendChild(li);
etc...
But, honestly, use jQuery with some of the suggestions from others. It's pretty small, and it will heavily clean up all of your javascript. Include it via Google and it will likely already be cached in the users browser.
https://developers.google.com/speed/libraries/devguide#jquery
I think a better alternative is to use jQuery, and then instead of using .html() (equivalent of innerHTML in jQuery), you can create a template with your html and use .load() instead. Works nicer and it's cleaner. And you don't have to worry about triple nesting quotes as you said.
Edit: I'm not sure why I'm getting downvoted so much here... The poster doesn't want to worry about triple nesting quotes. A simple and, to me, elegant solution is to use .load() and to create a template, rather than a really long string of html...

Any value in JavaScript/HTML Decoupling? if so how?

Lately I've been writing more and more JavaScript for the websites I've been creating. And I can't help but think that I'm doing something wrong, or there has to be a better way.
I have a clean separation of concerns on the server side, but on the client side, I find myself having entire sections of JavaScript that are dependent on specific element id's and class names, etc. For example, on one page, that has a lot of form fields, I may have a section of code that looks like:
$(document).ready(function() {
$("#ButtonID1").button();
$("#Grid").someGridFunction();
$(".data-fields").datepicker();
$(".submit-links").click(function() { this.closest("form").submit(); });
});
What I'd almost prefer is some way for the HTML elements to request to obtain certain functionality. Something like:
<input type="text" data-make="datepicker" />
But even that is flawed, because customization of that would require more and more attributes on the HTML element to detail specifics. I had a similar setup done with KnockoutJS and I really wasn't happy with the HTML that was required.
Maybe something along the lines of this:
<input type="text" data-init="buildDefaultDatePicker" />
where "buildDefaultDatePicker" is a JavaScript function that handles the necessary work.
In the end, the question I have is two fold. Is there any value in separating the JavaScript from the UI in regards to specific element ids and class names. And if so, what patterns, and or methods have you used to achieve this?
(Note, I'm using jQuery syntax above, but I think this question is framework agnostic, so shouldn't matter for the answers)
It looks to me like you've got the right idea already (using classes to apply JavaScript enhancement to specific elements). Using a custom attribute such as data-make or data-init would be just another (more fiddly) way of doing the same thing. The way you have things already, specific classes can be used as the request to obtain certain functionality.
The method I'd advise is keeping a clean separation between your HTML and JavaScript. The JavaScript should always be in external files, and written to target page elements on $(document).ready to provide the requested functionality.
I'd just use a class to signify the elements you want to attach behavior to. It has a semantic meaning, and you aren't coupling the html IDs or their locations into the javascript.
In the likely event that you need some specifics, like say a minimum or maximum date on a date picker, a light sprinkling of data attributes I think is an elegant way to provide it. But anything that would require more than a few data attributes is probably, in reality, a whole new kind of thing that deserves its own class, thus removing the need for the data attributes. For example, you might have a datepicker class, and find yourself constantly providing a minimum date of today to force a future date selection. Well, just make a 'futuredatepicker' class instead.

Giving my Hyperlinks custom attributes

I would like to give all of my URL's attributes. There are probably about 400 on each page. Sometimes only 40, just depending on which type of product is being viewed.
I would like something like this:
Stainless Steel Bolts
How can this be done?
I know that in HTML5 there is some kind of data thing, but I can't find it yet, so maybe I misread something somewhere.
Basically, when any one of those links are clicked, I will (PHP) insert that product into their shopping cart in the database. But, based on the attributes of any given link, I may need to do some calculations/adjustments/etc before I insert them into the DB.
And this seems like the only simple, logical (and somewhat fun) way to go about doing this. But I'm not sure about compatibility between browsers, or whether it's even valid or not.
You're right, it's the data- attribute you're looking for. [random reference]
Your link would look something like this:
<a data-partno="DBF-XJ3" data-qtyType="Box QTY" data-quantity="50">
Demo here: http://jsfiddle.net/wesley_murch/ey2pg/
It's really just a javascript hook, and since jQuery seems to handle it well in all browsers I checked (including IE6), I would say its "safe" to use. As far as I know, you can even make up attributes and it will work with jQuery (although it's not recommended). This is really the best way to avoid abusing rel and title and such (as a lot of people do), just for javascript interaction.
However: I would highly suggest using a <form> with hidden <input>s (and a <button> for easy styling) to submit the values. The other way is broken without javascript, you can enhance it with jQuery afterwards.
You'd do it like this:
$(document).ready(function(){
$("a[href]").each(function(){
if($(this).attr("href") == "link.html"){ //I put a condition here just in case you need one
$(this).attr({
"partno": "DBF-XJ3",
"qtyType": "Box QTY",
"quantity": "50"
});
}
});
});
If all your links need the same attributes, you can remove the condition.
Hope this helps. Cheers
PS: It will work in every browser, however HTML5 recommends to prepend the 'data-' prefix to your custom attributes. Example data-partno="DBF-XJ3"

write html content from javascript

There's one thing I want to do with javascript, but don't know how. In a perfect world it would look like this:
<p>My very cool page!</p>
<script type="text/javascript">
document.write('<div>some content</div>');
</script>
And this script would insert <div>some content</div> right before (or after, or instead of) script tag. But in the real world, document.write starts writing html anew, removing any static content in the page (<p> tag, in this case).
This is simplified example, but should give you the idea. I know that I can statically put <div id="some_id"></div> before script tag and insert html in it from js, but I wanna be able to use multiple instances of this snippet without changing it (generating random id manually) each time.
I'm ok to use jquery or any other existing library as well. Is there any way to achieve this? Thanks!
We are actually in that perfect world...
and your example would work as it is ..
http://www.jsfiddle.net/BtKGV/
Yes, but you always add or write it in relation to something else.
If you wanted to write something AFTER the first p tag, in jQuery, you could do something liek this
$('p:first').after( '<div>some content</div>' );
If you look at jQuery's API you will see they have many functions for this, such as before, after, append, etc.
You also might want to read about adding and removing elements to/from the DOM, such as in this article:
http://www.dustindiaz.com/add-remove-elements-reprise/
look up appendChild()
To close the question, here's how it has worked out in the end.
The trick was to store each widget's data in html tag, not in javascript. User inserts content like this
<div class="my_widget" feed_id="123"></div>
...
<div class="my_widget" feed_id="456"></div>
User also links script from our server. When page's loaded, script does $('div.my_widget').each and populates contents of each widget depending on its feed_id and other attributes.
Thanks to everyone (and +1 to Gaby and Kerry for attempts to help with such vague problem)

jQuery iFrame manipulation

I'm facing a problem while working with iFrames. What I need to do is, get the contents of a division 'contents' , display it in an iframe, and then remove all forms/form elements ONLY in that iframe. When i use $("#form").remove(), it removes the form both in iframe and in the window. Can someone help?
Thank You.
You can wrap the iframe in a DIV with an ID and remove forms only inside of that. Can you post some code? Would be easier to work off that. Or just grab the iframe (although I'm not sure it will work, haven't tested it).
$("iframe").find("#form").remove();
Do both the forms have the same id (#form)?
Give them separate ids (eg: <form id="inner"> and <form id="outer">) and you should be able to target them individually: $(#inner).remove()
I don't know it in jQuery but I think that this in strait javascript might help you.
var forms = document.getElementById('iframe_id').getElementsByTag('form')
for (var form in forms) {
forms[form].parent.removeChild(forms[form])
}
Disclaimer: I havn't tested this code, but with some debugging it should work... eventually. I just put it here so you maybe can guess to what you need to to do.
Perhaps the jQuery (now I'm just guessing) that you need is something like:
$('iframe_id').('#form').remove()
Or maybe dlabaeb's code already posted.

Categories

Resources