jquery link not working after removeClass('disabled') - javascript

I have a script that disables links with a class "disabled"
//disabled links
$(document).ready(function() {
$(".disabled a").click(function() {
return false;
});
});
Additionally, I have a script that when the ".edit" button is clicked toggles the disabled state of the inputs in it's own form. It also does a removeClass('disabled') on any matching links in the form.
//toggle form edit
$("#edit").click(function(e) {
e.preventDefault();
$(this).closest("form").find("input").prop('disabled',false);
$(this).closest("form").find(".input-group-addon").removeClass('disabled');
$("#save").prop('disabled',false);
$("#edit").prop('disabled',true);
$(".alert").hide(400, "swing");
});
Then there is a script for adding and deleting input fields
//add input fields
$(".form-group").on('click', 'a.addInput', function() {
var original = $(this).closest(".input-group");
original.clone().insertAfter(original);
});
//remove input fields
$(".form-group").on('click', 'a.deleteInput', function() {
var original = $(this).closest(".input-group");
if($(this).closest(".form-group").children(".input-group").length > 1) {
original.remove();
}
});
HTML:
<form class="edit">
<div class="panel">
<div class="panel-heading">
<span><i class="fa fa-user" aria-hidden="true"></i> Basic Information</span>
<span class="pull-right"><input id="save" class="btn btn-success" type="submit" value="Save" disabled></span>
<span class="pull-right"><button id="edit" class="btn btn-default">Edit</button></span>
</div>
<div class="panel-body">
<div class="form-group">
<label for="email">Email</label>
<div class="input-group">
<input type="email" class="form-control" placeholder="Email" name="email" value="engelo#dingosoft.us" disabled required>
<div class="input-group-addon disabled"><span class="fa fa-plus"></span></div>
<div class="input-group-addon disabled"><span class="fa fa-minus"></span></div>
</div>
</div>
<div class="form-group">
<label for="phone">Phone</label>
<div class="input-group">
<input type="tel" class="form-control" pattern="\d{3}[\-]\d{3}[\-]\d{4}" placeholder="Format: 555-555-5555" name="phone" value="419-555-1212" disabled required>
<div class="input-group-addon disabled"><span class="fa fa-plus"></span></div>
<div class="input-group-addon disabled"><span class="fa fa-minus"></span></div>
</div>
</div>
</div>
</div>
</form>
The problem I am having is that when the class "disabled" is removed from the links, the links ('a.addInput') & ('a.deleteInput') do not function. What am I missing here?

Click handlers are attached to elements, not to selectors. So when you do this:
$(".disabled a").click(function() {
return false;
});
You are assigning that behavior to all elements which match at that moment (in this case, when the document loads). No matter what changes you make to the DOM after the fact, any elements which were matched when you invoked the above code will still have the above click handler.
One approach here could be to assign the click handler to a common unchanging parent, instead of to the elements themselves. By using .on() in this way, you can evaluate the selector dynamically when the click event happens instead of just once when the page loads. Something like this:
$(document).on("click", ".disabled a", function() {
return false;
});
Then the second selector (".disabled a") will be evaluated with each click. So if the DOM has changed such that an element no longer matches that selector, this click handler won't be used.

You need to add prevent the event.
$(".form-group").on('click', 'a.addInput', function(e) {
e.preventDefault();
var original = $(this).closest(".input-group");
original.clone().insertAfter(original);
});
//remove input fields
$(".form-group").on('click', 'a.deleteInput', function(e) {
e.preventDefault();
var original = $(this).closest(".input-group");
if($(this).closest(".form-group").children(".input-group").length > 1) {
original.remove();
}
});
or you can add a href="javascript:void(0);" to addInput and deleteInput.
I hope it will be help to achieve your goal...

Related

javascript show/hide not working as expected with html field

