Add remove with numbering indicated dynamically - javascript

So currently I can easily add and remove multiple textarea
But what I'm trying to do is to put numbering per specific textarea
Here's my textarea
as you notice my default text area is Step 1
But I wanted to do is when I clicked add it will show another textarea that says
Step 2
<div class="optionBox">
<div class="block">
<div class="form-group">
<label for="exampleFormControlTextarea1">Step 1</label>
<textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
<span class="remove">Remove</span>
</div>
<div class="block"> <span class="add">Add Option</span>
</div>
</div>
My Javascript
$('.add').click(function () {
$('.block:last').before(' <div class="block"><div class="form-group"><label for="exampleFormControlTextarea1">Step</label><textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea></div><span class="remove">Remove</span></div>');
});
Here's the current output

To make this work you can add a span element with no content to the label within each .block. Then you can create a function which updates the number within that span based on the index of the element every time you add or remove a .block.
I would also strongly suggest that you clone elements instead of adding lots of HTML in to your JS logic, as this violates the Separation of Concerns principle due to tying the JS too closely with the HTML. In your case this can be done by simply adding one extra class on to the .block which holds the textarea elements. Try this:
$('.add').click(function() {
let $lastBlock = $('.block.step:last');
let $clone = $lastBlock.clone().insertAfter($lastBlock);
$clone.find('textarea').val('');
updateStepCounts();
});
$('.optionBox').on('click', '.remove', function() {
if ($('.block.step').length > 1) {
$(this).closest('.block').remove();
updateStepCounts();
}
});
let updateStepCounts = () => $('.block label span').text(i => i + 1);
updateStepCounts();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="optionBox">
<div class="block step">
<div class="form-group">
<label for="exampleFormControlTextarea1">Step <span></span></label>
<textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
<span class="remove">Remove</span>
</div>
<div class="block">
<span class="add">Add Option</span>
</div>
</div>

