I'm attempting to select the .item div which contains both tagOne and tagTwo span elements.
My div structure is as follows:
<div id="items">
<div id="block1" class="item">
<span class="tagOne tag">One</span>
<span class="tagTwo tag">Two</span>
</div>
<div id="block2" class="item">
<span class="tagOne tag">Java</span>
</div>
</div>
Using the following jQuery I'm able to locate the tags (with their parent div's) separately.
var blocks = $('#items .item');
blocks.filter('.item').find('[class*="tagOne"]').parent();
blocks.filter('.item').find('[class*="tagTwo"]').parent();
However, once I try to combine them to narrow it down to the one div that contains them both, I get no results and I can't seem to work out why!
blocks.filter('.item').find('[class*="tagOne"][class*="tagTwo"]');
My understanding is that the comma syntax will create an OR expression, and without creates an AND expression. I'm after the AND expression as I only want to return the div that contains all the criteria, or nothing at all.
Note: I'm doing it this way because I'm creating a toggle-filter based on the tags, and the criteria (i.e. tagOne, tagTwo) is a concatenation of the tags selected by the user (not shown) so it is preferable to try to do it in one operation.
EDIT: Moved duplicate id's to class names instead to make it valid and tweaked JavaScript code accordingly.
First of all, the ID should be unique. Now, the markup contains two elements with ID tagOne which is invalid markup.
You can use class instead of ID.
Select any of the element from the two(.tagOne or .tagTwo in this case)
Use siblings() to select the sibling element having the other class
Use closest() to select closest ancestor matching the selector.
The step #1, #2 and #3 above will select only those .item elements having both .tagOne and .tagTwo as descendent.
Code:
$('.tagOne') // Select one of the element
.siblings('.tagTwo') // Get second element if it is sibling
.closest('.item') // Get the closest ancestor
$('.tagOne') // Select one of the element
.siblings('.tagTwo') // Get second element if it is sibling
.closest('.item') // Get the closest ancestor
.addClass('selected'); // For Demo purpose
.item {
color: red;
}
div.selected {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="items">
<div id="block1" class="item">
<span class="tagOne tag">One</span>
<span class="tagTwo tag">Two</span>
</div>
<div id="block2" class="item">
<span class="tagOne tag">Java</span>
</div>
<div id="block3" class="item">
<span class="tagTwo tag">I Love JavaScript</span>
</div>
</div>
You can also use filter as follow.
Iterate over all the .item elements using filter()
Use context selector to check if the current .item has descendent .tagOne and .tagTwo.
Use length property on the jQuery object to get the number of elements selected by the selector.
Code:
$('.item').filter(function() {
return $('.tagOne', this).length && $('.tagTwo', this).length;
})
// Fiddle: https://jsfiddle.net/tusharj/8tuu1wxs/1/
// Iterate over all elements having item class
$('.item').filter(function() {
return $('.tagOne', this).length && $('.tagTwo', this).length;
}).addClass('selected');
.item {
color: red;
}
.selected {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="items">
<div id="block1" class="item">
<span class="tagOne tag">One</span>
<span class="tagTwo tag">Two</span>
</div>
<div id="block2" class="item">
<span class="tagOne tag">Java</span>
</div>
<div id="block3" class="item">
<span class="tagTwo tag">I Love JavaScript</span>
</div>
</div>
If the sequence/order of the elements is fixed, CSS general sibling selector ~ or adjacent sibling selector + can be used.
$('.tag1 ~ .tag2').closest('.item')
OR
$('.tag1 + .tag2').closest('.item')
// Fiddle: https://jsfiddle.net/tusharj/amdoLfou/1/
$('.tag1 ~ .tag2') // + can also be used instead of ~
.closest('.item') // Get closest ancestor
.css('color', 'blue'); // For Demo purpose
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="items">
<div id="block1" class="item">
<span class="tag1 tag">One</span>
<span class="tag2 tag">Two</span>
</div>
<div id="block2" class="item">
<span class="tag1 tag">Java</span>
</div>
</div>
While you've already accepted an answer, I felt that this is a question worthy of a plain JavaScript, rather than simply a jQuery, solution. So, with that in mind, I'd like to offer the following approach (which does use some ECMAScript 6 feastures, so does require a fairly modern browser):
// using an Immediately-Invoked Function Expression syntax,
// so that the enclosed function will be executed when
// encountered, rather than requiring the user to call it
// explicitly (this would need to run in a DOMReady callback
// or once the DOM has been constructed, however):
(function hasAll(opts) {
// setting the default settings for the function:
var settings = {
// a CSS Selector string to identify the ancestor
// element that you wish to identify:
'ancestorSelector': 'div',
// an array of CSS Selectors to identify the
// descendants by which the ancestor should
// be found:
'descendantSelectors': []
}
// looking at the named (not inherited) properties
// of the opts Object supplied by the user:
for (var property in opts) {
// if the opts Object has a given property
// name we set the corresponding property
// of the settings Object to be equal to that
// property-value:
if (opts.hasOwnProperty(property)) {
settings[property] = opts[property];
}
}
// finding all the elements represented by the first selector
// of the user-supplied selectors contained within an element
// matching the ancestor selector:
var firstElements = document.querySelectorAll(
settings.ancestorSelector + ' ' + settings.descendantSelectors[0]
),
// converting the NodeList returned by document.querySelectorAll()
// into an Array, using Array.from:
arrayOfFirsts = Array.from(firstElements),
// here we iterate over that Array, using Array.prototype.filter():
hasSiblings = arrayOfFirsts.filter(function(n) {
// we look for the parentNode of the current node (n):
var p = n.parentNode;
// we use Array.prototype.every() to ensure that every
// selector in the descendantSelectors Array returns
// a Node (document.querySelector() returns only the
// first node matching the given selector, or null if
// there is no element matching that selector).
// if Array.prototype.every() returns true (all elements
// of the Array match the supplied test) then the current
// node (n) is retained in the array returned by
// Array.prototype.filter():
return settings.descendantSelectors.every(function(selector) {
// Array.prototype.every() returns a Boolean,
// true : if all elements of the Array match
// the supplied test/assessment,
// false: if *any* of the elements of the Array
// fail to match.
// this is the test that we're matching against:
return p.querySelector(selector) !== null;
});
});
// here we iterate over the hasSiblings Array, and use
// Array.prototype.map() to form a new Array, using
// an Arrow function to take the current node (n)
// and find, and return, the closest element to that
// node which matches the supplied settings.ancestorSelector:
var found = hasSiblings.map(n => n.closest(settings.ancestorSelector));
// returning that array to the calling context:
return found;
})({
// this is the 'opts' Object that we're passing to the
// IIFE-contained function:
'ancestorSelector': '.item',
'descendantSelectors': ['.tagOne', '[data-demo]']
// using Array.prototype.forEach() to iterate over the
// returned elements, to add the class 'hasAll' to the
// the classList (the list of class-names) of the given
// node (n):
}).forEach(n => n.classList.add('hasAll'));
(function hasAll(opts) {
var settings = {
'ancestorSelector': 'div',
'descendantSelectors': []
}
for (var property in opts) {
if (opts.hasOwnProperty(property)) {
settings[property] = opts[property];
}
}
var firstElements = document.querySelectorAll(
settings.ancestorSelector + ' ' + settings.descendantSelectors[0]
),
arrayOfFirsts = Array.from(firstElements),
hasSiblings = arrayOfFirsts.filter(function(n) {
var p = n.parentNode;
return settings.descendantSelectors.every(function(selector) {
return p.querySelector(selector) !== null;
});
});
var found = Array.from( hasSiblings.map(n => n.closest(settings.ancestorSelector)) );
return found;
})({
'ancestorSelector': '.item',
'descendantSelectors': ['.tagOne ~ .tagTwo']
}).forEach(n => n.classList.add('hasAll'));
div {
width: 50%;
margin: 0.5em auto;
border: 2px solid #000;
border-radius: 1em;
padding: 0.5em;
box-sizing: border-box;
}
.hasAll {
border-color: #f90;
}
.hasAll span {
color: #f90;
font-weight: bold;
}
<div id="items">
<div id="block1" class="item">
<span class="tag tagOne">One</span>
<span class="tag tagTwo">Two</span>
</div>
<div id="block2" class="item">
<span class="tag tagOne">Java</span>
</div>
<div id="block3" class="item">
<span class="tag tagOne" data-demo="false">tag-one</span>
<span class="tag tagTwo">tag-two</span>
<span class="tag" data-demo="true">tag-three</span>
</div>
</div>
JS Fiddle demo.
Note that, with the above function, an ancestor element will be matched if any of its descendants', or its descendants' siblings, matches multiple selectors.
References:
Array.from().
Array.prototype.every().
Array.prototype.filter().
Array.prototype.forEach().
Array.prototype.map().
Arrow functions.
document.querySelector().
document.querySelectorAll().
Element.classList.
Element.closest().
for...in statement.
Object.hasOwnProperty().
Node.parentNode.
Try this
blocks.filter('.item').find('[id="tagOne"],[id="tagTwo"]');
Try using has jquery has selector it searches if selected nodes have certain children:
https://jsfiddle.net/96gbf7xg/
Related
I am new to HTML ,JavaScript and jQuery. I am currently doing a search box, when I start to type text on the search input the search list must appear and able to click the search list name and append it to search input, and close the search list and left with search input and current text that I clicked on the search list.
var $block = $('.no-results');
$(".personsMenu").hide();
$(".my-textbox").keyup(function() {
var textbox = document.getElementById("textboxEmp");
var val = $(this).val();
var isMatch = false;
var nameAp = document.getElementsByClassName("name12");
$(".personsMenu").show();
if (textbox.value == 0) {
$(".personsMenu").hide();
}
$(".personsMenu div").each(function() {
var content = $(this).html();
if ((content.toLowerCase().indexOf(val) == -1) && (content.toUpperCase().indexOf(val) == -1)) {
$(this).hide();
} else {
isMatch = true;
$(this).show();
}
});
$block.toggle(!isMatch);
});
function mySelect() {
$(".name12").appendTo($(".my-textbox"));
$(".personsMenu").hide();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="cover">
<div name="selected">
<i class="mdi-account-search mdi"></i><input class="my-textbox" id="textboxEmp" autofocus="autofocus" placeholder="search staff member" />
</div>
<div class="personsMenu">
<ul class="infor">
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Malubane Nyikiwe</li>
<li>nyikiwe.malubane#m-t.co.za</li>
</div>
<div class="no-results">no employee found by that name</div>
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Chamano Sydney</li>
<li>sydney.chamano#m-t.co.za</li>
</div>
<div class="nm1" name="selected">
<li class="name12" onclick="mySelect()">Diphofa Tumelo</li>
<li>tumelo.diphofa#m-t.co.za</li>
</div>
</ul>
</div>
</div>
There's several issues in your code which all need to be addressed:
You're using invalid HTML. ul elements can only contain li, not div. I'd suggest restructuring the HTML to use div containers to hold the information for each item in your list.
Use CSS to hide content which should not be visible when the page loads. This avoids the FOUC which can happen as JS only runs after the DOM is ready.
If you've included jQuery in the page, you may as well use it consistently to make your code more succinct.
Use the input method, not keyup, for listening to user input. input will also fire when the user copies content in to the field using the mouse for example, keyup won't.
Use unobtrusive event handlers, eg. jQuery's on() method, not inline onclick attributes. The latter is outdates and bad practice at it doesn't allow for good separation of concerns.
When searching text, equalise the cases of the search and target strings, don't search for both upper and lower versions.
Use text() to search for the content, not html().
To set the value of an input element use val(), not append(). The latter is for adding HTML/text content to an element, not setting its value property.
With all that said, the working code will look something like this:
var $noResults = $('.no-results');
var $names = $(".name12");
var $personsMenu = $('.personsMenu');
var $searchBox = $(".my-textbox").on('input', function() {
var value = $(this).val().trim().toUpperCase();
if (!value) {
$personsMenu.hide();
return;
}
var matches = $personsMenu.show().find('div').each(function() {
var content = $(this).text().toUpperCase();
$(this).toggle(content.indexOf(value) !== -1);
});
$noResults.toggle(matches.filter(':visible').length == 0);
});
$('.item').on('click', function() {
$searchBox.val($(this).find('.name12').text());
$personsMenu.hide();
});
.personsMenu,
.no-results {
display: none;
}
.item {
padding: 10px;
cursor: pointer;
}
.item:hover {
background-color: #CCC;
}
.item p {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="cover">
<div name="selected">
<i class="mdi-account-search mdi"></i>
<input class="my-textbox" id="textboxEmp" autofocus="autofocus" placeholder="search staff member" />
</div>
<div class="personsMenu">
<div class="no-results">no employee found by that name</div>
<div class="item">
<p class="name12">Malubane Nyikiwe</p>
<p class="email">nyikiwe.malubane#m-t.co.za</p>
</div>
<div class="item">
<p class="name12">Chamano Sydney</p>
<p class="email">sydney.chamano#m-t.co.za</p>
</div>
<div class="item">
<p class="name12">Diphofa Tumelo</p>
<p class="email">tumelo.diphofa#m-t.co.za</p>
</div>
</div>
</div>
I'm trying to find out if it's possible to clone an HTML div with JS, edit it and append it again as a new element. So my source is, for example, this code here:
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC"/>
</div>
</div>
After copying this element, I need to find a way to change the attribute id of the new cloned input, clear the input value and paste it again in the wrapper so that it looks like this at the end:
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC"/>
</div>
<div class="element">
<input id="test--2" value=""/>
</div>
</div>
Does that make sense to you? If yes, how can I get this done? Or is it better to assign the content to a variable to append it? I'm looking for the best way here and maybe my idea is a solution too.
You can use pure JavaScript to do this by just cloning the .element div using the cloneNode() method, assign new id and value to the clone div and finally append it back to the document using the insertBefore() method like this:
let x = document.querySelector(".element");
let y = x.cloneNode(true);
y.children[0].id = "test--2";
y.children[0].defaultValue = "";
x.parentNode.insertBefore(y, x.nextSibling);
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC"/>
</div>
</div>
JSFiddle with the above code: https://jsfiddle.net/AndrewL64/jvc7reza/18/
Based on this answer you could do like:
$('#cloneBtn').on('click', function() {
// get the last input having ID starting with test--
var $inp = $('[id^="test--"]:last'); // Or use :first if you need
// Get parent element
var $div = $inp.closest('.element');
// Create clone
var $div_clone = $div.clone();
// Retrieve number from ID and increment it
var num = parseInt($inp.prop("id").match(/\d+/g), 10) + 1;
// Generate new number and assign to input
$div_clone.find('[id^="test--"]').prop({id: 'test--' + num, value: ''});
// Insert cloned element
$div.after($div_clone); // Or use .before() if you need
});
.element {
padding: 10px;
outline: 2px solid #0bf;
}
<button id="cloneBtn">CLICK TO CLONE</button>
<div class="wrapper">
<div class="element">
<input id="test--1" value="ABC" />
</div>
</div>
Once done inspect the input elements to see the new IDs
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
Scrambled elements, retrieve highest ID, increment, clone, append.
If your numbered IDs are scrambled, we first need a way to retrieve the highest ID number. Here's an implementation in pure JavaScript:
function cloneElement () {
const inpAll = document.querySelectorAll('[id^="test--"]');
if (!inpAll.length) return; // do nothing if no elements to clone
const maxID = Math.max.apply(Math, [...inpAll].map(el => +el.id.match(/\d+$/g)[0]));
const incID = maxID + 1;
const element = document.querySelector('.element'); // Get one for cloning
const eleClone = element.cloneNode(true);
const inpClone = eleClone.querySelector('[id^="test--"]');
inpClone.id = 'test--'+ incID;
inpClone.value = incID; // just for test. Use "" instead
document.querySelector('.wrapper').prepend(eleClone);
}
document.querySelector('#cloneBtn').addEventListener('click', cloneElement);
.element {
padding: 10px;
outline: 2px solid #0bf;
}
<button id="cloneBtn">CLICK TO CLONE</button>
<div class="wrapper">
<div class="element">
<input id="test--1" value="1" />
</div>
<div class="element">
<input id="test--23" value="23" />
</div>
<div class="element">
<input id="test--7" value="7" />
</div>
</div>
Once done inspect the input elements to see the new IDs
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
I don't know what data you know, why you want to do such a thing but it can be done :-)
One way is like that:
const elemToCopy = document.getElementById("test--1").parentNode; // I assume you know id
const copiedElem = elemToCopy.cloneNode(true);
const newInput = copiedElem.querySelector("#test--1");
newInput.id = "test--2";
newInput.value = "";
elemToCopy.parentNode.append(copiedElem);
Let me know in a comment if something is not clear :-)
Yes, use jQuery's .clone().
Here is an example that might be relevant to your situation:
let newElement = $('.element').clone();
newElement.find('input').attr('id', 'test--2').val('');
$('.wrapper').append(newElement);
Explanation
In the first line, we created a new cloned element by using jQuery clone().
Then, we found it's child input, changed it's ID and reset the val().
Finally, we found the .wrapper element and appended the new cloned element to it.
I am trying to verify if the clicked cell on a devexpress grid is valid according to the following rules:
Click on a cell that has classes: .dxgv.dx-ar (This part is working)
If that element contains some element of the class gridValue AND this (child) element has a father with name: 'allowsEdit' (THIS CODE IS NOT WORKIING)
I was trying to avoid using the ".parent()..." adicional line, but combine multiple JQuery selector rules, but till now I was not able.
Any ideas?
JS
$('#' + gridIdName).unbind('click').on('click', '.dxgv.dx-ar', function (e) {
if ($(this).find('.gridValue:parent[name="allowsEdit"]').length !== 0) {
console.log('FOUND');
return
}
console.log('NOT FOUND');
});
HTML
/******** VALID *************/
<td id="devGrid1_tccell2_13" class="dxgv dx-ar">
<div style="width: 100%;" name="allowsEdit" class="contextMenuElement TargetIdstate VarietyId76 Year2018 CountryId2 PlanId11437">
<div style="width:100%;" id="state_76_2_2018" class="gridValue gridValueMin1 gridValueMax11">
2000
</div>
<div style="clear: both;"></div>
</div>
</td>
/******** NOT VALID *************/
<td id="devGrid1_tccell3_7" class="dxgv dx-ar" style="background-color:#E4AA8A;">
<div style="width: 100%;" name="" class="contextMenuElement TargetIdactual VarietyId82 Year2018 CountryId1 PlanId12732">
<div style="width:37px;" id="actual_82_1_2018" class="gridValue">
40000
</div>
<div style="clear: both;"></div>
</div>
</td>
You can use a simple css selector for this
[name="allowsEdit"] > .gridValue
this selects the .gridValue element. if you directly want the allowsEditElement you can use:
[name="allowsEdit"]:has(.gridValue)
find .gridValue class elements where direct parent have class: .allowEdit
$(this).find('[name="allowsEdit"]:has(.gridValue)').length
For more information you can read Mozzila's documentation about this
Click on a cell that has classes: .dxgv.dx-ar
If that element contains some element of the class gridValue AND this element has a father with name: 'allowsEdit'
Your HTML doesn't match that description, but the above is a straightforward combination of:
An attribute value selector
A descendant combinator
A pair of class selectors
A :has selector (which is a jQuery addition)
So all in one it would be: [name=allowsEdit] .dxgv.dx-ar:has(.gridValue)
E.g.:
$('#' + gridIdName).unbind('click').on('click', '[name=allowsEdit] .dxgv.dx-ar:has(.gridValue)', function (e) {
That's if you don't want the clicks at all unless it's a match.
But if you want the click regardless and then just want to check the other things afterward:
$('#' + gridIdName).unbind('click').on('click', '.dxgv.dx-ar', function (e) {
var $this = $(this);
if ($this.closest("[name=allowEdit]").length && $this.find(".gridValue").length) {
// Match
} else {
// No match
}
Let's assume we have this HTML structure:
<div id='test-div'>
<div class='random-class-1'>
<div class='useless-element-1'>
</div>
<div class='useless-element-2'>
</div>
<p>Just a paragraph, and useless</p>
</div>
<div class='random-class-2'>
<div class='useless-element-3'>
</div>
<div class='useless-element-4'>
</div>
<div class='useless-element-5'>
</div>
</div>
</div>
I need to select all children "DIV elements" (not grandchildren) inside the first DIV (in this example with id='test-div'), not from document but from element (div) itself.
So, I don't want to use the "query" below because I already have selected the element DIV [object HTMLDivElement]:
// I don't want to use this query
var children = document.querySelectorAll("div > div");
Just an example to achieve this (https://jsfiddle.net/t4gxt65k/):
// I already have selected DIV element
var el = document.getElementById("test-div")
// OR var el = document.querySelectorAll("#test-div");
var children = el.querySelectorAll(":scope > div");
But because of browser incompatibility I don't want to use ":scope"
The real question is:
How can I get the children (only DIV elements) of [object HTMLDivElement] using pure JavaScript?
As an option, you could set a temporary unique attribute for your scope element, and then use querySelectorAll() for its parent with the attribute selector prepended to what you would place after the :scope selector:
// The `scope` variable stores a reference to the scope element.
var attrName = '_scope' + Date.now();
scope.setAttribute(attrName, '');
var children = scope.parentNode.querySelector('[' + attrName + '] > DIV');
I’m not sure about how fast it is though.
Fwiw, specifically for getting child elements, there is the children DOM property:
var children = scope.children;
To get direct children of an element use a combination of parentNode.children or parentNode.childNodes, and Array.prototype.reduce like this:
var children = Array.prototype.reduce.call(el.children, function(acc, e) {
if(e.tagName == "DIV")
acc.push(e);
return acc;
}, []);
Similar to #Ibrahims answer in selecting children but less complicated since it does not address prototype and reduce. Instead it uses Array.from, Array.filter and Element.matches. Element.matches makes it more versatile since it uses a normal selector string (as you would in querySelectorAll).
Array.from(rootElement.children)
.filter(elm => elm.matches('div'))
const rootElement = document.getElementById('test-div')
Array.from(rootElement.children)
.filter(elm=>elm.matches('div'))
.forEach(elm=>elm.classList.add('matched'))
div {
padding: 1rem;
box-shadow: 0 0 0 1px gray inset;
}
.matched {
box-shadow: 0 0 0 1px red inset;
}
<div id='test-div'>
<div class='random-class-1'>
<div class='useless-element-1'></div>
<div class='useless-element-2'></div>
<p>Just a paragraph, and useless</p>
</div>
<div class='random-class-2'>
<div class='useless-element-3'></div>
<div class='useless-element-4'></div>
<div class='useless-element-5'></div>
</div>
</div>
<div class="parent">
<span>sometext</span>
plain text
<input class="child">
</div>
<div class="parent">
<span>sometext</span>
plain text
<input class="child">
</div>
<div class="parent">
<span>sometext</span>
plain text
<input class="child">
</div>
How do I safely remove everything in .parent except .child?
I'm using this code (where items is a stack of .child and each is a .child)
items.each(function(){
$(this).parent().children().each(function(){
if ($(this).hasClass('child'))
// do something
else
$(this).remove();
});
$(this).unwrap(); // remove parent, keep only .child
});
But it doesn't handle plain text.
You've said
There can be more than one .child inside .parent, we keep only a first one. So If there are three, second and third should be removed.
and that
items is a stack of .child and each is a .child
Okay, then this is what I would do:
items.parent('.parent').each(function() {
var parent = $(this),
child = parent.children('.child').first();
child.detach();
parent.empty().append(child);
});
What that does:
Moves from the set of .child elements up to the set of .parent elements. The resulting set will only have unique parents.
Loops through the parents.
Gets the first .child in each parent and detaches it.
Empties the .parent.
Re-attaches the .child.
End result is that each .parent will have only one .child (and no other children, whether .child or not).
Here you'd have a solution with pure JS: fiddle
So within your loop you can use the following:
this.parentNode.innerHTML = this.outerHTML;
If you'd have to keep attached event handlers:
var _this = this.cloneNode(true),
parent = this.parentNode;
parent.innerHTML = '';
parent.appendChild(_this);
Something like this will do it;
$('.parent').on('click', '.child', function(e) {
var $this = $(this),
$parent = $this.parent(),
$children = $parent.find('.child'); // or: $this.siblings('.child');
$parent
.empty() // Empty the "parent" element
.append($children); // Re-append all "child" element to "parent"
$this.focus(); // Focus the (input) element
});
Here's an alternative using a regex:
$('.parent').each(function() {
$(this).html($(this).html().match("<input class=.child.>"));
});