The following is the chose I am using to let the user manually choose working/starting time.
<input type="checkbox" class="testmethod" id="beastmode" name="beastmode" tabindex="5">Beast Mode</input>
<div class="input-group date" id="id_1">
<input type="text" name="day11" value="09:00 AM" class="form-control"
placeholder="End time" title="" required/>
<div class="input-group-addon input-group-append">
<div class="input-group-text">
<i class="glyphicon glyphicon-time fa fa-clock-o"></i>
</div>
</div>
</div>
<script>
$("#beastmode").click(function () {
if ($(this).prop('checked') === true) {
$('#id_1,#id_2').show();
} else {
$('#id_1,#id_2').hide();
}
});
</script>
By default the field should be hidden, but it is not. Instead even in the checkbox is not checked, the field is visible and to make it hidden I had to check the box and uncheck it again. Then the input field goes hidden. How can i fix this ?
Here is the jsfiddle link, it shows the same problem.
https://jsfiddle.net/shijilt/bs02m98w/
The code is only changing the visibility after clicking the #beastmode element. There's no explicit default otherwise.
You can hide it when the page loads:
$(function () {
$('#id_1,#id_2').hide();
});
Or, even better, style it to be hidden by default in your CSS:
#id_1,#id_2 {
display: none;
}
That way it's hidden by default from the styling itself, regardless of whether or not any JavaScript code successfully executes.
Example
Almost you code is fine. Try this it will work definitely.
<input type="checkbox" class="testmethod" id="beastmode" name="beastmode" tabindex="5">Beast Mode</input>
<div class="input-group date" id="id_1" style="display:none;">
<input type="text" name="day11" value="09:00 AM" class="form-control"
placeholder="End time" title="" required/>
<div class="input-group-addon input-group-append">
<div class="input-group-text">
<i class="glyphicon glyphicon-time fa fa-clock-o"></i>
</div>
</div>
</div>
<script>
$("#beastmode").click(function () {
if ($(this).prop('checked') === true) {
$('#id_1').show();
} else {
$('#id_1').hide();
}
});
</script>
First you have to hide div where id=#id_1 there are many ways to hide but i use simple method to hide it by display: none; in the style.
Second when you click on checkbox if its true its show the div where id=#id_1 else it will hide the div. If you pass two ids which is wrong because its not found #id_2 in the page that's the reason which not show/hide your content.

Select child input textbbox by parent class on focus in and focus out event

