jquery Remove siblings elements, doesn't work in IE7 - javascript

I'm trying to remove all the sibling elements after a particular div, lets say the div tag with id = id8.
<form>
<div id="id5">something ...<div>
<div id="id8">something ...<div>
<div id="id3">something ...<div>
<div id="id97">something ...<div>
<div id="id7">something ...<div>
...
<div id="idn">some text ...<div>
</form>
To do that I use the following code in jquery.
$("#id8 ~ div").remove();
It works fine in Firefox, but It doesn't work in IE7.
Is there an alternative way to archieve this, using jquery and just giving the tag id from the element I want to start removing the elements?
Thanks
Thanks everybody for your help
I end up with this solution based on the accepted answer
function removeAfter(el,tag){
element = $('#'+el);
var aElements = $(tag,element.parent());
var index = (aElements.index(element));
for(i=(index+1);i<aElements.length;i++) {
$('#'+$(aElements.get(i)).attr('id')).remove();
}
}
just call
removeAfter('id8', 'div')

Two things!
1) Close your <div> tags! It should look like this:
<form>
<div id="id5">something ...</div>
<div id="id8">something ...</div>
<div id="id3">something ...</div>
<div id="id97">something ...</div>
<div id="id7">something ...</div>
<div id="idn">some text ...</div>
</form>
2) The ~ operator only matches siblings that follow the matched element (ie it will match id3, id97, id7 and idn, but not id5). To match every sibling, including id5, you do this:
$("#id8").siblings("div").remove();
That should leave you with just id8. I tested this in Firefox 3.5.5 and IE7.0something. Hope that helps!

Three steps here:
Find the index number of the element we've clicked, with respect to its parent.
Loop through all the div elements contained within this parent, starting after the one we just found
Delete each div found
$(document).ready(function(){
$('#parent').children().click(function(){
var index = ($('div',$(this).parent()).index(this));
for(i=(index+1);i<$('div',$(this).parent()).length;i++){
$($('div',$(this).parent()).get(i)).hide();
}
});
});
This will work on this HTML
<div id="parent">
<div id="c1">c1</div>
<div id="c2">c2</div>
<div id="c3">c3</div>
<div id="c4">c4</div>
<div id="c5">c5</div>
</div>
Comment here if you've got any more problems on the matter!
P.S. An application of this solution exact to your request is the following
function removeAfter(el){
element = $('#'+el);
var index = ($('*',element.parent()).index(element));
for(i=(index+1);i<$('*', element .parent()).length;i++){
$($('*', element.parent()).get(i)).hide();
}
};

