Check if value of array is greater than. Than do other styling - javascript

Iam currently working with jquery mobile and have an dynamic notification panel. Thereby I want to check the count of character in the text to base the styling on. So for example if text of a notification is > 10 than set height to Xpx.
But what I first do is this:
for(var count = 0; count < info.data.length; count++){
var shortmessage = info.data[count][3];
var category = info.data[count][4];
if(category === 'douane'){
douaneHtml = douaneHtml + "<div class='notification-item'>" +
"<div class='ui-grid-a notification-grid'>" +
"<div class='ui-block-a'>" +
"<img class='notification-image' src=" + imgPath + ">"+
"</div>" +
"<div class='ui-block-b'>" +
"<span class='notification-text'>" + shortmessage + "</span>" +
"</div>" +
"</div>";
$('.douane-notification-append').empty().prepend(douaneHtml);
}
}
So basically what I want to do is check:
if ( shortmessage.val().length() > 10 ){
$('.notification-item').css('min-height', '100px');
}
But when I do a console.log(shortmessage.val()); inside the if(category === 'douane') I'll get this in return:
shortmessage.val is not a function
Could someone help me out on this so basically what I want to do is count the characters in shortmessage and based on that do different styling.
This is the output of console.log(info.data[count]);

shortmessage is a String, you need to read the length property :
I've cleaned up with string generation, use an array of strings and join them after. much nicer!
Check if its too short and alter style variable
Then use this in template
for(var count = 0; count < info.data.length; count++){
var shortmessage = info.data[count][3];
var category = info.data[count][4];
var style = '';
// if long message, set the style
if ( shortmessage.length > 10 ){
style = 'min-height: 100px';
}else if ( shortmessage.length > 20 ){
style = 'min-height: 200px';
}else if ( shortmessage.length > 30 ){
style = 'min-height: 300px';
}
if(category === 'douane'){
douaneHtml = [
douaneHtml,
"<div class='notification-item' style='" + style + "'>",
"<div class='ui-grid-a notification-grid'>",
"<div class='ui-block-a'>",
"<img class='notification-image' src=" + imgPath + ">",
"</div>",
"<div class='ui-block-b'>",
"<span class='notification-text'>" + shortmessage + "</span>",
"</div>",
"</div>"
].join('');
$('.douane-notification-append').empty().prepend(douaneHtml);
}
}
If you can, try the new ES2015 strings.
Cleans up code a lot.
douaneHtml = `
${douaneHtml}
<div class='notification-item' style='${style}'>
<div class='ui-grid-a notification-grid'>
<div class='ui-block-a'>
<img class='notification-image' src='${imgPath}'>
</div>
<div class='ui-block-b'>
<span class='notification-text'>${shortmessage}</span>
</div>
</div>`;

Problem : val() method can't be called on string and since the shortmessage contains string message that will throw an error.
Suggested solution : just remove the extra .val() and it will works :
if ( shortmessage.length > 10 ){
$('.notification-item').css('min-height', '100px');
}
NOTE : length is a property so you should remove the () from the length.
Hope this helps.

Related

innerHTML has value but only shows first element