I want to add "invalid-class" in my iti class div when someone focusin the input textbox and also remove the "invalid-class" class when someone focusout from the textbox. I want to do it by using .iti class. Is there any method in jquery for that
<div class="form-group col-md-6">
<div class="d-flex position-relative">
<div class="iti">
<div class="iti__flag-container">
<div class="iti__selected-flag" role="combobox">
<div class="iti__flag iti__in"></div>
</div>
</div>
<input type="text" name="phone" id="phone" value="" class="form-control">
<span class="error-block text-danger"><span>Invalid Phone Number</span></span>
</div>
<label for="phone" class="col-form-label ">Phone</label>
</div>
</div>
I tried below Code
$(".iti > input").focusin(function(){
$(this).addClass("round");
});
Based on #Devsi answer, however used toggle class instead of remove and add.
$('input').on('focus blur', function() {
$(this).parents('.iti').toggleClass('active round');
});
.active{
background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="iti">
<div class="iti__flag-container">
<div class="iti__selected-flag" role="combobox" aria-owns="iti-1__country-listbox" aria-expanded="false" title="India (भारत): +91">
<div class="iti__flag iti__in"></div>
</div>
</div>
<input type="text" name="phone" id="phone" value="" class="form-control">
</div>
You can use focus() and blur()
I have added active so you can understand by red background on it.
You can add/remove your class accordingly.
$('.iti input').focus( function() {
if($(this).val()){
$(this).parents('.iti').addClass('active round');
}
});
$('.iti input').blur( function() {
$(this).parents('.iti').removeClass('active round');
});
$('.iti input').on('keyup', function() {
if($(this).val()){
$(this).parents('.iti').addClass('active round');
} else {
$(this).parents('.iti').removeClass('active round');
}
});
.active{
background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="iti">
<div class="iti__flag-container">
<div class="iti__selected-flag" role="combobox" aria-owns="iti-1__country-listbox" aria-expanded="false" title="India (भारत): +91">
<div class="iti__flag iti__in"></div>
</div>
</div>
<input type="text" name="phone" id="phone" value="" class="form-control">
</div>
I have a solution in plain javascript.
If I understand correctly you have to add/remove a class for each input element in the outer div container. In this case you can use event delegation, in this way you must not add a listener for each element and you can add the listener to the container/root element. But there is a problem, focus and blur events don't bubble thereby you have to use focusin and focusout.
<div class="iti">
<div class="iti__flag-container">
<div class="iti__selected-flag" role="combobox" aria-owns="iti-1__country-listbox" aria-expanded="false" title="India (भारत): +91">
<div class="iti__flag iti__in"></div>
</div>
</div>
<input type="text" name="phone" id="phone" value="" class="form-control">
</div>
<script>
document.addEventListener("DOMContentLoaded", (event)=>{
let inEl = document.querySelector(".iti");
inEl.addEventListener("focusin",handler);
inEl.addEventListener("focusout",handler);
});
function handler(event) {
let target = event.target;
switch(target.id){
case "phone":
case "anotherIdInput":
target.classList.toggle("round");
break;
}
}
</script>
The only problem is that you are forced to add a case for each input element in the switch (though this can be automatized too).
Furthermore I have not considered possible backward compatibility problems. For instance blur and focus are everywhere, focusin and focusout are DOM3, the same with addEventListener,and so on. It isn't safe to reference an element with the class because more elements can have the same class .

selecting all class within this in query

well right now I am doing something like this to find all textbox values which has the same class name.
function generalBottom(anchor) {
var sends = $('input[data-name^="noValues"]').map(function(){
$(this).attr('value',$(this).val());
return $(this).val();
}).get();
}
and i call this function on a onclick of submit button like generalBottom(this)
and I have something like as per my requirement
When I click submit button of User I call a general function passing this as a parameter, but the above code gives me the text values of client as well
["perfect", "hyperjack", "julie", "annoying", "junction", "convulated"], which is undesired, I want only ["annoying", "junction", "convulated"] using my anchor params.
How to do this via my this parameter, I thought to traverse through my tags using children(), parent() but I won't be knowing how many fields user have added as its all dynamic, user can add as many values(text boxes).
I tried this
1) $(anchor).find('.rightAbsNo')
2) $(anchor).find('input[data-name^="noValues"]')
3) $(anchor).find('.rightAbsNo').map(function () {
console.log($(this).find('. showNoButton')); })
None of this worked for me.
My html is somewhat like this, code
<div id="attach0" class="leftbottomno">
<div style="overflow: hidden" class="leftbottomAbsolute" id="">
<form>
<span class="absno"><input type="text" required=""
id="absdelete" data-inputclass="leftbottomAbsoluteNo_class"
value="" class="leftbottomabsolutenotest keys" data-value=""
style="margin-bottom:4px; color: #1c1c1c;"> </span>
<a onclick="addAbsoluteValues(this);" style="margin-left: 50px">
<i class="fa fa-plus-circle color-blue-grey-lighter"></i> </a>
</form>
<a onclick="deleteAbsoluteEmpty(this);> </a><br>
<div class="rightAbsNo" id="yesValueattach">
<div class="rightAbsNoValue">
<input type="text" id="nonattach" placeholder="values"
data-name="noValues" data-inputclass="absYes_class" value="annoying"
class="showNoButton showActivity value" data-value="">
<button type="button" onclick="generalBottom(this);">
<i class="glyphicon glyphicon-ok"></i></button>
</div>
</div>
<div class="rightAbsNo" id="yesValueattach">
<div class="rightAbsNoValue" id=""> <input type="text"
data-name="noValues" data-inputclass="absYes_class" subattribute=""
value="" class="showNoButton showActivity value" data-value="">
<button type="button" onclick="generalBottom(this);">
<i class="glyphicon glyphicon-ok"></i></button>
</div>
</div>
<div class="rightAbsNo" id="yesValueattach">
<div class="rightAbsNoValue" id="">
<input type="text" data-name="noValues"
data-inputclass="absYes_class" placeholder="values" subattribute=""
value="junction" class="showNoButton showActivity value"
data-value="" >
<button type="button" style="display: none;"
onclick="generalBottom(this);">
<i class="glyphicon glyphicon-ok"></i>
</button>
</div>
</div>
</div>
</div>
First of all, you need to define a container to the groups with something like :
<div class="container">input groups</div>
<div class="container">input groups</div>
and change <button type='submit'> to <button type='button'> to prevent submitting the form.
Then change your function to this:
function generalBottom(anchor) {
var all_inputs = $(anchor).parent(".container").find("input");
var input = $(anchor).siblings('input').first();
all_inputs.each(function(){
$(this).val(input.val());
});
}
Here's Jsfiddle
first $(anchor).siblings(input) find inputs
then go through each element from first step and return their value
function generalBottom(anchor) {
var input = 'input[data-name^="noValues"]'
var values = $.map($(anchor).siblings(input), (elemnt, index)=>{
return elemnt.value
})
$('#shows').val(values.join())
}
$('button').on('click',function(){
generalBottom(this)
})
hope this helps