I removed the div.block surrounding the "add option" span and used .append on the newly added div.block-container element instead of .before to add the next textarea to the bottom of the options container. i think this reads a little better symantically.
Also using string interpolation i am able to insert the total number of div.block + 1 to track the number of textareas visible on the page.
Hope this helps.
$('.add').click(function () {
const numberOfBlocks = $(".block").length;
$(".block-container")
.append(`
<div class="block">
<div class="form-group">
<label for="exampleFormControlTextarea1">Step ${numberOfBlocks + 1}</label>
<textarea class="form-control rounded-0" id="exampleFormControlTextarea1" rows="10"></textarea>
</div>
<span class="remove">Remove</span>
</div>`
);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="optionBox">
<div class="block-container">
</div>
<span class="add">Add Option</span>
</div>

Related

How to use divs as radio button and save data from inside the selected div to valiables using javascrip?

I have multiple divs in my HTML with sample class name and I want these divs to behave like a radio button, that is when a div is clicked / selected, I want to achieve following.
1: Change the selected div background color
2: Get values from different elements those are inside the selected div and save the values in variables.
I am able to change the color but I am not able to get the unique values from inside the selected div.
Here is the HTML
<div class="col-lg-4 text-center">
<div class="package">
<input type="hidden" class="packageId" value="5" />
<p class="small">Deep</p>
<h4 class="packageTitle">Deep Cleaning</h4>
<p>All-inclusive cleaning service</p>
<p class="small">Price Per Cleaner</p>
<p class="price packagePrice">41.90 <span class="small">/h</span></p>
</div>
</div>
<div class="col-lg-4 text-center">
<div class="package">
<input type="hidden" class="packageId" value="4" />
<p class="small">Last Minute</p>
<h4 class="packageTitle">Last-Minute Cleaning</h4>
<p>Last minute & after party cleaning</p>
<p class="small">Price Per Cleaner</p>
<p class="price packagePrice">43.90 <span class="small">/h</span></p>
</div>
</div>
<div class="col-lg-4 text-center">
<div class="package">
<input type="hidden" class="packageId" value="3" />
<p class="small">Moving</p>
<h4 class="packageTitle">Move-In-Out Cleaning</h4>
<p>For move-ins, and move-outs</p>
<p class="small">Price Per Cleaner</p>
<p class="price packagePrice">41.90 <span class="small">/h</span></p>
</div>
</div>
And here the the Script
var packageId = "";
var packageTitle = "";
var packagePrice = "";
var packages = document.getElementsByClassName('package');
Array.prototype.forEach.call(packages, function (element) {
element.addEventListener('click', function () {
$('.package').css("background-color", "#FFFFFF");
$(this).css("background-color", "#FCF6CC");
packageId = $('.packageId').attr('value');
packageTitle = $('.packageTitle').text();
packagePrice = $('packagePrice').text();
console.log(packageId);
console.log(packageTitle);
console.log(packagePrice);
});
});
The reason that youre not getiing the unique value is because you are using get element by class ,
ie packagePrice = $('.packagePrice').text();
and there are 3 elements with same class name , to fix this issue
const elem = $(this);
packagePrice = elem.find('.packagePrice').text();

Scroll to error message on form element when using tab key for page navigation

I have a form with multiple input elements. Some of the input elements have an error message below the input.
When I use the tab key for page navigation, the website scrolls to the focused input element. When the focused input element has an error message, I can`t see the message below the input element, because the page scrolls only to the focused input. I need to scroll the page down a little bit, so the user can see the error message.
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
<link rel="stylesheet" type="text/css" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<form>
<div class="row">
<div class="col">
<input type="text" class="form-control">
</div>
<div class="col">
<input type="text" class="form-control">
</div>
</div>
<div class="row">
<div class="col">
<input type="text" class="form-control">
</div>
<div class="col">
<input type="text" class="form-control">
</div>
</div>
<div class="row">
<div class="col">
<input type="text" class="form-control">
</div>
<div class="col">
<input type="text" class="form-control">
</div>
</div>
<div class="row">
<div class="col">
<input type="text" class="form-control">
</div>
<div class="col">
<input type="text" class="form-control">
</div>
</div>
<div class="row">
<div class="col">
<input type="text" class="form-control is-invalid">
<div class="invalid-feedback">
Error Text.
</div>
</div>
<div class="col">
<input type="text" class="form-control is-invalid">
<div class="invalid-feedback">
Error Text.
</div>
</div>
</div>
</form>
Use the tab key to navigate throu the form inputs. When you focus the last inputs with the error messages, you can`t see the error text below the input fields.
Assuming you have jquery installed (not slim, because animate is not defined in the slim version), you just have to modify height offset (line_height) as you need to scroll further than the focused element.
$("input").focus(function() {
var error_input = $(this);
if(error_input.hasClass("is-invalid")){
var line_height = $(".invalid-feedback").height();
//FIXME
console.log(error_input.offset().top + line_height);
$('html, body').animate({
scrollTop: error_input.offset().top + line_height
}, 600);
}
});
Here is the : fiddle
It's more common to put inline validation messages above, or to the right of the input, rather than below it. This would solve your scrolling issue and make the error message more visible.
When it comes to web accessibility, simple solutions often work better than complex ones.
I've also noticed that you aren't using label elements or explicitly specifying the relationships between your error messages and your input elements. Any reason why?
I'm including a link (below) that outlines some very useful techniques for associating error messages with the respective input elements.
https://developer.paciellogroup.com/blog/2016/01/simple-inline-error-message-pattern/
I wanted to share my solution to this problem.
Now, I use the solution from this post: Scroll into view if needed
Here is the code from my Polymer Web Component:
_onFocus(e) {
const scrollWrapper = document.querySelector('.i-flex-content-scroll-container');
this._scrollIfNeeded(this, scrollWrapper);
}
_scrollIfNeeded(element, container) {
if (element.offsetTop < container.scrollTop) {
container.scrollTop = element.offsetTop;
} else {
const offsetBottom = element.offsetTop + element.offsetHeight;
const scrollBottom = container.scrollTop + container.offsetHeight;
if (offsetBottom > scrollBottom) {
container.scrollTop = offsetBottom - container.offsetHeight;
}
}
}
Now, it only scrolls if needed.

How to count number of classes generated using jQuery?

I have following HTML code.
Here 2 add/remove link exists. 1) Add More Details(+) 2) Add(+)
when I click on Add(+) link its clone the tour_wrap class div and counting the number of trip_counting class div cloned/added. Like: Trip 1, Tip 2, Trip 3 etc..
And, I have another link called Add More Details (+) which is clone the tour_wrap div.
So when I click on this link twice for e.g then it's clone the tour_wrap div 2 times, That's good.
Now I have 3 tour_wrap div. In this div's you can see that I have the link Add(+) 3 times, right? Yes. So when I click on any Add(+) link then it's counting the Total number of trip_counting classes added But I want to count only corresponding trip_counting classes.
Check this image:
HTML Code:
<div class="tour_wrap">
<!-- some other html code for the tour -->
<div class="trip_wrap">
<h5 class="badge badge-success trip_counting">Trip 1</h5>
<div class="col-md-4">
<div class="form-group">
<label>From</label>
<input type="text" name="ow_from[]" class="form-control" placeholder="From">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>To</label>
<input type="text" name="to[]" class="form-control" placeholder="To">
</div>
</div>
<div class="col-md-12">
<div class="change_trip text-right">
<a class="btn add_button_trip trip_btn">Add(+)</a>
</div>
</div>
</div> <!-- end trip_wrap -->
</div> <!-- end tour wrap -->
<div class="row">
<div class="col-md-12">
<div class="form-group change text-right">
<a class="btn add_button add_more add_more_btn"><strong>Add More Details (+)</strong></a>
</div>
</div>
</div> <!-- end row -->
jQuery Code:
// for all way
$("body").on("click",".add_button",function(){
var html = $(".tour_wrap").first().clone();
$(html).find(".change").html("<a class='btn remove remove_more'>Remove Details(-)</a>");
$(".tour_wrap").last().after(html);
$('.counting').each(function(i, elm) {
$(elm).text('Detail ' + (i + 1));
});
});
$("body").on("click",".remove",function(){
$(this).parents(".tour_wrap").remove();
});
// add more trip
$("body").on("click",".add_button_trip",function(){
var html = $(".trip_wrap").first().clone();
$(html).find(".change_trip").html("<a class='btn remove_trip remove_more trip_btn_remove'>Delete(-)</a>");
//$(".trip_wrap").last().after(html);
$('.trip_wrap').each(function(i, elm) {
$(elm).last().after(html);
});
$('.trip_counting').each(function(i, elm) {
$(elm).text('Trip ' + (i + 1));
});
});
$("body").on("click",".remove_trip",function(){
$(this).parents(".trip_wrap").remove();
});

