I have a DOM like this, when i fill the input field and click the button i need to create a textarea element and and stored the input value there.
if i click multiple times create multiple textarea and multiple ID's, How can i do this please check my code, Best answers must be appreciated
$('#note').on('click', function(){
var storedNoteVal = $('#enterVal').val();
var count_id = 1;
var noteCov = $('.note_cover');
$('#content_bag').prepend('<div class="full-width note_cover" id="noteId"><textarea></textarea></div>');
$(noteCov).find('textarea').val(storedNoteVal);
$(noteCov).each(function(index, element) {
$(this).attr('id', 'noteId' + count_id);
count_id++;
});
});
.full-width.note_cover {
float: left;
margin-bottom:15px;
}
.note_cover textarea {
height: auto !important;
height: 45px !important;
resize: none;
width: 100%;
/*border:none;*/
}
<div class="col-md-11 col-md-offset-1 col-sm-8 col-xs-12 mtp" id="content_bag">
</div><!-- #content_bag -->
<input type="text" placeholder="Enter project Tags" class="majorInp" id="enterVal" />
<button id="note">click me</button>
Your code is working fine, just put storedNoteVal in text-area, and input won't generate any text-area if its blank.
$('#note').on('click', function() {
var storedNoteVal = $('#enterVal').val();
var count_id = 1;
var noteCov = $('.note_cover');
if(storedNoteVal){
$('#content_bag').prepend('<div class="full-width note_cover" id="noteId"><textarea>' + storedNoteVal + '</textarea></div>');
//$(noteCov).find('textarea').val(storedNoteVal);
$(noteCov).each(function(index, element) {
$(this).attr('id', 'noteId' + count_id);
count_id++;
});
}
});
.full-width.note_cover {
float: left;
margin-bottom: 15px;
}
.note_cover textarea {
height: auto !important;
height: 45px !important;
resize: none;
width: 100%;
/*border:none;*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="col-md-11 col-md-offset-1 col-sm-8 col-xs-12 mtp" id="content_bag">
</div>
<!-- #content_bag -->
<div>
<input type="text" placeholder="Enter project Tags" class="majorInp" id="enterVal" />
<button id="note">click me</button>
</div>
Building on Abhinshek answer -
Your code actually reassign id's to the textareas, since you loop through all the elements after prepending them.
You could define count_id as a window variable (outside the click function) and then just use it.
Also, you don't need to wrap noteCov with $() since $('.note_cover') returns a jQuery objects array
var count_id = 1;
$('#note').on('click', function() {
var storedNoteVal = $('#enterVal').val();
$('#content_bag').prepend('<div class="full-width note_cover" id="noteId_'+count_id+'"><textarea>' + storedNoteVal + '</textarea></div>');
count_id++;
});
This way each textarea gets it's own unique id that doesn't change
Related
I'm having trouble with some dynamic HTML. I've got a slider that adds or removes DOM elements as the value changes. Each time it increases, an element is added, and each time it decreases, an element is removed.
Here's the HTML:
<input type="range" min="3" max="16" class="rgb-slider" value="3" tabindex="-1" oninput="slider(this.value)">
<div class="container">
<div class="boxes">
<div class="box"><span></span></div>
<div class="box"><span></span></div>
<div class="box"><span></span></div>
</div>
</div>
Here's the JS:
var colorCount = 3;
function slider(value) {
if (colorCount < parseInt(value)) {
$('.boxes').append('<div class="box"><span></span></div>');
colorCount = value;
} else {
$('.box:last-child').remove();
colorCount = value;
}
}
http://jsfiddle.net/meu9carx/
However, when I quickly move the slider, it seems to skip or trip up, and I end up with more or fewer than I started with. The slider has a range from 3-16, but sometimes the min value goes to more or less than 3. Sometimes, all the boxes vanish.
Is there a smarter way to code this? I'm trying to avoid hard-coding divs here.
If the mouse moves fast, it's possible for the input value to change by more than one (in either direction) during a single input event. Use the value in the input to determine how many squares there should be exactly, rather than adding or removing only a single element each time.
const boxes = $('.boxes');
$('input').on('input', function() {
const targetSquares = Number(this.value);
while (boxes.children().length < targetSquares) {
boxes.append('<div class="box"><span></span></div>');
}
while (boxes.children().length > targetSquares) {
$('.box:last-child').remove();
}
});
body{
background: #777;
font-family: 'Arimo', sans-serif;
}
.container { padding: 20px 0; }
.boxes { display: flex; }
.box {
padding: 10px;
background: #ffffff;
height: 100px;
flex: 1;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="range" min="3" max="16" class="rgb-slider" value="3" tabindex="-1">
<div class="container">
<div class="boxes">
<div class="box"><span></span></div>
<div class="box"><span></span></div>
<div class="box"><span></span></div>
</div>
</div>
When I click a button, I want to append a <div> to the container <div class='container'></div>. Then, I want to append the value of the number of the div within its array to <input type='hidden' value='"+number_within_array+"'>. So, if I click the button once and create one div, its input value should be either 0 or 1, depending on the system you use. Then, if I click the button again, the value of the new div's input will be either 1 or 2. Here's an example to visualize what I'm trying to say:
https://jsfiddle.net/crduling/yzsgue0b/8/
You can have declare a counter variable ,so on click everytime counter will be increment by 1 . Try like below :
//declaring count
var count=1;
$(".add-div").click(function() {
//apending div wit input
let append = "<div>value <input type='hidden' value='"+count+"'/></div>"; //html to be appended
console.log("<input type='hidden' value='"+count+"'/>");
//increment count
count++;
$(append).appendTo(".container"); //add html to div tag on click event
var divs = $(".container").find("div"); //find the array with the appended divs...
$(".resulting-values").append(divs.length + "<br>"); //...and count how many divs have been appended
//How do I get it so that the numeric value is put inside of the appended divs? Ex: <input type='hidden' value='" + numeric value + "'>
});
.add-div {
position: absolute;
width: 10%;
height: 5%;
top: 0;
right: 0;
}
.find {
position: absolute;
top: 5%;
width: 10%;
height: 5%;
right: 0;
}
.container {
display: inline-block;
}
.resulting-values {
position: absolute;
left: 10%;
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="container"></div>
<div class='resulting-values'></div>
<button class="add-div">Add div</button>
You should declare a external variable and inside the function increment it:
let counter = 0;
$('.add-div').click(function() {
let append = `<div>value ${counter}</div>`;
$(append).appendTo('.container');
let inputHidden = `<input type="hidden" value="${counter}">`;
$('.resulting-values').append(inputHidden);
counter++;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container"></div>
<div class='resulting-values'></div>
<button class="add-div">Add div</button>
I have seen many similar problems but when I try them they end up failing. It has gotten to the point where my code is totally messed up and I need some help both cleaning it up and fixing my issue. (using chrome)
So far I have tried selecting the value of the form and putting that into a div,
I have tried to use the button as just a link to start the script so that the page doesn't reset and also many other answers found on-line, none of them are helping so I am asking for a personalised help.
function on_comment_add() {
var main = document.getElementById("div1");
var add_user_name = document.createElement("div");
var add_user_comment = document.createElement("div");
add_user_name.setAttribute("id", "add_user_name");
add_user_comment.setAttribute("id", "add_user_comment");
<!-- var node = document.createTextNode("This is new."); -->
var node_1 = document.getElementById("user_name").value;
var node_2 = document.getElementById("user_comment").value;
add_user_name.appendChild(node_1);
add_user_comment.appendChild(node_2);
var element = document.createElement("div");
element.setAttribute("id", "display_comment_div");
element.appendChild(add_user_name);
element.appendChild(add_user_comment);
main.appendChild(element);
main.innerHTML = element;
return false;
}
body {
background-color: lightGreen;
}
div.middle {
width: 80%;
margin-left: 10%;
background-color: #47e077;
height: 940px;
font-size: 10pt;
font-family: aubrey;
border: 3px solid gold;
}
.comments-form {
text-align: center;
}
#display_comment_div {
background: rgba(200, 54, 54, 0.1);
width: 80%;
margin-left: 9%;
border: 0.1px solid lightGreen;
border-radius: 25px;
}
#add_user_name {
width: 45%;
float: left;
}
#add_user_comment {
width: 45%;
display: inline-block;
float: right;
}
<div class="middle">
<div class="comments-form">
<form>
<label for="name" style="width:100px; display:inline-block;">Name</label>
<input id="user_name" type="text" placeholder="name goes here" style="width:300px; margin-left:5px;" />
<br><br>
<label for="comment" style="width:100px; display:inline-block;">Comment</label>
<textarea id="user_comment" placeholder="comment goes here" maxlength="150" style="width:300px;max-width:300px;"></textarea><br>
<button style="margin-left:310px;" onmousedown="return on_comment_add">Submit</button>
</form>
<div id="div1">
</div>
</div>
</div>
I guess what I am asking is if anyone can help me display the username and comment below the form but it seems tricky for me because I have gone through so many answers that don't work for me that I cannot think of any other ways to do it.
For clarification this code is not meant to keep the comments from the form nor is it meant to be a fully functioning site. I am just making slight modifications to some code so that I can hand it in as a college assignment.
Using onclick and pass the event inside:
<button style="margin-left:310px;" onclick="on_comment_add(event)">Submit</button>
And disable the default form submit action:
function on_comment_add(e) {
e.preventDefault()
var main = document.getElementById("div1");
var add_user_name = document.createElement("div");
var add_user_comment = document.createElement("div");
add_user_name.setAttribute("id", "add_user_name");
add_user_comment.setAttribute("id", "add_user_comment");
var node_1 = document.createElement("div");
node_1.innerHTML= document.getElementById("user_name").value;
var node_2 = document.createElement("div");
node_2.innerHTML = document.getElementById("user_comment").value;
add_user_name.appendChild(node_1);
add_user_comment.appendChild(node_2);
var element = document.createElement("div");
element.setAttribute("id", "display_comment_div");
element.appendChild(add_user_name);
element.appendChild(add_user_comment);
main.appendChild(element);
return false;
}
Workable example: https://jsfiddle.net/kingychiu/z6gnqswn/
Change type to "button" to prevent automatical form sending and add parentheses to onmousedown expression:
<button type="button" style="margin-left:310px;" onmousedown="return on_comment_add()">Submit</button>
Then change this
add_user_name.appendChild(node_1);
add_user_comment.appendChild(node_2);
to this (since node_1, node_2 are values, not elements):
add_user_name.innerHTML = node_1;
add_user_comment.innerHTML = node_2;
And remove that line
main.innerHTML = element;
above
return false;
That should work.
I have a modal which I am using for alphabetical searching. Along the top, there is a horizontal bar with A-Z buttons. I want each of these buttons to scroll the div (with overflow:auto) to the appropriate letter.
Eg if the user clicks "G", it will scroll the div down to the G results.
I would like to set these onclicks with js or jquery. Here's what I have so far:
$('.search__strip__letter').each(function () {
var number = $(this).data('letter');
$(this).click(function () {
var target = '#search__results__letter--'+number;
$('.search-results').animate({scrollTop:$(target).position().top}, 200);
})
})
Why isn't this working...?
EDIT: Here's a fiddle.
Added clearfix class on floated elements, updated jquery selector spelling Fixed here.
$('.search__strip__letter').each(function () {
var number = $(this).data('letter');
$(this).click(function () {
console.log('click');
var target = '#search__results__letter--' + number;
console.log(target,$('.search-results'));
$('.search-results').animate({
scrollTop: $(target).offset().top + 100
}, 200);
})
})
http://jsfiddle.net/Aerious/z17nyh2s/8/
UPDATE
You should be using $(target).offset().top, it works independent of the style's position property.
You must scrollTop to 0 and subtract the .search-results offset's top, also.
UPDATE II
If you want to animate for both sides, instead of scrollingTop to 0, you must get the current scrollTop and sum it, take a look below:
[].forEach.call('ABCDEFGHIJKLMNOPQRSTUVWXYZ', function(l, i) {
var a = document.createElement('a');
a.textContent = l;
a.addEventListener('click', function(e) {
var target = '#search__results__letter--' + i;
var now = $('.search-results').scrollTop();
$('.search-results').animate({ scrollTop: $(target).offset().top - $('.search-results').offset().top + now }, 200);
});
document.getElementById('letters').appendChild(a);
var div = document.createElement('div');
div.id = 'search__results__letter--' + i;
div.textContent = 'Letter ' + l;
document.querySelector('.search-results').appendChild(div);
});
#letters a {
display: inline-block;
width: 25px;
height: 25px;
background-color: darkblue;
margin: 2px;
line-height: 25px;
text-align: center;
color: white;
font-family: Verdana;
cursor: pointer;
}
.search-results {
height: 120px;
overflow-y: auto;
}
.search-results div {
height: 100px;
background-color: aqua;
margin: 2px;
font-family: Verdana;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="letters">
</div>
<div class="search-results">
</div>
I suggest you use the jquery.scrollTo plugin. It's highly customizable, supports animations and is very easy to use. You just need to replace your animate code with something like this:
$('.search-results').scrollTo($(target), 200);
You need a couple modifications to your code to make it work as I understand it. First, you need to give the .search-results element some context. You do this by adding position:relative to that element. Now that it's the relative parent of your search__results__letter--* elements, you can scroll to them with your animate snippet. However, you also need to calculate the scroll position relative to the offset scroll of the parent. Simple math will handle that part by first getting the scroll position of the search__results__letter--* element and adding it to the scrollTop() of .search-results. You can see this method in the demo code below:
$('.search__strip__letter').each(function () {
var number = $(this).data('letter');
$(this).on('click', function () {
var target = '#search__results__letter--'+number;
var currentPosition = $('.search-results').scrollTop();
$('.search-results').animate({scrollTop:currentPosition + $(target).position().top}, 200);
})
})
.search-results {
border: 1px solid;
height: 100px;
overflow: auto;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
<li>F</li>
</ul>
<div class="search-results">
<p id="search__results__letter--A">Search Results A</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<p id="search__results__letter--B">Search Results B</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<p id="search__results__letter--C">Search Results C</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<p id="search__results__letter--D">Search Results D</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<p id="search__results__letter--E">Search Results E</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<p id="search__results__letter--F">Search Results F</p>
</div>
EDIT:
I've adapted the original poster's fiddle using my code. One addition I had to make was to force the .search__results__letter back into flow by making a new block formatting context on that class. I did this by adding display:inline-block;width:100%; Adding overflow:hidden; or overflow:auto; should also accomplish the same thing. Also, see MDN docs on block formatting context for other methods to force it.
https://jsfiddle.net/gLpvzgu5/
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();
}