jQuery and creating HTML are strings required - javascript

I have written the below code to be an e-mail signature.
What I am confused about is what is the best way to split it up (Do I have to? I have seen some places split every line up into a string) so that I can fill in the variables that I have set within my jQuery.
This is a snippet of my code however I have a form that allows me to generate the below HTML code within a textbox for copying (But I just need to know the best way to fill it in) :)
I have also included my current jQuery snippet so you can get an idea of what I have
HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div style="width:500px; height:459px;">
<div>
<p style="margin:0 0 5px 10px; font-weight:bold; font-size:18px;">
Name</p>
<p style="margin:0 0 5px 10px; font-weight:bold; font-size:18px;">
Position</p>
<p style="margin:0 0 5px 10px; font-weight:bold; font-size:18px;">
Lodge</p>
</div>
<div><img alt="Lodge" height="164" src=
"Logo Url" style=
"margin:10px 0 0 0;" width="257"></div>
<div>
<p style="margin:0 0 0 10px; color:#ccc; font-size:10px;">
Address</p>
<p style="margin:0 0 0 10px; font-size:10px">Email</p>
<p style="margin:0 0 0 10px; color:#ccc; font-size:10px">Phone</p>
<p style="margin:0 0 0 10px; font-size:10px"><span>Website</span> |
<span>Facebook</span></p>
</div>
<div>
<p style=
"margin:5px 0 0 10px; font-weight:bold; font-size:13px; font-style: italic;">
"Company Slogan."</p>
</div>
<div><img alt="2015 Award" height="57" src=
"Award Url" style=
"margin:10px 0 0 0;" width="266"></div>
</div>
</body>
</html>
JS:
$(document).ready(function() {
var name = $('#name').val();
var position = $('#position').val();
var phone = $('#phone').val();
var email = $('#email').val();
var lodge = $('#lodge').val();
var address = $('#address').val();
var facebook = $('#facebook').val();
var website = $('#website').val();
var html = $('#showInline');
var file = $('#html');
$("#generate").click(function(){
if(html.is(':checked'))
{
$('#inlineDIV').fadeIn("slow");
}else
{
$('#inlineDIV').fadeOut("slow");
}
});
});

I would change placeholders to something more specific like
<p style="margin:0 0 5px 10px; font-weight:bold; font-size:18px;">[[[NAME]]]</p>
and then I would load template into single string, no need to do it line by line.
Then I would simply do var updatedTemplate = bareTemplate.replace('[[[NAME]]]',name)
You could also give ID's to your template like:
<p id="name" style="margin:0 0 5px 10px; font-weight:bold; font-size:18px;">Name</p>
Then create element from template like:
var templateElement = $(bareTemplate)
and operate on it like:
templateElement.find("#name").text(name)
Where bareTemplate is this html posted in question.
If you load template to file then bareTemplate would be contents of file as string.
https://jsfiddle.net/gv2q6oos/1/

Related

Click to reveal div using Javascript

