Add div to javascript code - javascript

Trying to add a div around some javascript code.
Here's the code I'm trying to modify:
slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>');
if (slider.pagingCount > 1) {
for (var i = 0; i < slider.pagingCount; i++) {
slide = slider.slides.eq(i);
item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>';
if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) {
var captn = slide.attr( 'data-thumbcaption' );
if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>';
}
slider.controlNavScaffold.append('<li>' + item + '</li>');
j++;
}
}
Here's the resulted outcome when you add <div class="container"> before the <ol> and closing </div> tag after </ol> in the code above...as you can see the list closes before list items make it inside:
<div class="container"><ol class="flex-control-nav flex-control-paging"></ol><li><a>1</a></li><li><a>2</a></li><li><a>3</a></li><li><a>4</a></li></div>
Here's what I'm trying to output.
<div class="container"><ol class="flex-control-nav flex-control-paging"><li><a class="">1</a></li><li><a class="flex-active">2</a></li><li><a>3</a></li><li><a>4</a></li></ol></div>
Code that isn't working:
slider.controlNavScaffold = $('<div class="container"><ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol></div>');
if (slider.pagingCount > 1) {
for (var i = 0; i < slider.pagingCount; i++) {
slide = slider.slides.eq(i);
item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>';
if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) {
var captn = slide.attr( 'data-thumbcaption' );
if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>';
}
slider.controlNavScaffold.append('<li>' + item + '</li>');
j++;
}
}

You didn't post it, but I suspect that you changed that first line to
slider.controlNavScaffold = $('<div><ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol></div>');
That will cause the code to do exactly what you describe, because the .append() calls will append to the outer element (the <div>).
Instead, leave that first line alone, and then at the end — after the <li> elements have been added — add this:
slider.controlNavScaffold.wrap( $('<div/>', { "class": "container" }) );
After that, in order to have things work properly when you actually add the stuff to the DOM, you'll want to find the parent of the <ol> and make sure that that's what you add:
slider.controlNavWrapper = slider.controlNavScaffold.parent();
(or however you want to keep track of it).

Related

How to run an if statement inside of an append statement