I'm trying to generate elements with JS after a Query to a SP List. The problem is I can't make a div innerHTML show changes in a loop. The HTML code is this:
<div style="width: 100%;">
<div class="FXmasonryWrapper" id="letterContainers">
<div class="bioBarTitle" id="letterButtons"></div>
<br>
</div>
</div>
The function that generates the items for letterContainers and letterButtons is this:
<script type="text/javascript">
var letters = new Array;
var foundLetters = '';
//QueryList( Repository, ListName, StartingRow, EndRow, SuccessCallback, FailCallback );
QueryList( '/sites/SKCopspcs/testing/', 'QAVGlossary', 1, 1000, function( sender, args ){
//Success -> queryItems
var foundItems = queryItems.getEnumerator();
var letterButtons = document.getElementById( 'letterButtons' );
var letterContainers = document.getElementById( 'letterContainers' );
var _all = "";
var done = 0;
while( foundItems.moveNext() )
{
var found = foundItems.get_current();
var title = found.get_item( 'Title' ) + '';
var definition = found.get_item( 'n5ud' ) + '';
var letter = found.get_item( 'Category' ) ;
if( !foundLetters.includes( letter ) )
{
foundLetters += letter + ', ';
letters.push( letter );
letterButtons.innerHTML += "<span class=\"bioTitle\" id=\"" + letter + "Span\" onclick=\"Show( this )\">" + letter + "</span>";
letterContainers.innerHTML += "<div class=\"FXmasonry bio\" id=\"" + letter + "\"></div>";
}
document.getElementById( letter ).innerHTML += "" +
"<div class=\"FXmasonryItem\">" +
"<span class=\"titleB\">" + title + "</span>" + "<br>" + definition +
"</div>";
_all += "" +
"<div class=\"FXmasonryItem\">" +
"<span class=\"titleB\">" + title + "</span>" + "<br>" + definition +
"</div>";
}
letterButtons.innerHTML += "<span class=\"bioTitle\" id=\"AllSpan\" onclick=\"Show( this )\">All</span>";
letterContainers.innerHTML += "<div class=\"FXmasonry bio\" id=\"All\"></div>";
document.getElementById( 'All' ).innerHTML = _all;
console.log( letterButtons.innerHTML );
}, function( s, a ){
//Fail\"
alert( 'Could not query list "QAVGlossary"' );
});
</script>
letterContainers generates all of it's items correctly, but letterButtons only shows the first element (A button with letter 'A') and when I log the innerHTML of letterButtons, it contains all the span buttons! But only shows 'A' and in the DOM Explorer it only contains the first element (The 'A' button)! If I copy an paste the generated innerHTML (Which I log in console after everything is "generated") from letterButtons in the DOM Explorer, it shows everything!
Why does this happen?
letterButtons.innerHTML contains all the generated items correctly, but it's only showing one and I can't figure out why. I even surrounded the code with try catch, made logs inside the loop and there are 0 erros. Everything is correctly, except that letterButtons.innerHTML contains the correct value but show only the first element.
P.D: I also tried concatenating the items to a variable string ( _genItems += "<span....>"; ) in the loop and in the end do the same:
letterButtons.innerHTML = _genItems;
And the result is the same but in this case it shows nothing. If I log the letterButtons.innerHTML value it contains all the elements but in the DOM Explorer it shows nothing.
After hours of trying to solve this issue I tried this with this piece of code:
<div style="width: 100%;">
<div class="FXmasonryWrapper" id="letterContainers">
<div class="bioBarTitle" id="letterButtons"></div>
<br>
</div>
</div>
I took out the BarTitle from the Wrapper and now works. I really don't have a reason of why this is happening.
<div style="width: 100%;">
<div class="bioBarTitle" id="letterButtons"></div>
<br>
<div class="FXmasonryWrapper" id="letterContainers"></div>
</div>

Uncaught SyntaxError: Unexpected token p in JSON at position 36

