Hy, I have a problem with my JavaScript that I use it for the content of a table. My function is for users when they right click on a table row appears a context menu where they can choose what they want to do. The problem is that right click doesn't work any more when I go to the next pages in the table (my page load with 10 records in the table).
My script:
<script type='text/javascript'>
$(window).load(function(){
(function ($, window) {
$.fn.contextMenu = function (settings) {
return this.each(function () {
// Open context menu
$(this).on("contextmenu", function (e) {
// return native menu if pressing control
if (e.ctrlKey) return;
//open menu
var $menu = $(settings.menuSelector)
.data("invokedOn", $(e.target))
.show()
.css({
position: "absolute",
left: getMenuPosition(e.clientX, 'width', 'scrollLeft'),
top: getMenuPosition(e.clientY, 'height', 'scrollTop')
})
.off('click')
.on('click', 'a', function (e) {
$menu.hide();
var $invokedOn = $menu.data("invokedOn");
var $selectedMenu = $(e.target);
var $selectedFileId = $menu.data("invokedOn").find('.datatable_fixed_column').attr('id');
settings.menuSelected.call(this, $invokedOn, $selectedMenu, $selectedFileId);
});
return false;
});
//make sure menu closes on any click
$('body').click(function () {
$(settings.menuSelector).hide();
});
});
function getMenuPosition(mouse, direction, scrollDir) {
var win = $(window)[direction](),
scroll = $(window)[scrollDir](),
menu = $(settings.menuSelector)[direction](),
position = mouse + scroll;
// opening menu would pass the side of the page
if (mouse + menu > win && menu < mouse)
position -= menu;
return position;
}
};
})(jQuery, window);
$("#datatable_fixed_column td").contextMenu({
menuSelector: "#contextMenu",
menuSelected: function (invokedOn, selectedMenu, id) {
switch(selectedMenu.text()){
case 'Modificare':{
var rand = invokedOn.parent().children();
var idpost = $(rand[0]).text();
window.location.href = "organigrama_add.php?control=update&id=" + idpost;
}
break;
case 'Stergere':{
var rand = invokedOn.parent().children();
var marca = $(rand[1]).text();
if (marca == '0')
{
var idpost = $(rand[0]).text();
var departament = $(rand[5]).text();
var subdepartament = $(rand[6]).text();
var schimb = $(rand[9]).text();
var functie = $(rand[10]).text();
var msg = "Sunteti sigur ca doriti sa stergeti aceasta inregistrare?" + "\nDepartament: " + departament + "\nSubdepartament: " + subdepartament + "\nSchimb: " + schimb + "\nFunctie: " + functie;
var confirmare = confirm(msg);
if (confirmare == true)
{
window.location.href = "organigrama.php?control=delete&id=" + idpost;
}
}
else
{
var msg = "Nu se poate sterge acest post. Doar posturile libere se pot sterge.";
alert(msg);
}
}
break;
case 'Renunta':{
return false;
}
break;
}
}
});
});
</script>
And context menu used for this:
<ul id="contextMenu" class="dropdown-menu" role="menu" style="display:none" >
<li><a tabindex="-1">Modificare</a></li>
<li><a tabindex="-1" href="#">Stergere</a></li>
<li class="divider"></li>
<li><a tabindex="-1" href="">Renunt</a></li>
</ul>
Edit: I forget to mention that the javascript is before the </body> end tag and context menu is after <body> start tag.
so basically the problem here is that the newly added rows in the table will not get the bindings from the initial load of the page. so the fix needed here is to bind the event to the main document by using this
$(document).on('contextmenu', target, function)
this will allow jquery to run the specific function to a targeted element on 'right click/contextmenu' event
Related
Is there any easy way how to set Y position of the screen by the element?
Tried to do with scrolling but didn't make wanted effect, so maybe setting screen view position would do the trick.
have a div with string:
Function is in use with elementor (wordpress) toggle tabs which generating anchor links for tabs and they making a trick which opens exact tab by link.
<script type="text/javascript">
jQuery(document).ready(function($){
setTimeout(function(){
var current = window.location.href;
var current = current.split('#tab');
if(current.length>1) {
$('.elementor-tab-title').removeClass('elementor-active');
$('.elementor-tab-title[data-tab="'+current[1]+'"]').addClass('elementor-active');
$('.elementor-tab-content').hide();
$('.elementor-tab-content[data-tab="'+current[1]+'"]').show();
}
}, 200);
$('.elementor-tab-title[data-tab]').click(function(){
var current_location = window.location.href;
current_location = current_location.split('#');
window.location = current_location[0]+'#tab'+$(this).attr('data-tab');
})
})
jQuery(document).ready(function ($) {
setTimeout(function () {
var current = window.location.href
var current = current.split('#tab')
if (current.length > 1) {
showAndScrollToTab($, current)
}
}, 200);
// change the browser url according to selected tab
$('.elementor-tab-title[data-tab]').click(function () {
var current_location = window.location.href;
current_location = current_location.split('#')
window.location = current_location[0] + '#tab' + $(this).attr('data-tab')
})
// activate tab also from anchor link in the same page
$('a').on('click', function () {
var anchorUrl = $(this).attr('href')
var anchor = anchorUrl.split('#tab')
if (anchor.length > 1) {
showAndScrollToTab($, anchor)
}
})
})
function showAndScrollToTab($, current) {
// adding class
$('.elementor-tab-title').removeClass('elementor-active')
$('.elementor-tab-title[data-tab="' + current[1] + '"]').addClass('elementor-active')
// scroll to
var customOffset = '20';
$([document.documentElement, document.body]).animate({
scrollTop: $('.elementor-tab-title[data-tab="' + current[1] + '"]').closest('.elementor-widget-container').offset().top - customOffset }, 1000)
}</script>
Html in use for toggle tab headings:
<div class="elementor-toggle-item">
<div id="elementor-tab-title-2287" class="elementor-tab-title elementor-active" data-tab="7" role="tab" aria-controls="elementor-tab-content-2287">
How to modify the function for making device screen view top is 40px to the .elementor-tab-title[data-tab="' + current[1] + '"] div? Is it possible to adjust offset from div element to top by device (mobile, tablet, desktop)?
Any other solutions are welcome how to do that!
I have a horizontal category bar. this is populated by php - i set a data-cat-id property on the anchor. then use a jquery click function to get this value like this:
$('.filterCat').click(function() {
alert('cat id is:'+$(this).data("cat-id"))
return false;
});
This works fine. But the horizontal bar has a function that adds list elements to a "more" sub menu when the width gets smaller than its content. using the code:
$(function() {
alignMenu();
$(window).resize(function() {
$("#horizontal").append($("#horizontal li.hideshow ul").html());
$("#horizontal li.hideshow").remove();
alignMenu();
});
function alignMenu() {
var w = 0;
var mw = $("#horizontal").width() - 150;
var i = -1;
var menuhtml = '';
jQuery.each($("#horizontal").children(), function() {
i++;
w += $(this).outerWidth(true);
if (mw < w) {
menuhtml += $('<div>').append($(this).clone()).html();
$(this).remove();
}
});
$("#horizontal").append(
'<li style="position:relative;" href="#" class="hideshow">' + 'More ' + '<span style="font-size:13px">↓</span>' + '<ul>' + menuhtml + '</ul></li>');
$("#horizontal li.hideshow ul").css("top",
$("#horizontal li.hideshow").outerHeight(true) + "px");
$("#horizontal li.hideshow").click(function() {
$(this).children("ul").toggle();
});
if (menuhtml == '') {
$("#horizontal li.hideshow").hide();
} else {
$("#horizontal li.hideshow").show();
}
}
});
This also works but now when there is a "more" button (because the content is bigger) the click function does not work anymore.
i have made a fiddle - if you click on a normal menu item it shows the alert, but if you click on a item that is places under "more" it does nothing see FIDDLE: https://jsfiddle.net/quosa60e/
For dynamically created elements .click() does not work
document.on('click','SELECTOR',function(){});
So you should use:
$(document).on('click','.filterCat',function() {
alert('cat id is:'+$(this).data("cat-id"))
return false;
});
The following single page site uses a waypoint script to navigate and highlight nav items - http://www.jbleitch.co.uk/dt/
It works well - the issue is that we need to alter a link to navigate to an external website - but the script prevents default on any links - so its reasonably complicated!
this is the original script -
//Cache some variables
var links = $('.navigation').find('li');
slide = $('.slide');
button = $('.button');
mywindow = $(window);
htmlbody = $('html,body');
var dataslider = 1;
var clicked = false;
var windowWidth = window.innerWidth;
var narrow = (windowWidth <= 1000);
var navblock = $('.navBlock');
var dataslide = 1;
var myDirection = 'down';
var curSlide = 0;
slide.waypoint(function(direction) {
if (direction === "down") {
dataslide = $(this).attr('data-slide');
curslide = dataslide;
if (narrow) {
navScroll(dataslide);
}
$('.navigation li[data-slide="' + dataslide + '"]').addClass('active').prev().removeClass('active');
}
}, {
offset: '25%'
}).waypoint(function (direction) {
if (direction === "up") {
dataslide = $(this).attr('data-slide');
curslide = dataslide;
if (narrow) {
navScroll(dataslide);
}
links.removeClass('active');
$('.navigation li[data-slide="' + dataslide + '"]').addClass('active');
}
}, {
offset: '-25%'
});
//waypoints doesnt detect the first slide when user scrolls back up to the top so we add this little bit of code, that removes the class
//from navigation link slide 2 and adds it to navigation link slide 1.
mywindow.scroll(function () {
if (mywindow.scrollTop() == 0) {
$('.navigation li[data-slide="1"]').addClass('active');
$('.navigation li[data-slide="2"]').removeClass('active');
}
//if (dataslide === 0 && $('.slide[data-slide=2]').offset().top > 10) {
// navblock.hide();
//}
});
//Create a function that will be passed a slide number and then will scroll to that slide using jquerys animate. The Jquery
//easing plugin is also used, so we passed in the easing method of 'easeInOutQuint' which is available throught the plugin.
function goToByScroll(dataslide) {
//alert(myDirection);
//alert(dataslide + ' ' + curSlide);
var scrollto = $('.slide[data-slide="' + dataslide + '"]').offset().top
//if (dataslide > curSlide) {
// scrollto = scrollto + 1;
// //alert("down");
//}
//else if (dataslide < curSlide) {
// //alert("up");
// scrollto = scrollto - 1;
//}
htmlbody.stop().animate({
scrollTop: scrollto
}, 3200, 'swing', function () {
if (narrow) {
navScroll(dataslide);
}
else {
navblock.removeClass('nofix');
navblock.removeAttr('style');
}
curSlide = dataslide
});
//setTimeout(function () { }, 3300);
}
//When the user clicks on the navigation links, get the data-slide attribute value of the link and pass that variable to the goToByScroll function
links.click(function (e) {
e.preventDefault();
dataslider = $(this).attr('data-slide');
clicked = true;
if (narrow) {
navblock.fadeOut();
}
goToByScroll(dataslider);
});
//When the user clicks on the button, get the get the data-slide attribute value of the button and pass that variable to the goToByScroll function
button.click(function (e) {
e.preventDefault();
dataslider = $(this).attr('data-slide');
clicked = true;
if (narrow) {
navblock.fadeOut();
}
goToByScroll(dataslider);
});
function navScroll(dataslide) {
//alert('div[data-slide="' + dataslide + '"]');
var slidepos = $('.slide[data-slide="' + dataslide + '"]').offset.top;
navblock.addClass('nofix');
//navblock.hide();
navblock.css({ top: $('.slide[data-slide="' + dataslide + '"]').offset().top });
navblock.fadeIn('slow');
//alert(navblock.attr('class'));
//alert("nav scroll");
}
this is the navigation list -
<ul class="navigation">
<li data-slide="2" class="nv1 active">Services</li>
<li data-slide="3" class="nv2">Fees & Reporting</li>
<li data-slide="4" class="nv3">News</li>
<li data-slide="5" class="nv4">Meet the Team</li>
<li data-slide="5" class="nv4"><a style="color:inherit!important; text-decoration:none" href="http:www.othersite.com">Careers</a></li>
<li data-slide="7" class="nv6">Our Credentials</li>
<li data-slide="8" class="nv7">Contact</li>
</ul>
I need to change the careers site to navigate to the url but the script above prevents it from doing so - I have tried the following alteration -
links.click(function (e) {
if(!=".nv5"){
e.preventDefault();
dataslider = $(this).attr('data-slide');
clicked = true;
if (narrow) {
navblock.fadeOut();
}
goToByScroll(dataslider);
}
});
But no luck - can anyone suggest an alternative!?
Usually I get the info i want in a data attribute, and then i can make anything
<li data-slide="5" class="nv4">
Careers
</li>
Then, in the click handler:
links.click(function (e) {
if($(this).attr("data-ref") != ""){
//get the link
var link = $(this).attr("data-ref");
//go to link
window.location.href = link;
} else {
e.preventDefault();
dataslider = $(this).attr('data-slide');
clicked = true;
if (narrow) {
navblock.fadeOut();
}
goToByScroll(dataslider);
}
});
You can simply add a condition to your link method whereby it will check for an attribute or some other property and follow through with the link if required
You were on the right track with your initial attempt. This should work
links.click(function (e) {
if(!$(this).hasClass("nv5")){
e.preventDefault();
dataslider = $(this).attr('data-slide');
clicked = true;
if (narrow) {
navblock.fadeOut();
}
goToByScroll(dataslider);
}
});
That's assuming you have the class nv5 on the links you want to remove the behaviour from
need help with some jquery/js/jsp functionality..
I have a collapsible table script:
(function($){
$.fn.extend({
setupCollapstable: function(options) {
var defaults = {
displayStyle: "Image",
autoCheckbox: true,
toggleMinus: "/resource/images/collapse_close.gif",
togglePlus: "/resource/images/collapse_open.gif"
};
var options = $.extend(defaults, options);
var toggleMinus = options.toggleMinus
var togglePlus = options.togglePlus
return this.each(function() {
//Creating a reference to the object
var obj = $(this);
//Break out the individual tbody elements
var rowGroups = $('tbody', obj);
//Loop through every tbody to setup collapsable and click events
$.each( rowGroups, function( intIndex, objValue ){
parentRow = $('th:first-child', objValue);
childCount = parentRow.parent().siblings().length;
if (childCount != 0) {
//console.log ("ParentRow: " + parentRow + " - ChildCount is: " + childCount);
parentRow.prepend('<img src="' + togglePlus + '" alt="collapse this section" />');
parentRow.parent().siblings().fadeOut('fast');
$('img', parentRow).addClass('clickable').click(function(e) {
e.preventDefault();
var toggleSrc = $(this).attr('src');
if ( toggleSrc == toggleMinus ) {
$(this).attr('src', togglePlus).parents('tr').siblings().fadeOut('fast');
} else{
$(this).attr('src', toggleMinus).parents('tr').siblings().fadeIn('fast');
};
});
var parentCheckbox = $(':checkbox', parentRow.siblings())
var childCheckboxes = $(':checkbox', parentRow.parent().siblings());
parentCheckbox.click(function(e){
var checked_status = parentCheckbox.attr('checked')?1:0;
childCheckboxes.each(function(){
this.checked = checked_status;
});
});
} else {
parentRow.addClass("indented");
}
});
//console.dir (objValue);
});
}
});
})(jQuery);
From my JSP I call it as such....
<script type="text/javascript" src="/resource/js/jquery.collapstable.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('table.collapstable').setupCollapstable();
});
</script>
usage:
<table class="collapstable NoTableBorder">
when I click on the image icon the table properly collapses and expands, however I want it to be initially expanded if a certain checkbox is checked (on the JSP).
so I would have an onclick="showOrHide()" function for that checkbox input which would collapse or expand the table.
i've attached an image to for a visual representation, the collpase table is the "+/-" icon (next to the bold VISA header) while the checkbox which decides if it should be expanded for shown is the "active" checkbox..
any help with this would be amazing...
You can add a condition just before the collapse / expand function call
<script type="text/javascript">
$(document).ready(function(){
if (checkboxname.checked){
// Set flags to show the table expanded
}else{
// Set flags to show the table collapsed
}
$('table.collapstable').setupCollapstable();
});
</script>
am trying to use javascript for custom styled select boxes from www.gerrendesign.com/entry_images/selectboxdemo.zip
and as I have plenty entries inside one of select box I need to make but am stuck in creation of scrolling function.
As this select boxes are compatible with almost all older and new browsers. I need only suggestion or solution how to add scroll in this linked/attached files above - if select box is populated with plenty of entries (example cities, states, or exchange rates...)
Am stuck here...
Thanks for your cooperation
Ivan
THIS IS CODE:
$(document).ready(function(){
// first locate all of the select tags on the page and hide them
$("select.changeMe").css('display','none');
//now, for each select box, run this function
$("select.changeMe").each(function(){
var curSel = $(this);
// get the CSS width from the original select box
var gddWidth = $(curSel).css('width');
var gddWidthL = gddWidth.slice(0,-2);
var gddWidth2 = gddWidthL - 28;
var gddWidth3 = gddWidthL - 16;
// build the new div structure
var gddTop = '<div style="width:' + gddWidthL + 'px" class="selectME" tabindex="0"><div class="cornerstop"><div><div></div></div></div><div class="middle"><div><div><div>';
//get the default selected option
var whatSelected = $(curSel).children('option:selected').text();
//write the default
var gddFirst = '<div class="first"><span class="selectME gselected" style="width:'+ gddWidth2 + 'px;">'+ whatSelected +'</span><span id="arrowImg"></span><div class="clears"></div></div><ul class="selectME">';
// create a new array of div options from the original's options
var addItems = new Array();
$(curSel).children('option').each( function() {
var text = $(this).text();
var selVal = $(this).attr('value');
var before = '<li style="width:' + gddWidthL + 'px;"><a href="#" rel="' + selVal + '" tabindex="0" style="width:' + gddWidth3 + 'px;">';
var after = '</a></li>';
addItems.push(before + text + after);
});
//hide the default from the list of options
var removeFirst = addItems.shift();
// create the end of the div selectbox and close everything off
var gddBottom ='</ul></div></div></div></div><div class="cornersbottom"><div><div></div></div></div></div>'
//write everything after each selectbox
var GDD = gddTop + gddFirst + addItems.join('') + gddBottom;
$(curSel).after(GDD);
//this var selects the div select box directly after each of the origials
var nGDD = $(curSel).next('div.selectME');
$(nGDD).find('li:first').addClass("first");
$(nGDD).find('li:last').addClass('last');
//handle the on click functions - push results back to old text box
$(nGDD).click( function(e) {
var myTarA = $(e.target).attr('rel');
var myTarT = $(e.target).text();
var myTar = $(e.target);
//if closed, then open
if( $(nGDD).find('li').css('display') == 'none')
{
//this next line closes any other selectboxes that might be open
$('div.selectME').find('li').css('display','none');
$(nGDD).find('li').css('display','block');
//if user clicks off of the div select box, then shut the whole thing down
$(document.window || 'body').click( function(f) {
var myTar2 = $(f.target);
if (myTar2 !== nGDD) {$(nGDD).find('li').css('display','none');}
});
return false;
}
else
{
if (myTarA == null){
$(nGDD).find('li').css('display','none');
return false;
}
else {
//set the value of the old select box
$(curSel).val(myTarA);
//set the text of the new one
$(nGDD).find('span.gselected').text(myTarT);
$(nGDD).find('li').css('display','none');
return false;
}
}
//handle the tab index functions
}).focus( function(e) {
$(nGDD).find('li:first').addClass('currentDD');
$(nGDD).find('li:last').addClass('lastDD');
function checkKey(e){
//on keypress handle functions
function moveDown() {
var current = $(nGDD).find('.currentDD:first');
var next = $(nGDD).find('.currentDD').next();
if ($(current).is('.lastDD')){
return false;
} else {
$(next).addClass('currentDD');
$(current).removeClass('currentDD');
}
}
function moveUp() {
var current = $(nGDD).find('.currentDD:first');
var prev = $(nGDD).find('.currentDD').prev();
if ($(current).is('.first')){
return false;
} else {
$(prev).addClass('currentDD');
$(current).removeClass('currentDD');
}
}
var curText = $(nGDD).find('.currentDD:first').text();
var curVal = $(nGDD).find('.currentDD:first a').attr('rel');
switch (e.keyCode) {
case 40:
$(curSel).val(curVal);
$(nGDD).find('span.gselected').text(curText);
moveDown();
return false;
break;
case 38:
$(curSel).val(curVal);
$(nGDD).find('span.gselected').text(curText);
moveUp();
return false;
break;
case 13:
$(nGDD).find('li').css('display','none');
}
}
$(document).keydown(checkKey);
}).blur( function() {
$(document).unbind('keydown');
});
});
});
You could render the list inside a div, that has either a fixed height or a max-height (depending on your cross-browser requirements). Presuming the default scroll bar is ok...
If structure is something in the direction of
<div class="select_data_container">
<ul class="select_rows">
<li>row1</li>
<li>row2</li>
</ul>
</div>
CSS-example could be
.select_data_container {overflow-y: auto; height: 200px;}
.select_rows {display:block;}