I'm having some problems regarding a jQuery modal window. I'm a dba and SQL programmer and my goal is to build up a query which dynamically builds an HTML which contains a flash which links to a modal window that has another flash in it. Well the query is done and works flawlessly. However, I tried it on Internet Explorer and (unlike firefox and chrome) when you want to close the modal window it closes the whole browser window (with a warning message that says "beware, the browser's trying to close this tab etc").
I used an already existing jquery modal window code and styling (I believe that both matter). The problem is, that the whole query is done and if I change the whole jquery modal window, I'll have to change the query's logic, and drastically (believe me, I've checked).
So, my fastest solution would be to correct the jQuery code that is messing up the whole close thing (changing the sql stored proc would take a LOT of work). This is because the original example I used as a reference had this problem (I just didn't notice, due to jQuery supposively being a cross-browser solution for everything). You will see that it works flawlessly on FF and Chrome but not in IE
Here's the link: http://www.mediafire.com/?mcz70n870qmjch9
Thanks a lot!!!
Just in case I'm posting the code here as well:
/// <reference path="jquery-1.3.2.min-vsdoc.js" />
/************************************************************************************************************
* SIMPLE MODAL v 2.0
* © 2009 FISHBOWL MEDIA LLC
* http://fishbowlmedia.com
***********************************************************************************************************/
(function ($) {
/**********************************
* CUSTOMIZE THE DEFAULT SETTINGS
* Ex:
* var _settings = {
* id: 'modal',
* src: function(sender){
* return jQuery(sender).attr('href');
* },
* width: 800,
* height: 600
* }
**********************************/
var _settings = {
width: 800, // Use this value if not set in CSS or HTML
height: 600, // Use this value if not set in CSS or HTML
overlayOpacity: .85, // Use this value if not set in CSS or HTML
id: 'modal',
src: function (sender) {
return jQuery(sender).attr('href');
},
fadeInSpeed: 0,
fadeOutSpeed: 0
}
/**********************************
* DO NOT CUSTOMIZE BELOW THIS LINE
**********************************/
$.modal = function (options) {
return _modal(this, options);
}
$.modal.open = function () {
_modal.open();
}
$.modal.close = function () {
_modal.close();
}
$.fn.modal = function (options) {
return _modal(this, options);
}
_modal = function (sender, params) {
this.options = {
parent: null,
overlayOpacity: null,
id: null,
content: null,
width: null,
height: null,
modalClassName: null,
imageClassName: null,
closeClassName: null,
overlayClassName: null,
src: null
}
this.options = $.extend({}, options, _defaults);
this.options = $.extend({}, options, _settings);
this.options = $.extend({}, options, params);
this.close = function () {
jQuery('.' + options.modalClassName + ', .' + options.overlayClassName).fadeOut(_settings.fadeOutSpeed, function () { jQuery(this).unbind().remove(); });
}
this.open = function () {
if (typeof options.src == 'function') {
options.src = options.src(sender)
} else {
options.src = options.src || _defaults.src(sender);
}
var fileExt = /^.+\.((jpg)|(gif)|(jpeg)|(png)|(jpg))$/i;
var contentHTML = '';
if (fileExt.test(options.src)) {
contentHTML = '<div class="' + options.imageClassName + '"><img src="' + options.src + '"/></div>';
} else {
contentHTML = '<iframe width="' + options.width + '" height="' + options.height + '" frameborder="0" scrolling="no" allowtransparency="true" src="' + options.src + '"></iframe>';
}
options.content = options.content || contentHTML;
if (jQuery('.' + options.modalClassName).length && jQuery('.' + options.overlayClassName).length) {
jQuery('.' + options.modalClassName).html(options.content);
} else {
$overlay = jQuery((_isIE6()) ? '<iframe src="BLOCKED SCRIPT\'<html></html>\';" scrolling="no" frameborder="0" class="' + options.overlayClassName + '"></iframe><div class="' + options.overlayClassName + '"></div>' : '<div class="' + options.overlayClassName + '"></div>');
$overlay.hide().appendTo(options.parent);
$modal = jQuery('<div id="' + options.id + '" class="' + options.modalClassName + '" style="width:' + options.width + 'px; height:' + options.height + 'px; margin-top:-' + (options.height / 2) + 'px; margin-left:-' + (options.width / 2) + 'px;">' + options.content + '</div>');
$modal.hide().appendTo(options.parent);
$close = jQuery('<a class="' + options.closeClassName + '"></a>');
$close.appendTo($modal);
var overlayOpacity = _getOpacity($overlay.not('iframe')) || options.overlayOpacity;
$overlay.fadeTo(0, 0).show().not('iframe').fadeTo(_settings.fadeInSpeed, overlayOpacity);
$modal.fadeIn(_settings.fadeInSpeed);
$close.click(function () { jQuery.modal().close(); });
$overlay.click(function () { jQuery.modal().close(); });
}
}
return this;
}
_isIE6 = function () {
if (document.all && document.getElementById) {
if (document.compatMode && !window.XMLHttpRequest) {
return true;
}
}
return false;
}
_getOpacity = function (sender) {
$sender = jQuery(sender);
opacity = $sender.css('opacity');
filter = $sender.css('filter');
if (filter.indexOf("opacity=") >= 0) {
return parseFloat(filter.match(/opacity=([^)]*)/)[1]) / 100;
}
else if (opacity != '') {
return opacity;
}
return '';
}
_defaults = {
parent: 'body',
overlayOpacity: 85,
id: 'modal',
content: null,
width: 800,
height: 600,
modalClassName: 'modal-window',
imageClassName: 'modal-image',
closeClassName: 'close-window',
overlayClassName: 'modal-overlay',
src: function (sender) {
return jQuery(sender).attr('href');
}
}
})(jQuery);
And the style:
.modal-overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
background: #131313;
opacity: .85;
filter: alpha(opacity=85);
z-index: 101;
}
.modal-window {
position: fixed;
top: 50%;
left: 50%;
margin: 0;
padding: 0;
z-index: 102;
background: #fff;
border: solid 8px #000;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
}
.close-window {
position: absolute;
width: 47px;
height: 47px;
right: -23px;
top: -23px;
background: transparent url(../images/close-button.png) no-repeat scroll right top;
text-indent: -99999px;
overflow: hidden;
cursor: pointer;
}
Thanks a ton in advance everyone =-)
EDIT: Daniele suggested that the problem might be on this line:
jQuery('.' + options.modalClassName + ', .' + options.overlayClassName).fadeOut(_settings.fadeOutSpeed, function () { jQuery(this).unbind().remove(); });
I did what he suggested and the result was this: It still doesn't work at all on IE (meaning that it still asks to close the whole window and not just the modal), and correctly shows and closes a first modal in FF and chrome, but after closing the first one its not able to correctly show another one.
Replace close() method of modal with closeModal or something similar:
$.modal.closeModal = function () {
_modal.closeModal();
}
[...]
this.closeModal = function () {
jQuery('.' + options.modalClassName + ', .' + options.overlayClassName).fadeOut(_settings.fadeOutSpeed, function () { jQuery(this).unbind().remove(); });
}
[...]
$close.click(function () { jQuery.modal().closeModal(); });
$overlay.click(function () { jQuery.modal().closeModal(); });
for me it works...
Related
I'm having trouble customizing this code to have a bubble chat icon that stays within my website when I scroll down. Anyone with an idea of how I can improve it?
Here is my code so far:
<!-- Add this script tag without any modification to the target webpage -->
<script type="application/javascript">
var ciscoBubbleChat = (function() {
var smHost = 'socialminer.uonbi.ac.ke';
var widgetId = '1';
var msgMustAcceptCert = 'Certificate must be accepted to start the conversation.';
var msgAcceptCertButtonLabel = 'Accept Certificate';
var msgCloseButtonLabel = 'Close';
var msgWaitingCertAcceptance = 'Waiting for certificate acceptance.';
var msgConnectivityIssues = 'We are experiencing connectivity issues. Try later.';
var appId = 'cisco_bubble_chat';
var appMargin = 15;
var appUrl = 'https://' + smHost + '/ccp/ui/BubbleChat.html?host=' + smHost + '&wid=' + widgetId;
var connectivityCheckUrl = 'https://' + smHost + '/ccp/ui/ConnectivityCheck.html';
var messageEventListener;
var addNoCacheQueryParam;
return {
showChatWindow: function(injectedData) {
var logPrefix = 'CISCO_BUBBLE_CHAT: ';
if (document.getElementById(appId)) {
console.log(logPrefix + 'Not loading BubbleChat as it is already loaded');
return;
}
var validateInjectedData = function(formData) {
// browser compatible way to check whether it is an object with 10 fields and all the values are strings
var result = true;
if (formData && typeof formData === 'object' && formData.constructor === Object) {
var counter = 0;
for (var key in formData) {
if (!(typeof formData[key] === 'string' || formData[key] instanceof String)) {
result = false;
break;
}
counter++;
if (counter > 10) {
result = false;
break;
}
}
} else {
result = false;
}
return result;
};
if (injectedData) {
if (validateInjectedData(injectedData.formData)) {
appUrl += '&injectedFormData=' + encodeURIComponent(JSON.stringify(injectedData.formData));
} else {
if (typeof injectedData.validationErrorCallback === 'function') {
injectedData.validationErrorCallback();
} else {
console.log(logPrefix + 'Could not invoke validationErrorCallback as it is not a function');
}
}
}
var iframe = document.createElement('iframe');
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');
iframe.setAttribute('id', appId);
iframe.setAttribute('style', 'position: fixed; width: 312px; height: 410px; border: none; bottom: 0px; right: 0; z-index:999;');
document.body.appendChild(iframe);
var frameWindow = iframe.contentWindow ? iframe.contentWindow : iframe;
var frameDoc = frameWindow.document;
// Trigger a page load for iframe inline content loading to work in Firefox
frameDoc.open();
frameDoc.close();
frameDoc.body.innerHTML = '<div id="secure-connectivity-check-container" style="position: fixed; width: 300px; height: 395px; ' +
'bottom: 10px; right: 10px; font-family: Helvetica; font-size: 14px; color: #4F5051;' +
'box-shadow: 0 0 3px #000; background: #fff; display: flex; flex-direction: column; display: none;">' +
'<div style="height: 25%;"></div>' +
'<div style="height: 25%; display: flex; align-items: flex-start; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<div id="secure-connectivity-check-msg"></div>' +
'<a id="accept-cert-button" style="display:none; padding-top: 10px" href="#" onclick="acceptCertificate(); return void(0);">' +
msgAcceptCertButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%; display: flex; align-items: flex-end; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<a href="#" onclick="window.parent.postMessage({messageType: \'unmount\'}, \'*\'); return void(0);">' +
msgCloseButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%;"></div>' +
'</div>';
frameWindow.acceptCertificate = function() {
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = msgWaitingCertAcceptance;
frameDoc.getElementById('accept-cert-button').style.display = 'none';
window.open(addNoCacheQueryParam(connectivityCheckUrl), 'SM_CERT_PAGE');
};
if (!addNoCacheQueryParam) {
addNoCacheQueryParam = function(url) {
return url + (url.indexOf("?") === -1 ? '?' : '&') + 'nocache=' + new Date().getTime();
}
}
if (!messageEventListener) {
messageEventListener = function(event) {
console.log(logPrefix + 'Received event from origin: ' + event.origin);
console.log(logPrefix + 'Received event data: ' + JSON.stringify(event.data));
switch (event.data.messageType) {
case 'resize':
document.getElementById(appId).style.height = event.data.height + appMargin + 'px';
console.log(logPrefix + 'Successfully resized');
break;
case 'unmount':
document.body.removeChild(document.getElementById(appId));
window.removeEventListener('message', messageEventListener);
console.log(logPrefix + 'Successfully unmounted BubbleChat and removed event listener for message');
break;
case 'bubblechat-cert-accepted':
document.getElementById(appId).setAttribute('src', addNoCacheQueryParam(appUrl));
console.log(logPrefix + 'Successfully validated certificate acceptance and loaded BubbleChat');
break;
default:
console.log(logPrefix + 'Unknown message type');
}
};
}
window.addEventListener('message', messageEventListener);
console.log(logPrefix + 'Event listener for message added');
// Check HTTPS connectivity and show appropriate screen
var showConnectivityIssue = function(message, showAcceptCertLink) {
window.postMessage({
messageType: 'resize',
height: 395
}, '*');
frameDoc.getElementById('secure-connectivity-check-container').style.display = 'block';
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = message;
frameDoc.getElementById('accept-cert-button').style.display = showAcceptCertLink ? 'block' : 'none';
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState === 4) {
console.log(logPrefix + 'Connectivity check status: ' + this.status);
switch (this.status) {
case 200:
iframe.setAttribute('src', addNoCacheQueryParam(appUrl));
break;
case 0:
showConnectivityIssue(msgMustAcceptCert, true);
break;
default:
showConnectivityIssue(msgConnectivityIssues, false);
}
}
};
console.log(logPrefix + 'Checking connectivity to: ' + connectivityCheckUrl);
xhr.open('GET', addNoCacheQueryParam(connectivityCheckUrl), true);
xhr.send();
}
};
})();
</script>
<!--
Use the function 'ciscoBubbleChat.showChatWindow() as the event handler for initiating chat.
eg: <button onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button>
Optionally, invisible form data can be submitted, which will be submitted along with the fields customer fills in.
Upto 10 fields can be passed. If more than 10 fields are passed, the invisible form data will not be used and
the provided error callback will be invoked. For injecting form data, an object should be passed to
ciscoBubbleChat.showChatWindow() as an argument. The object should be of the form:
{
formData: {
InjectedField1: 'InjectedValue1',
InjectedField2: 'InjectedValue2'
...
},
validationErrorCallback: function(){console.log('business specific logic goes here');}
}
The form data can have any string as field name and value. The submitted invisible form data values will be
shown in the agent desktop, as well as will be updated in ContextService if the specified fieldset(s) in the widget
contains these field names just like the regular visible chat form fields data.
eg:
<button onclick="ciscoBubbleChat.showChatWindow({
formData: {
AnyFieldName1: 'AnyFieldValue1',
AnyFieldName2: 'AnyFieldValue2',
AnyFieldName3: 'AnyFieldValue3',
AnyFieldName4: 'AnyFieldValue4',
AnyFieldName5: 'AnyFieldValue5',
AnyFieldName6: 'AnyFieldValue6',
AnyFieldName7: 'AnyFieldValue7',
AnyFieldName8: 'AnyFieldValue8',
AnyFieldName9: 'AnyFieldValue9',
AnyFieldName10: 'AnyFieldValue10'
},
validationErrorCallback: function(){console.log('error in validating injected data');}
})">Click to chat</button>
-->
<html>
<body>
<button class onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button>
</body>
</html>
I want to customize it so that it can have a better look, and find a way to keep it within my website. Does anyone have any ideas?
The best solution would be to add position: fixed; on the button, for example: <button style="position: fixed; bottom: 0; right: 0;" onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button> That would force the button to stay on the lower right side of screen at all times. And for the icon, just add an <img> tag.
Demo:
.chatBtn {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 2;
}
.chatBtn img {
width: 40px; /* Change this to what you want. */
height: 40px; /* Change this to what you want. */
}
<button class="chatBtn" onclick="ciscoBubbleChat.showChatWindow()"><img src="https://icon-library.com/images/talk-bubble-icon-png/talk-bubble-icon-png-2.jpg"> <!-- You can put your own image here. -->
</button>
<!-- Add this script tag without any modification to the target webpage -->
<script type="application/javascript">
var ciscoBubbleChat = (function () {
var smHost = 'socialminer.uonbi.ac.ke';
var widgetId = '1';
var msgMustAcceptCert = 'Certificate must be accepted to start the conversation.';
var msgAcceptCertButtonLabel = 'Accept Certificate';
var msgCloseButtonLabel = 'Close';
var msgWaitingCertAcceptance = 'Waiting for certificate acceptance.';
var msgConnectivityIssues = 'We are experiencing connectivity issues. Try later.';
var appId = 'cisco_bubble_chat';
var appMargin = 15;
var appUrl = 'https://' + smHost + '/ccp/ui/BubbleChat.html?host=' + smHost + '&wid=' + widgetId;
var connectivityCheckUrl = 'https://' + smHost + '/ccp/ui/ConnectivityCheck.html';
var messageEventListener;
var addNoCacheQueryParam;
return {
showChatWindow: function (injectedData) {
var logPrefix = 'CISCO_BUBBLE_CHAT: ';
if (document.getElementById(appId)) {
console.log(logPrefix + 'Not loading BubbleChat as it is already loaded');
return;
}
var validateInjectedData = function(formData) {
// browser compatible way to check whether it is an object with 10 fields and all the values are strings
var result = true;
if (formData && typeof formData === 'object' && formData.constructor === Object){
var counter = 0;
for (var key in formData) {
if (!(typeof formData[key] === 'string' || formData[key] instanceof String)) {
result = false;
break;
}
counter++;
if (counter > 10) {
result = false;
break;
}
}
} else {
result = false;
}
return result;
};
if (injectedData) {
if (validateInjectedData(injectedData.formData)) {
appUrl += '&injectedFormData=' + encodeURIComponent(JSON.stringify(injectedData.formData));
} else {
if (typeof injectedData.validationErrorCallback === 'function') {
injectedData.validationErrorCallback();
} else {
console.log(logPrefix + 'Could not invoke validationErrorCallback as it is not a function');
}
}
}
var iframe = document.createElement('iframe');
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');
iframe.setAttribute('id', appId);
iframe.setAttribute('style', 'position: fixed; width: 312px; height: 410px; border: none; bottom: 0px; right: 0; z-index:999;');
document.body.appendChild(iframe);
var frameWindow = iframe.contentWindow ? iframe.contentWindow : iframe;
var frameDoc = frameWindow.document;
// Trigger a page load for iframe inline content loading to work in Firefox
frameDoc.open();
frameDoc.close();
frameDoc.body.innerHTML = '<div id="secure-connectivity-check-container" style="position: fixed; width: 300px; height: 395px; ' +
'bottom: 10px; right: 10px; font-family: Helvetica; font-size: 14px; color: #4F5051;' +
'box-shadow: 0 0 3px #000; background: #fff; display: flex; flex-direction: column; display: none;">' +
'<div style="height: 25%;"></div>' +
'<div style="height: 25%; display: flex; align-items: flex-start; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<div id="secure-connectivity-check-msg"></div>' +
'<a id="accept-cert-button" style="display:none; padding-top: 10px" href="#" onclick="acceptCertificate(); return void(0);">' +
msgAcceptCertButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%; display: flex; align-items: flex-end; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<a href="#" onclick="window.parent.postMessage({messageType: \'unmount\'}, \'*\'); return void(0);">' +
msgCloseButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%;"></div>' +
'</div>';
frameWindow.acceptCertificate = function () {
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = msgWaitingCertAcceptance;
frameDoc.getElementById('accept-cert-button').style.display = 'none';
window.open(addNoCacheQueryParam(connectivityCheckUrl), 'SM_CERT_PAGE');
};
if (!addNoCacheQueryParam){
addNoCacheQueryParam = function (url) {
return url + (url.indexOf("?") === -1 ? '?' : '&') + 'nocache=' + new Date().getTime();
}
}
if (!messageEventListener) {
messageEventListener = function (event) {
console.log(logPrefix + 'Received event from origin: ' + event.origin);
console.log(logPrefix + 'Received event data: ' + JSON.stringify(event.data));
switch (event.data.messageType) {
case 'resize':
document.getElementById(appId).style.height = event.data.height + appMargin + 'px';
console.log(logPrefix + 'Successfully resized');
break;
case 'unmount':
document.body.removeChild(document.getElementById(appId));
window.removeEventListener('message', messageEventListener);
console.log(logPrefix + 'Successfully unmounted BubbleChat and removed event listener for message');
break;
case 'bubblechat-cert-accepted':
document.getElementById(appId).setAttribute('src', addNoCacheQueryParam(appUrl));
console.log(logPrefix + 'Successfully validated certificate acceptance and loaded BubbleChat');
break;
default:
console.log(logPrefix + 'Unknown message type');
}
};
}
window.addEventListener('message', messageEventListener);
console.log(logPrefix + 'Event listener for message added');
// Check HTTPS connectivity and show appropriate screen
var showConnectivityIssue = function (message, showAcceptCertLink) {
window.postMessage({ messageType: 'resize', height: 395 }, '*');
frameDoc.getElementById('secure-connectivity-check-container').style.display = 'block';
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = message;
frameDoc.getElementById('accept-cert-button').style.display = showAcceptCertLink ? 'block' : 'none';
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(logPrefix + 'Connectivity check status: ' + this.status);
switch (this.status) {
case 200:
iframe.setAttribute('src', addNoCacheQueryParam(appUrl));
break;
case 0:
showConnectivityIssue(msgMustAcceptCert, true);
break;
default:
showConnectivityIssue(msgConnectivityIssues, false);
}
}
};
console.log(logPrefix + 'Checking connectivity to: ' + connectivityCheckUrl);
xhr.open('GET', addNoCacheQueryParam(connectivityCheckUrl), true);
xhr.send();
}
};
})();
</script>
<!--
Use the function 'ciscoBubbleChat.showChatWindow() as the event handler for initiating chat.
eg: <button onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button>
Optionally, invisible form data can be submitted, which will be submitted along with the fields customer fills in.
Upto 10 fields can be passed. If more than 10 fields are passed, the invisible form data will not be used and
the provided error callback will be invoked. For injecting form data, an object should be passed to
ciscoBubbleChat.showChatWindow() as an argument. The object should be of the form:
{
formData: {
InjectedField1: 'InjectedValue1',
InjectedField2: 'InjectedValue2'
...
},
validationErrorCallback: function(){console.log('business specific logic goes here');}
}
The form data can have any string as field name and value. The submitted invisible form data values will be
shown in the agent desktop, as well as will be updated in ContextService if the specified fieldset(s) in the widget
contains these field names just like the regular visible chat form fields data.
eg:
<button onclick="ciscoBubbleChat.showChatWindow({
formData: {
AnyFieldName1: 'AnyFieldValue1',
AnyFieldName2: 'AnyFieldValue2',
AnyFieldName3: 'AnyFieldValue3',
AnyFieldName4: 'AnyFieldValue4',
AnyFieldName5: 'AnyFieldValue5',
AnyFieldName6: 'AnyFieldValue6',
AnyFieldName7: 'AnyFieldValue7',
AnyFieldName8: 'AnyFieldValue8',
AnyFieldName9: 'AnyFieldValue9',
AnyFieldName10: 'AnyFieldValue10'
},
validationErrorCallback: function(){console.log('error in validating injected data');}
})">Click to chat</button>
-->
EDIT:
A chat bubble icon has been added.
This codes does what i want but by default everywhere on my website where there is title attribute it changes the style which i do not want.
I want it to work in just some places where i assign it.
could someone show me how to?
the css
#tooltip {
background: #C7100C;
color:#fff;
padding: 3px 10px;
width:20%;
white-space: pre-line;
}
Here is the js
(function () {
var ID = "tooltip", CLS_ON = "tooltip_ON", FOLLOW = true,
DATA = "_tooltip", OFFSET_X = 20, OFFSET_Y = 10,
showAt = function (e) {
var ntop = e.pageY + OFFSET_Y, nleft = e.pageX + OFFSET_X;
$("#" + ID).html($(e.target).data(DATA)).css({
position: "absolute", top: ntop, left: nleft
}).show();
};
$(document).on("mouseenter", "*[title]", function (e) {
$(this).data(DATA, $(this).attr("title"));
$(this).removeAttr("title").addClass(CLS_ON);
$("<div id='" + ID + "' />").appendTo("body");
showAt(e);
});
$(document).on("mouseleave", "." + CLS_ON, function (e) {
$(this).attr("title", $(this).data(DATA)).removeClass(CLS_ON);
$("#" + ID).remove();
});
if (FOLLOW) { $(document).on("mousemove", "." + CLS_ON, showAt); }
}());
Just replace "*[title]" with something like ".make-tooltip" and assign this class to elements you want to have that tooltip.
This way you don't target all elements which have a title, but only those elements, which have the .make-tooltip class.
(function () {
var ID = "tooltip", CLS_ON = "tooltip_ON", FOLLOW = true,
DATA = "_tooltip", OFFSET_X = 20, OFFSET_Y = 10,
showAt = function (e) {
var ntop = e.pageY + OFFSET_Y, nleft = e.pageX + OFFSET_X;
$("#" + ID).html($(e.target).data(DATA)).css({
position: "absolute", top: ntop, left: nleft
}).show();
};
$(document).on("mouseenter", ".make-tooltip", function (e) {
$(this).data(DATA, $(this).attr("title"));
$(this).removeAttr("title").addClass(CLS_ON);
$("<div id='" + ID + "' />").appendTo("body");
showAt(e);
});
$(document).on("mouseleave", "." + CLS_ON, function (e) {
$(this).attr("title", $(this).data(DATA)).removeClass(CLS_ON);
$("#" + ID).remove();
});
if (FOLLOW) { $(document).on("mousemove", "." + CLS_ON, showAt); }
}());
#tooltip {
background: #C7100C;
color:#fff;
padding: 3px 10px;
width:20%;
white-space: pre-line;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'm a link<br>
I'm a link<br>
I'm a link<br>
I'm a link<br>
I'm a link<br>
I have created a JavaScript exercise that changes the ID of an HTML object.
I want to set up a button that will cycle between choices. Right now the button is not executing the function.
Please take a look at the code and let me know what I am doing wrong.
a = 0;
n = 1;
i = 0;
function changexc(a, n) {
document.getElementById('effect00').id = "effect00" + (a + i);
}
function counterxc() {
i = n++;
return n;
}
document.write("<br>" + "a is " + a + "<br>");
document.write(" i is " + i + "<br>");
document.write(" n is " + n + "<br>");
document.write(" n + a is " + (n + a) + "<br>");
changexc(a);
<style>#effect001 {
max-width: 100px!important;
height: 200px;
background-color: red;
display: block;
}
#effect002 {
max-width: 200px!important;
height: 100px;
background-color: blue;
display: block;
}
#effect003 {
max-width: 300px!important;
height: 300px;
border-radius: 50%;
background-color: yellow;
display: block;
}
</style>
<div id="effect00"></div>
<button type="button" id="thatdarnbutton" onclick="counterxc ()">Click Me</button>
This code works - see explanation below
var a = 0;
var n = 1;
var i = 0;
function changexc() {
console.log(" added class : " + "effect00" + (a + i));
document.getElementById("effect00").className = "effect00" + (a + i);
console.log("<br>" + "a is " + a + "<br>");
console.log(" i is " + i + "<br>");
console.log(" n is " + n + "<br>");
console.log(" n + a is " + (n + a) + "<br>");
}
function counterxc() {
i = n + 1;
n++;
if(n >3) {
n = 0;
}
changexc();
}
changexc();
.effect001 {
max-width: 100px!important;
height: 200px;
background-color: red;
display: block;
}
.effect002 {
max-width: 200px!important;
height: 100px;
background-color: blue;
display: block;
}
.effect003 {
max-width: 300px!important;
height: 200px;
border-radius: 50%;
background-color: yellow;
display: block;
}
<div id="effect00">
hello world!
</div>
<button type="button" onClick="counterxc();">Click Me</button>
Its just "use strict"; javascript environment (node, browser etc) would assume/say that you can't use variables before you declare them and I suggest you do that. Its good practise:
However, as other have commented - start from basics, learn how browser uses javascript as well other environments such as node. I am still getting used to the new ES6 and ES7 syntax and all the new build systems. Its a whole lot to mention here but i would recommend the "You don't know JS" series of books
You code work fine, but need a little work.
First of you have to make sure that all element been loaded before you begin your work use setTimeout.
See down i have fixed your problem here and this should now work
a = 0;
n = 1;
i = 0;
var id = "effect00";
function changexc(a, n) {
document.getElementById(id).setAttribute("id", "effect00" + (a + i));
id = "effect00" + (a + i);
}
function counterxc() {
i = n++;
write();
return n;
}
function write() {
var resultDiv = document.getElementById(id);
var resultstring = "<br>" + "a is " + a + "<br>"
resultstring += " i is " + i + "<br>"
resultstring += " n is " + n + "<br>"
resultstring += " n + a is " + (n + a) + "<br>"
resultstring += "id is " + "effect00" + (a + i);
resultDiv.innerHTML = resultstring;
changexc(a)
}
setTimeout(function() { /// this is importent, wait untill elemtns have loaded
changexc(a);
write();
}, 100);
#effect001 {
max-width: 100px!important;
height: 200px;
background-color: red;
display: block;
}
#effect002 {
max-width: 200px!important;
height: 100px;
background-color: blue;
display: block;
}
#effect003 {
max-width: 300px!important;
height: 300px;
border-radius: 50%;
background-color: yellow;
display: block;
}
<button type="button" id="thatdarnbutton" onclick="counterxc()">Click Me</button>
<div id="effect00"></div>
In this coding I showed progress bar on the text box. but i need loading indicator in span tag when searching for something. I added two images to better understand about it. please answer me the question.
this is flat progress in text box:
but i need the progress on span
CSS:
<style type="text/css">
.loader
{
background: url(resources/images/loader.gif);
background-repeat: no-repeat;
background-position: right;
}
</style>
JS:
try {
console.log('connections url ' , urlHolder.getconnectedusersByName);
$("#auto-complete-tag").autocomplete({
source: function(request, respond) {
$("#auto-complete-tag").addClass('loader');
var givenUserName = $("#auto-complete-tag").val();
$.post(urlHolder.getconnectedusersByName, {
userId : signedUserId,
username : givenUserName
}, function(response) {
$('#auto-complete-tag').removeClass('loader');
if(!response){
respond([]);
length = 0;
}
this.connectionsList = new Array();
for (var counter = 0; counter < response.users.length; counter++) {
var getConnectedUsers = new Object();
getConnectedUsers = {
value : response.users[counter].name,
//profileId : "onclick=return false",
image : response.users[counter].defaultImageFileName,
id:response.users[counter].id
}
this.connectionsList.push(getConnectedUsers);
}
respond (this.connectionsList);
});
},
delay: 0 ,
search: function (e, u) {
},
select : function(event, ui) {
return false;
},
response: function(event, ui) {
length = ui.content.length;
console.log('length',length );
if(length === 0) {
var noResult = {label:"No results found for you" };
ui.content.push(noResult);
}
},
}) .data('ui-autocomplete')._renderItem = function(ul, item) {
if(length !== 0){
return $('<li>')
.data( "ui-autocomplete-item", item)
.append(
'<a style="background-color: #E0F0EF; color:#0d78a3; margin-bottom: 3px; margin-top: 3px; margin-left: 3px; margin-right: 3px; font-weight: bold;">' +
'<span style="color:#86BBC9; font-weight: normal;">' +
item.label + '</span>' + '<br>'+'<span>Text message</span>'+
'<button style="margin-bottom:14px; margin-right:5px;" class=\"yellow-btn apply-btn\" id=\"apply-user-' + item.id + '\" onclick=\"openDFAChatWithUser(\'' + item.id + '\')\">Chat</button>'
+ '<span class="ui-autocomplete-icon pull-right"></span>' +
'</a>'
)
.appendTo(ul);}else{
return $('<li>')
.data( "ui-autocomplete-item", item)
.append('<a>' +
'<span class="ui-autocomplete-user">' +
item.label + '</span>' +
'<span class="ui-autocomplete-divider"></span>' +
'<span class="ui-autocomplete-icon pull-right"></span>' +
'</a>')
.appendTo(ul);
}
};
//console.log(' this.connectionsList >>> ', this.connectionsList);
} catch (e) {
console.log('getAllConnections error >>> ', e);
}
This question already has answers here:
How can I center an absolutely positioned element in a div?
(37 answers)
Closed 8 years ago.
So I have a rotator, which works good. However the master box is determined by the largest image. And all images (if smaller and such) should float in the center of the master box. However my margin edits don't seem to be doing anything in the code. Any ideas why they aren't applying?
var postimgrotator = $('.postimgrotator'),
preloader = $('#loading-images');
postimgrotator.each(function () {
this['tmp'] = '';
this.tmp2 = '';
this.postimages = new Array();
this.cur = 0;
this.count = 0;
console.log($(this));
this['postimages'] = $(this).html().trim().split(" ");
this['count'] = this['postimages'].length;
$(this).html("");
for (this['cur'] = 0; this['cur'] < this['count']; this['cur']++) {
this['tmp'] += '<img src="' + this['postimages'][this['cur']].trim() + '" alt="Image ' + this['cur'] + '" class="postimgelm" />';
this['tmp2'] += '<img src="' + this['postimages'][this['cur']].trim() + '" alt="Image ' + this['cur'] + '" />';
}
$(this).css({
'width': this['tmp'],
'height': this['tmp2']
});
$(this).html(this['tmp'].trim());
preloader.html(this['tmp2']);
var width = 0,
height = 0;
preloader.find('img').each(function () {
if (width < parseInt($(this).width())) {
width = parseInt($(this).width());
}
if (height < parseInt($(this).height())) {
height = parseInt($(this).height());
}
});
console.log('Width: ' + width + ' Height: ' + height);
$(this).css({
'width': width,
'height': height
});
var images = $(this).find('img');
this['cur'] = 0;
images.not(':first').hide();
images.first().css({
'marginTop': '-' + parseInt(images.first().height()),
'marginLeft': '-' + parseInt(images.first().width())
});
var imgcur = 0,
count = this['count'];
this.imgrotate = setInterval(imgrotator, 5000);
function imgrotator() {
console.log(parseInt(images.eq(imgcur).height()));
images.eq(imgcur).css({
'marginTop': '-' + parseInt(images.eq(imgcur).height()),
'marginLeft': '-' + parseInt(images.eq(imgcur).width())
});
console.log(images.eq(imgcur));
images.eq(imgcur).fadeOut(300, function () {
imgcur += 1;
if (imgcur === count) {
imgcur = 0;
}
images.eq(imgcur).fadeIn('slow');
});
}
});
#loading-images {
position:absolute;
top:0;
left:-9999px;
}
.postimgrotator {
position: relative;
background-color: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
text-align: center;
margin: 10px;
}
.postimgrotator img {
position: absolute;
top: 50%;
left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="postimgrotator">http://i1291.photobucket.com/albums/b551/ToxicBKFX/Abstractweek2_zps25dbb861.png http://s28.postimg.org/xkim4q9xp/Aliens_Movie.png http://i.imgur.com/l2SQ4qW.png</div>
<div class="postimgrotator">http://i1291.photobucket.com/albums/b551/ToxicBKFX/Abstractweek2_zps25dbb861.png http://s28.postimg.org/xkim4q9xp/Aliens_Movie.png http://i.imgur.com/l2SQ4qW.png</div>
<div id="loading-images"></div>
Does this help?
var postimgrotator = $('.postimgrotator'),
preloader = $('#loading-images');
postimgrotator.each(function () {
this['tmp'] = '';
this.tmp2 = '';
this.postimages = new Array();
this.cur = 0;
this.count = 0;
console.log($(this));
this['postimages'] = $(this).html().trim().split(" ");
this['count'] = this['postimages'].length;
$(this).html("");
for (this['cur'] = 0; this['cur'] < this['count']; this['cur']++) {
this['tmp'] += '<img src="' + this['postimages'][this['cur']].trim() + '" alt="Image ' + this['cur'] + '" class="postimgelm" />';
this['tmp2'] += '<img src="' + this['postimages'][this['cur']].trim() + '" alt="Image ' + this['cur'] + '" />';
}
$(this).css({
'width': this['tmp'],
'height': this['tmp2']
});
$(this).html(this['tmp'].trim());
preloader.html(this['tmp2']);
var width = 0,
height = 0;
preloader.find('img').each(function () {
if (width < parseInt($(this).width())) {
width = parseInt($(this).width());
}
if (height < parseInt($(this).height())) {
height = parseInt($(this).height());
}
});
console.log('Width: ' + width + ' Height: ' + height);
$(this).css({
'width': width,
'height': height
});
var images = $(this).find('img');
this['cur'] = 0;
images.not(':first').hide();
images.first().css({
'marginTop': '-' + parseInt(images.first().height()),
'marginLeft': '-' + parseInt(images.first().width())
});
var imgcur = 0,
count = this['count'];
this.imgrotate = setInterval(imgrotator, 5000);
function imgrotator() {
console.log(parseInt(images.eq(imgcur).height()));
images.eq(imgcur).css({
'marginTop': '-' + parseInt(images.eq(imgcur).height()),
'marginLeft': '-' + parseInt(images.eq(imgcur).width())
});
console.log(images.eq(imgcur));
images.eq(imgcur).fadeOut(300, function () {
imgcur += 1;
if (imgcur === count) {
imgcur = 0;
}
images.eq(imgcur).fadeIn('slow');
});
}
});
#loading-images {
position:absolute;
top:0;
left:-9999px;
}
.postimgrotator {
position: relative;
background-color: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
text-align: center;
margin: 10px;
}
.postimgrotator img {
position: absolute;
top: 50%;
left: 50%;
transform:translate(-50%,-50%); /* this */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="postimgrotator">http://i1291.photobucket.com/albums/b551/ToxicBKFX/Abstractweek2_zps25dbb861.png http://s28.postimg.org/xkim4q9xp/Aliens_Movie.png http://i.imgur.com/l2SQ4qW.png</div>
<div class="postimgrotator">http://i1291.photobucket.com/albums/b551/ToxicBKFX/Abstractweek2_zps25dbb861.png http://s28.postimg.org/xkim4q9xp/Aliens_Movie.png http://i.imgur.com/l2SQ4qW.png</div>
<div id="loading-images"></div>