Count Upwards for ID jQuery - javascript

I have the following HTML structure
<div id="test-1-yay"></div>
... bunch of code ...
<div id="test-2-yay"></div>
... bunch of code ...
<div id="test-3-yay"></div>
I was wondering how I can use jQuery to basically identify each of these "id's" and then apply some jQuery to them ? I'm new to this so little unsure ? Something like
if $('#test-1-yay' || '#test-2-yay' || '#test-3-yay') {
do stuff to all ID's
}
But the prob is I want this to continue as it could go to #test-201-yay, #test-202-yay etc ?
Thx

Why don't you add a class to the divs?

You could try something like:
$("div[id^='test']")
or
$("div[id$='yay']")
or try to combine the two
Manual

You could use a substring selector to get most of the way there:
var divs = $('div[id^=test-]'); // All divs with IDs starting with "test-"
...which would work better if you changed the naming convention a bit so the number was at the end. But I think I'd lean toward using some other aspect of the structure (the parent node), or a class, or a data-xyz attribute...
Edit A pair of substring selectors can do it:
var divs = $('div[id^=test-]').filter("div[id$=yay]");
That gets all of the ones whose IDs start with "test-" and then filters out the ones that don't end with "yay". Close, anyway...

you could do it like that:
$("div[id^=test-]").each(function(){ //selects all dives having the string 'test-' in it
$that = $(this)
$that.text($that.attr("id").split("-")[1]) //splits the sting by "-" and gives you out the middle part (in your case the number)
})
test it here http://jsfiddle.net/aj5Qk/1/

Related

I'm not able to change HTML in jQuery

I need to change HTML code in jQuery, currently my HTML code looks like this:
<div class="intro-lead-in"><span>Creating quality Foods, Since 1940</span></div>
Expecting HTML code like below using jQuery:
<div class="intro-lead-in"><span>Creating quality Foods,<span class="class-name">Since 1940</span></span></div>
How can I accomplish this using jQuery?
I'm not sure about how do you determine what class names to put and where to split spans, but I'm assuming you wanna do it on commas.
Assuming a container of class intro-lead-in:
First, setup what classes do you want for each text fragment. I'm supposing from your exemple:
fragmentClassBindings = ['', 'class-name']
Then, do the actual replacing...
fragments = $('.intro-lead-in').html().split(',')
fragments.forEach(fragment => {
full = $('.into-lead-in').html()
cls = fragmentClassBindings[fragments.indexOf(fragment)]
$('.intro-lead-in').html(full.replace(fragment, `<span class="${cls}">${fragment}</span>`))
})
However, too much things are assumed here, you really need more explanation in your question. What are you trying to accomplish? What logic leads to the exemple you've provided?

jQuery + JSON - .each not retrieving unique values

This is my codepen: http://codepen.io/JTBennett/pen/OpEeBG
This is the jQuery in question:
$('.gvListing').each(function(){
var cntTxt = $('.dispCntry').text()
$(this).attr('data-country',cntTxt)
var valueC = $('.ddCountry:selected').val();
var valueR = $('.ddRegion:selected').val();
$('#testDiv').text(valueC)
});
(^this all happens at the bottom of the JS on the codepen link)
The issue looks like this:
So the data attribute is being filled up with every .dispCntry div's contents even though I'm doing this function in .each() .gvListing div. I have a feeling I'm missing something stupid, like the letter i somewhere - but I can't seem to get it right.
var cntText=$('.dispCntry').text();
will take every text of input that has .dispCntry class.
It does not concentrate on your .each() .gvListing div.
Either you have to use only one .dispCntry class input, or give unique class or id to each .dispCntry elements

jQuery how to do the following