Is there a more efficient way of creating this function with Javascript.
As you can see in the demo, the first block works fine but not the second block. I plan to roll this out across hundreds of categories, so wonder if there's a neater solution here.
const btn = document.getElementById("category36SeeMore");
btn.addEventListener("click", function(e){
e.preventDefault();
const id = this.id.replace('SeeMore', '')
document.querySelectorAll('.' + id).forEach(el=>el.style.display = 'block')
});
.category36 {
margin: 5px;
padding: .5rem;
box-shadow: 2px 2px 5px rgba(0,0,0,0.03);
border-radius: 4px;
background: Skyblue;
border-bottom: 1px solid #F9F2D6;
border-right: 1px solid #F9F2D6;
}
<p>
See more
</p>
<div class="category36">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<hr>
<p>
See more
</p>
<div class="category37">
test
</div>
<div class="category37" style="display:none;">
test
</div>
<div class="category37" style="display:none;">
test
</div>
<div class="category37" style="display:none;">
test
</div>
Demo: https://jsfiddle.net/qzfesw5d/
Is jQuery a better approach here? We use that on the site already.
You have to target all the elements and loop through them to attach the event. You can either use attribute starts with selector or use a common class to target the elements:
const btnList = document.querySelectorAll("a[id^=category");
btnList.forEach(function(btn){
btn.addEventListener("click", function(e){
e.preventDefault();
const id = this.id.replace('SeeMore', '')
document.querySelectorAll('.' + id).forEach(el=>el.style.display = 'block')
});
});
.category36, .category37 {
margin: 5px;
padding: .5rem;
box-shadow: 2px 2px 5px rgba(0,0,0,0.03);
border-radius: 4px;
background: Skyblue;
border-bottom: 1px solid #F9F2D6;
border-right: 1px solid #F9F2D6;
}
<p>
See more
</p>
<div class="category36">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<hr>
<p>
See more
</p>
<div class="category37">
test
</div>
<div class="category37" style="display:none;">
test
</div>
<div class="category37" style="display:none;">
test
</div>
<div class="category37" style="display:none;">
test
</div>
If you're using plain javascript (like your example) you could apply the following logic:
Give a specific class to all your container like category-container
Instead of selection ONE using the ID, select them ALL using the classname
Loop over them to add the event
Make sure that the event will change the display of the children of the current parent
Adding new categories will not break anything. This should be entirely scalable.
Using jQuery might make things a little simpler. Here is one approach with plain JavaScript.
const categoryCount = 36
for (let i = 0; i < categoryCount; i++) {
const btn = document.getElementById(`category${i+1}SeeMore`)
if (btn) {
btn.addEventListener("click", e => {
e.preventDefault();
document.querySelectorAll(`.category${i+1}`)
.forEach(el => el.style.display = 'block')
})
}
}
You can change all ...SeeMore elements to class and then add data-* attribute to all to point to the collection that you want to show like:
See more
Then loop through each class and on click of any seemore, you can get the id easily using:
const id = this.dataset.id
and then easily show the collections divs like:
document.querySelectorAll('.category' + id).forEach(el=>el.style.display = 'block')
const btns = document.querySelectorAll(".SeeMore");
btns.forEach(function(btn) {
btn.addEventListener("click", function(e) {
e.preventDefault();
const id = this.dataset.id
document.querySelectorAll('.category' + id).forEach(el => el.style.display = 'block')
});
});
.category36, .category37 {
margin: 5px;
padding: .5rem;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.03);
border-radius: 4px;
background: Skyblue;
border-bottom: 1px solid #F9F2D6;
border-right: 1px solid #F9F2D6;
}
<p>
See more
</p>
<div class="category36">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<div class="category36" style="display:none;">
test
</div>
<hr>
<p>
See more
</p>
<div class="category37">
test
</div>
<div class="category37" style="display:none;">
test
</div>
<div class="category37" style="display:none;">
test
</div>
<div class="category37" style="display:none;">
test
</div>

Javascript manipulate HTML string

I have a string like this:
<!-- Offer Conversion: godaddy --> <iframe src="http://example.go2cloud.org/aff_l?offer_id=90" scrolling="no" frameborder="0" width="1" height="1"></iframe> <!-- // End Offer Conversion -->
godaddy
Now I wanna to toggle some parameter into src attribute based on a javascript event.
please see the JsFiddle
To manipulate HTML in string create empty element and set it's content with string. Later do what you want.
var string = '<!-- Offer Conversion: godaddy --> <iframe src="http://example.go2cloud.org/usr_l?offer_id=90" scrolling="no" frameborder="0" width="1" height="1"></iframe> <!-- // End Offer Conversion -->';
$('input').change(function() {
var content = $('<div>');
content.html(string);
var iFrameSrc = content.find('iframe').attr('src');
if ($('#e1').is(':checked')) {
iFrameSrc += '&e1='+$('#e1').val();
}
if ($('#e2').is(':checked')) {
iFrameSrc += '&e2='+$('#e2').val();
}
content.find('iframe').attr('src', iFrameSrc);
$('#result').show().text(content.html().replace(/&/g, '&'));
});
#result {
margin-top: 50px;
background: #dcfffb;
color: #044f47;
padding: 10px;
font-size: 1em;
font-family: monospace !important;
text-align: left;
direction: ltr;
border: 1px dotted #9dd3cd;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input id="e1" type="checkbox" value="someValue1"/>
<label for="e1">firstParam</label>
</div>
<div>
<input id="e2" type="checkbox" value="someValue2"/>
<label for="e2">secondParam</label>
</div>
<div id="result"></div>