I´m populating webpage with sharepoint so I do a json to get data with ajax like these:
function completeFleet(data, target, eng) {
var items = data.d.results;
console.log(items);
var prefix = "<div class='row'>";
var sufix = "</div>";
var menu = "<div class='col-md-4'>";
var cat = "";
var spec = "";
var counter = 0;
var obj = null;
for (item in items) {
spec = "";
if (counter == 1) {
menu += "</div><div class='col-md-4'>";
counter = 0;
}
if (eng) {
obj = JSON.parse(items[item].Specifications);
for (var key in obj) {
spec += "<div class='row'><div class='col-md-12 ftBottomSeparator'><span class=' t10'>" + key + "</span> <span class='t06' style='float:right;'>" + obj[key] + "</span></div></div>";
}
menu += "<div class='row ftContainerOut'><div class='col-md-12 ftContainer'><div class='row ftHeader'><div class='col-xs-9 t09'>" + items[item].Title + "</div><div class='col-xs-3 text-right'></div></div><div class='row'><div class='col-md-6' style='padding-top:10px'><img src='" + items[item].Imagen.Url + "' class='img-responsive img-center' style='border:0px solid blue; max-width:150px;max-height:120px;' /></div><div class='col-md-6'>" + spec + "</div></div></div></div>";
} else {
obj = JSON.parse(items[item].Especificaciones);
for (var key in obj) {
spec += "<div class='row'><div class='col-md-12 ftBottomSeparator'><span class=' t10'>" + key + "</span> <span class='t06' style='float:right;'>" + obj[key] + "</span></div></div>";
}
menu += "<div class='row ftContainerOut'><div class='col-md-12 ftContainer'><div class='row ftHeader'><div class='col-xs-9 t09'>" + items[item].Title + "</div><div class='col-xs-3 text-right'></div></div><div class='row'><div class='col-md-6' style='padding-top:10px'><img src='" + items[item].Imagen.Url + "' class='img-responsive img-center' style='border:0px solid blue; max-width:150px;max-height:120px;' /></div><div class='col-md-6'>" + spec + "</div></div></div></div>";
}
counter++;
}
$(target).html("<div class='panel-body'><div class='container-fluid'>" + prefix + menu + sufix + "</div></div>");
}
I have 5 objects different, but one of these don´t show data, my webpage is in english and spanish, in english it charge all data, but in spanish one of these
doesn´t works and I get error at position 36, and position 36 is the item don´t show. Any idea what is wrong here? Regards
These one works
and this no works
---------Update------------
If I comment this line:
//obj = JSON.parse(items[item].Especificaciones);
and put
if(items[item].Especificaciones){
JSON.parse(items[item].Especificaciones);
}
it now runs with image, but now I don´t have my "Especificaciones" lists
Now when I use
var stringifyObj = JSON.stringify(items[item].Especificaciones);
var obj = JSON.parse(stringifyObj);
I get something like these:
make sure value is not null for the corresponding key inside JSON.parse. For example-
JSON.parse(items[item].Specifications)
make sure items have value in item index and items[item] has the property Specifications.
you can check if items[item].Specifications is not null before JSON.parse.
if(items[item].Specifications){
JSON.parse(items[item].Specifications)
}
Update
JSON.parse() is used to convert a string containing JSON notation into a Javascript object. To be valid JSON, strings must be in double quotes.
Try stringify the object and then parse again.
var stringifyObj = JSON.stringify(items[item].Especificaciones);
var obj = JSON.parse(stringifyObj);
The reason for the error is that JSON.parse() expects a String value and items[item].Especificaciones is an Array
"Eslora":100 pies"
You should probably opening the quotes when you start writing a string value

How to add additional functionalities?

