jQuery insert after the last element - javascript

I want to add elements after the last one.
My current code
<div class="find"><div id="FirstElement"> /*First element loaded first */ </div><div>
$('#AddNextElement' + id).click(function (e) {
$('<div id="NextElement' + id +'">' + /*Add after the last element*/ + '</div>').insertAfter($("#FirstElement"));
}
Current it adds only it after the first element:
1
4
3
2
I want it to add after the last element every time:
1
2
3
4
I've followed these links and I didn't find what I'm looking for:
jQuery insertAfter last item
insertAfter specific element based on ID
jQuery: Add element after another element
Thank you in advance!.
How I fixed it:
$('#AddNextElement' + id).click(function (e) {
$('<div id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>').insertAfter($("#FirstElement").parent().find('.Finder').last());
}
I found the .parent().find('.find').last(); then insert after the last

Just you need last() method
$('<div id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>')
.insertAfter($('[id^="NextElement"]').last());

How about adding a class to all elements? It will be easier to find the last:
$('.element-class:last').after('<div class="element-class" id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>');
This of course means that your First element must also have the class:
<div class="element-class" id="FirstElement"> /*First element loaded first */ </div>

Find the last element in the DOM, in your case it'll be 'NextElementxx' and then use 'after':
$('#NextElement2').after( ..new stuff.. );

HTML:
<div id="FirstElement"> First element loaded first </div>
<div id="AddNextElement">Click me</div>
JS:
var current = 0;
$('#AddNextElement').click(function (e) {
var $el = (current == 0) ? $("#FirstElement") : $("#NextElement"+current);
current++;
$('<div id="NextElement' + current +'">Other element '+current+'</div>').insertAfter($el);
});
Try yourself on jsfiddle

You can just use this:
jQuery('##AddNextElement').last().after();

one way is to store the last element.
<div id="FirstElement"> /*First element loaded first */ </div>
var lastElement = $('#FirstElement');
$('#AddNextElement' + id).click(function (e) {
var element = $('<div id="NextElement"' + id +'>' + /*Add after the last element*/ + '</div>'));
element.insertAfter(lastElement);
lastElement = element;
}

You can try below code, it will add the new div after the last "NextElement" div
JS Code:
$(function(){
$('#AddNextElementButton').on("click", function (e) {
var id = $("[id^='NextElement']").length ? $("[id^='NextElement']").length+1 : 1;
if($("[id^='NextElement']").length){
$('<div id="NextElement'+ id +'">Add after the last element</div>').insertAfter($('[id^="NextElement"]').last());
} else {
$('<div id="NextElement'+ id +'">Add after the last element</div>').insertAfter($('#FirstElement'));
}
});
});

**hope this will make you understand well GitHub:Omar-baksh **
// code by GitHub: omar-baksh
// jquery is required online !!
/*
//this scricp test if jquery loded
window.onload = function() {
if (window.jQuery) {
// jQuery is loaded
alert("Yeah!");
} else {
// jQuery is not loaded
alert("Doesn't Work");
}
}
*/
var gfather = document.getElementsByClassName('Gfather');
var father = document.getElementsByClassName('father');
var son = document.getElementsByClassName('son');
function gf(argument) {
$(gfather).mouseenter(function(){
for (let i = 0; i < father.length; i++) {
father[i].style.display='block';
};
// show father fun() body show body last ...
});
$(father).mouseenter(function(){
for (let i = 0; i < son.length; i++) {
son[i].style.display='block';
};
// son show body last ...
});
// gf body last ...
}
// show form setting bottun fun()
function add(){
const x = document.getElementById("frm").style.display='block';
alert('setting opened');
}
// form add element fun()
var clslist=document.getElementsByClassName("list");
var inher =document.getElementById("level");
var num =document.getElementById("num").value;
var txt =document.getElementById("inp-text");
// var add-btn = document.getElementById("btn-secsuce");
/*
$("#inher").change(function () {
alert(inher);
document.getElementById("inp-text")="you selected"+ document.getElementById("level").value;
// body...
});
*/
var clss ="";
var ii;
$( "#btn-secsuce" ).click(function () {
//txt.value="class name "+inher.value;
if( String(inher.value) =="Grand father"){
clss ="Gfather";
jQuery('<div/>', {
id: Math.ceil(Math.random() * 999),
text:txt.value,
"class": clss,
title: clss+clss.length
}).appendTo(clslist);
alert("add class "+inher.value+gfather.length);
}
else { // alert("class enhhert is roung you chose " +inher.value )
}
/// add father to g father
if( String(inher.value) =="father"){
var txt2 = $("<div class="+"father"+"></div>").text(txt.value);
$(father[num-1]).after(txt2);
}
else{
}
});
.Gfather{
width: 60px;
height: auto;
border-left: 6px dashed red;
border-bottom: 6px dashed red;
 background-color: silver;
top:0;
display:block;
position:relative ;
margin-left:9px;
white-space: nowrap;
}
.father{
width: 60px;
border-left: 6px dashed red;
border-bottom: 6px dashed red;
bottom:0;
padding-top:0px;
border-right-width: small;
left:66px;
white-space: nowrap;
position:relative ;
background-color: #550088;
color:white;
display: block;
}
<head>
<title>tree js</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./tree.css">
</head>
<body>
<div class="list">
<div class ="Gfather" onmouseover="gf();">
grand father 1
</div>
<div class ="father">
father
</div>
<div class ="son">son
</div>
<div class ="son">son
</div>
</div>
<!-- add element show setting btn -->
<button id="add" onclick="add()" > add setting</button>
<form id="frm">
<h6>1</h6>
<select id="level">
<option>Grand father</option>
<option>father</option>
<option>son</option>
</select>
<h6>2</h6>
<select id="num">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
</select>
<br>
<h6>3</h6>
<input id="inp-text" type="text">
<h5 >4</h5>
<button type="button" id="btn-secsuce" >Add The Element </button>
</form>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<script type="text/javascript" src="./tree.js"></script>

Related

Switch classes on click next or back

I'm trying to setup multiple-step form in which the first step is visible by default and rest of the steps are hidden with class "hide". I'd like to switch the class with Next and Back button so only one step is visible at a time. Could you please help with this (Already spent an hour on this)
<div class="steps">
<div class="step1">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
$('.next').click(function(){
$('div:not(.hide)').next().removeClass('hide');
$('.hide').prev().removeClass('hide')
})
Try combining the 2 actions into one, like so:
$('.next').click(function(){
$('.steps div:not(.hide)').addClass('hide').next().removeClass('hide');
})
That way, you add the .hide class on your current div and then remove it on the next one.
You can use something similar for the Back button, by replacing .next() with .previous()
$('.next').click(function() {
// find the div that is not hidden
var $current = $('.steps div:not(.hide)');
// only perform logic if there is a proceeding div
if ($current.next().length) {
// show the next div
$current.next().removeClass('hide');
// hide the old current div
$current.addClass('hide')
}
});
$('.back').click(function() {
// find the div that is not hidden
var $current = $('.steps div:not(.hide)');
// only perform logic if there is a preceeding div
if ($current.prev().length) {
// show the previous div
$current.prev().removeClass('hide');
// hide the old current div
$current.addClass('hide')
}
});
.hide { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
<div class="step1">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
You can add a current step variable to track the currently displayed step and two css for styling and showing your content.
jQuery(function($) {
let currentstep = 1;
let maxsteps = 4;
function showstep(step) {
let step_c = '.step' + step;
for (i = 1; i <= maxsteps; i++) {
var step_selector = '.step' + i;
$(step_selector).removeClass('show');
$(step_selector).addClass('hide');
}
$(step_c).removeClass('hide');
$(step_c).addClass('show');
};
$('.next').click(function() {
currentstep = currentstep + 1;
currentstep = (currentstep % (maxsteps + 1));
if (currentstep == 0) currentstep = 1;
showstep(currentstep);
});
$('.back').click(function() {
currentstep = currentstep - 1;
currentstep = (currentstep % (maxsteps + 1));
if (currentstep == 0) currentstep = 4;
showstep(currentstep);
});
});
.hide {
display: none;
}
.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
<div class="step1 show">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
I converted Taplar's answer to a jQuery plugin.
You are essentially navigating left or right by one, using the previous and next functions. These functions navigate through the sibling elements.
(function() {
$.fn.moveRight = function(className) {
var $curr = this.find('div:not(.' + className + ')');
if ($curr.next().length) $curr.next().removeClass(className);
else this.find('div:first-child').removeClass(className);
$curr.addClass(className);
return this;
};
$.fn.moveLeft = function(className) {
var $curr = this.find('div:not(.' + className + ')');
if ($curr.prev().length) $curr.prev().removeClass(className);
else this.find('div:last-child').removeClass(className);
$curr.addClass(className);
return this;
};
})(jQuery);
$('.next').on('click', (e) => $('.steps').moveRight('hide'));
$('.back').on('click', (e) => $('.steps').moveLeft('hide'));
.hide {
display: none;
}
.nav {
width: 260px;
text-align: center;
}
.nav .nav-btn::selection { background: transparent; }
.nav .nav-btn::-moz-selection { background: transparent; }
.nav .nav-btn {
display: inline-block;
cursor: pointer;
}
.steps {
width: 260px;
height: 165px;
border: thin solid black;
text-align: center;
line-height: 165px;
font-size: 3em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
<div class="step1">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="nav">
<div class="nav-btn back">[ << Back ]</div>
<div class="nav-btn next">[ Next >> ]</div>
</div>

remove class to sibling of elemnt jquery

I have this Jquery function, with a filter that adds a class named selected to the filter by click and shows all that data filter tags of the selected filter.
I want to define that if the sibling of the chosen element has a class named selected, that class needs to be removed from the rest and has to be added to only the selected element.
Function Script
(function ($) {
"use strict";
$.fn.filter = function (options) {
var defaults = {
nav: '[data-filter]' //
}
var $this = this,
settings = $.extend(defaults, options),
$target = $(settings.target),
selected = [];
return this.each( function() {
var $element = $(this);
$(settings.nav).each( function() {
$(this).click( function(event) {
// add selected class
$(this).toggleClass('selected');
// manipulate selected terms array
if ($.inArray($(this).data('filter'), selected) < 0 ) {
selected.push($(this).data('filter'));
} else {
var index = $.inArray($(this).data('filter'), selected);
selected.splice(index, 1);
}
// show/hide elements
$element.find('[data-filter-tags]').each( function() {
var terms = $(this).data('filter-tags').split(','),
show = null;
for (var i=0;i<selected.length;i++) {
show = ($.inArray(selected[i], terms) >= 0 && show !== false);
}
if (show || selected.length == 0) {
$(this).fadeIn();
} else {
$(this).fadeOut();
}
});
event.preventDefault();
});
});
});
};
}(jQuery));
HTML
<div id="tags">
<div id="cities" data-activeclass="selected">
תל אביב
רמת גן
הכל
<div>
</br>
משרה מלאה
משרה חלקית
הכל
</br>
מזכירות
הפעלה
הכל
</br>
</nav>
<div id="filter">
<div class="block" style="background: green" data-filter-
tags="time,kind,city,telaviv,full,sec">תל אביב משרה מלאה מזכירות</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,full,sec">רמת גן מלאה מזכירות</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,part,op">רמת גן חלקית הפעלה</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,telaviv,full,op">תל אביב מלאה הפעלה</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,part,sec">רמת גן חלקית מזכירות</div>
</div>
I want to define that if the sibling of the choosen elemnts has class named
"selected" remove the class from them and add it only to the selected element.
If clicking the element selects it and deselects all of its siblings, then in your click handler:
$(this).addClass("selected").siblings().removeClass("selected");
Simplified live example:
$("[data-filter]").on("click", function() {
$(this).addClass("selected").siblings().removeClass("selected");
});
[data-filter] {
border: 1px solid blue;
}
.selected {
background-color: yellow;
}
<div>
<span data-filter="1">one</span>
<span data-filter="2">two</span>
<span data-filter="3">three</span>
<span data-filter="4">four</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If clicking the element toggles it, we want toggleClass (which you have) but the rest is the same:
$(this).toggleClass("selected").siblings().removeClass("selected");
...since the .siblings().removeClass("selected"); part just won't do anything if the current element was the one that was selected.
Simplified live example:
$("[data-filter]").on("click", function() {
$(this).toggleClass("selected").siblings().removeClass("selected");
});
[data-filter] {
border: 1px solid blue;
}
.selected {
background-color: yellow;
}
<div>
<span data-filter="1">one</span>
<span data-filter="2">two</span>
<span data-filter="3">three</span>
<span data-filter="4">four</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

One click multiple functions with arrays

I'm trying to create this piece of code in which an element is pushed into an array, displayed and get a style added which gives them a random hex color. I got the hex color and the pushing into the array partly done, but I can't seem to be able to add the style nor display the div… Here is my code so far:
JS
var colorBg = '#' + (Math.random() * 0xFFFFFF << 0).toString(16)
var elements = []
var el = '<div class="element bg"></div>'
document.getElementById("addEl").onclick = () => {
elements.push(el)
//console.log(elements)
for (i = 0; i < elements.length; i++) {
console.log(elements[i])
document.write(elements[i])
//elements[i].style.backgroundColor = colorBg
}
}
HTML
<div class="container">
<div class="element bg"></div>
</div>
<input type="button" value="Add Block" id="addEl"/>
CSS
html, body{
height:80%;
}
.container{
width:100%;
height:100%;
}
.element{
width:100px !important;
height:100px;
}
Do not use document.write(). Instead, create HTML elements with document.createElement() and then append them to other elements.
You can also just set their color and append them once when you create the element. No need to do all that for ALL the elements every time you click the button.
If you want to randomize the color of every element on every button press, you could instead select all of the elements, iterate over them, and randomize their color that way.
document.getElementById("addEl").onclick = () => {
var el = document.createElement("div");
el.className = ["element bg"];
var colorBg = '#' + (Math.random() * 0xFFFFFF << 0).toString(16)
el.style.backgroundColor = colorBg
document.getElementById("container").append(el)
}
html, body{
height:80%;
}
#container{
}
.element{
width:100px !important;
height:100px;
margin:10px;
border:1px solid black;
}
<div id="container">
</div>
<input type="button" value="Add Block" id="addEl"/>
To give structure to the code it is nice to have each operation as a separate function. Random color string generation, new DOM element construction (without displaying it), main actions. This way it is easy to read the code: can start reading at any point and understand what the lines of code are doing, not necessary having to learn the whole code logic.
What's happening here. It starts with a button click, which fires a "click" event, that has function addEl() bound to it. addEl() would acquire a new DOM element from createEl(), place it inside container element and push the element to the elements array if its required for some other functionality not covered in the original question.
function getColor() {
return '#' + (Math.random() * 0xFFFFFF << 0).toString(16);
}
function createEl(){
var el = document.createElement("div");
el.className = "element bg";
el.style.backgroundColor = getColor();
return el;
}
function addEl() {
var el = createEl();
container.appendChild(el);
elements.push(el);
}
var container = document.getElementById("container");
var elements = [];
document
.getElementById("addEl")
.addEventListener('click', addEl)
;
html, body{
height:80%;
}
#container{
width:100%;
height:100%;
}
.element{
width:100px !important;
height:100px;
float:left;
}
<div id="container"></div>
<input type="button" value="Add Block" id="addEl"/>
You would create elements using DOM methods instead of using document.write(). It's usage is discouraged. The following will do what you are after:
document.getElementById("addEl").addEventListener('click', () => {
let container = document.querySelector('.container');
let el = document.createElement("div");
el.className = 'element bg';
el.innerText = 'foo';
el.style.backgroundColor = getRandomColor();
container.appendChild(el);
});
function getRandomColor() {
return '#' + (Math.random() * 0xFFFFFF << 0).toString(16);
}
html, body{
height:80%;
}
.container{
width:100%;
height:100%;
}
.element{
width:100px !important;
height:100px;
}
<div class="container">
<div class="element bg"></div>
</div>
<input type="button" value="Add Block" id="addEl"/>
This can be simply done using jquery
$(function () {
var elements = []
var el = '<div class="element bg"></div>'
$("#addEl").click(function () {
var colorBg = '#' + (Math.random() * 0xFFFFFF << 0).toString(16)
var el = $("<div />",
{
class: "element bg",
css: {
width: "20px",
height: "10px",
backgroundColor: colorBg
}
});
elements.push(el)
$("#mycontainer").append(el);
});
})
html, body{
height:80%;
}
.container{
width:100%;
height:100%;
}
.element{
width:100px !important;
height:100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container" id="mycontainer">
<div class="element bg"></div>
</div>
<input type="button" value="Add Block" id="addEl"/>

Wrap individual character in <span> on keyUp using jQuery

I want to wrap each character to wrapped in a <span></span> and desire output is <span>a</span><span>b</span><span>c</span>.
I have tried following but its not helping.
JSFIDDLE
<div contenteditable="true" id="text1" type="text" placeholder="type something...">
$(function() {
$("#text1").keyup(function(event) {
$(this).wrapInner( "<span class='test'></span>" )
});
});
It outputs following; which is not what I required. Any help?
<span class="test">
<span class="test">
<span class="test">
<span class="test">ffdf</span>
</span>
</span>
</span>
Here is my solution. There is tag code below the input div, for control what is content of the div:
txt = $("#text1").html();
$("#out").text(txt);
$(function() {
$("#text1").keyup(function(event) {
txt = txt + "<span class='test'>"+String.fromCharCode(event.which)+"</span>";
$(this).html(txt);
$("#out").text($(this).html());
});
});
#text1 {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
<code id="out"></code>
Pure function of replacing char looks like:
txt = $("#text1").html();
$(function() {
$("#text1").keyup(function(event) {
txt += "<span>" + String.fromCharCode(event.which) + "</span>";
$(this).html(txt);
});
});
Here is another one where case-sensitive func keypress used along with preventDefault() to prevent a redundant character appear:
txt = $("#text1").html();
$(function() {
$("#text1").keypress(function(event) {
txt += "<span>" + String.fromCharCode(event.which) + "</span>";
event.preventDefault();
$(this).html(txt);
$("#out").text(txt);
});
});
#text1 {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
<code id="out"></code>
is this what you need ?
$(function(){
$("#text1").keyup(function(event) {
$('.test').each(function (index) {
var characters = $(this).text().split("");
$this = $(this);
$this.empty();
$.each(characters, function (i, el) {
$this.append("<span>" + el + "</span");
});
});
});
});
#text1 {
background: #ccc none repeat scroll 0 0;
height: 24px;
width: 127px;
}
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
<span class="test">ffdf</span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
May be try using text() and do substr() ti get last character entered recently and add the <span>
$(document).ready(function() {
$("#text1").keyup(function(event) {
var txt = $(this).text();
$(this).wrapInner("<span class='test'>" + txt.substr(txt.length, txt.length - 1) + "</span>");
});
});
#text1 {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something...">
You need to split the content by .split("")
var myText = $("#text").html();
var myTextArr = myText.split("");
$("#text").empty();
myTextArr.forEach(function(val, idx){
$("#text").append("<span class='test'>" + val + "</span>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='text'>ABC</div>
Since goal is to type/replace (simultaneously!), i have used this:
arr=[];
$(function() {
$("#text1").keyup(function(event) {
clean=$( this )
.contents()
.filter(function() {
return this.nodeType === 3;
}).text();
output="";
arr.push(clean.charAt(clean.length-1));
for(i=0;i<arr.length;i++) {
output+="<span class='test'>"+arr[i]+"</span>";
}
$(this).html(output);
//console.log(output);
});
});
#text1 {
border: 1px solid #ccc;
height:200px;
}
.test {
background:pink;
color:white;
margin-left:3px;
display:inline-block;
width:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="text1" type="text" placeholder="type something..."></div>
So, first - filter just text inside div, and wrap it with desired html.
P.S. span CSS is here just for test purposes.
P.S. 2 Not sure about white spaces (and desired functionality) - but they can be removed, too...
Test without span CSS: https://jsfiddle.net/aau75w9q/4/ (produced HTML is what is required, if i understand correctly)
What about splitting your string first ?
$(function() {
$("#text1").keyup(function(event) {
$(this).text().split('').wrapInner( "<span class='test'></span>" )
});
});

Custom html tab implementation problems

my use case : create tab like experience. clicking on add button creates a (horz tab button) and a corresponding div, which is linked via onclick listener, dynamically.
problems :
on clicking add button, values from previous tabs are reset (which is obvious wrt to the way $tabs_prev & $menu_prev is populated) and
their respective js goes away (which I can't understand, why?)
a remove tab implementation (because the way I've coded these tabs, removing a tab and corresponding div isn't really simple, so, any clues in this direction, maybe?)
code : fiddle : http://jsfiddle.net/g58fzs75/1/
HTML:
<body>
<input id="hidden" type="hidden" value="1"></input>
<div id="template_tabBtn" style="display:none">
<input type="button" value="add" onclick="addTab()"></input>
</div>
<ul id="menu">
</ul>
<div id="tabs">
</div>
<div id="template_tabBar" style="display:none">
<li>
<input type="button" id="tab_btn" class="template_tabBar" value="Tab" onclick="tabClick(this)"></input>
</li>
</div>
<div id="template_tabs" style="display:none">
<div id="tabs" class="template_tabs tab_div" value="1">
<input type="text" id="txt" class="template_tabs" value="alert"></input>
<input type="button" id="btn" class="template_tabs" value="alert"></input>
</div>
</div>
</body>
CSS:
<style>
ul#menu {
padding: 0;
}
ul#menu li {
display: inline;
}
ul#menu li input {
background-color: black;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 4px 4px 0 0;
}
ul#menu li input:hover {
background-color: orange;
}
</style>
jQuery :
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script>
$tabs_prev = "";
$menu_prev = "";
$add_btn = "";
$current_tabID = "";
function tabClick(id) {
showCurrent($(id).attr('id'));
}
function addTab() {
var tabCount = parseInt($('#hidden').val()) + 1;
$('#hidden').val(tabCount);
run(tabCount);
showCurrent($('#tabs-' + tabCount).attr('id'));
}
$(document).ready(function() {
$add_btn = "<li>" + $('#template_tabBtn').html() + "</li>";
run(1);
});
function run(tabCount) {
//$tabs_prev += main($('#template_tabs'),tabCount);//alert("tabs\n"+$tabs_prev);
$menu_prev += main($('#template_tabBar'), tabCount); //alert("menu\n"+$menu_prev);
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
$('#menu').html($menu_prev + $add_btn);
logic(tabCount);
}
function main(target, tabCount) {
$htmlBackup = $(target).html();
$('.' + $(target).attr('id')).each(function() {
$(this).attr('id', $(this).attr('id') + "-" + tabCount).removeClass($(target).attr('id'));
$(this).attr('value', $(this).attr('value') + "-" + tabCount);
});
$html = $(target).html();
$(target).html($htmlBackup);
return $html;
}
function logic(tabCount) {
$('#btn-' + tabCount).click(function() {
alert($('#txt-' + tabCount).val());
});
}
function showCurrent(current_id) {
$('.tab_div').each(function() {
var id = $(this).attr('id');
var id_num = id.substr(id.lastIndexOf('-') + 1, id.length);
var current_id_num = current_id.substr(current_id.lastIndexOf('-') + 1, current_id.length);
if (id_num == current_id_num) {
$("#tabs-" + id_num).show();
$('#tab_btn-' + id_num).css({
"background-color": "orange"
});
} else {
$("#tabs-" + id_num).hide();
$('#tab_btn-' + id_num).css({
"background-color": "black"
});
}
});
}
</script>
The reason why your javascript is disappearing is because resetting the innerHTML deletes the onclick handlers on the elements. Why: the original elements are destroyed, including references to events and new elements are created.
The code responsible for this:
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
Please use jQuery's appending of an element by cloning the template tab:
$('#tabs').append($('#template_tabs').clone(true));
Append appends htmlstrings or elements to an parent element. It's a buffed up version of the documents native 'appendChild'.
clone clone the template element (makes a copy). You can do this in your function main and return it to the append function.
function main(tabCount)
{
var node = $('#template_tabs').clone(true));
//do things with the node, like setting an onclick handler, or id.
//example
node.setAttribute("id", "tab" + tabCount);
}
Removing can be done also:
function removeNode(node)
{
//provide a node via jQuery
//example: removeNode($("#tab2")) <-- now tab2 will be removed from the DOM.
node.remove();
}

Categories