forcing iframe submit to open in parent window

I am trying to embed a form on my wix website. The idea is that when someone submits the form, a "thank you" page will be displayed instead of the original parent page. Right now, the way the code is written, the "thank you" page is displayed upon submit, but is shown within the iframe, with scrolls up/down and to the sides. I want to force the "thank you" page to be displayed out of the iframe.
I'm a novice to coding, so I would really appreciate it if you could tell me what code I should enter and where in the code it should go. I've included the original code of the form.
Thanks in advance,
Anat
<!-- AT Popup Beta 2017 BEGIN -->
<link href="//cdn-media.web-view.net/popups/style/v1/main_combined.css" rel="stylesheet" type="text/css" />
<div id="_atPopupSU" class="shown"><div class="bl-template row-fluid bl-content-removable popup-dir-ltr" id="template-body" data-page-width="383" data-new-from-template="false"> <!-- BEGIN TEMPLATE OUTER --> <div class="bl-template-main-wrapper span12" id="bl_0" valign="top"> <!-- BEGIN TEMPLATE MARGIN (Outside Margin - Padding) --> <div class="bl-template-margin span12" id="bl_1" valign="top"> <!-- BEGIN TEMPLATE WRAPPER (Background) --> <div class="template-main-table bl-template-background span12" id="bl_2" valign="top"> <!-- BEGIN TEMPLATE CONTAINER (Border, Inner Padding) --> <div class="bl-template-border span12" id="bl_3" valign="top"> <!-- BEGIN ZONES CONTAINER --> <!--zone-marked--> <div class="bl-zone bl-zone-dropable bl-zone-body row-fluid" id="bl_4" style="margin-top: 0px !important; background-color: transparent;" name="BodyZone" valign="top" height=""> <div class="bl-block bl-block-signuptextpage" id="bl_5" blocktype="signuptextpage" name="signuptextpage" style="width: 383px;"><div class="bl-block-content" contenteditable="false"> <div> <div class="bl-block-content-table bl-block-dir-ltr span12"> <div class="bl-block-content-row bl-block-content-first-row bl-block-content-last-row span12" style="border-radius: 10px;"> <div class="bl-block-content-row-inner span12" style="padding: 50px 20px 18px;"><div class="bl-block-content-column bl-block-content-new-column span12"><div class="bl-padding-columns bl-content-wrapper span12"> <div class="bl-signup-container pull-left span12" at-form-width="12" style="border: 0px solid #191919; border-radius: 5px; padding: 8px 10px; background-color: transparent;"> <div class="bl-block-content-item bl-block-content-item-signupfieldpage bl-content-item-unremovable fields-left" style="text-align: center; margin-bottom: 14px;" data-is-auto-fill="true"><input type="text" maxlength="50" class="signup-field span12 input-ltr first-input" readonly="readonly" data-field-type="email" data-field-source="Email" data-mandatory="true" placeholder="Email " data-field-validation-msg="This is not a valid email" style="font-size: 12px; margin-bottom: 14px; height: 30px; line-height: 12px; font-family: arial, helvetica, sans-serif; text-align: left;" data-custom-values="" data-input-type="text"><input type="text" maxlength="50" class="signup-field span12 input-ltr" readonly="readonly" data-field-type="text" data-field-source="Ext1" data-mandatory="false" placeholder="Full Name" data-field-validation-msg="This is not a valid full name" style="font-size: 12px; margin-bottom: 14px; height: 30px; line-height: 12px; font-family: arial, helvetica, sans-serif; text-align: left;" data-custom-values="" data-input-type="text"><div class="confirm-emails" data-field-validation-msg="Please approve in order to receive our emails" style="font-family: arial, helvetica, sans-serif;"> <div class="checkbox ltr"> <label style="cursor: auto;"> <input type="checkbox" disabled="disabled" style="text-align: left;"><label class="confirm-label dir-label" style="font-family: arial, helvetica, sans-serif; text-align: left; cursor: auto; font-size: 11px; color: #000000;">I approve receiving emails</label></label></div> </div></div> <div class="bl-padding-columns bl-content-wrapper-columns" style="text-align: center;"> <div class="bl-block-button-content-wrapper" style="display: block; border-radius: 5px; background-color: #4ea3a3;"> <div class="bl-block-button-content-item-wrapper" style="font-size: 16px; padding: 9px;"> <div class="bl-block-content-item bl-block-content-item-button bl-content-item-unremovable" style="min-width: 1px; min-height: 16px; display: block; text-align: center; text-decoration: none;"><span style="font-size:14px;"><strong><span style="color:#FFFFFF;"><span style="font-family:arial,helvetica,sans-serif;">Sign Up Now</span></span></strong></span></div> </div> </div> </div> </div> </div></div></div> </div> </div> </div> </div></div> </div> <!-- END ZONES CONTAINER --> </div> <!-- END TEMPLATE CONTAINER --> </div> <!-- END TEMPLATE WRAPPER --> </div> <!-- END TEMPLATE MARGIN --> </div> <!-- END TEMPLATE OUTER --></div></div>
<script type='text/javascript'>
(function () {
var _atpopq = window._atpopq || (window._atpopq = []);
window._atpopobj = {};
if (!_atpopq.loaded) {
var atpopjs = document.createElement('script');
atpopjs.type = 'text/javascript';
atpopjs.async = true;
atpopjs.src = '//cdn-media.web-view.net/popups/lib/v1/loader.min.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(atpopjs, s);
_atpopq.loaded = true;
}
_atpopq.push(['UserId', 'zzae3adduwau']);
_atpopq.push(['PopupId', 'z3zdad']);
_atpopq.push(['IsraelCode', '104']);
_atpopq.push(['CountryCode', '226']);
_atpopq.push(['IsEmbed', true]);
_atpopq.push(['IgnoreMainCss', true]);
_atpopq.push(['OnEventCallback', 'handleATPopupEvent']);
})();
</script>
<script type="text/javascript">
//Sample event handler function
function handleATPopupEvent(ev,args){
switch(ev){
case 'display':
//Do this when the popup is displayed
break;
case 'close':
//Do this when the popup gets closed by the user
break;
case 'submit':
//Do this when popup gets submitted and the user doesn't get redirected to a URL
break;
}
}
</script>
<!-- AT Popup Beta END -->
As I understand this part of code, you should just place the code line:
window.top.location.href = "http://www.yourthankyoupage.com";
in case of 'submit'.