I got a simple JavaScript based blog . First have a look at the below codes and I will ask my question.
Index.html have the following codes in its body
<script language="javascript" type="text/javascript" src="blog/config.js"> </script>
<script language="javascript" type="text/javascript" src="blog/single.js"> </script>
<script language="javascript" type="text/javascript" src="blog/posts.js"> </script>
config.js has
//This is the configuration file of the blog system.
//change these variables to suit your style and needs
var head = "h2"; //the heading style, ex. h1, h2, ect. use "h2" rather than "<h2>"
var text = "text"; //the text style, from your style sheet, it's in a <div> tag
var divider = "<hr>"; //the division between posts
var newer = "newer"; //the class for the link to the next newest page
var older = "older"; //the class for the link to the next oldest page
var pageclass = "page"; //the class for the text that displays the page number
var dateclass = "date"; //the class for the date
var pagesize = 4; //the number of posts on each page
var navclass = nav; //the configuration for the navigation`
posts.js
var posts = 1; //add 1 to this after adding a post. should be equal to the id of the newest post.
initblog(posts);
var id = 1; //make sure that this number is one greater than the one below it
var date = "mm/dd/yyyy"; //The date of the post
var heading = "Post 1"; //The title
var entry = ""; //reset the string
//don't worry about formatting and stuff like that, the system takes care of it all for us.
//VV your entry VV
entry += "<p>Wow, this post is on another page, If you have this many real posts, congratulations!</p>";
//^^ The most important part ^^
add_entry(id,date,heading,entry); //adds the entry to the blog
single.js
var maxpost;
function initblog(posts){
maxpost = posts;
var address = window.location.search;
if (address.substring(0, 1) == '?') {
page = address.substring(1);
} else{
window.location = "post.html?" + posts;
}
page = parseInt(page);
if (page > maxpost){
page = maxpost;
}
if (page < 1){
page = 1;
}
}
function add_entry(id,date,heading,entry) {
for (i=page;i>page - 1;i--){
if (id == i){
var entrytext = "";
entrytext += "<div class=" + text + ">";
entrytext += "<" + head + ">";
entrytext += "<a name=" + id + "></a>";
entrytext += "<span class='date'>[" + date + "]</span> ";
entrytext += heading;
entrytext += "</" + head + ">";
entrytext += entry;
entrytext += "</div>" + divider;
document.write(entrytext);
}
}
}
function pages(){
entrytext = ""
entrytext += "<table class=\"nav\"><tr>";
entrytext += "<td width=25% class = " + newer + ">&nbsp";
if (page < maxpost){
entrytext += "<A HREF=javascript:prev()>Newer Posts </A>";
}
entrytext += "</td><td width=50% class = " + pageclass + "><br><A HREF=javascript:newest()> Back to Index</A></td>";
entrytext += "<td width=25% class = " + older + ">&nbsp";
if (page-1 > 0){
entrytext += "<A HREF=javascript:next()>Older Posts</A>";
}
entrytext += "</td></table>";
entrytext += "";
document.write(entrytext);
}
function next(){
page = page - 1;
if (page < 1) {
page = page + 1;
}
window.location = "post.html?" + page;
}
function prev(){
page = page + 1;
if (page > maxpost) {
page = maxpost;
}
window.location = "post.html?" + page;
}
function newest(){
window.location = "index.html?" + maxpost;
}
Well , this is the whole blog script . I ain't added styles and you may see the comments on each lines for simplicity.
This blog doesn't have options to add title and meta description , keyword etc. Due to the style of applying it can do nothing outside the body tag.
1 . How to add an option to take/load titles?
2 . How to add the feature to load meta tag?
Don't tell me to edit and add titles on the template (index.HTML) , because that make no sense
As you see the heading block is for the title of the blog. All you need is just making it more visible.
var entrytext = "";
entrytext += "<div class=" + text + ">";
entrytext += "<h1>" + heading + "</h1>";
entrytext += "<" + head + ">";
entrytext += "<a name=" + id + "></a>";
entrytext += "<span class='date'>[" + date + "]</span> ";
entrytext += "</" + head + ">";
entrytext += entry;
entrytext += "</div>" + divider;
document.write(entrytext);
document.title = heading;
This will solve your problem about titles.
Regarding to meta tags, usually (actually by standard) meta tags are written betweeen <head> tags in HTML. To make it SEO compilant you need add them into these tags. More detailed: http://www.w3schools.com/tags/tag_meta.asp
But, if this code is generated on client-side. There is no meaning to generate it, because search engine will not parse on-fly generated meta tags. Because it's executed on browser.

event.target.id.indexOf("foo") not working - Not working in IE

