I have a problem with the bootstrap Popover. It works sometime but other times it doesn't. I use it to generate a popover with a users information when a visitor hovers over the users name. The page is generated by ajax so at first I thought that it simply was an issue of content being loaded after but the issue is that it works sometimes.
$(document).on('mouseenter', '.postusername', function(e){
var userid = this.parentElement.parentElement.children[0].innerHTML;
var te = this;
if(userid)
{
$.get('/Requests/getuinfo.php', {id : userid})
.done(function(data){
var uinfo = JSON.parse(data);
boo = uinfo;
$(te).popover({
html : true,
template : '<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>',
content : '<div class="popover-holder" style="background-image:url(\'/Style/Media/CoverPics/' + uinfo.coverpic + '\');">' + uinfo.name
+ '</div>',
placement: 'auto'
});
$(te).popover('show');
});
}
});
$(document).on('mouseleave', '.postusername', function(e){
$(this).popover('hide');
});
That is the Javascript I used.
As you've found, the problem was the fact that you were trying to create a new popover for something when it had already been done. Removing the popover after hiding it has fixed that problem.
However, this should fix the problem without removing it, and will mean you will also only get user information once per user...
var userids = [];
$(document).on('mouseenter', '.postusername', function(e){
var userid = this.parentElement.parentElement.children[0].innerHTML;
var te = this;
if(userid)
{
if (userids.indexOf(userid) === -1) {
$.get('/Requests/getuinfo.php', {id : userid})
.done(function(data){
var uinfo = JSON.parse(data);
boo = uinfo;
$(te).popover({
html : true,
template : '<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>',
content : '<div class="popover-holder" style="background-image:url(\'/Style/Media/CoverPics/' + uinfo.coverpic + '\');">' + uinfo.name
+ '</div>',
placement: 'auto'
});
$(te).popover('show');
userids.push(userid);
});
}
else {
$(te).popover('show');
}
}
});
$(document).on('mouseleave', '.postusername', function(e){
$(this).popover('hide');
});
It keeps an array of the user ids that you've got info for, and only gets the info if you've not already done it.
Related
I have going to add the below code in the revolution slider in the WordPress website from adding to the "Html/Text" Layer. Output showing the inner sider but not showing the user interface.
After saving the code that is converted in the NoScript tag.
Note: My motive is that how can I add " onClick="goog_report_conversion
('https://apps.apple.com/us/app/people-app/id1335211174')" on image click.
there are a few step to with this.
Setup your Google Analytics account for your site.
Hyperlink your Slides and/or Layers.
Add the "ga-button" class to your hyperlinks.
Add the following script to your slider's Custom JavaScript section.
jQuery('body').on('click', '.ga-button', function() {
var $this = jQuery(this),
data = $this.attr('data-link') || $this.attr('href');
if(!data) {
data = $this.attr('data-actions');
if(data) data = data[0].url;
if(!data) data = $this.attr('id');
}
gtag('event', 'click', { event_category: 'outbound', event_action: 'click', event_label: data});
});
Track All Slide Changes:
jQuery(window).on('load', function() {
jQuery('.rev_slider').each(function() {
var ids = jQuery(this).attr('id').split('rev_slider_')[1].split('_')[0],
api = eval('revapi' + ids);
api.on('revolution.slide.onchange', function(e, data) {
var data = 'Slider ' + ids + ' changed to slide #' + data.slideIndex;
gtag('event', 'click', { event_category: 'outbound', event_action: 'click', event_label: data});
});
});
});
All done Enjoy;
I have a jcarousel with 3 elements inside with unique id (1,2,3).
On load, the jcarouselPagination items work perfectly and they got the right targeter ("data-item=1,2,3").
But when I resize my screen to small or tiny media, the jcarouselPagination items don't target correctly. They start at 2 resulting in ("data-item=2,3,4").
Here is my jquery part where pagination items are created:
if ($(".ce_jcarousel").length == 0) {
return;
}
$('.ce_jcarousel').jcarousel();
$('.cejcarousel-pagination')
.on('cejcarouselpagination:active', 'a', function () {
$(this).addClass('active');
})
.on('cejcarouselpagination:inactive', 'a', function () {
$(this).removeClass('active');
})
.jcarouselPagination({
'item': function (page, carouselItems) {
return '<a data-item="'+ page +'" class="slider_ce_text ' + (page == 1 ? "active" : "") + '" href="#' + page + '"><div class="grey_dot"></div></a>';
}
}
);
I only call this function on page load, never on resize, so i have trouble getting what is happening!
Thanks!
Ok, so i didn t really figured out why it didn t work out or why my carousel kept generating pagination items on resize..
But it seems that I had to unbind the resize.jcarousel function
so here is my new (and working) code if anyone is interested!
if ($(".ce_jcarousel").length == 0) {
return;
}
jcarousel.jcarousel({
wrap: 'circular'
});
$(window).unbind('resize.jcarousel');
$('.cejcarousel-pagination')
.on('jcarouselpagination:active', 'a', function () {
$(this).addClass('active');
})
.on('jcarouselpagination:inactive', 'a', function () {
$(this).removeClass('active');
})
.jcarouselPagination({
perPage: 1,
item: function (page) {
return '<a data-item="' + page + '" class="slider_ce_text" href="#' + page + '"><div class="grey_dot"></div></a>';
},
});
window.onload = $("[data-item = '1']").addClass("active");
Not sure that it's the absolute answer but it works!
I have many popovers in my page (JSBin), each data-toggle is linked to a html div. It is now realized by the following script:
<script>
$('[data-toggle="popover0"]').popover({
html: true,
content: function() {
return $("#popover0-html").html()
}});
$('[data-toggle="popover1"]').popover({
html: true,
content: function() {
return $("#popover1-html").html()
}});
$('[data-toggle="popover2"]').popover({
html: true,
content: function() {
return $("#popover2-html").html()
}});
</script>
I would like to simply the above code by saying "for all data-toggle with an ID, we return the html whose id is ID + -html". Does anyone know how to realize this?
One option is:
$('[data-toggle]').popover({
html: true,
content: function() {
var id = "#" + this.getAttribute('data-toggle') + "-html";
return $(id).html();
}
});
The above script uses value of the data-toggle attribute for selecting the target element. It works for 1 or many elements.
<script>
for (var i=0;i<3;i++) {
var selector = '[data-toggle="popover'+ i +'"]';
var popover = '#popover' + i +'-html';
$(selector ).popover({
html: true,
content: function() {
return $(popover ).html()
}});
}
</script>
I am woking with jQuery UI and I made an attempt to create a "to do list" app. I have it functioning up to a point, but the task won't display correctly in the sort div I have attempted to create. It's supposed to display as a "bar" with a delete button and a completed option. But it currently displays as text. Am I supposed to incorporate jQuery directly inline in the html as well?
Here is my fiddle of the app in it's current state:
Todo List App FIDDLE
I will display only the jQuery portion of the coding. The complete version is on the Fiddle.
$("document").ready(function() {
$('#due_date').datepicker();
$('#add_task').button({ icons: { primary: "ui-icon-circle-plus" } }).click(function() {
$('#new_task').dialog('open'); }); // end click
$('#new_task').dialog({ width: 350,
height: 300,
modal: true,
autoOpen: false,
close: function() {
$('#new_task input').val(' '); /*clear fields*/
}, buttons: {
"Add Task" : function() {
var task_name = $('#task').val();
var due_date = $('#due_date').val();
var begin_li = '<li><span class="done">%</span><span class="delete">x</span>';
var task_li = '<span class="task">' + task_name + '</span>';
var date_li = '<span class="due_date">' + due_date + '</span>';
var end_li = '</li>';
$('#task_list').prepend(begin_li + task_li + date_li + end_li);
$('#task_list').hide().slideDown(250).find('li:first')
.animate({ 'background-color':'rgb(255,255,204)' },250)
.animate({ 'background-color':'white'},750)
.animate;
// end animate
$(this).dialog('close');
}, "Cancel" : function() {
$(this).dialog('close');
}
}
});
// end dialog
//Marking as complete
$('#task_list').on('click', '.done', function() {
var task_item = $(this).parent('li');
var $this = $(this);
$this.detach();
$('#completed_list').prepend($this);
$this.slideDown();
});
});
//Sortable
$('.sortlist').sortable({
connectWith: '.sortlist',
cursor: 'pointer',
placeholder: 'ui-state-highlight',
cancel: '.delete,.done'
});
//Delete
$('.sortlist').on('click','.delete', function() {
task_item.effect('puff', function() {
$(this).remove();
});
});
Help and guidance is greatly appreciated!
One problem is with your click event. You are only moving the .done span element to the completed list. Try this:
$('#task_list').on('click', '.done', function () {
var $this = $(this);
var task_item = $this.parent('li');
$this.detach();
$('#completed_list').prepend(task_item);
task_item.slideDown();
});
In this case, the span.done is still being removed, but the whole li element is moved to the lower list.
There is also a problem in your CSS, corrected code below:
#task_list li, #completed_list li {
border: 1px solid rgba (0, 0, 0, 0.3);
padding-top: .1em;
line-height: 170%;
margin-top: .2em;
}
The original code had an extra curly brace after rgba, which presumably had a knock on effect on subsequent code.
EDIT
The delete function is also a little faulty. Here's the corrected code:
$('.sortlist').on('click', '.delete', function () {
var task_item = $(this).parent('li');
task_item.effect('puff', function () {
$(this).remove();
});
});
(basically, task_item wasn't defined).
Regarding the title, the problem is that id attributes must be unique, but in your HTML, 2 elements have id="task". If you change your input tag to something like:
<input type="text" name="task_title" id="task_title">
...and your jQuery code to:
var task_name = $('#task_title').val();
...the title should appear.
I have many images on a page that show the status of the machine. If you click on the image then modal window opens and you can select new status. Status gets send via ajax to the DB. If I try to change another machines status the previous machines status gets changed also. Every status that I have touched gets resend every time as the last status that I selected.
It somehow creates an array of the machines I have changed and with every change posts all of them. Refresh of the page empties the array.
I think I need to use something similar to unset in php or move the inner click function outside of the first click function.
$(function() {
$('#mach_status_dialog').hide();
$('.mach_status').click(function(){
var mach = $(this).attr('id');
$('#mach_status_dialog').dialog({
modal: true,
draggable: false,
resizable: false,
width: 500,
title: 'Mach ' + mach + ' status'
});
$('.statuses').click(function(){
var user = user;
var class = $(this).attr('class');
class = class.substring(10);
var status = $(this).first().find('p').parent().text();
var data_string = 'mach=' + mach + '&status=' + status + '&user=' + user;
$.ajax({
url: 'ajax_op_mach_status.php',
type:'POST',
data: data_string,
dataType: 'json',
cache: false,
success: function(response){
var newSrc = 'images/Circle2_'+class+'_25.png';
console.log($('#'+mach+'.mach_status').attr('src', newSrc));
$('#'+mach+'.mach_status').attr('src', newSrc);
$('#'+mach+'.mach_status').attr('title', status);
$( "#mach_status_dialog" ).dialog('close');
}
});
});
});
});
$(function() {
$('#mach_status_dialog').hide();
$('.mach_status').click(function(){
var mach = $(this).attr('id');
$('#mach_status_dialog').dialog({
modal: true,
draggable: false,
resizable: false,
width: 500,
title: 'Mach ' + mach + ' status'
});
});
$(document).on('click', '.statuses', function(){
var user = user;
var class = $(this).attr('class');
class = class.substring(10);
var status = $(this).first().find('p').parent().text();
var data_string = 'mach=' + mach + '&status=' + status + '&user=' + user;
$.ajax({
url: 'ajax_op_mach_status.php',
type:'POST',
data: data_string,
dataType: 'json',
cache: false,
success: function(response){
var newSrc = 'images/Circle2_'+class+'_25.png';
console.log($('#'+mach+'.mach_status').attr('src', newSrc));
$('#'+mach+'.mach_status').attr('src', newSrc);
$('#'+mach+'.mach_status').attr('title', status);
$( "#mach_status_dialog" ).dialog('close');
}
});
});
});
As you say, just move the .click event into the DOM ready callback. As it stands, every time you click on a mach_status, you are assigning a new click event handler. So if I click on mach_status 10 times, then click on a statuses link once, you'll get 10 AJAX requests.
If you only want to bind onto a statuses click when the user clicks on mach_status, add a class onto the element to tell it when it's ready:
$(function() {
$('#mach_status_dialog').hide();
$('.mach_status').click(function(){
$(".statuses").addClass("ready");
var mach = $(this).attr('id');
$('#mach_status_dialog').dialog({
modal: true,
draggable: false,
resizable: false,
width: 500,
title: 'Mach ' + mach + ' status'
});
});
$('.statuses.ready').click(function(){
// Do AJAX
});
});
The problem is here...
$('.statuses').click(function(){
Every time you click on *.mach_status* element, it adds the event listener for all the statuses. You can changes this to
$(this).find('.statuses').click(function abc(){
.
.
.
this.removeEventListner('click', abc);
});
Notice How I am using the named functions and removing them from event queue once they are fired.