onchange only detects first checkbox of div - javascript

This is the div
<div class="col-lg-4 pre-scrollable" id="all-menus-div">
<h3 class="text-center">Tum menu listesi</h3>
<div class="list-group" id="all-menus-checkboxes" th:each="menu : ${allMenusList}">
<input th:id="${menu.id}" th:text="${menu.item}" th:value="${menu.item}" type="checkbox"/>
</div>
<button class="btn btn-success" disabled id="add-menus-to-role-btn" type="submit">Ekle</button>
</div>
<button class="btn btn-success" id="update-menus-for-role-btn" type="submit">Rolu guncelle</button>
</div>
it gets from model object.
This is the function of it for onchange:
$('#all-menus-checkboxes').on('change', function () { // on change of state
var addButton = document.getElementById('add-menus-to-role-btn');
lengthOfCheckedAllMenus = $('#all-menus-div :checked').length;
debugger;
console.log(" lengthOfCheckedAllMenus: " + lengthOfCheckedAllMenus);
addButton.disabled = lengthOfCheckedAllMenus <= 0;
});
it calls this function when I click the first checkbox only. And i can see only the log at this time. So, only button disabled becomes false only when i click the first one.
When i click others, nothing happens, no logs.
But when i click for example second one, then click first one, it shows 2 of them are selected.
Why is that?
Simple allMenuslist:
[MenuDTO{id=1, href='/check-deposit-money', menuName='Kontrol-Onay Ekranları', roles=[RoleDTO{id=1, name='ADMIN'}], iconName='null', item='Cüzdana Para Yükleme - Kontrol', className='null'}]