I'm trying to run an if statement inside of an append but it seems to come out as true regardless of what I expect the result to be. The problematic code is on lines 13 and 14, Code:
I've tried declaring it using the typical method of...
if(xxx != "false") but this broke the entire page and no JS ran.
$.getJSON("https://raw.githubusercontent.com/Fazyyy/Fazyyy.github.io/master/data/product.json", function(posts) {
for(var post = 0; post < posts.length; post++) {
$(".posts").append("<li " +
"data-price='"+ posts[post].price + "'" +
"data-reviews='"+ posts[post].reviews + "'" +
"data-name='"+ posts[post].name + "'" +
"data-saving='"+ posts[post].was_price + "'" +
">" +
"<div class='spacer'>" +
"<img src='./img/" + posts[post].img +".jpg' />" +
"<h2>" + posts[post].name + "</h2>" +
"<p>" + "£<span class='price'>" + posts[post].price + "</span></p>" +
( posts[post].was_price != "false" ? "<p class='red'>£<span class='strike'>" + posts[post].was_price + "</span></p>" : '<p></p>') +
( posts[post].reviews != "false" ? "<p class='reviews'>" + posts[post].reviews + "% reviews score" : '<p></p>') +
"<p><a href='#' class='basket'>Add To Basket</a></p>" + "</div>" + "</li>"
);
}
});
Quick answer is don't.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
you should abstract your problems following the DRY principles 'dont repeat yourself' and focus on making it easy to read and everything just has one responsibility.
you can see in my example that it almost looks like it would in html but in your example you have to struggle to parse the logic.
Another few things to note was you were doing something != 'false' where you had to do != instead of !== because you were comparing 'false' to false. read up on type equality
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
$.getJSON("https://raw.githubusercontent.com/Fazyyy/Fazyyy.github.io/master/data/product.json", function(posts = []) {
// appending only after we've created all posts to stop appending multiple times
appendToPosts(posts.reduce((acc, post) => acc + createPost(post), ''))
});
function appendToPosts(html) {
$(".posts").append(html);
}
function createPost(post) {
return `<li
data-price='${post.price}'
data-reviews='${post.reviews}'
data-name='${post.name}'
data-saving='${post.was_price}'>
<div class='spacer'>
<img src='./img/${post.img}.jpg' />
<h2>${post.name}</h2>
<p>£<span class='price'>${post.price}</span></p>
${hasPreviousPrice(post)}
${hasReviews(post)}
</div>
</li>`;
}
function hasPreviousPrice(post) {
return post.was_price ?
`<p class='red'>£<span class='strike'>${post.was_price}</span></p>` :
``
}
function hasReviews(post) {
return post.reviews ?
`<p class='reviews'>${post.reviews}% reviews score` :
`<p><a href='#' class='basket'>Add To Basket</a></p>`
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="posts"></div>
Here's another approach. This one does not append multiple times, as it's a more expensive operation.
const productTmpl = ({was_price, reviews, price, name, img}) => {
const wasPriceNode = was_price
? `<p class="red">£<span class="strike">${was_price}</span></p>`
: "<p></p>"
const reviewsNode = reviews
? `<p class="reviews">${reviews}% reviews score</p>`
: "<p></p>"
return `
<li data-price="${price}"
data-reviews="${reviews}"
data-name="${name}"
data-saving="${was_price}"
>
<div class="spacer'">
<img src="./img/${img}.jpg"/>
<h2>${name}</h2>
<p>£<span class="price">${price}</span></p>
${wasPriceNode}
${reviewsNode}
<p>
Add To Basket
</p>
</div>
</li>
`;
}
$.getJSON(
"https://raw.githubusercontent.com/Fazyyy/Fazyyy.github.io/master/data/product.json",
products => {
const listItems = products.reduce((acc, cur) => acc + productTmpl(cur), "");
$(".posts").html(listItems);
}
);

Issue trying to escape a string in javascript plugin

I'm trying to use a Bootstrap Tab plugin for CKEditor, and it works well. But, when i use a single quote on content (doesn't matter if the string is "'", or " or '), it broke up.
I guess is just a escape issue. I tried with escape() and encodeURI(), but fails.
Error: SyntaxError: missing ) after argument list;
Source:
x)PRE3015 Pino 1/2'' 15mm Ponta Balistica Aço 3,1 15
The piece of plugin code for tabs is:
data: function() {
var bootstrapTab_d = new Date();
var bootstrapTab_id = bootstrapTab_d.getTime();
var bootstrapTab_item = bootstrapTab_contents = '';
for (var bootstrapTab_i = 0; bootstrapTab_i <= this.data.bootstrapTab_total; bootstrapTab_i++) {
eval("bootstrapTab_title = this.data.bootstrapTab_item" + bootstrapTab_i);
bootstrapTab_title = bootstrapTab_title != undefined ? bootstrapTab_title : '';
eval("bootstrapTab_content = this.data.bootstrapTab_content" + bootstrapTab_i);
bootstrapTab_content = bootstrapTab_content != undefined ? bootstrapTab_content : '';
eval("bootstrapTab_itemClass = this.data.bootstrapTab_itemClass" + bootstrapTab_i);
bootstrapTab_itemClass = bootstrapTab_itemClass != undefined ? bootstrapTab_itemClass : '';
eval("bootstrapTab_contentClass = this.data.bootstrapTab_contentClass" + bootstrapTab_i);
bootstrapTab_contentClass = bootstrapTab_contentClass != undefined ? bootstrapTab_contentClass : '';
if (bootstrapTab_title) {
bootstrapTab_item += '<li role="presentation" class="' + bootstrapTab_itemClass + '">' + bootstrapTab_title + '</li>';
bootstrapTab_contents += '<div role="tabpanel" class="' + bootstrapTab_contentClass + '" id="tab' + bootstrapTab_id + '_' + (bootstrapTab_i + 1) + '">' + bootstrapTab_content + '</div>'
}
}
this.element.setAttribute('id', 'collapse' + bootstrapTab_id);
this.element.$.innerHTML = '<div role="tabpanel"><ul class="nav nav-tabs" role="tablist">' + bootstrapTab_item + '</ul><div class="tab-content">' + bootstrapTab_contents + '</div></div>'
}
I'd refactor the code, and not use eval!
eval is evil http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx
instead of
eval("bootstrapTab_title = this.data.bootstrapTab_item" + bootstrapTab_i);
use bootstrapTab_item as an array and do this
bootstrapTab_title = this.data.bootstrapTab_item[bootstrapTab_i]
really don't know if the error is there, but I think the path to find the error is refactor to eliminate those eval, that could be the source of your problem.