can't call function on element after creating it with javascript [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 5 years ago.
I 'm using coreUi static template.
So I'm manipulating a form.
I'm stuck at this form row that should contain websites, originally it contains 1row: input text, input URl, and a closeIcon.
There's also a add web button, so when I click it, another row in created. I successfullty implemented this feature with JS.
Now, when I press the closeIcon, I want the corresponding row to be deleted.
The problem is when I click the original's row close Button, the method is called, but when I press the other rows' close Buttons, that have been created with js, the function is not being called.
$(document).ready(function(){
$("#add_web_links").click(function(){
add_web_links();
});
$('.close').click(function(){
close_row();
});
});
function add_web_links()
{
var text="<div class='form-group row web'><label class='col-1 col-form-label'>Text</label><div class='col-2'><input class='form-control' type='text'></div> <label class='col-1 col-form-label'>URL</label> <div class='col-4'><input class='form-control' type='url'> </div> <div class='col-1'> <button type='button' class='close' aria-label='Close'> <span aria-hidden='true'>×</span></button></div></div>";
$('.web').last().after(text);
}
function close_row()
{
alert("closed");
}
<h6><B>Web Links</B></h6>
<div class="form-group row">
<label class="col-1 col-form-label">Text</label>
<div class="col-2">
<input class="form-control" type="text">
</div>
<label class="col-1 col-form-label">URL</label>
<div class="col-4">
<input class="form-control" type="url">
</div>
<div class="col-1">
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<div class="col-6">
<button id="add_web_links" type="button" class="btn btn-link px-0">add web links</button>
</div>
</div>
Then I inspect the created close icons, they all have the class="close".
The event handler you've got doesn't trigger because the elements you're adding using script didn't exist when the handler was set up.
Use $(document).on("click", ".close", function() { //... . This will add the listener to the whole page instead, but then delegate handling of the event down to elements matching ".close", which do not have to exist when the handler is declared. For more information go to https://api.jquery.com/on/ - read the section "Direct and delegated events".
when you have element created after DOM rendered, I mean created dynamically you have to take approach of jquery event delegation concept.
$(document).on('click','<selector>',function(){
//Your code will go here.
......
});
The $('.close').click(...) adds handler to existing close button. But the handler doesn't listen another elements that will be created in future. Use event bubbling instead. Add this handler to parent container using on() method with selector to specify elements that trigger the event:
$('#myform').on('click', '. close', function() {
close_row();
});
you should deligate action when dynamically create new div and hide parent.prev elements + clicked button:
<script>
$(document).ready(function(){
$("#add_web_links").click(function(){
add_web_links();
});
$('.col-1').delegate("button","click",function(){
$( this ).parent().prevUntil().hide();
$(this).hide();
});
});
function add_web_links()
{
var text="<div class='form-group row web'><label class='col-1 col-form-label'>Text</label><div class='col-2'><input class='form-control' type='text'></div> <label class='col-1 col-form-label'>URL</label> <div class='col-4'><input class='form-control' type='url'> </div> <div class='col-1'> <button type='button' class='close' aria-label='Close'> <span aria-hidden='true'>×</span></button></div></div>";
$('.web').last().after(text);
$('.col-1').delegate("button","click",function(){
$( this ).parent().prevUntil().hide();
$(this).hide();
});
}
</script>
<div class="form-group row">
<label class="col-1 col-form-label">Text</label>
<div class="col-2">
<input class="form-control" type="text">
</div>
<label class="col-1 col-form-label">URL</label>
<div class="col-4">
<input class="form-control" type="url">
</div>
<div class="col-1">
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<div class="col-6">
<button id="add_web_links" type="button" class="btn btn-link px-0">add web links</button>
</div>
</div>
<div class="web"></div>

jQuery send submited range slider value to a remote server

I have a page that has multiple range sliders with matching submit buttons so i can submit each slider value after the user changes it and send it to a server where a program is running a function that returns the square of this value and return it back to me. This is the code i'm using :
$(window).on("load", function(){
var slider = $(".slider");
slider.change(function(){
var output= this.value;
$(".formoid").submit(function(event) {
posting= $.get( "http://192.168.4.49:8002/data", { n:output });
posting.done(function(data){
console.log(data)
});
});
});
});
(Html)
<div id='Services' style="display:none;">
<span class="Content_Title"> Demand <i class="fa fa-chevron-right" aria-hidden="true"></i> Tertiary <i class="fa fa-chevron-right" aria-hidden="true"></i> Services </span>
<div id="svg_Services"></div>
<div id="slider_box">
<div class="Slider"><input type="range" class="slider" min="0" max="100" name="output10"></div>
<b><div class="output" id="output10">value: %</div></b>
</div>
<form class="formoid" title="" method="get">
<div>
<input type="submit" class="btn-info" id="submitButton" name="submitButton" value="Submit Value">
</div>
</form>
</div>
<div id='Agriculture' style="display:none;">
<span class="Content_Title"> Demand <i class="fa fa-chevron-right" aria-hidden="true"></i> Tertiary <i class="fa fa-chevron-right" aria-hidden="true"></i> Agriculture </span>
<div id="svg_Agriculture"></div>
<div id="slider_box">
<div class="Slider"><input type="range" class="slider" min="0" max="100" name="output11"></div>
<b><div class="output" id="output11">value: %</div></b>
</div>
<form class="formoid" title="" method="get">
<div>
<input type="submit" class="btn-info" id="submitButton" name="submitButton" value="Submit Value">
</div>
</form>
</div>
The problem is that each time i submit another slider's value i get the previous one as well.For example if i move the first slider to a value of 3 i get 9 in my console.If after this i move another slider to a value of 2 i get 9 and 4. Does anybody know how to fix this?
You don't really want the form to submit, therefore you don't need a 'submit' handler, let alone an accumulation of 'submit' handlers that grows every time one of the sliders is changed.
Instead, attach a 'click' handler that :
inhibits form submission
finds the button's corresponding slider element
executes $.get(...)...
$(window).on("load", function() {
$(".formoid").on('click', 'button', function(e) { // guess; adjust as necessary to delegate button click handling to the form.
e.preventDefault(); // prevent buttons submitting the form
var $slider = $(this).prev('input'); // guess; adjust as necessary to select the appropriate slider relative to the clicked button
$.get( "http://192.168.4.49:8002/data", { n: $slider.val() }).then(function(data) {
console.log(data);
});
});
});
Without sight of the HTML, there's a couple of guesses in there so be prepared to do some debugging.
EDIT:
With sight of the HTML, the javascript becomes :
$(window).on("load", function() {
$(".btn-info").on('click', function(e) {
e.preventDefault(); // prevent form submission.
var $slider = $(this.form).closest('div').find("input.slider");
$.get( "http://192.168.4.49:8002/data", { n: $slider.val() }).then(function(data) {
console.log(data);
});
});
});

Categories