Reputation: 1467
I have a HTML like this :
<span class="section2 section4">hello</span>
<span class="section1">World</span>
<div class="tab" id="tab1"></div>
<div class="tab" id="tab2"></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"></div>
<div class="tab" id="tab5"></div>
I need a jquery function able to give me this result :
<div class="tab" id="tab1"><span class="section1">World</span></div>
<div class="tab" id="tab2"><span class="section2">hello</span></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"><span class="section4">hello</span></div>
<div class="tab" id="tab5"></div>
My try so far :
$.each($(".tab"), function() {
var id = $(this).attr('id').substring(3);
if ($(".section" + id).length == 0) {
return true;
}
$(".section" + id).removeClass("section" + id).appendTo($(this));
})
How can i improve my function for correct work?
Upvotes: 3
Views: 3257
Reputation: 166
There may have two Case Described bellow:
If the id
of the appending div
are serially increased i.e. tab1, tab2, tab3 ...
then you can take the benefit of the "index"
of each element.
Bellow is the optimized code to do the task.
$.each($(".tab"), function(index) {
element_index = ++index;
if ( $('.section'+ element_index ).length ){
html_text = $(".section"+element_index).html();
$(this).html('<span class="section">'+html_text+'</span>');
}
});
If the id
of the appending div
are not serially increased i.e. tab1, tab5, tab3, tab6 ...
then you need to check existence of both the element.
Bellow is the optimized code to do the task.
$.each($(".tab"), function(index) {
element_id = $(this).attr('id').slice(-1);
if ( $('.section'+ element_id ).length ){
html_text = $(".section"+element_id).html();
$(this).html('<span class="section">'+html_text+'</span>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="section2 section4">hello</span>
<span class="section1 section6">World</span>
<div class="tab" id="tab1"></div>
<div class="tab" id="tab6"></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"></div>
<div class="tab" id="tab5"></div>
Upvotes: 0
Reputation: 115212
Iterate over the divs and based on the number in id append the cloned span element. Use append()
method with callback which iterates over the element and appends the callback return value.
// get all span with classname start with `section`
var $sec = $('span[class^=section]');
// iterate over div element and append the returned value
$('div.tab').append(function() {
// generate the class name from id
var cls = 'section' + this.id.match(/\d+$/)[0];
// filter element from $sec
return $sec.filter('span.' + cls)
// clone the element
.clone()
// updaet the class to remove other class name
// you can also use `prop('className',cls)`
.attr('class', cls);
});
// remove the span elements from dom
$sec.remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="section2 section4">hello</span>
<span class="section1">World</span>
<div class="tab" id="tab1"></div>
<div class="tab" id="tab2"></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"></div>
<div class="tab" id="tab5"></div>
UPDATE : If you want to maintain the other class or the span, then do something like.
// get all span with classname start with `section`
var $sec = $('span[class^=section]');
var $tab = $('div.tab');
// generate classnames based on tabs for removing later
var remove = $tab.map(function() {
return 'section' + this.id.match(/\d+$/)[0];
}).get().join(' ');
// iterate over div element and append the returned value
$tab.append(function() {
// generate the class name from id
var cls = 'section' + this.id.match(/\d+$/)[0];
// filter element from $sec
return $sec.filter('span.' + cls)
// clone the element
.clone()
// remove other class name
.removeClass(remove).addClass(cls);
});
// remove the span elements from dom
$sec.remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="section2 section4">hello</span>
<span class="section1 section8">World</span>
<div class="tab" id="tab1"></div>
<div class="tab" id="tab2"></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"></div>
<div class="tab" id="tab5"></div>
Upvotes: 2
Reputation: 45966
If you're using new versions of jQuery which support .prop() try this :
var origSections=[];
$.each($(".tab"), function() {
var id = $(this).prop('id').substring(3);
var sections=$(".section" + id);
if (sections.length === 0) {
return true;
}
sections.each(function(){
origSections.push($(this));
var section=$(this).clone();
section.removeClass().addClass("section" + id);
section.appendTo($('#tab'+id));
});
});
$.each(origSections,function(){
$(this).remove();
});
Otherwise, try this one :
var origSections=[];
$.each($(".tab"), function() {
var id = $(this).attr('id').substring(3);
var sections=$(".section" + id);
if (sections.length === 0) {
return true;
}
sections.each(function(){
origSections.push($(this));
var section=$(this).clone();
section.removeClass().addClass("section" + id);
section.appendTo($('#tab'+id));
});
});
$.each(origSections,function(){
$(this).remove();
});
Upvotes: 0
Reputation: 1945
$.each($(".tab"), function() {
var id = $(this).attr('id').substring(3);
if ($(".section" + id).length == 0) {
return true;
}
var _this = $(this);
var _section = $(".section" + id);
_section.removeClass("section" + id);
var _clonedSection = _section.clone();
_clonedSection.appendTo(_this);
_this.appendTo('#conteiner');
})
$("#tmp").remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="conteiner">
</div>
<div id="tmp">
<span class="section2 section4">hello</span>
<span class="section1">World</span>
<div class="tab" id="tab1"></div>
<div class="tab" id="tab2"></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"></div>
<div class="tab" id="tab5"></div>
</div>
result html:
<div id="conteiner">
<div class="tab" id="tab1"><span class="">World</span></div>
<div class="tab" id="tab2"><span class="">hello</span></div>
<div class="tab" id="tab4"><span class="">hello</span><span class="">hello</span></div>
</div>
Upvotes: 0
Reputation: 176
Try script Like this
$.each($(".tab"), function() {
var id = $(this).attr('id').substring(3);
$('span').each(function(){
var str = $(this).attr('class');
var str1 = str.toString();
if(str1.indexOf('section'+id) > -1){
$("#tab"+id).append("<span class='section"+id+"'>"+$('.section'+id).text()+"</span>");
}
});
});
Upvotes: 0
Reputation: 10177
The problem in your code is you are just removing the original element and appending to similar id div and for section2
and section4
span are same so when script works for 4th div it removes from 2nd element and append to 4th.
You need to use .clone()
and let the original span be at it place just clone it and append on as much div as you want and hide the initial span with css.
$.each($(".tab"), function() {
var id = $(this).attr('id').substring(3);
if ($(".span_wrap .section" + id).length != 0) {
$(".span_wrap .section" + id).removeClass("section" + id).clone().appendTo($(this));
}
})
.span_wrap span {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="span_wrap">
<span class="section2 section4">hello</span>
<span class="section1">World</span>
</div>
<div class="tab" id="tab1"></div>
<div class="tab" id="tab2"></div>
<div class="tab" id="tab3"></div>
<div class="tab" id="tab4"></div>
<div class="tab" id="tab5"></div>
Upvotes: 1