How to find a file with javascript?

My app is looking into a folder and then show all folders and html file inside it in a dropdown menu, and display any html files inside an iframe. I have a file called "highlighted.html" which I don't want to show in the dropdown menu, but if it is in the current directory I do want to show it automatically in an iframe.
This is my code to show what is in folder:
First function create a dropdown box loading dynamically folders or files (with html extension).
In second function: if click on an existing subfolder, then open that folder and look inside for html file(s) to open it in a iframe
function rendSelects($currentSelectItem, strPath) {
var currentSelectLevel = (null === $currentSelectItem ? -1 : parseInt($currentSelectItem.attr('data-selector-level'))),
nextOneSelectorHtml =
'<select ' +
'class="dropdown selectpicker" ' +
'name="dd" ' +
'data-selector-level="' + (currentSelectLevel + 1) + '" ' +
'data-path="' + strPath + '" ' +
'onchange="onFsSelectChange(this)"' +
'><option text selected> -- select an option -- </option>';
$('div.selectors-container select.dropdown').each(function (i, el) {
if (parseInt(el.getAttribute('data-selector-level')) > currentSelectLevel) {
el.parentNode.removeChild(el);
$(el).selectpicker('destroy');
}
});
if (fsStructure[strPath].subfolders.length > 0) {
for (var i = 0; i < fsStructure[strPath].subfolders.length; i++) {
nextOneSelectorHtml +=
'<option ' +
'class="subfolder-option" ' +
'data-subfolder="' + fsStructure[strPath].subfolders[i] + '" >' + fsStructure[strPath].subfolders[i] +
'</option>';
}
}
if (fsStructure[strPath].subshtmls.length > 0) {
for (var i = 0; i < fsStructure[strPath].subshtmls.length; i++) {
nextOneSelectorHtml +=
'<option ' +
'class="html-page-option" ' +
'data-html-page-name="' + fsStructure[strPath].subshtmls[i] + '">' + fsStructure[strPath].subshtmls[i] +
'</option>';
}
}
nextOneSelectorHtml += '</select>';
$('div.selectors-container').append(nextOneSelectorHtml);
$('div.selectors-container').trigger('dropdownadded.mh');
}
function onFsSelectChange(el) {
var currentSelectorPath = el.getAttribute('data-path'),
selectedOption = el.options[el.selectedIndex];
if (selectedOption.classList.contains('subfolder-option')) {
loadFolderStructure(currentSelectorPath + '/' + selectedOption.getAttribute('data-subfolder'), $(el))
}
if (selectedOption.classList.contains('html-page-option')) {
playSwf(currentSelectorPath + '/' + selectedOption.getAttribute('data-html-page-name'));
}
}
I have provided a working demo at http://tdhtestserver.herobo.com/.
SOLVED
Well. If highlighted.html does exist in folder, no select constitution. Let's display an iFrame with src=highlighted.html IIUC. Am I OK ?
First function create a dropdown boxes where it load dynamically folders or files with html extension.
Ok, so let's check if highlighted.html is here.
function rendSelects($currentSelectItem, strPath) {
//here : (begin of change)
if(strPath.indexOf("hightlighted")>=0) {
$("#myiFrame").attr('src', /path/to/highlighted)
}
// enfd of change. The continue as :
var currentSelectLevel = (null === $currentSelectItem ? -1 : parseInt($currentSelectItem.attr('data-selector-level'))),
nextOneSelectorHtml =....
ACTUALLY, the matter is to choose between : 1. $(myframeid).attr(src...) AND 2. $('div.selectors-container').append(nextOneSelectorHtml); /// you have to "render" 1 or 2, depending on finding highlighted in or not.
function rendSelects($currentSelectItem, strPath) {
//1of3 // let's add a boolean
var is_highlighted_here = false;
var highlighted_path="";
//done.
var currentSelectLevel = (null === $currentSelectItem ? -1 : parseInt($currentSelectItem.attr('data-selector-level'))),
nextOneSelectorHtml =
'<select ' +
'class="dropdown selectpicker" ' +
'name="dd" ' +
'data-selector-level="' + (currentSelectLevel + 1) + '" ' +
'data-path="' + strPath + '" ' +
'onchange="onFsSelectChange(this)"' +
'><option text selected> -- select an option -- </option>';
$('div.selectors-container select.dropdown').each(function (i, el) {
if (parseInt(el.getAttribute('data-selector-level')) > currentSelectLevel) {
el.parentNode.removeChild(el);
$(el).selectpicker('destroy');
}
});
if (fsStructure[strPath].subfolders.length > 0) {
for (var i = 0; i < fsStructure[strPath].subfolders.length; i++) {
nextOneSelectorHtml +=
'<option ' +
'class="subfolder-option" ' +
'data-subfolder="' + fsStructure[strPath].subfolders[i] + '" >' + fsStructure[strPath].subfolders[i] +
'</option>';
}
}
if (fsStructure[strPath].subshtmls.length > 0) {
for (var i = 0; i < fsStructure[strPath].subshtmls.length; i++) {
// 2of3 // oh !! look at here :
if( fsStructure[strPath].subshtmls[i].indexOf("highlighted")>=0 )
{
s_highlighted_here=true;
highlighted_path = fsStructure[strPath].subshtmls[i];
}
//done. scroll to bottom.
nextOneSelectorHtml +=
'<option ' +
'class="html-page-option" ' +
'data-html-page-name="' + fsStructure[strPath].subshtmls[i] + '">' + fsStructure[strPath].subshtmls[i] +
'</option>';
}
}
nextOneSelectorHtml += '</select>';
// 3of3 // here finally
if(is_highlighted_here) {
$("#myiFrame").attr('src', highlighted_path);
}
else {
$('div.selectors-container').append(nextOneSelectorHtml);
$('div.selectors-container').trigger('dropdownadded.mh');
}
}//function end
Well, if i display only changed :
- at the very function start :
//1of3
var is_highlighted_here = false;
var highlighted_path="";
when parsing the folder struct :
// 2of3 // oh !! look at here :
if( fsStructure[strPath].subshtmls[i].indexOf("highlighted")>=0 )
{
s_highlighted_here=true;
highlighted_path = fsStructure[strPath].subshtmls[i];
}
And finally, when rendering :
// 3of3
if(is_highlighted_here) {
$("#myiFrame").attr('src', highlighted_path);
}
else {
$('div.selectors-container').append(nextOneSelectorHtml);
$('div.selectors-container').trigger('dropdownadded.mh');
}
I answer on my question because some of you haven't understood my issue or they don't know how to do it. So I found that was so easy and all i've done was only one line of code.
high( currentSelectorPath + '/'+selectedOption.getAttribute('data-subfolder')+'/highlighted.html');
This line was changed everything, where high is a new iframe
function onFsSelectChange( el ) {
var
currentSelectorPath = el.getAttribute('data-path'),
selectedOption = el.options[el.selectedIndex];
if ( selectedOption.classList.contains('subfolder-option') ) {
loadFolderStructure( currentSelectorPath + '/' + selectedOption.getAttribute('data-subfolder'), $(el) )
high( currentSelectorPath + '/'+selectedOption.getAttribute('data-subfolder')+'/highlighted.html');
}
if ( selectedOption.classList.contains('html-page-option') ) {
playSwf( currentSelectorPath + '/' + selectedOption.getAttribute('data-html-page-name') );
}
}

Give condition from value that have called

Hello i'd like to put condition for my code in javascript if the code has already called, so after the _edg.source it wont to called again:
for (var j in GexfJS.graph.edgeList) {
var _edg = GexfJS.graph.edgeList[j]
if ( (_edg.target == _curra) && (_edg.source != _nodeIndex) && (_edg.target != _n)) {
var _nod = GexfJS.graph.nodeList[_edg.source];
if(_n != _nod){
_str += '<li><div class="smallpill" style="background: ' + _nod.color.base +'"></div>' + _nod.label + 'b' + ( GexfJS.params.showEdgeWeight && _edg.weight ? ' [' + _edg.weight + ']' : '') + '</li>';
}
}
}
}
try to use condition with an object and set the true value after the value has called, insert this code after the var _nod
check={};
if(check[_nod.label] != true){
......
}
check[_nod.label] = true;