onchange event must to bind on the <input>.
bind event must to after <input> appended.
But your <input> like by dynamic generation, recommend use 'event delegation':
add class to <input>.
<input class="all-menus-checkboxes" />
use event delegation.
<script>
$('#all-menus-div').on('change', '.all-menus-checkboxes', function () { ... }
</script>

try this
$('#all-menus-checkboxes > input[type=checkbox]').on('change', function () { // on change of state
var addButton = document.getElementById('add-menus-to-role-btn');
lengthOfCheckedAllMenus = $('#all-menus-div :checked').length;
debugger;
console.log(" lengthOfCheckedAllMenus: " + lengthOfCheckedAllMenus);
addButton.disabled = lengthOfCheckedAllMenus <= 0;
});

Related

I want to know the value of the button I pressed in a table

I have an array of buttons arranged in each row of a table. When I click on a certain button, I want to know the row number the clicked button is positioned.
I add each time a row to existing table, where in each row there is a button. I tried to put each button in an array, so when I click on one of them, I will get the index number from the array. Didn't succeed
var btns[];
var btn=document.createElement("BUTTON");
btn.innerHTML="Edit";
btns.push(btn);
cell1.appendChild(btns[btn_num]);
btn_num=btn_num+1;
I expect to get the row number, so I can edit a specific row in a table.
You don't need to store button in memory var btns. I see a couple of practical ways to do this:
Create button with a class name
<button class="btn-edit" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" onclick="BtnEditClick(this)">Edit</button>
<script>
function BtnEditClick(clickedElement){
var btns = document.getElementsByClassName("btn-edit")
var result = -1
for(var i=0;i<btns.length; i++) {
if(clickedElement == btns[i]){
result = i
}
}
if(result != -1)
alert("found " + result)
else
alert("not found")
}
</script>
Reference to the value using data-attr in html5
<button class="btn-edit" data-index="0" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" data-index="1" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" data-index="2" onclick="BtnEditClick(this)">Edit</button>
<script>
function BtnEditClick(clickedElement){
var index = clickedElement.getAttribute("data-index")
alert("click index: " + index)
}
</script>
Pass index directly to the function
<button class="btn-edit" data-index="0" onclick="BtnEditClick(0)">Edit</button>
<button class="btn-edit" data-index="1" onclick="BtnEditClick(1)">Edit</button>
<button class="btn-edit" data-index="2" onclick="BtnEditClick(2)">Edit</button>
<script>
function BtnEditClick(index){
alert("clicked on item:" + index)
}
</script>
Yes there are still a few other ways. For myself most of the time I use the second approach that get the element ( the button object that get clicked ) and then read the data that I want from data-attr ( you can define any data-attr you want e.g data-index, data-id ). This is very convenient, you will find it useful because sometimes you might need more data than just an index of the element inside the list. I hope it helps
One possible approach is: for each added button you can add an the HTML attribute id equal table row. Besides that, you can add the HTML attribute onclick="onClickButton(this.id)" to the created button. So you can use the folowing script to get the id value when the button gets clicked:
<script>
function onClickButton(e) {
console.log(e);
}
</script>

changin form ID and using button submit event firing old submit ID

I have apiece of code where i am changing the ID of the form
like this;
$("form").prop('id','FormApplied');
before the above formID was Form1
i have two functions
$(document).on('submit','#FormApplied',function(e) {
$(document).on('submit','#Form1',function(e) {
it is always firing the Form1, even i had changed the formID, how can i fix that because both functions have separate logic written
Thanks
When you apply an event listener to a form element, the event doesn't know about what selector was used (In this case you are selecting the element by ID.)
There are several choices.
You could use one event handler and then use that to decide which logic to use, but that has the bad effect of mixing logic (what to do when the button is pressed) with presentation logic (the ID of the button).
You could set a data-* property on the element and select off that, but think even that is a bit more awkward.
Instead, I would use two buttons, and just toggle the visibility based upon the rules
function showButton(butNumber) {
document.getElementById("but1").style.display = "none";
document.getElementById("but2").style.display = "none";
document.getElementById("but" + butNumber).style.display = "";
}
showButton(1);
document.getElementById("but1").addEventListener("click", function() {
console.log("Button 1");
showButton(2);
});
document.getElementById("but2").addEventListener("click", function() {
console.log("Button 2");
showButton(1);
});
<form>
<button type="button" id="but1">Button 1</button>
<button type="button" id="but2">Button 2</button>
</form>
It doesn't trigger both functions
function changeValue(){
$('#formId').prop('id', 'formId2');
console.log('form Id changed');
}
$(document).on('submit','#formId',function(e) {
console.log('submitted');
});
$(document).on('submit','#formId2',function(e) {
console.log('submitted 2');
});
function restoreId(){
$('#formId2').prop('id', 'formId');
console.log('form Id restored');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id='formId'>
<input type='hidden' value=0 id='hiddenInput'/>
<input type='button' value='click to change the id ' onclick='changeValue()'/>
<input type='button' value='click to restore the id ' onclick='restoreId()'/>
<input type='submit' value='submit' />
</form>

find the button that submitted the form

I have this javascript:
$('#new_campaign_update').on('submit', function(event) {
debugger;
});
Is there a way I can find the button that submitted the form?
<%= form.submit 'Publish', class: 'button button-large button-primary accent-black', title: 'Publish this update now' %>
That is the button I clicked in order to submit the form can I find it on the event or something?
Yes you can with the event's currentTarget:
const buttons = document.querySelectorAll('input');
buttons.forEach(b => b.addEventListener('click', (e) => {
console.log(e.currentTarget);
e.currentTarget.style = "background-color:blue;";
}));
<input type="submit" id="a">
<input type="submit" id="b">
<input type="submit" id="c">
<input type="submit" id="d">
Assuming you have a form with id=new_campaign_update, and inside you have a single button with a class button-primary, the button will be accessible by $(this).find(".button-primary"), so you will access it like this:
$('#new_campaign_update').on('submit', function(event) {
const $button = $(this).find(".button-primary");
});
$(this) inside jQuery callbacks refers to the element that fired the callback. Inside the element you find the button with .find(".button-primary)"
Alternatively, if you have many buttons in a single form, you can add an onclick handler to the buttons themselves like this:
$('#new_campaign_update .button-primary').click(function() {
const $button = $(this);
}

Color input's border when nothing is entered doesn't work

I have an input text that has to be something in it for the form to work.
So I wish to add some functionality to the Confirm button that checks if the input field is empty, and if so, recolor the border of that input.
I'm doing the following:
$(function mainListeners () {
"use strict";
var confirm = $('#addNewConfirm');
var cancel = $('#addNewCancel');
var eventBox = $('#eventname_input');
console.log("RUNS!!");
confirm.onclick = function (e) {
if (eventBox.val() == ''){
//so if we have an empty event
//recolor borders.
console.log("CHANGES!!");
eventBox.css('border-color','#d81919');
}else {
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="yesno IFlexible">
<button id="addNewConfirm" >Confirm</button>
<button id="addNewCancel">Cancel</button>
</div>
<div >
<label>Event:</label>
<input id="eventname_input" type="text" />
</div>
Here I get no errors and I always see the RUNS!! message, so my script is attached. However, I never see the CHANGES!! message, so the condition eventBox.val() == '' is never true. I looked up the internet on how to check if an input text's text is empty, and this is what I found, and it clearly isn't working.
How can I sort out this recolor of border if the input has no text?
Use JQuery click() function instead of onclick like so:
$(document).ready(function() {
var confirm = $("#addNewConfirm");
var cancel = $("#addNewCancel");
var eventBox = $("#eventname_input");
console.log("RUNS!!");
confirm.click(function(e) {
if (!eventBox.val()) {
console.log("CHANGES!!");
eventBox.css("border-color", "#d81919");
} else {
eventBox.css("border-color", 'inherit');
// whatever you want
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="yesno IFlexible">
<button id="addNewConfirm">Confirm</button>
<button id="addNewCancel">Cancel</button>
</div>
<div>
<label>Event:</label>
<input id="eventname_input" type="text" />
</div>
Try using either the Jquery method of setting a click event (.click()) or the vanilla JS way of retrieving a DOM element(document.getElementById()).
Below is a working example of changes!! getting called.
$(function mainListeners () {
"use strict";
var confirm = document.getElementById('addNewConfirm'); //GET DOM ELEMENTS THIS WAY OR SEE BELOW FOR CLICK
var cancel = $('#addNewCancel');
var eventBox = $('#eventname_input');
console.log("RUNS!!");
confirm.onclick = function (e) {//OR CHANGE THIS TO CLICK()
if (eventBox.val() == ''){
//so if we have an empty event
//recolor borders.
console.log("CHANGES!!");
event.css('border-color','#d81919');
}else {
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="yesno IFlexible">
<button id="addNewConfirm" >Confirm</button>
<button id="addNewCancel">Cancel</button>
</div>
<div >
<label>Event:</label>
<input id="eventname_input" type="text" />
</div>
The fact is that onclick is vanilla Javascript and you are trying to use it on the confirm jQuery object.
In order to fix it, you can use confirm[0].click = function(e) syntax or confirm.click(function (e). I suggest you to use jQuery syntax: if you load this library you are encouraged to use it in order to strengthen readability.

Strange behavior with a "confirm" modal jquery

I am trying to make a modal act like a confirm button. You click the button, a popup opens up and askes yes or no, if yes, stores some info in database, removes that item from the DOM then adds an item somewhere else. But, right now, if they click the confirm "yes", it runs the ajax call multiple times. I feel like it is running it for other places where data-express="yes" but I don't know why it could...shouldn't $(this) only be the button that is clicked? I don't see what in here would make it run more than one time.
The button -
<ul class="list-inline center-block">
<li><button type="button" class="btn btn-primary center-block express_button" data-confirm="yes" data-dismiss="modal">Yes</button></li>
<li><button type="button" class="btn btn-primary center-block express_button" data-confirm="no" data-dismiss="modal">No</button></li>
</ul>
JS
$('.snf_interest').on('submit', function(e){
e.preventDefault();
var id = $(this).find('input[name=resid]').val();
var ppcode = $('.placement_item_' + id + ' .pdcode' + id).text();
var ppdate = $('.placement_item_' + id + ' .pp_date').text();
var dcpname = $(this).find('input[name=dcpname]').val();
var dcpemail = $(this).find('input[name=dcpemail]').val();
var prefcom = $(this).find('input[name=prefcom]').val();
var ppid = $(this).find('input[name=ppid]').val();
var patientneeds = $('.placement_item_' + id + ' .patientneeds').text();
var dcphone = $('.placement_item_' + id + ' .dcphone').text();
var dcnote = $(this).find('input[name=notes]').val();
$('#express_interest_modal').modal();
//if(confirm('Are you sure you want to express interest in this patient')){
$('.express_button').on('click', function(){
console.log($(this));
if($(this).data('confirm') == 'yes'){
$.ajax({
// url: "/snf/express_interest",
type: "POST",
data: { 'ppid' : ppid,
'status' : status,
'dcpname' : dcpname,
'dcpemail' : dcpemail,
'prefcom' : prefcom
},
success:function(){
// $('#interest_modal').modal('show');
$('#panel-placement .panel-body').append('<ul class="list-group list-group-no-pad"><li class="list-group-item clearfix well well-sm"><label>'+ppcode+'| Posted: '+ppdate+'</label><form class="pull-right" action="http://dev.goodcareconnection.com/snf/" method="post"><input type="hidden" name="ppid" value="'+ppid+'"><div class="btn-group" role="group" aria-label="..."><input class="btn btn-sm btn-danger" type="submit" name="ppbutn" value="Hide This Patient"></div></form></li><li class="list-group-item clearfix"><div class="col-md-12"><label>Needs: <h5 class="patientneeds">'+patientneeds+'</h5></label></div></li><li class="list-group-item clearfix"><div class="col-md-4"><label>Posted by: <h5>'+dcpname+'</h5></label></div><div class="col-md-4"><label>Email: <h5>'+dcpemail+'</h5></label></div><div class="col-md-4"><label>Phone: <h5>(303) 570-9863 M: (303) 570-9863</h5></label></div></li><li class="list-group-item clearfix"><div class="col-md-6"><div class="form-group"><h5><label>Notes</label></h5><textarea id="ppnote35" class="form-control update_note" name="notes" readonly="">'+dcnote+'</textarea></div></div><div class="col-md-6"><form class="snf_interest"><button class="btn btn-danger btn-sm pull-right" name="submit">Remove Interest</button></form></div></li></ul>');
$('.placement_item_'+ppid).remove();
var number = $('.express_badge').html();
number = parseInt(number);
number = number + 1;
$('.express_badge').html(number);
var number = $('.bulletin_count').html();
number = parseInt(number);
number = number - 1;
$('.bulletin_count').html(number);
}
})
}
})
});
The problem stems from adding one event handler inside another event handler.
The first time submit is triggered...the express_button elements do not have a click handler that would do the ajax previously attached. It gets added in this first submit event
Clicking "Yes" should only do make one ajax request.
The next time submit is triggered it will add the same event handler again.
Now clicking "Yes" will run 2 instances of the event handler and make 2 requests.
Every submit will increment the number of requests made
A simple solution would be remove the click handler as soon as it gets used.
Beware though that if modal gets closed using methods other than the buttons the event handler will still be there and problem will persist
$('.express_button').on('click', function(){
$(this).off('click')
// other code
});
A better solution would be separate the submit and click handlers by storing the data that needs to be sent so it would be accessible when "Yes" is clicked

Categories

Resources