I'm trying to wrap the two divs <div class="cm-cp-title"> and <div class="cm-cp-value"> inside a div called cm-cp-container. Actually it is working, but it merges all together, it is shown like below after I put the wrapAll();
what is that issues? im wonder how to separate each of it?
Below is the result i needed,
$(function() {
// document
'use strict';
var coupon = $('div.cm-coupon');
// Settings
coupon.each(function() {
var _coupon = $(this);
var cpValue = _coupon.attr("data-value") + "";
// Different Data type
if (_coupon.data('type') == "c1")
{
_coupon.addClass('red').css(
{
"background" : "black",
"display": "table"}
);
_coupon.append(
'<div class="cm-cp-title">' + 'black here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>'
);
}
else if (_coupon.data('type') == "c2")
{
_coupon.addClass('green').css(
{
"background" : "green",
"display": "table"}
);
_coupon.append('<div class="cm-cp-title">'+ 'green here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>');
}
else if (_coupon.data('type') == "c3")
{
_coupon.addClass('blue').css(
{
"background" :"blue",
"display": "table"}
);
_coupon.append('<div class="cm-cp-title">'+ 'blue here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>');
} else {
return false;
}
});
$('.cm-cp-title, .cm-cp-value').wrapAll("<div class='cm-cp-container'/>");
// alignment to middle
$('.cm-coupon').on('resize',function() {
$(".cm-cp-container").css('margin-top', function() {
return($('.cm-coupon').height() - $(this).height()) / 2
});
}).resize();
});//end
.cm-coupon {
width: 340px;
height: 156px;
float: left;color: #fff;
margin: 0 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cm-coupon" data-type="c1" data-value="50"></div>
<div class="cm-coupon" data-type="c2" data-value="20"></div>
<div class="cm-coupon" data-type="c3" data-value="70"></div>
Working Snippet :
$(function() {
'use strict';
var coupon = $('div.cm-coupon');
var colors = new Map([["c1", "black"], ["c2", "green"], ["c3", "blue"]]);
// Settings
coupon.each(function() {
var _coupon = $(this);
var cpValue = _coupon.attr("data-value") + "";
var color = colors.get(_coupon.data('type'));
_coupon.addClass(color).css({
"background" : color,
"display": "table"
});
_coupon.append('<div class="cm-cp-title">' + color + ' here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>');
$(_coupon.children()).wrapAll("<div class='cm-cp-container'/>");
});
// alignment to middle
$('.cm-coupon').on('resize',function() {
$(".cm-cp-container").css('margin-top', function() {
return($('.cm-coupon').height() - $(this).height()) / 2
});
}).resize();
});//end
.cm-coupon {
width: 340px;
height: 156px;
float: left;
color: #fff;
margin: 0 10px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cm-coupon" data-type="c1" data-value="50"></div>
<div class="cm-coupon" data-type="c2" data-value="20"></div>
<div class="cm-coupon" data-type="c3" data-value="70"></div>
Explanation :
First
I reduced the code removing the if statements because the only difference between the blocks if/else/else was the color ("black"/"green"/"blue"). I used a Map instead, to switch the value of the color according to the type.
What I did:
var colors = new Map([["c1", "black"], ["c2", "green"], ["c3", "blue"]]);
coupon.each(function () {
var _coupon = $(this);
var color = colors.get(_coupon.data('type'));
And then use color where need to.
Second
The problem you are encoutering is because you are not wrapping all the divs into the container, but wrapping the children of the divs.
So
$('.cm-cp-title, .cm-cp-value').wrapAll("<div class='cm-cp-container'/>");
becomes
$(coupon).wrapAll("<div class='cm-cp-container'/>");
EDIT :
It seems like you want to wrap the inner elements of the coupons instead.
Then use _coupon.children() instead, like this
$(_coupon.children()).wrapAll("<div class='cm-cp-container'/>");
and move it inside the each loop.
I edited the snippet. you can check.
In fact, the way you did it in your code, it is selecting all the matching elements in the document and wrapping it altogether. That is why the last two were moving inside the black div.
Related
I have to alter the following code somehow to add line breaks to the labels on the buttons generated by AddRemoteButtonText. Tried everything I found on this site, but nothing worked yet (most probably because I`m just starting out coding javascript). Mostly tried adding another variable to the function and then implementing it by "\n" .
var size = 20;
var repeat_timer;
function AddRemoteButtonText(num, posx, posy, wx, wy, color, label, remote, command, initial_delay, repeat_delay)
{
document.write('<div id="' + num + '" class="button ' + color + '" style="position:absolute; top:' + posy + 'px; left:' + posx + 'px; height:' + wy + 'px; width:' + wx + 'px; line-height: ' + wy + 'px;" align="center">' + label + '</div>');
document.getElementById(num).onmouseup = function () { SendIRCommand (num,remote,command,initial_delay,repeat_delay); EndSendCommand (num) };
document.getElementById(num).onmouseleave = function () { EndSendCommand (num) };
}
}
};
Thanks for your answer!
Add '<br>' like in the below example
document.write(variable +'<br/>'+ variable2);
I would probably do it like this (simplified for example purposes):
var i = 0;
var aboveLineBreak;
var belowLineBreak;
function AddRemoteButtonText() {
console.log(i);
//define some text to print to the button
aboveLineBreak = "above br" + i;
belowLineBreak = "below br" + i;
//create a button object
var btn = document.createElement("DIV");
//add our text, including the line break, to the button
btn.appendChild(document.createTextNode(aboveLineBreak));
btn.appendChild(document.createElement("BR"));
btn.appendChild(document.createTextNode(belowLineBreak));
//define our button's CSS style
btn.setAttribute("class", "button red");
//to set the position, do:
//btn.style.position = "absolute";
//btn.style.top = whatever;
//and so on...
//add listeners if needed...
btn.onmouseup = function () { console.log("foo"); };
//finally add the button to the document's body and increment i
document.body.appendChild(btn);
i++;
}
.button {
width: 33%;
height: 45px;
}
.red {
background-color: darkred;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button onClick="AddRemoteButtonText();"> Add Remote Button Text </button>
</body>
</html>
Not the most beautiful buttons, but if you simply substitute my CSS with your own you should have a working line break. If not, we will need you to post your CSS so we can have a look at it.
hi guys how can I display the data only once not like on my attached screenshot
I display that data by hovering on the corresponding markers on the map
hi I have updated my code for better look of what I have now
Screenshot
Here is my updated Codes
HTML
<div id="searchcontainer"></div>
My Javascript
function displayData(e)
{
var html = '';
var html2 = '';
var notice = '';
var mapDiv = document.getElementById('mapContainer'), i = 0,
dataIndex, tooltipDiv, key
mapMarkers = $(mapDiv).find('.e-mapMarker'), index = 0;
for (i = 0; i < mapMarkers.length; i++) {
if (e.target.parentNode.parentNode == mapMarkers[i])
{
index = i;
break;
}
}
html += '<div id="infocontainer">';
html += '<div class="p-image"><img src="src/images/retrofit.png"/></div>';
html += '<div class="popupdetail">';
html += '<div class="p-name"> Site Name: ' + flsSites[index].site_name + '</div>';
html += '<div class="p-name"> Site Status: ' + flsSites[index].status + '</div>';
html += '<div class="p-name"> Country: ' + flsSites[index].country_name + '</div>';
html += '</div>';
html += '</div>';
`html2 += '<div class="rightcontainer" onclick="DisplayProfileCard();">';
html2 += '<img id="productimage" src="src/images/retrofit.png"/>';
html2 += '<div id="imagedetail">';
html2 += '<span class="details">Product Type</span>';
html2 += '<span class="details">Version / Size</span>';
html2 += '<span class="details">Estimated annual Spend</span>';
html2 += '<span class="details">Site name / manufacturer</span>';
html2 += '<span class="details">Selling Sales Eng</span>';
html2 += '</div>';
html2 += '</div>';`
if (!document.getElementById('map_tooltip')) {
tooltipdiv = $("<div></div>").attr('id', "map_tooltip");
$(document.body).append(tooltipdiv);
$(tooltipdiv).css({
"display": "block", "padding": "5px",
"position": "absolute",
"z-index": "13000",
"cursor": "default",
"font-family": "Segoe UI",
"color": "#707070",
"font-size": "12px", "pointer-events": "none",
"background-color": "#FFFFFF",
"border": "1px solid #707070"
});
}
else
{
tooltipdiv = $("#map_tooltip");
$(tooltipdiv).css({
"left": (e.pageX + 5),
"top": (e.pageY + 5)
});
$(tooltipdiv).html(html).show("slow");
$('#searchcontainer').innerHTML = "";
//$('#defaulttext').hide();
$('#searchcontainer').append(html2);
$('.rightcontainer').eq($(this).index()).addClass('background');
}
If I understand correctly, you need a mechanism to allow a hover handler displayData() to know whether or not a .rightcontainer for the hovered element has been created previously.
The simplest way to do this is to exploit jQuery's .data() to keep a reference to each .rightcontainer as it is created. Thus, there's something to test next time round.
I have had a good hack at all the code to knock it into better shape, though there's no guarantee I've not introduced errors.
function displayData(e) {
var mapMarkers = $('#mapContainer .e-mapMarker').get(),
$tooltipDiv = $('#map_tooltip'),
grandParent = e.target.parentNode.parentNode,
flsSite = flsSites[mapMarkers.indexOf(grandParent)],
$searchcontainer = $('#searchcontainer');
if(!flsSite) return; // probably?
// Create tooltip if it doesn't already exist.
if ($tooltipdiv.length === 0) {
$tooltipdiv = $('<div id="map_tooltip">' +
'<div id="infocontainer">' +
'<div class="p-image"><img src="src/images/retrofit.png"/></div>' +
'<div class="popupdetail">' +
'<div class="p-name site"> Site Name: <span></span></div>' +
'<div class="p-name status"> Site Status: <span></span></div>' +
'<div class="p-name country"> Country: <span></span></div>' +
'</div></div></div>').css({
'display': 'block',
'position': 'absolute',
'z-index': '13000',
'padding': '5px',
'border': '1px solid #707070',
'cursor': 'default',
'pointer-events': 'none',
'font-family': 'Segoe UI',
'font-size': '12px',
'color': '#707070',
'background-color': '#FFFFFF'
}).appendTo(document.body);
}
// Surely, the code below needs to be executed whether the tooltipdiv is freshly created or not, therefore shouldn't be in an else block.
$tooltipdiv.find('.site span').text(flsSite.site_name).end()
.find('.status span').text(flsSite.status).end()
.find('.country span').text(flsSite.country_name).end()
.css({ 'left': e.pageX + 5, 'top': e.pageY + 5 })
.show('slow');
// If a previously created rightcontainer doesn't exist, then create one and keep a reference to it.
if(!$(this).data('rightCont')) {
$(this).data('rightCont', $('<div class="rightcontainer">' +
'<img id="productimage" src="src/images/retrofit.png"/>' +
'<div id="imagedetail">' +
'<span class="details">Product Type</span>' +
'<span class="details">Version / Size</span>' +
'<span class="details">Estimated annual Spend</span>' +
'<span class="details">Site name / manufacturer</span>' +
'<span class="details">Selling Sales Eng</span>' +
'</div></div>').on('click', DisplayProfileCard).appendTo($searchcontainer));
}
// Unhighlight all rightcontainers and highlight the current one, whether it was made earlier or just now.
$searchcontainer.find('.rightcontainer').removeClass('background');
$(this).data('rightCont').addClass('background');
}
tested only for parse errors
There is not so much different to show from hidden , adding background color you will see understand this if not let me know i can explain as much as possible i know
$('.first > ul > li').mouseenter(function(){
$('.second > ul > div').eq($(this).index()).addClass('background').removeClass('invisiblediv');
}).mouseleave(function(){
$('.second > ul > div').eq($(this).index()).removeClass('background').addClass('invisiblediv');
})
.first,.second{
display:inline-block;
}
.first > ul > li {
width:50px;
background-color:#fff;
text-align:center;
}
.first > ul > li:hover {
background-color:#ff5722;
}
li{
list-style-type: none;
}
.background{
background-color:red;
}
.invisiblediv{
visibility:hidden;
}
img {
width:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='first'>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<div class='second'>
<ul>
<div class='invisiblediv'><img src="https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg"> </div>
<div class='invisiblediv'><img src="https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg"> </div>
<div class='invisiblediv'><img src="https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg"> </div>
</ul>
</div>
I'm trying to make this more generic, not sure how to use the data tags...
My headers with < a > anchor tags looks like this:
<h4>Prohibited items<a class="anchor" id="prohibited-items" href="#prohibited-items" onclick="$('#prohibited-items').ScrollTo();"></a></h4>
I would like my < h4 > headers to look like this:
<h4 data-anchor="prohibited-items">Prohibited items</h4>
How can I inject anchor tags dynamically to all the < h4 > that contain the data-anchor tag?
UPDATE: this is what I ended up doing (now working with jQuery 3):
// Generate anchor tags where data-anchor data tag is used
// if data-anchor does not have a value the element text will be used to generate the anchor id
// for example: <h4 data-anchor>Sample title</h4> or <h4 data-anchor="custom-id">Sample title</h4>
$("[data-anchor]").each(function () {
var text = $(this).text();
var id = $(this).attr("data-anchor"); // Check if a custom id was provided
if (id != null && id.replace(/ /g, "") === "") {
id = text.replace(/[^\w\s]/gi, "-"); // Remove special characters
id = id.replace(/ /g, "-").toLowerCase(); // Replace spaces with "-"
}
if (!$(this).hasClass("cursor-pointer"))
$(this).addClass("cursor-pointer");
// console.log("id = " + id + ", text = " + text);
$(this).attr("onclick", "$('html, body').stop().animate(" +
"{ scrollTop: $('#" + id + "').offset().top }, '400', 'swing'); " +
"document.location='#" + id + "'; return false;");
$(this).html("<div class='anchor-space'>" + text + "</div><a " +
"class='anchor-marker no-print' " +
"id='" + id + "' " +
"href='#" + id + "' " +
"></a><span " +
"class='anchor-symbol no-print'" +
"></span>");
});
and
.anchor-marker {
top: -110px;
position: relative;
display: block;
}
.anchor-space {
margin-right: 30px;
}
.anchor-symbol {
float: right;
margin-top: -30px;
&:before {
font-family: "FontAwesome";
content: "\f13d"; // http://fontawesome.io/icon/anchor/
float: right;
}
}
Try the following
$('[data-anchor]').click(function(){
var id = $(this).attr('data-anchor');
$(id).scrollTo();
});
or:
$('[data-anchor]').each(function() {
var text = $(this).text();
var id =$(this).attr('data-anchor');
$(this).html(text+'<a class="anchor" id="'+id.substring(1)+'" href="'id'" onclick="$('+id+').ScrollTo();"></a>')
});
Try:
$("h4[data-anchor]").on('click', function(){
var anchorElement = $(this).data("anchor");
$(anchorElement).scrollTo();
}
You can use something like below:
Put "Prohibited items" text inside span like
<h4><span>Prohibited items</span><a class="anchor" id="prohibited-items" href="#prohibited-items" onclick="$('#prohibited-items').ScrollTo();"></a></h4>
The jayascript code is below:
$(document).ready(function(){
$('h4').each(function(){
$(this).data('anchor',$(this).find('span').text());
});
});
Hope this helps.
I'm using a small javascript to display a question mark icon with a explanatory tooltip next to product options on our ecommerce (bigcommerce) site. As it is, the script shows the icon for every product option, whether I've specified the content or not.
The content of the tooltip is set by using the following in the description section on the page:
<span id="[name of option]" style="display:none">[content of tooltip]</span>
If the content for the tooltip is not set, it displays "Description not available yet"
Here's an example of a page where the content is set:
http://www.www-savvyboater-com.mybigcommerce.com/carver-pontoon-bimini-top-sunbrella-a9sq4893ub
And here's an example of how it looks without the content set:
http://www.www-savvyboater-com.mybigcommerce.com/carver-bimini-top-double-duck-d5457ub
What I'd like is for the question mark icon to only show for the options where I've specified content for the tooltip. I don't know enough about javascript to figure it out on my own.
Here's the script in question:
$(document).ready(function() {
$(".productAttributeValue").each(function() {
var optionLabel = $(this).siblings('div');
var optionLabelText = optionLabel.children("label").children("span.name").text();
if ($("img", this).length < 1) {
$(this).siblings('div')
.children("label")
.children("span.name")
.append(" <div class='help_div' style='display: inline;'><img src='/product_images/uploaded_images/help.gif' alt='" + optionLabelText + "'/></div>");
}
});
$('.help_div').each(function() {
var slug = slugify($("img", this).prop('alt'));
var html = $("#" + slug).html();
var titleq = $("img", this).prop('alt').replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
titleq = "<strong style='font-size: 12px'>" + titleq + "</strong><br/>"
if (!html) html = "Description not available yet."
$(this).qtip({
content: titleq + html,
position: {
corner: {
tooltip: 'topRight',
target: 'bottomLeft'
}
},
style: {
tip: {
corner: 'rightTop',
color: '#6699CC',
size: {
x: 15,
y: 9
}
},
background: '#6699CC',
color: '#FFFFFF',
border: {
color: '#6699CC',
}
}
});
});
function slugify(text) {
text = text.replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
text = text.replace(/-/gi, "_");
text = text.replace(/^\s+|\s+$/g, "");
text = text.replace(/\s/gi, "-");
text = text.toLowerCase();
return text;
}
});
The best way to do this is to not create the HTML for the ? in the first place.
$(document).ready(function() {
$(".productAttributeValue").each(function() {
var optionLabel = $(this).siblings('div');
var optionLabelText = optionLabel.children("label").children("span.name").text();
// check that optionLabelText is not an empty string
if ($("img", this).length < 1 && slugify(optionLabelText).trim().length) {
$(this).siblings('div')
.children("label")
.children("span.name")
.append(" <div class='help_div' style='display: inline;'><img src='/product_images/uploaded_images/help.gif' alt='" + optionLabelText + "'/></div>");
}
});
$('.help_div').each(function() {
var slug = slugify($("img", this).prop('alt'));
var html = $("#" + slug).html();
var titleq = $("img", this).prop('alt').replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
titleq = "<strong style='font-size: 12px'>" + titleq + "</strong><br/>"
if (!html) html = "Description not available yet."
$(this).qtip({
content: titleq + html,
position: {
corner: {
tooltip: 'topRight',
target: 'bottomLeft'
}
},
style: {
tip: {
corner: 'rightTop',
color: '#6699CC',
size: {
x: 15,
y: 9
}
},
background: '#6699CC',
color: '#FFFFFF',
border: {
color: '#6699CC',
}
}
});
});
function slugify(text) {
text = text.replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
text = text.replace(/-/gi, "_");
text = text.replace(/^\s+|\s+$/g, "");
text = text.replace(/\s/gi, "-");
text = text.toLowerCase();
return text;
}
});
If that is not possible then there are two ways to handle this:
Hide the ? in CSS by default and then show them using javascript if data exists
.help_div {
display:none;
}
And in your javascript:
var slug = slugify($("img", this).prop('alt'));
var html = $("#" + slug).html();
var titleq = $("img", this).prop('alt').replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
titleq = "<strong style='font-size: 12px'>" + titleq + "</strong><br/>"
if (html) {
$(this).show();
}
Have the ? visible by default but destroy them if no data is found:
In your javascript:
var slug = slugify($("img", this).prop('alt'));
var html = $("#" + slug).html();
var titleq = $("img", this).prop('alt').replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
titleq = "<strong style='font-size: 12px'>" + titleq + "</strong><br/>"
if (!html) {
$(this).remove();
}
Option 1 has less chance of causing issues/being jarring but it's up to you how you would like to implement this.
function createList() {
var list = '';
var listID;
$.each(obj_JSON.colors, function(index, value) {
listID = "clr_" + index;
list = list + "<div id=" + listID + " alt='" + obj_JSON.colors[index].name + "'></div>"
clrList.html(list);
updateListColours(listID);
});
}
function updateListColours(x) {
$('#' + x).css({"background-color":"rgb(255, 0, 0)", "height":"25px", "width":"25px"});
}
When I watch it get created. The first div gets the style applied to it. Then the second gets created and the style is wiped from the first div and applied to the second and it goes on until the list is complete...
Why is this happening and how can I apply the style to each div? Expecting answer that shows i've done something really stupid as usual
Because this line clrList.html(list);, you are removing the previous element then add new created.
Instead, do it with:
$.each(obj_JSON.colors, function(index, value) {
listID = "clr_" + index;
list = "<div id=" + listID + " alt='" + obj_JSON.colors[index].name + "'></div>"
clrList.append(list);
updateListColours(listID);
});
There's a much easier solution:
function createList() {
$.each(obj_JSON.colors, function() {
var d = document.createElement('div');
d.setAttribute("alt",this.name);
d.className = "listcolour";
clrList.appendChild(d);
// ^ assumes `clrList` is a DOM node, not a jQuery object
});
}
And CSS:
.listcolour {
width: 25px;
height: 25px;
background-color: #f00;
}