EDIT:
Editing the answer below to add what should be a fix for the problem:
$("#id8").nextAll().remove();
END EDIT.
Ok. This appears to be an interesting bug - initial testing seems to indicate it's a jquery bug although I haven't found any specific mention of it anywhere.
The bug seems to be that if your initial selector tag is the same type as its siblings then it will fail to return any siblings in IE7.
I tested it using the jQuery example code for the selector itself and was able to duplicate your problem in IE8 emulating IE7.
If you check the jquery example code I'll stick below you can see that the actual element they're using as the initial selector is a span and the sibling elements are all divs whcih seems to me to indicate they know about this bug and haven't documented it, which is both cunning and shitty.
<script>
$(document).ready(function(){
$("#prev ~ div").css("border", "3px groove blue");
});
</script>
<div>div (doesn't match since before #prev)</div>
<span id="prev">span#prev</span>
<div>div sibling</div>
<div>div sibling <div id="small">div niece</div></div>
<span>span sibling (not div)</span>
<div>div sibling</div>
Change the #prev span to a div and you'll get the same failure as you're getting currently. I'd submit a bug with the jquery team.

Related

Get the Count of Input Tags inside a Div Element using the Closest Property Jquery

I know it is a stupid question but i couldn't find a solution for this. Knocking my head for hours.
I have a HTML Structure,
<div class= 'container'>
<div class="someclass">
<input>some content</input>
<input>some content</input>
</div>
<input id="question-xxx" type="hidden"></input>
</div>
I need to get the count of all the Input elements inside the class = 'someclass' using the id = "question-xxx".
I tried using
$("#question-xxx").closest('.someclass').find('input').length;
or
$('#question-xxx').closest('.someclass').children().length;
I googled it out, and I have no clue what I'm doing wrong. Any help would be quite appreciable.
.someclass will not be found using closest try finding it by siblings.
closest is used to find the parent element of given element. Here someclass is not parent of question-xxx.
closest and parent are same. You can find more info here
$("#question-xxx").siblings('.someclass').find('input').length
var count = $('#question-xxx').prev('.someclass').find('input').length;
alert(count)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class= 'container'>
<div class="someclass">
<input>some content</input>
<input>some content</input>
</div>
<input id="question-xxx" type="hidden"></input>
</div>
use .prev() to get the div that contains the input
Description: Get the immediately preceding sibling of each element in the set of matched elements. If a selector is provided, it retrieves the previous sibling only if it matches that selector.
use .length to count

Get <div> elements without id in GWT

If i have html like this.Is there a way get a text apple between < div class="a" > and send it trought ajax to gwt application ?
<div class="A">
<div class="B">
<img class="icon" src="/images/ico.png" alt="" />
<div class="a">apple</div>
<div class="b">bannana</div>
</div>
</div>
and i have JavaScript like this :
$function(){
$('.B .icon').click(function(){
$(this).closest('.B').addClass('marked');
});
}
I would add this as a comment if I had enough reputation as I'm confused about your structure and question in general. Apologies if I don't understand correctly, but if you're typically traversing back up the DOM structure to the parent in your case could you use find to grab the element? .html() will grab the current content of said element.
$(function() {
$('.icon').click(function(){
var html = $(this).closest('.B').find('div.a').html();
// Do what you want with the contents. Simple alert as example.
alert(html);
});
});
This should get you what you're looking for. Please mark it as the answer if you find it matches what you need.
I'd suggest using .parent() rather than .closest('.B') if your elements will always be in the order you've posted and if further searching of the ancestor elements isn't needed.

Find instance following given element

I have a question about dom navigation with jquery. I'm trying to find an element with a given class that is closest in the dom following a given element.
I have a table like structure, created through divs and styled in css. I have an element being edited, and when the user presses enter I want to focus the following editable element. However, it's not a sibling of the element being edited.
HTML
<div class="calendarEntry">
<div when="2014,9,18" class="when">Sep 18</div>
<div class="items">
<div class="item">
<div code="ABC" class="type">ABC123</div>
<div offered="2014,9,15" class="offered dateish">Sep 15
<div class="offer editable">10</div>
<div class="sku editable">TH1</div>
<button>Publish</button>
</div>
</div>
<div class="item">
<div code="DEF" class="type">DEF321</div>
<div offered="2014,9,14" class="offered dateish">Sep 14
<div class="offer editable">10</div>
<div class="sku editable">TH2</div>
<button>Publish</button>
</div>
</div>
<div class="item">
<div code="GHI" class="type">GHI852</div>
<div offered="2014,9,12" class="offered dateish">Sep 12
<div class="offer editable">10</div>
<div class="sku editable">TH3</div>
<button>Publish</button>
</div>
</div>
</div>
</div>
Note: There are multiple calendar entries on the page.
Say the user is editing the offer of the DEF312 item. When they hit enter I want to edit the offer of GHI852. I have the code to make the div editable, by replacing it with a text field with a class of offer editing. If they're editing the final offer in this calendar entry, then the enter key should focus the first editable offer of the following calendar entry, if there is one. If we're at the bottom of the list I don't want to wrap back to the top (which I think would overly complicate matters anyway).
The bit I'm stuck with is how to find the next offer (all offers are editable).
Here's what I've tried:
var nextOffer = $('.offer').find('.editing').next('.editable');
Clearly, this doesn't work. The problem is that the following editable offer isn't a sibling of the current offer being edited, so next() doesn't work for me. The following offer could be in the current calendar entry, or it's just as likely to be in the next calendar entry. Either way, it's a few divs away, at varying depths.
Can I even do this with jquery dom traversals, or am I better just brute forcing it through javascript (i.e. looping through all .editable instances and returning the one after .editing?
Adding the class 'editing' to simulate the the input:
<div class="item">
<div code="DEF" class="type">DEF321</div>
<div offered="2014,9,14" class="offered dateish">Sep 14
<div class="offer editable">10</div>
<div class="sku editable editing">TH2</div>
<button>Publish</button>
</div>
</div>
you can do:
function findEditable(currentItem) {
var nextEditable = undefined,
selectors = [".item", ".calendarEntry"];
$.each(selectors , function (idx, selector) {
var ref = currentItem.closest(selector);
nextEditable = ref.parent()
.children("div:gt(" + ref.index() + ")")
.find(".offer.editable")
.first();
return nextEditable.length === 0;
})
return nextEditable;
}
findEditable($(".editing")).css({
color: 'red'
});
jsfiddle demo
You can use parents() to get the .offered element which contains the .offer element like so:
var offered = $('.offer').find('.editing').parents('.offered');
From that you can use next() to get into the .offered element's sibling .item element, and find the .editable element within that:
offered.next('.item').find('.editable');
JSFiddle demo. Note that I've manually added this .editing element within your DEF321 item's .offer element - I assume this gets added dynamically on your side, but either way isn't included in your question.
Edit: The HTML in the question has now been changed. Based on this, instead of getting the .offered parent, you'd get the .item parent:
var item = $('.offer').find('.editing').parents('.item');
And proceed in the same way as before:
item.next('.item').find('.editable');
JSFiddle demo.
try this
var current=document.activeElement,
all=$(".editable"),
index=all.indexOf(current),
next=all[index+1]
It first finds the current element and the list of elements,
then it will find the current element in the list.
It will then add 1 to the index and select it from the list.
To extend the array with the indexOf function;
if(!Array.prototype.indexOf){
Array.prototype.indexOf=function(e/*,from*/){
var len=this.length>>>0,
from=Number(arguments[1])||0;
from=(from<0)?Math.ceil(from):Math.floor(from);
if(from<0)from+=l;
for(;from<len;from++){
if(from in this&&this[from]===e)return from;
}
return -1;
};
}

Randomize div id order

I'm trying to get some divs with an id to randomize the order they appear in. I've found a script that supposedly will do this, but for the life of me, I can't figure out why mine isn't working.
Basically, when the page loads the HTML will read like this:
<div class="main">
<div id="box">1</div>
<div id="box">2</div>
<div id="box">3</div>
<div id="box">4</div>
</div>
But the code when applied will randomize the order in which they appear (in the browser), like so:
<div class="main">
<div id="box">3</div>
<div id="box">1</div>
<div id="box">4</div>
<div id="box">2</div>
</div>
And here is the javascript that supposedly is making it all work:
function reorder() {
var grp = $(".main").children();
var cnt = grp.length;
var temp,x;
for (var i = 0; i < cnt; i++) {
temp = grp[i];
x = Math.floor(Math.random() * cnt);
grp[i] = grp[x];
grp[x] = temp;
}
$(grp).remove();
$(".main").append($(grp));
}
I thought it was because I had an id property, but even if I strip that out and just make it a plain old div tag, it doesn't work :/
Here is the the like to a js fiddle of the code in question...
js fiddle
There are a few questions here similar to this, but they're all older topics, so I hope no one minds my making a new one. I'm still pretty new to javascript, if that isn't already obvious :D
Just change
<div class=".main">
<div id="#box">1</div>
<div id="#box">2</div>
<div id="#box">3</div>
<div id="#box">4</div>
</div>
to
<div class="main">
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
</div>
Two errors :
the ".main" which should be "main" as you look for $(".main").children().
the id "#box" that you were using for more than one element
In your fiddle, you also forgot to import jQuery.
Demonstration (click "Run with JS")
First, as was said before, ID should be unique, and they don't start with a #. The selector for ids uses a #.
Same for classes, they should start with a letter, only the selector uses a dot.
Now for your fiddle. You visibly use jQuery, here, so include jQuery on your fiddle, in the menu on the left.
Then, what you are doing in your fiddle is defining a function, but you never call it.
Just add a call to your function at the end of your code (that will be called by jsFiddle on load of the document, like this:
reorder();
Worked for me on your fiddle.

this find parent of another div and toggle its child using jQuery

I've done some research and nothing seems to be working. Here is the HTML followed by the JavaScript I am putting together. What I am trying to do is set it up so that whenever dashboard_gear_options is clicked, it toggles the appropriate hidden options row. Each block of code exists multiple times at different locations on the page. I tried using this, find, parent, next and children to no avail.
HTML:
// start block
<div class="content_block_holder">
<div class="content_top">
<div class="dashboard_gear_options"></div>
<div class="dashboard_gear_divider"></div>
</div>
<div class="dashboard_holder">
<div class="hidden_options_row"></div>
</div>
</div>
// end block
// start block
<div class="content_block_holder">
<div class="content_top">
<div class="dashboard_gear_options"></div>
<div class="dashboard_gear_divider"></div>
</div>
<div class="dashboard_holder">
<div class="hidden_options_row"></div>
</div>
</div>
// end block (etc..)
JS:
$(document).ready(function(){
$('.dashboard_gear_options').click(function(){
$(this).parent('.content_block_holder').find('.hidden_options_row').toggle();
});
});
Try using closest([selector]) ( http://api.jquery.com/closest/ ) instead of parent in your selector. It will traverse up the tree and find "content_block_holder". parent([selector]) will just check the immediate parent and return an empty set if it doesn't match the selector provided.
$(document).ready(function(){
$('.dashboard_gear_options').click(function(){
$(this).closest('.content_block_holder').find('.hidden_options_row').toggle();
});
});
JSFiddle based on your code: http://jsfiddle.net/gK7yM/
try this
$(this).closest('.content_block_holder').find('.dashboard_holder').find('.hidden_options_row').toggle();
Also this chain works:
$(this).parent().next('.dashboard_holder').children('.hidden_options_row').toggle();
or
$(this).parent().next('.dashboard_holder').find('.hidden_options_row').toggle();

Categories

Resources