Mulitple file inputs display issues with css and javascript

Hi have multiple input to upload 5 pictures, but the issue is that the css is not displaying properly (it only affect the first one for the text block) and the javascript is not reacting to the correct input.
So I have this html structure for the 5 input:
<div class="form-group col-md-12" id="imagesSup">
<label for="imagesSup" class="col-md-12">Images supplémentaires: </label>
<div class="image">
<img src='' class="conteneurImagesSup col-md-2" id="conteneurImagesSup0">
<p><span>Chargez une image</span></p>
<input type="file" name="imagesSup[]" id="imageSup0" class="inputImagesSup" style="display: none">
</div>
<div class="image">
<img src='' class="conteneurImagesSup col-md-2" id="conteneurImagesSup1">
<p><span>Chargez une image</span></p>
<input type="file" name="imagesSup[]" id="imageSup1" class="inputImagesSup" style="display: none">
</div>
<div class="image">
<img src='' class="conteneurImagesSup col-md-2" id="conteneurImagesSup2">
<p><span>Chargez une image</span></p>
<input type="file" name="imagesSup[]" id="imageSup2" class="inputImagesSup" style="display: none">
</div>
<div class="image">
<img src='' class="conteneurImagesSup col-md-2" id="conteneurImagesSup3">
<p><span>Chargez une image</span></p>
<input type="file" name="imagesSup[]" id="imageSup3" class="inputImagesSup" style="display: none">
</div>
<div class="image">
<img src='' class="conteneurImagesSup col-md-2" id="conteneurImagesSup4">
<p><span>Chargez une image</span></p>
<input type="file" name="imagesSup[]" id="imageSup4" class="inputImagesSup" style="display: none">
</div>
</div>
The css:
.conteneurImagesSup{
height: 160px;
border: dashed darkgrey medium;
border-radius: 5px;
margin-right: 25px;
text-decoration: none;
text-align: center;
padding: 0;
}
.image {
position: relative;
cursor:pointer;
}
.image p {
position: absolute;
top: 60px;
left: 0;
}
.image p span {
color: white;
font: bold medium Helvetica, Sans-Serif;
letter-spacing: -1px;
background: rgb(0, 0, 0); /* fallback color */
background: rgba(0, 0, 0, 0.7);
padding: 10px;
}
Which give us this result, where we can see the 4 text block missing:
And finally the javascript, when I add a picture I want it to be displayed in the corresponding field but, whatever the way I use to affect the img corresponding it only affects the last one:
for(var i=0; i<4; i++)
{
$("#conteneurImagesSup"+i).on('click', function(e){
e.preventDefault();
$("#imageSup"+i).trigger('click');
});
}
$(".inputImagesSup").change(function(event) {
$(this).siblings("img").attr('src',URL.createObjectURL(event.target.files[0]));
});
Which gives us:
I can only explain you the thing about the image always displayed in the last square.
you have a for loop :
for(var i=0; i<4; i++)
{
// smthg not relevent now
}
which is the same than :
var i = 0;
for (; i<4; i++){ // I want to explain you that i is declared out of the scope of the for loop.
}
So, when the following is run :
$("#conteneurImagesSup"+i).on('click', function(e){
//not relevant now
});
i has the value you want him to have.
But, when the "sub" function is called ($("#imageSup"+i).trigger('click');), i, that was declared out of the for scope, has currently the last value it had (4).
So, if you want to make it work correctly, you need to declare a new variable inside the scope of the for :
for(var i=0; i<4; i++)
{
var index = i;
$("#conteneurImagesSup"+i).on('click', function(e){
e.preventDefault();
$("#imageSup"+index).trigger('click');
});
}
I'm not sure as to why only the first square shows "Chargez une image", but have one remark:
If you want to match the last image (conteneurImagesSup4) also, make sure that the for loop's i reaches 4: for (var i = 0; i < 5; i += 1)
Ok I solved the jquery issue, you need to pass the i value to the event data or you will always have the last value of i. https://api.jquery.com/event.data/
But still cannot resolve the css problem.