I've the following question, let say we have a div like this:
These are dynamically formatted divs, with the classes 'row', 'element' and 'isotope-item' are always present. Everything in between can vary per div.
What I want is to the following:
As you see the commmas are no longer there and seperate classes between the commas are now one class.
Anyone any idea?
I already have the following to remove the commas:
$('div.element').each(function () {
var _sCurrClasses = jQuery(this).attr('class');
jQuery(this).attr('class', _sCurrClasses.replace(/,/g, ' '));
});
I would advise doing this backend,but in JavaScript you could:
This will not account for the space in the words though.
You would need to pass then trough separately one by one and replace.
or store them in a data-attribute and format when you need them.
<string>
var classesFormat = classes.replace(/,/g, '');
var classesList = classesFormat.split(" ");
for(String c : classesList)
{
$("#id").addClass(c);
}
</string>
So you could create a data-attribute for each one instead.
Go through each one, format and the add to class.
<div data-id="Microsoft Office," class="test test test">
With the script
$(this).attr("data-id") // will return the string "Microsoft Office,"
or .data() (if you use newer jQuery >= 1.4.3)
$(this).data("id") // will return the Microsoft Office,
And then do your replace after that and addClass.
I don't think classes work like you think they do
the first PICTURE you posted would result in that div having the follwing classes
row
element
Microsoft
Office,
My
SQL,
Page
Rank
isotope-item
Note the , is PART of the class
You want, according to the second PICTURE
row
element
MicrosoftOffice
MySQL
Page
Rank
isotope-item
Removing , is just as you posted ... the problem is, how do you determine which spaces to remove, and which to keep?
(I posted this as an ANSWER, but I KNOW IT IS NOT AN ANSWER)

JSF Set CSS Style Using Javascript?

I have been looking with no success to see if I can dynamically apply a css style to JSF component or div using javascript. Is this possible.
This is pseudo code
<div style="myJSStyleFunction("#{myBean.value}")"> stuff </div>
And the function would return something like "position:relative;left:25px;"
I've had no luck and maybe it can't be done but would like a second opinion.
Edit:
I'm trying to see if I can keep a separation / reduce the coupling between the presentation/view and the model/controller. This is for indenting commenting or product reviews (to nest replies to comments or reviews). The most I really want to track is an integer on how deep a reply is. First level = 0 second level = 1, and so on. So a comment or product review would be 0 deep, a reply to the comment or review would be 1 and so on.
Then in the EL I wanted to call a javascript function and do something like
<script>
myJSStyleFunction(depth){
if(depth<=5){
var nest=20*depth;
var style="position:relative;left:" + nest + "px;";
return style;
}
}
</script>
And then then say for a third level comment (a reply to a reply) it would look like this:
<div style="position:relative;left:40px;"> stuff </div>
where
#{myBean.value}
evaluates to 2
I suspect like Daniel says I'll have to tightly couple the view but I'd rather not have to. I'd think there has to be a way. But maybe not.
I don't know where there are cleaner solutions for this. However this is one suggestion.
Assume your page looks like below and myBean.getValue() method returns an integer.
<h:form id="frm">
<div style="#{myBean.value}"> div1 </div>
<div style="#{myBean.value}"> div2 </div>
</h:form>
So you can do something like this at 'window.onload'.
<head>
<script>
window.onload = function() {
var childList = document.forms['frm'].childNodes;
for(var i = 0; i < childList.length; i++) {
if(childList[i].nodeName == 'DIV') {
var _div = childList[i];
var depth = _div.getAttribute('style');
_div.setAttribute('style', 'position:relative;left:' +(depth *20)+ 'px;');
}
}
}
</script>
</head>
Note: 1. In above sample code I assume all the DIVs inside the form should be indented.
2. For IE you may need to use _div.style.setAttribute('cssText','position:relative;left:' +(depth *20)+ 'px;')
3. Another solution for your question is using <script> tags immediately after your divs and putting the js part inside them. In this way you don't have to use fake styling style="#{myBean.value}" or window.onload event because you can directly call #{myBean.value} in your script.
I decided to skip the javascript approach and settled on a simpler and I think cleaner method to create the dynamic css classes for my situation. I already capture/calculate the depth value for each comment when it is entered. So I am just returning that value in EL and concatenating it to a 'base name' for the css class like so:
<div class="indent_#{(comment.commentDepth le 5) ? comment.commentDepth : 5}" >
comment comment blah blah blah
</div>
"indent_" is the base name for the css class. So for a 0 level comment it will have a class="indent_0". A reply to that comment will have class="indent_1".
I use the ternary so that if there are lot of replies under a given comment it doesn't indent right off the right hand side of the page. Even though you can keep going deeper, it will only indent up to 5 levels.
For my case at the moment, this is a simpler and cleaner method of adding some dynamically generated css class names. Right now I have to define 6 classes for this in the css file, but perhaps I'll figure out how to nest the boxes but it isn't a priority this works just fine for me for now.