When to combine common functionality? - A public static object w/ initialization

This is a common occurence when I code...I see some code that looks kind of alike..and I know that it is obviously not good to have redundant functionality in my code.
However , is this absolute? 0 Redundancy? I have two functions below, which look kind of alike. ViewH.bookmark and ViewH.tweet.
I'm trying to decide if I should pull out the common functionality into a function called ViewH.mark().
EDIT
var ViewH = {
MARK:
{
FIELD: '|',
ROW: '||',
PASS: '<xx_p>',
FAIL: '<xx_f>'
},
return_string: '',
mark: function(passed_function, embeddedAml)
{
var return_string,
first_split,
element_count,
second_split;
return_string = '';
first_split = embeddedAml.split( ViewH.MARK.ROW );
for( element_count=0; element_count < first_split.length; element_count++)
{
second_split = first_split[element_count].split( ViewH.MARK.FIELD );
passed_function(second_split);
}
return ViewH.return_string;
},
bookmark: function ( embeddedAml )
{
ViewH.return_string='';
return ViewH.mark(ViewH.bookmark_inner, embeddedAml);
},
tweet: function ( embeddedAml )
{
ViewH.return_string='';
return ViewH.mark(ViewH.tweet_inner, embeddedAml);
},
portfolio: function ( embeddedAml )
{
ViewH.return_string='';
return ViewH.mark(ViewH.portfolio_inner, embeddedAml);
},
bookmark_inner: function ( second_split )
{
ViewH.return_string = ViewH.return_string
+ '<img name="bo_im" class="c" src="'
+ 'http://www.google.com/s2/favicons?domain='
+ second_split[0]
+ '" onerror="Arc.BookmarkError(this)"><a target="_blank" name="bookmark_link" class="b" href = "'
+ second_split[1]
+ '">'
+ second_split[2]
+ '</a>';
},
tweet_inner: function ( second_split )
{
ViewH.return_string = ViewH.return_string
+ '<div class="Bb2b"><img class="a" src="'
+ Constant.PICTURES + second_split[ 0 ]
+ '.jpg" alt=""/><a class="a" href="javascript:void(0)\">'
+ second_split[ 1 ]
+ ' posted '
+ ViewH.pretty( second_split[ 2 ],second_split[ 3 ] )
+ '</a><br/><p class="c">'
+ second_split[ 4 ]
+ '</p></div>';
},
portfolio_inner: function ( second_split )
{
if( ( second_split[ 1 ] === 'docx' ) || ( second_split[ 1 ] === 'xlsx' ) )
{
ViewH.return_string = ViewH.return_string
+ '<img name="bo_im" class="c" src="'
+ Constant.IMAGES + second_split[1]
+ '.ico"><a target="_blank" name="bookmark_link" class="b" href = "/'
+ Constant.ROOT
+ second_split[1]
+ '/'
+ second_split[0]
+ '.'
+ second_split[1]
+ '">'
+ second_split[0]
+ '.'
+ second_split[1]
+ '</a>';
}
else
{
ViewH.return_string=ViewH.return_string
+ '<simg name="bo_im" class="c" src="'
+ Constant.IMAGES
+ 'generic'
+ '.ico"><a target="_blank" name="bookmark_link" class="b" href = "'
+ Constant.TEXT
+ second_split[0]
+ '.txt">'
+ second_split[0]
+ '.'
+ second_split[1]
+ '</a>';
}
},
This is a great question, but there is no answer that will apply to all cases. It really is going to depend on what your code looks like. Redundancy is generally to be avoided but it is sometimes worse to over-engineer your code and try to make it fit into a box that it does not really fit into.
In your case you could definitely benefit from taking common code and pulling it into a common method. It looks like the only difference between your methods is the rendering part and it would be simple to pass a rendering function into your "mark" method.
Your "mark" method would look a bit like this:
mark: function(embeddedAml, renderer) {
var return_string,
first_split,
element_count,
second_split;
return_string = '';
first_split = embeddedAml.split( ViewH.MARK.ROW );
for( element_count=0; element_count < first_split.length; element_count++)
{
second_split = first_split[element_count].split( ViewH.MARK.FIELD );
return_string = return_string + renderer(second_split);
}
return return_string;
}
You would keep your bookmark and tweet methods but they would change as well:
bookmark: function (embeddedAml) {
return this.mark(embeddedAml, function(data) {
return '<img name="bo_im" class="c" src="' +
'http://www.google.com/s2/favicons?domain=' +
data[0] +
'" onerror="Arc.BookmarkError(this)"><a target="_blank" name="bookmark_link" class="b" href = "' +
data[1] + '">' +
data[2] + '</a>'
});
}
Now your rendering code (the only code that was different) is controlled independently, but the code that overlapped is in a common place and if it changes you only have to update it in one place.
Generally, yes.
One deciding factor is whether the code is similar coincidentally, or because it performs a similar task. If the latter is true, should you change the functionality of one in the future (particularly that part of the functionality which is shared), will you also want to change the functionality in the other? If so, that makes your decision easy - merge the code where you can.
Even if the code is similar coincidentally, it may still make sense to create a generic library function that cleans up your code.
I would definitely attempt to combine them. You'll notice that the body of the for loop is the only thing that's different between the two. Here's one approach (most of ViewH elided):
var ViewH = {
bookmark: function(embeddedAml) {
return ViewH.combinedFunc(embeddedAml, function(parts) {
return '<img name="bo_im" class="c" src="' +
'http://www.google.com/s2/favicons?domain=' +
parts[0] +
'" onerror="Arc.BookmarkError(this)"><a target="_blank" name="bookmark_link" class="b" href = "' +
parts[1] + '">' +
parts[2] + '</a>';
});
},
combinedFunc: function (embeddedAml, handler) {
var return_string,
first_split,
element_count,
second_split;
return_string = '';
first_split = embeddedAml.split(ViewH.MARK.ROW);
for(element_count=0; element_count < first_split.length; element_count++) {
second_split = first_split[element_count].split(ViewH.MARK.FIELD);
return_string = return_string + handler(second_split);
}
return return_string;
},
}
You could easily do the same thing for tweet. Clearly, you'll want to name the function something better than combinedFunc, but you'll need to choose that name based on context.

Categories

Resources