CSS Lines Appearing

Edit: the issue seems to only appear on OSX Mavericks w/ Latest Google Chrome (for me)
I have an event log that posts messages from the top down, and with every message, small black lines are appearing at the bottom right of each message and I can't figure out why.
Here is a working version of my game, click "Hunt for Blood" and when a few event log messages stack up, you'll see what I'm talking about.
http://codepen.io/RUJordan/pen/dcwLC
Here's a picture as well:
Here is my CSS relevant to the log div and msg div
.msg {
float: left;
width:auto;
overflow:auto;
padding: 5px;
font-size: small;
}
.column {
padding:3px;
float: left;
width:30%;
border:1px solid black;
background-color:#222222;
} /* Hidden Elements */
.hp, .cycle, .gold, .log, .middleCol,
.battle, .hiddenCounter {
display:none;
}
And here is my HTML schema.
<!DOCTYPE html>
<html>
<head>
<title>A Vampire's Hunt</title>
<link rel="stylesheet" href="vamp.css">
</head>
<body>
<h1 class="title">A Vampire's Hunt</h1>
<div class="main">
<div id="stats" class="column">
<div>
<h3 class="miniTitle">Stats</h3>
<hr />
<span id="spanCounter" class="hiddenCounter noRed">You have been dead for <span id="counter">0</span> hour<span id="singularHours" class="noRed"></span>..</span>
<span id="spanInitMsg" class="spanInitMsg noRed">You are dead!</span>
</div>
<div id="divCycle" class="cycle">It is currently: <span id="cycle"></span></div>
<div>Blood: <span id="blood">0</span></div>
<div class="hp" id="hpDiv">HP: <span id="hp">20</span></div>
<div class="gold" id="goldDiv">Gold: <span id="gold">0</span></div>
<h3 class="miniTitle">Actions</h3>
<hr />
</div>
<div id="middleCol" class="column middleCol">
<div id="shop" class="shop">
<h4 class="miniTitle">A Dark Alleyway</h4>
<hr />
Herp Derp Derp
</div>
<div id="battle" class="battle">
<hr />
</div>
</div>
<div id="log" class="log column">
<h3 class="miniTitle">Event Log</h3>
<hr />
<div id="msg" class="msg"></div>
</div>
</div>
<script src="player.js"></script>
<script src="element.js"></script>
<script src="engine.js"></script>
<script src="vampire.js"></script>
<div class="footer">
Follow This Project on Github!
</div>
</body>
</html>
I do not think the JavaScript is the culprit, but just in case, here is the event log function, along with the functions it calls.
eventMsg : function(txt) {
this.addBorder("log");
this.showElement("log","block");
var msg = document.getElementById("msg");
txt = "-"+txt+"<br />"+msg.innerHTML;
msg.innerHTML = txt;
},
addBorder : function(id) {
document.getElementById(id).style.border = "1px solid black";
},
showElement : function(id,style) {
document.getElementById(id).style.display = style;
},
This appears to work on FireFox and Safari, but not on Chrome.
Try using display: inline-table on div id "log". Note that it uses inline CSS that is reset on each click, so you'll have to overwrite this, otherwise it won't work.
EDIT : display: table should work too.
The lines seem to appear because you had border-width: 0 0 1px 0; instead of this:
hr:before {
border-width: 0;
}
Although, I have not tested on other browsers, but it seems to work with chrome.
Chrome Version 31.0.1650.57 m
fixed the line issue by changing:
eventMsg : function(txt) {
this.addBorder("log");
this.showElement("log","block");
var msg = document.getElementById("msg");
txt = "-"+txt+"<br />"+msg.innerHTML;
msg.innerHTML = txt;
},
addBorder : function(id) {
document.getElementById(id).style.border = "1px solid black";
},
showElement : function(id,style) {
document.getElementById(id).style.display = style;
},
to:
eventMsg : function(txt) {
this.showElement("log","block");
var msg = document.getElementById("msg");
txt = "-"+txt+"<br />"+msg.innerHTML;
msg.innerHTML = txt;
},
addBorder : function(id) {
document.getElementById(id).style.border = "1px solid black";
},
showElement : function(id,style) {
document.getElementById(id).style.display = style;
},
Have another potential fix for you, change the css from:
.msg {
float: left;
width:auto;
overflow:auto;
padding: 5px;
font-size: small;
}
to
.msg {
float: left;
width:100%;
overflow:auto;
padding: 5px;
font-size: small;
}

Categories

Resources