Another jquery dynamic selector

I just asked a question here about selecting all id's of the form id_* where * is any string and id is the id of the element. I got a great working solution:
$("*[id^=" + id + "_]").each(function() {... // id is the element name
I need to take this one step further now:
All of my ids will be of the form: a_b_c ... where a b and c are arbitrarity strings (that do NOT contain a ''). So, now rather than selecting all the elems of the form id_* where * could be a_b_c ... I need only to select 1 level deep: i.e. all elems of the form id_a. So in other words it stops at the next ''. Is this possible?
As an example:
If my id is: first
And there exist id's: first_second, first_second_third
It will select only first_second
Sounds like you are storing too many values in the id of the field. With HTML5 we now have data- attributes.
Perhaps, you should be making use of data- attributes something like this to link them?
<div id="a">
</div>
<div id="b0" data-parentId='a'>
</div>
<div id="b1" data-parentId='a'>
</div>
<div id="b2" data-parentId='a'>
</div>
<div id="c" data-parentId='b1'>
</div>
It will still validate, as any non-standard attribute starting with data- will be considered valid.
See: http://ejohn.org/blog/html-5-data-attributes/
Your jQuery selectors can then make use of this new attribute, rather than trying to parse strings
Something like this would select all of a's children
var childrenOfA = $("div[data-parentId='a']);
What I ended up doing (and I'm open to faster implementations) is:
$("*[id^=" + id + "_]").each(function() {
//here I simply split the id and test the size of the array
//if its too large (i.e. too deep in the tree), I return true (to continue
// to the next iteration):
var row = $(this);
var split = row.attr('id').split("_");
if(split.length > SOME_PREDETERMINED_VAL)
return true;
//code here
});
I am not totally happy with this since it still traverses all elements (or would it do this anyway regardless of the filter in the each() function??).
This doesn't give you the whole solution, but you could try the attribute prefix selector or the attribute starts with selector
That will allow you to select any descendant of an element:
$("[id^='a_b_']").each(....
Will think how to remove the grandchildren etc, but this might get you started.
EDIT
I have just found that a similar question was asked about jQuery wildcards - this looks as if it will do what you need.
It seems like you are seriously overcomplicating this task. Let's say your structure is currently like this:
<div id="a">
<div id="a_b">
<div id="a_b_c">
</div>
</div>
</div>
Why don't you just do something along these lines...
<div id="a">
<div class="b">
<div class="c">
</div>
</div>
</div>
So, if I JUST wanted #a .b I would do:
$("#a .b").not("#a .c").show();
Makes it a bit more semantic and readable as well. Am I understanding what you're trying to do? Might need to shed a bit more light on what exactly you're doing
The obvious solution is changing your document, for example instead of
<div id="a"></div>
<div id="a_b"></div>
<div id="a_b_c"></div>
you could write
<div id="a" class="l1"></div>
<div id="a_b" class="l2"></div>
<div id="a_b_c" class="l3"></div>
and then select $('.l2[id^=a_]'). If that is not an option, you could try some sort of sieve scheme:
var set = $('[id^='+id+'_]'), i = 0;
while (i < set.length) {
var e = set.eq(i);
if (e.attr('id').substr(id.length+1).match('_')) {
set = set.not(e);
} else {
i++;
}
set = set.not($('[id^='+e.attr('id')+'_]'));
}
(I haven't tested, so there might be errors, and I'm not sure not is the one that subtracts from a result set, but you get the idea.)
It depends on the document structure and browser whether this will be actually faster than the naive implmentation of simply walking through the while set and skipping everything with two _ in the id. (High number of branches per node helps, and it will be probably faster on browsers which have a native implementation of the CSS3 prefix selector which jQuery can call on.)
update: fixed some mistakes. The logic might change depending on your structure, e.g. the innermost if branch is unnecessery if foo_bar always precedes foo_bar_baz.

Categories

Resources