how to hide skill div on close class click

how to hide div on object of div click
I am adding jquery path than my html code is here as it is and than after I am apply script to delete label class="main" with span and div class close1
but it's not perform
<label class="main ">
<span class="tag-value">mysql </span>
<div class="close1">X</div>
</label>
<label class="main ">
<span class="tag-value">codeigniter </span>
<div class="close1">X</div>
</label>
<label class="main ">
<span class="tag-value">ajax </span>
<div class="close1">X</div>
</label>
<label class="main ">
<span class="tag-value">jquery </span>
<div class="close1">X</div>
</label>
<script>
$(function(){
$(".close1").click(function(){
$(this).parent(".main").hide();
});
});
</script>
Check that JQ lib. is in the head of you r document, also, you can probably just use .parent()
http://jsfiddle.net/Yx4EU/
<script>
$(function(){
$(".close1").click(function(){
$(this).parent().hide();
});
});
</script>
If this does not work, I suggest adding a fiddle for someone to look at.
Check this out: http://jsfiddle.net/8436y/1/
In this fiddle you will notice I haven't defined the parent, since it is not necessary (in this case).
http://jsfiddle.net/8436y/5/
here I have used the .closest() to define the closest class="main" , which also works ;)

Targeting a specific class with jQuery

I am trying to display a hidden class in jQuery but it is no applying to the class I am targeting. It displays the whole class:
<div class="feeds">
<input class="post_id" />
<textarea class="commentdata"></textarea>
<button class="mmore">More</button>
<p class="time">time</p>
<div class = "comment_data">
<div class = "comment">
<p> Comments </p>
</div>
</div>
</div>
<div class="feeds">
<input class="post_id" />
<textarea class="commentdata"></textarea>
<button class="mmore">More</button>
<p class="time">time</p>
<div class = "comment_data">
<div class = "comment">
<p> Comments </p>
</div>
</div>
<div class="feeds">
<input class="post_id" />
<textarea class="commentdata"></textarea>
<button class="mmore">More</button>
<p class="time">time</p>
<div class = "comment_data">
<div class = "comment">
<p> Comments </p>
</div>
</div>
</div>
The class comment_data is display: none by default and should only be displayed whenever the More button is clicked. Working but it is displaying all the comments for 3 div.
This is my jQuery code:
$( ".mmore" ).click(function() {
$('.comment_data').slideToggle("slow");
});
$('.mmore').click(function() {
$(this).parents('.feeds').find('.comment_data').slideToggle('slow')
});
You can use .closest() to find .feeds div and then use .find() for *.comment_data* div
$('.mmore').click(function() {
$(this).closest('.feeds').find('.comment_data').slideToggle('slow')
});
You're selecting all objects matching the selector .comment_data.
You'll need to limit it to the same container that the clicked button is in. There's a number of ways you could do this. One easy one would be:
$( ".mmore" ).click(function() {
$(this).parent().find('.comment_data').slideToggle("slow");
});

Categories

Resources