I have a content page which is loaded via Ajax with a checkbox on it. The checkboxes works as it should when I click the normal menu buttons on my webpage to get to the content. But when I go to another page and use the back button to get back to the page which has the checkboxes, the checkboxes stop working.
html:
<div id="filters">
<ul id="filters-background">
<li id="option-type">Filter Options</li>
<li class="wave2"><label for="white">White<input type="checkbox" name="white" value=".White" id="white"></label></li>
<li class="wave2"><label for="blue">Blue<input type="checkbox" name="blue" value=".Blue" id="blue"></label></li>
</ul>
</div>
<script type="text/javascript">
OnSort();
</script>
js:
function OnSort(e) {
console.log('aaa');
// filter button click
var filterCheckboxes = $('#filters input');
var filters = [];
filterCheckboxes.change(function() {
console.log('clicked checkbox');
filterCheckboxes.filter(':checked').each(function() {
console.log('working');
filters.push( this.value );
});
});
}
If you look at the above code, the console will output 'aaa' when I click on the back button but if I test a checkbox it will not output 'clicked checkbox' in the console. How can I make it so the checkboxes will keep working even after I use the browser back button?
Maybe relevant PageLoad and Backbutton Ajax code:
function OnLoadPage(e) {
e.preventDefault();
var pageurl = $(this).data('url');
$.ajax({
type: 'GET',
url: pageurl,
success: function(data) {
$('#content').html(data['content']); // update content
if(data['menu']) { // update menu
$('#menu').html(data['menu']);
}
else {
$('#menu').html('');
}
// update url
window.history.pushState({path:pageurl}, '', pageurl);
},
error: function(response) {
alert('ERROR:' + response.responseText);
}
});
}
function InitOverrideBrowserBackButton() {
// override the back button to get the ajax content without page reload
$(window).bind('popstate', function() {
$.ajax({url:location.pathname+'?rel=tab', success: function(data){
$('#content').html(data['content']); // update content
if(data['menu']) { // update menu
$('#menu').html(data['menu']);
}
else {
$('#menu').html('');
}
}});
});
}
I've also tried:
$(document).on('click', '#filters input', function() {
console.log('clicked checkbox');
filterCheckboxes.filter(':checked').each(function() {
console.log('working');
filters.push( this.value );
});
});
Which will output 'aaa' and 'clicked checkbox' but not 'working'.
Figured it out with help from others on StackOverflow. Here's the answer:
function OnSort(e) {
console.log('aaa');
// filter button click
var filters = [];
$(document).on('click', '#filters input', function() {
console.log('clicked checkbox');
$('#filters input', document).filter(':checked').each(function() {
console.log('working');
filters.push( this.value );
});
});
}
Related
I am using checkbox on every row to do multi delete record in datatable. I want to show delete button only if any checkbox is checked. On first page, onchange is working. But on second page so on, onchange not working.
Below is my code :
$(".isdt-selected").on("change", function() {
$(".isdt-selected").each(function(index, elem) {
if($(elem).is(':checked')){
$('#btn-delete-bulk').show();
return false;
}else{
$('#btn-delete-bulk').hide();
}
});
});
I solved it with below code :
"drawCallback": function(settings) {
$(".isdt-selected").on("change", function() {
$(".isdt-selected").each(function(index, elem) {
if($(elem).is(':checked')){
$('#btn-delete-bulk').show();
return false;
}else{
$('#btn-delete-bulk').hide();
}
});
});
I saw the reference from here https://datatables.net/reference/option/drawCallback
Try this:
$(document).ready(function(){
$(".isdt-selected").on("change", function() {
$(".isdt-selected").each(function(index, elem) {
if($(elem).is(':checked')){
$('#btn-delete-bulk').show();
return false;
}else{
$('#btn-delete-bulk').hide();
}
});
});
});
I need to toggle between "edit.png" and "ok.png" . Initially web page loads the page contains "edit.png" image buttons. Like in the screen shot below
My requirement is, once i click on the edit.png it should be remains as edit.png image state. And once again i click on the edit.png it should changed to "ok.png". So how can i do this anyone help me.
What i tried is
$(function(){
$('.edit').on('click',function(){
$(this).toggle();
//show the ok button which is just next to the edit button
$(this).next(".ok").toggle();
});
$('.ok').on('click',function(){
$(this).toggle();
$(this).next(".edit").toggle();
});
})
$('#projectsTable').Tabledit({
url: '#',
deleteButton: false,
buttons: {
edit: {
class: 'btn btn-primary secodary',
html: '<img src="/concrete5/application/images/animated/btn_edit.png" class="edit" /><img src="/concrete5/application/images/animated/btn_ok.png" class="ok" style="display:none" />',
action: 'edit'
}
},
columns: {
identifier: [1, 'Projects'],
hideIdentifier: true,
editable: [[1, 'Projects'], [2, 'Subprojects'],[8, 'Project Status', '{"1": "Open", "2": "Closed"}']]
},
onDraw: function() {
console.log('onDraw()');
},
onSuccess: function(data, textStatus, jqXHR) {
console.log('onSuccess(data, textStatus, jqXHR)');
console.log(data);
console.log(textStatus);
console.log(jqXHR);
},
onFail: function(jqXHR, textStatus, errorThrown) {
console.log('onFail(jqXHR, textStatus, errorThrown)');
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
},
onAlways: function() {
console.log('onAlways()');
},
onAjax: function(action, serialize) {
console.log('onAjax(action, serialize)');
console.log(action);
console.log(serialize);
}
});
$(function(){
$('.edit').on('click',function(){
$(this).toggle();
//show the ok button which is just next to the edit button
$(this).next(".ok").toggle();
});
$('.ok').on('click',function(){
$(this).toggle();
$(this).next(".edit").toggle();
});
})
Use a click counter, so when you click on the button the second time, it shows the "edit" button and resets the counter back to 0.
When you then click on the "ok" button it changes back to the "edit" button, and because you now have done the first edit, next time you click on the button it changes to "ok" right away.
$('.edit').each(function() {
var clickCounter = 0, // Sets click counter to 0 - No clicks done yet
firstEdit = false; // Sets first edit to false
$(this).on('click', function() {
clickCounter++;
if( clickCounter == 2 || firstEdit == true ) {
$(this).toggle();
$(this).next('.ok').toggle();
clickCounter = 0; // Reset counter
firstEdit = true;
}
});
});
$('.ok').on('click', function() {
$(this).toggle();
$(this).prev('.edit').toggle();
});
Working Fiddle
$(window).ready(function(){
$('.edit').each(function(){
var counter=0;//add a counter to each edit button
this.on('click',function(){
counter++;//increase counter
console.log(counter);
if(counter===2){//if button clicked twice
$(this).toggle();
//show the ok button which is just next to the edit button
$(this).next(".ok").toggle();
counter=0;//reset counter
}
});
});
});
or taking pure ES6:
window.onload=function(){//when the page is loaded
var imgs=[...document.getElementsByClassName("edit")];//get all edit imgs
imgs.forEach(img=>{//loop trough images
var counter=0;//add a counter for each image
img.onclick=function(){
counter++;//onclick increase counter
if(conter===2){//if img was clicked twice
this.src="ok.png";//replace the img
counter=0;
}
}
});
};
You can use one class to control and change the state of your button:
$('.edit').on('click',function(){
if ($(this).hasClass('is-state1')) {
$(this).next(".ok").toggle();
$(this).toggle();
}
$(this).toggleClass('is-state1');
});
$('.ok').on('click',function(){
$(this).toggle();
$(this).next(".edit").toggle();
});
Also I'm thinking you are wrong in ok button event as you want change your previous and not your next button:
$('.ok').on('click',function(){
$(this).toggle();
$(this).prev(".edit").toggle();
});
I had an issue with delete button.
ex: I press delete at driver 1 and choose no, after that I press delete at driver 2 and choose yes. driver 1 also deleted automatically.
here's my delete button code :
$(document).ready(function(){
$('#datatable tbody').on('click', '.delete', function(event) {
event.preventDefault();
$('.modal-header h4').html($(this).data('title'));
$('.modal-body p').html($(this).data('message'));
var url = $(this).data('url');
var datatable = $('#datatable').DataTable();
$('#confirmDel').on('click', function(e) {
e.preventDefault();
$.ajax({
headers: {
'X-CSRF-TOKEN': $('.modal-body input[name="_token"]').val()
},
url: url,
type: "DELETE",
success: function (data) {
console.log(data);
datatable.ajax.reload();
$.gritter.add(
{
title: "Record has been deleted succesfully",
});
},
error: function (data) {
console.log(data);
}
});
$('#modalDelete').modal('hide');
});
});
});
Any Idea ?
Do you use the same button with id ConfirmDel inside the modal?
Try unbinding the button event:
$('#confirmDel').unbind('click');
Before binding it again:
$('#confirmDel').on('click', function(e) { ...
I think this is an event bubble. Clicking on child element will fire the
click event on parent element also.
try something like this:
child.on('click', function(e){
e.stopPropagation();
});
I created a small jQuery plugin that shows and hides a div when the user clicks on the button .show and the button .hide, respectively. I want to pass a function as a plugin option to do some specific processing for onhide. But the onhide function executes as many times as the show and hide buttons are clicked.
Here is the jsfiddle.
When you click show/hide buttons more then once then the alert will show the same number of times.
I think it should alert only once for the hide button.
$.fn.showhide = function(options){
var popup = this;
defaultOptions = {
onHide : function() { },
onShow : function() { }
};
var Options = $.extend({},defaultOptions, options);
this.each(function() {
$(this).on('click',function(e){
var id = $(this).data('id');
$('#'+id).show();
$('.hide').on('click',function(){
var id = $(this).data('id');
$('#'+id).hide();
if (Options.onHide.call() === false) {
return;
}
});
});
});
}
$('.show').showhide({
onHide :function() {
alert('hide');
}
}
);
It's because you're implementing your onHide method inside a loop.
Move this bit:
$('.hide').on('click',function(){
var id = $(this).data('id');
$('#'+id).hide();
if (Options.onHide.call() === false) {
return;
}
});
to right before your closing bracket of your method and everything works fine!
Edit: Fiddle here: https://jsfiddle.net/ka9gw09t/10/
Just replace
$('.hide').on('click',function(){
To
$('.hide').one('click',function(){
Explanation:
With your code, each time the user clicks on .show you attach one more delegation .click to the button. one will do it just once.
$.fn.showhide = function(options){
var popup = this;
defaultOptions = {
onHide : function() { },
onShow : function() { }
};
var Options = $.extend({},defaultOptions, options);
this.each(function() {
$(this).on('click',function(e){
var id = $(this).data('id');
$('#'+id).show();
$('.hide').unbind('click').one('click',function(){
var id = $(this).data('id');
$('#'+id).hide();
if (Options.onHide.call() === false) {
return;
}
});
});
});
};
$('.show').showhide({
onHide :function() {
alert('hide');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="show" data-id="123">
Show
</button>
<button class="hide" data-id="123">
Hide
</button>
<div class="showhide" id="123" style="display:none;">
This is div with id 123
</div>
Update
I was added unbind('click') before the one to unbind the older listeners.
How can I remove all elements including its parent when click. The tabs is generated dynamically. What I tried so far is:
I'm using bootbox for the confirmation.
function remove() {
bootbox.confirm("Are you sure?", function(result) {
if( result != false ) {
var anchor = $(this).siblings('a');
$(anchor.attr('href')).remove();
$(this).parent().remove();
$(".nav-tabs li").children('a').first().click();
}
});
}
The tab that I will remove is generated through this:
$(document).on('submit','#pop-form', function(e) {
// make an ajax request
$.post('../admin/FLT_add_tab.do',
$('#pop-form').serialize(),
function( data ) {
// if data from the database is empty string
if( $.trim( data ).length != 0 ) {
// hide popover
$('#popover').popover('hide');
//append new tab and new tab content
var id = $(".nav-tabs").children().length - 1;
$('#popover').closest('li').before('<li>' + data + ' </li>');
$('.tab-content').append('<div class="tab-pane" id="tab_' + id + '"> <c:import url="flt-pis.html"></c:import> </div>');
} else {
// error handling later here
}
}
);
e.preventDefault();
});
UPDATE:
remove() is called by appending <i> when the user hover the tab
$(document).ready( function() {
$(document).on('mouseenter', 'a.g-tabs', function() {
$( this ).append( $('<i class="icon-clear-remove" onClick="tabRemove();"></i>') );
});
$(document).on('mouseleave', 'a.g-tabs', function() {
$( this ).find( ".icon-clear-remove:last" ).remove();
});
});
The JS that concern if the page is refreshed
<!-- Other tabs from the database -->
<c:forEach var="tabNames" items="${ allTabs }">
<li>${ tabNames.key } </li>
</c:forEach>
Popover for adding new tab
<!-- Add new tab -->
<li>New <i class="icon-plus-sign"></i></li>
The main problem is remove method does not know on which element it is getting called, I've changed the remove to use jQuery handler instead of inlined click handler.
Try
$(document).on('mouseenter', 'a.g-tabs', function () {
$(this).append($('<i class="icon-clear-remove"></i>'));
});
$(document).on('mouseleave', 'a.g-tabs', function () {
$(this).find(".icon-clear-remove:last").remove();
});
jQuery(function () {
$(document).on('click', '.icon-clear-remove', function () {
var $this = $(this);
bootbox.confirm("Are you sure?", function (result) {
if (result != false) {
alert('delete:' + $this[0].tagName)
var $a = $this.closest('.g-tabs');
alert($a.length)
$($a.attr('href')).remove();
$a.parent().remove();
$(".nav-tabs li").children('a').first().click();
}
});
})
})
I can't tell exactly how you are implementing this but if my guess is right this should work.
If it doesn't work, you should consider setting up a fiddle.
function remove() {
bootbox.confirm("Are you sure?", function(result) {
if (result) { $(this).remove(); }
});
}