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.
Related
I load a JSON file from a server with angular and Ionic.
This is my code:
$scope.showAlert = function(mo,di,mi,don,fr,sa,so) {
$ionicPopup.alert({
title: 'Success',
content: mo + "<br>" + di + "<br>" + mi + "<br>" + don + "<br>" + fr + "<br>" + sa+ "<br>" + so
}).then(function(res) {
console.log('Test Alert Box');
});
};
For the Item:
<i class="icon ion-ios-clock-outline links" ng-click="showAlert(item.openingHours[0], item.openingHours[1], item.openingHours[2], item.openingHours[3],
item.openingHours[4], item.openingHours[5], item.openingHours[6]
)"></i>
My Problem is that sometimes the results, for example item.openingHours[6] is undefined. I don't want a undefined text in my alert. How can I check if the value is undefined in the alert?
Use conditional (ternary) operator ?, to check that str is defined, if defined return the value with br, if not - empty string:
$scope.showAlert = function(mo, di, mi, don, fr, sa, so) {
function getStrWithBr(str) {
return str ? str + '<br/>' : '';
}
var content =
getStrWithBr(mo) +
getStrWithBr(di) +
getStrWithBr(mi) +
getStrWithBr(fr) +
getStrWithBr(sa) +
so || '';
...
From a short tutorial I started this widget script to grab posts on Blogger. In the theme I originally made it in, it works fine without error. However, when I try to use the exact same code in a new template I'm working on, it throws the error:
Uncaught TypeError: Cannot read property 'url' of undefined
For the love of god I cannot figure out why it's doing that. For debugging purposes I tried removing all other scripts, placing the code right after the <body> tag and just before the </body> tag.
I really don't know anything about scripting and did this widget as a starting point in learning, but it's been months since I messed with it. Looking at it now I just don't see the problem. Here is the script:
<script type="text/javascript">
//<![CDATA[
function postGrabber(json) {
// The Magic
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
// Thumbnail Stuff
var orgImgUrl = json.feed.entry[i].media$thumbnail.url ? json.feed.entry[i].media$thumbnail.url : 'http://1.bp.blogspot.com/-mxinHrJWpBo/VD6fqbvI74I/AAAAAAAAcn8/LslulDeOROg/s72-c/noimage-chalkboard.jpg';
var newImgUrl = orgImgUrl.replace('s72-c', 's' + imgSize + '-c');
var imgTag = '<a class="item-link-post" href="' + postUrl + '"><img class="item-img-thumbnail" src="' + newImgUrl + '" width="' + imgSize + '" height="' + imgSize + '"/></a>';
var authorName = json.feed.entry[i].author[0].name.$t;
var authorURL = json.feed.entry[i].author[0].uri.$t;
var authorOriImgUrl = json.feed.entry[i].author[0].gd$image.src;
var authorNewImgUrl = authorOriImgUrl.replace('s512-c', 's' + authorImgSize + '-c');
var authorImgTag = '<a class="item-link-author" href="' + authorURL + '" target="_blank" rel="nofollow"><img class="item-img-author" src="' + authorNewImgUrl + '" alt="' + authorName + '"/></a>';
// Standard Stuff
var postTitle = json.feed.entry[i].title.$t;
var postCommentCount = json.feed.entry[i].thr$total.$t;
var postSummary = json.feed.entry[i].summary.$t;
var entryShort = postSummary.substring(0, '' + summaryLength + '');
var entryEnd = entryShort.lastIndexOf(" ");
var postContent = entryShort.substring(0, entryEnd) + '...';
var postDate = json.feed.entry[i].updated.$t ? json.feed.entry[i].updated.$t : json.feed.entry[i].published.$t;
var shortDate = postDate.substring(0,10);
// Let's Make Options Here
var toggleImg = showImg ? '' + imgTag + '' : '';
var toggleTitle = showTitle ? '<h1 class="item-title">' + postTitle + '</h1>' : '';
var toggleSummary = showSummary ? '<p class="item-snippet">' + postContent + '</p>' : '';
var toggleDate = showDate ? '<span class="item-date">' + shortDate + '</span>' : '';
var toggleAuthorImg = showAuthorImg ? '' + authorImgTag + '' : '';
var toggleCommentCount = showCommentCount ? '<span class="item-comment-count">' + postCommentCount + '</span>' : '';
// The Output
var itemPost = '<div class="item-post"><div class="item-imgs">' + toggleImg + toggleAuthorImg + '</div>' + toggleCommentCount + '<a class="item-link" href=' + postUrl + '>' + toggleTitle + '</a>' + toggleSummary + toggleDate + '</div>';
// Let's Write It Down
document.write(itemPost);
}
}
//]]>
</script>
<script type="text/javascript">
// The Default Options
var imgSize = 96;
var summaryLength = 142;
var authorImgSize = 36;
var showImg = true;
var showTitle = true;
var showSummary = true;
var showDate = true;
var showAuthorImg = true;
var showCommentCount = true;
</script>
<script src="/feeds/posts/summary?orderby=published&max-results=5&alt=json-in-script&callback=postGrabber"></script>
In all those lines of code, the only reference I can see to a url property is here...
var orgImgUrl = json.feed.entry[i].media$thumbnail.url ? json.feed.entry[i].media$thumbnail.url : 'http://1.bp.blogspot.com/-mxinHrJWpBo/VD6fqbvI74I/AAAAAAAAcn8/LslulDeOROg/s72-c/noimage-chalkboard.jpg';
so, I'm guessing that what the error is saying is that json.feed.entry[i] doesn't have a property named media$thumbnail...it is "undefined". You need to correct that, whether it is a typing error or something else, make sure that that property exists.
If the property is "optional" then change your evaluation to check for the existence of that property as below...
var orgImgUrl = (json.feed.entry[i].media$thumbnail != null
&& json.feed.entry[i].media$thumbnail.url)
? json.feed.entry[i].media$thumbnail.url
: 'http://1.bp.blogspot.com/-mxinHrJWpBo/VD6fqbvI74I/AAAAAAAAcn8/LslulDeOROg/s72-c/noimage-chalkboard.jpg';
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).
Hit a slight bump on something.
So I have a spreadsheet feed coming through via json.
Once they are loaded, if they contain a certain word, I want an elment that is already on the page to do something.
Having some trouble.
Here is my code:
/*feed*/
function displayContent(json) {
var len = json.feed.entry.length
var divtag = ''
for (var i=0; i<len; i++) {
divtag += [
'<div id=' +' tooltipwrap' + i + '>' +
'<span style="font-size:22px; font-weight:600;">',
json.feed.entry[i].gsx$studentname.$t + ' ' +
'<span class="hide" style="font-size:18px; font-weight:300;">',
json.feed.entry[i].gsx$classlevel.$t
+ '</span>' + '<span id=' + 'tooltipside' + i +'>' +
json.feed.entry[i].gsx$gender.$t + '-' +
'</span>',
'</div>'
].join('');
}
document.getElementById('tipswrap').innerHTML = divtag
}
/* what I wanted to do */
if ($('#tooltipside0').html() === "Senior") {
$("#test1").addClass('no');
}
Here is the JSFiddle
Pay attention to the tabulation. Right now your code is hard to read because you have failed to do so.
Here:
var len = json.feed.entry.length
var divtag = ''
you are missing semi-colons. You have to put semi-colon at the end of any operation, like this:
var len = json.feed.entry.length;
var divtag = '';
Semi-colons serve as operation separators.
Here:
divtag += [
'' +
'',
json.feed.entry[i].gsx$studentname.$t + ' ' +
'',
json.feed.entry[i].gsx$classlevel.$t
+ '' + '' +
json.feed.entry[i].gsx$gender.$t + '-' +
'',
'</div>'
].join('');
You have multiple problems:
You have failed to put your html attributes into quotes, so the resulting html will be invalid. Also, you have used comma instead of plus at the last concatenation.
CONCLUSION: You are obviously not ready to implement this code, because:
- You lack Javascript syntax knowledge
- You lack HTML syntax knowledge
- You do not pay attention to tabulation
As a consequence, your main problem is not what the question states, namely, how to add a class to an element depending on JSON feed. Your main problem is that you lack Javascript and HTML education. Please, follow some tutorials to be able to solve a problem and after that try again to solve your problem. If you fail to do so, then you will have at least an educated guess.
After adding the content to tipswrap add the condition
document.getElementById('tipswrap').innerHTML = divtag; //$('#tipswrap').html(divtag)
if ($.trim($('#tooltipside0').html()) === "Senior") {
$("#test1").addClass('no');
}
Demo: Fiddle
I recommend you add a class to all of your rows called student and then from there use this javascript:
function displayContent(json) {
var len = json.feed.entry.length
var divtag = ''
for (var i = 0; i < len; i++) {
divtag +=
'<div class="student" id="tooltipwrap'+i+'">'+
'<span style="font-size:22px; font-weight:600;">'+
json.feed.entry[i].gsx$studentname.$t +
'<span class="hide" style="font-size:18px; font-weight:300;">'+
json.feed.entry[i].gsx$classlevel.$t +
'</span> '+
'<span id="tooltipside'+i+'">'+
json.feed.entry[i].gsx$gender.$t + '-' +
'</span>'+
'</span>'+
'</div>';
}
document.getElementById('tipswrap').innerHTML = divtag
}
jQuery(document).ready(function($) {
$('.student').each(function() {
if ($(this).text().toLowerCase().indexOf("senior") >= 0)
$(this).addClass('senior');
});
});
Here's a demo
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.