I have a JavaScript function that loops through classes and gets an ID which I have wrapped in a div called 'item'. Once they click on a button it bubbles up through the div which I have wrapped information in and collected the ID. For Example:
output = "<div id='item" + json_output[i].id + "'>" +
"<div class = 'itemBoxes'>"+
"<h3 class ='itemTitle'>" +json_output[i].classname + "</h3>" +
"<div class = 'paddingBottom'></div>" +
"<p class = 'itemDesc'>" + json_output[i].classdescription + '</p>' +
"<div class ='itemInfo'>" +
"<div class ='bookingItems'> <img src = 'img/glyphicons-268-credit-card.png'</img> <p class = 'itemDetails'>£" + json_output[i].classprice + "</p></div> "+
"<div class ='bookingItems'> <img src = 'img/glyphicons-46-calendar.png'</img> <p class = 'itemDetails'>" + json_output[i].classdate + "</p></div>" +
"<div class ='bookingItems'> <img src = 'img/glyphicons-55-clock.png'</img><p class = 'itemDetails'>"+ json_output[i].classstarttime +"</p></div>" +
"<div class ='bookingItems'> <img src = 'img/glyphicons-44-group.png'</img><p class = 'itemDetails'>" + json_output[i].classparticipants + " spaces </p></div>" +
"</div>" +
"<p id ='bookingBox'> <input type='button' class='bookingSubmit' value='Book Now'/> </p>" +
"</div>" +
"</div>";
target.innerHTML += output;
The code I use to find the ID is:
var fetchModifyButton;
//Gets the button that says 'Modify'
fetchModifyButton = _c("bookingSubmit");
//Remove Button.
for (var i = 0, j = fetchModifyButton.length; i < j; i++) {
fetchModifyButton[i].addEventListener("click", function () {
var e, productID, newID;
//Bubbles up and finds the ID of the product they want to modify
e = event.target;
while (e.id.indexOf('item') == -1) {
e = e.parentNode;
}
productID = e.id;
//Removes everything but the numbers.
newID = productID.replace(/[^0-9.]/g, "");
getClassInfoForBooking(newID, newID);
});
}
This works perfectly in Google Chrome, IE11, and most other browsers.
It doesn't work in IE8,9 or 10.
The error message I get in is:
SCRIPT5007: Unable to get property 'id' of undefinded or null reference
Then it points to the line: while (e.id.indexOf('item') == -1) {
I wondered if anyone had any ideas why?
use event.srcElement for IE
var addEvent = window.addEventListener||window.attachEvent;
fetchModifyButton[i].addEvent("click", function () {
var e, productID, newID;
//Bubbles up and finds the ID of the product they want to modify
e = event.target||event.srcElement;
while (e.id.indexOf('item') == -1) {
e = e.parentNode;
}
productID = e.id;
//Removes everything but the numbers.
newID = productID.replace(/[^0-9.]/g, "");
getClassInfoForBooking(newID, newID);
});

How to dynamically assign an id to an image

var intFields = 0;
var maxFields = 10;
function addElement() {
"use strict";
var i, intVal, contentID, newTBDiv, message = null;
intVal = document.getElementById('add').value;
contentID = document.getElementById('content');
message = document.getElementById('message');
if (intFields !== 0) {
for (i = 1; i <= intFields; i++) {
contentID.removeChild(document.getElementById('strText' + i));
}
intFields = 0;
}
if (intVal <= maxFields) {
for (i = 1; i <= intVal; i++) {
intFields = i;
newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id', 'strText' + intFields);
newTBDiv.innerHTML = "<input placeholder='recipient" + intFields + "#email.com' type='text' name='" + intFields + "'/><a href='javascript:removeElement();'><img id='strImg + " + intFields + "' src='images/minus.png' alt='Add A Field'/></a><input type='text' value='" + newTBDiv.id + "'/>";
contentID.appendChild(newTBDiv);
message.innerHTML = "Successfully added " + intFields + " fields.";
}
} else {
for (i = 1; i <= maxFields; i++) {
intFields = i;
newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id', 'strText' + intFields);
newTBDiv.innerHTML = "<input placeholder='recipient" + intFields + "#email.com' type='text' name='" + intFields + "'/><a href='javascript:removeElement();'><img id='strImg + " + intFields + "' src='images/minus.png' alt='Add A Field'/></a><input type='text' value='" + newTBDiv.id + "'/>";
contentID.appendChild(newTBDiv);
message.innerHTML = "Unable to create more than 10 receipient fields!";
}
}
}
My script here dynamically adds up to 10 fields where users will be able to enter an email address and to the right of the text box i add an image of a minus sign that calls another script. I'm having trouble working out how to assign and keep track of the minus signs. I need to be able to have the minus sign script's recognize the text box it is by and remove it. I can write the remove script easily enough but I'm unsure of how to tell the image which text box to remove. Any help, suggestions, or comments are greatly appreciated.
Thanks,
Nick S.
You can add a class to the field called minus and then check through like that. I would suggest using jquery for this.
To add the class
$("#element").addClass("minus");
To remove all elements with that class
$("body input").each(function (i) {
if($(this).attr("class") == "minus"){
$(this).remove();
}
});
The two best options, imo, would be 1) DOM-traversal, or 2) manipulating ID fragments.
Under the first way, you would pass a reference to the element where the event takes place (the minus sign) and then navigate the DOM from there to the get the appropriate text box (in jQuery you could use $(this).prev(), for example).
Under the second way, you would assign a prefix or a suffix to the ID of the triggering element (the minus sign), and the same prefix or suffix to the target element (the text box). You can then (again) generate the appropriate ID for your target element by simple string manipulation of the ID from the triggering element.
Is that sufficient to get you started?
Try adding a class to the field and the same class to the minus sign.
So add this right after the setAttribute id,
newTBDiv.setAttribute('class', 'field' + intFields);
then just remove any elements that have that class.

Categories