Looping through a split array and outputting with wrapInner - javascript

I am having difficulty figuring out the best method of doing the following. I am getting anywhere from 0 to x number of string names, ie: Zillow, Trulia. What I am wanting to do is associate an image with those string names and then display them into a list. I am attempting to do a switch statement, but am unsure if that will work for more than 1 condition...please correct me if I am wrong.
So for instance, the variable list is holding two items (Zillow/Trulia), how can I check ky split function variable for multiple values and then add the output: $('#review-icon-list').wrapInner('<li class="review-icon">' + zillowImg + '</li>');
Right now my switch case is throwing an unexpected token error, but I do not think I am using the right method anyways. Does anyone know how I would do this? Would I be doing some sort of loop and if so, how would I structure it?
var reviewSiteNames = 'Zillow,Trulia';
reviewSiteNames = reviewSiteNames.split(',');
console.log(reviewSiteNames);
var zillowImg = '<img src="https://s3.amazonaws.com/retain-static/www/zillow.jpg" alt="Zillow">';
var truliaImg = '<img src="https://s3.amazonaws.com/retain-static/www/trulia.png" alt="Trulia">';
if (reviewSiteNames == '') {
$('#no-current-reviewSites').html('No review sites currently added')
}
/*else if (reviewSiteNames) {
$('#review-icon-list').wrapInner('<li class="review-icon"></li>');
}*/
switch (true) {
case (reviewSiteNames.indexOf('Zillow') >= 0):
$('#review-icon-list').wrapInner('<li class="review-icon">' + zillowImg + '</li>');
break;
case (reviewSiteNames.indexOf('Realtor.com') >= 0):
$('#review-icon-list').wrapInner('<li class="review-icon">' + realtorDotComImg + '</li>');
break;
case (reviewSiteNames.indexOf('Trulia') >= 0):
$('#review-icon-list').wrapInner('<li class="review-icon">' + truliaImg + '</li>');
default: return '';
}​;
New method of trying this. The only image that is displaying is the last if statement in the each function.
$.each(reviewSiteNames, function (index, value) {
if (reviewSiteNames.includes('Zillow')) {
$('#review-icon-current').wrapInner('<li class="review-icon">' + zillowImg + '</li>');
}
if (reviewSiteNames.includes('Trulia')) {
$('#review-icon-current').wrapInner('<li class="review-icon">' + truliaImg + '</li>');
}
//return (value !== 'three');
});

Here is how I would write what I understand from your code:
I think you want to check if some specific word are in the reviewSiteNames array to determine how to wrap the #review-icon-list element.
// Site names as a string
var reviewSiteNames = 'Zillow,Trulia';
// Site names as an array
reviewSiteNames = reviewSiteNames.split(',');
//console.log(reviewSiteNames);
// Some images used in li wrappers...
var zillowImg = '<img src="https://s3.amazonaws.com/retain-static/www/zillow.jpg" alt="Zillow">';
var truliaImg = '<img src="https://s3.amazonaws.com/retain-static/www/trulia.png" alt="Trulia">';
// If the array is empty
if (reviewSiteNames.length == 0) {
$('#no-current-reviewSites').html('No review sites currently added')
}
var myHTMLtoInsert = "";
// Check if specific values are in array
if( $.inArray('Zillow', reviewSiteNames) ){
myHTMLtoInsert += '<li class="review-icon">' + zillowImg + '</li>';
}
if( $.inArray('Realtor.com', reviewSiteNames) ){
myHTMLtoInsert += '<li class="review-icon">' + realtorDotComImg + '</li>';
}
if( $.inArray('Trulia',, reviewSiteNames) ){
myHTMLtoInsert += '<li class="review-icon">' + truliaImg + '</li>';
}
$('#review-icon-list').html(myHTMLtoInsert);

// The names:
var names = 'Zillow,Trulia';
names = names.split(',');
// The images mapper: an object that has names as keys and images as values
var images = {
"Zillow": '<img src="https://s3.amazonaws.com/retain-static/www/zillow.jpg" alt="Zillow">',
"Trulia": '<img src="https://s3.amazonaws.com/retain-static/www/trulia.png" alt="Trulia">'
};
// if names is empty: (names == '' won't work because names is no longer a string, it's an array now)
if (names.length === 0) {
$('#no-current-reviewSites').html('No review sites currently added')
}
// if there is names
else {
// loop through all names
names.forEach(function(name) {
// if this name got an image in the images mapper (images[name] !== undefined)
if(images[name]) {
// then do magic stuff with it
$('#review-icon-list').wrapInner('<li class="review-icon">' + images[name] + '</li>');
}
});
}
I hope this is usefull as I'm not quite sure what the goal really is.

Related

How to load only part of a document in javascript?

I am new to JavaScript and I have an html page that loads the source code from this page into a given div and I am using the code provided by the user rob-w which works fine but my main goal is to learn how to show only part of the returned text starting at a given value and ending at a given value after that
popup.js
chrome.runtime.onMessage.addListener(function(request, sender) {
if (request.action == "getSource") {
message.innerText = request.source;
}
});
function onWindowLoad() {
var message = document.querySelector("#message");
chrome.tabs.executeScript(null, {
file: "getPagesSource.js"
}, function() {
// If you try and inject into an extensions page or the webstore/NTP you'll get an error
if (chrome.runtime.lastError) {
message.innerText = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
}
});
}
window.onload = onWindowLoad;
getPagesSource.js
// #author Rob W <http://stackoverflow.com/users/938089/rob-w>
// Demo: var serialized_html = DOMtoString(document);
function DOMtoString(document_root) {
var html = '',
node = document_root.firstChild;
while (node) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
html += node.outerHTML;
break;
case Node.TEXT_NODE:
html += node.nodeValue;
break;
case Node.CDATA_SECTION_NODE:
html += '<![CDATA[' + node.nodeValue + ']]>';
break;
case Node.COMMENT_NODE:
html += '<!--' + node.nodeValue + '-->';
break;
case Node.DOCUMENT_TYPE_NODE:
// (X)HTML documents are identified by public identifiers
html += "<!DOCTYPE " + node.name + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') + (!node.publicId && node.systemId ? ' SYSTEM' : '') + (node.systemId ? ' "' + node.systemId + '"' : '') + '>\n';
break;
}
node = node.nextSibling;
}
return html;
}
chrome.runtime.sendMessage({
action: "getSource",
source: DOMtoString(document)
});
I have played around with many DOM functions and getBy functions but I have not been able to apply them correctly and I don't think they are exactly what I am after. If someone can point me in the right direction it would be appreciated
My solution uses String.prototype.match() to get an array containing all values between strings x and y but not including strings x and y.
function getStringsBetweenXandY(html) {
var matches = html.match(/x[\s\S]*?y/g), i = matches.length;
while(i--) {
matches[i] = matches[i].match(/x([\s\S]*?)y/)[1];
}
return matches;
}
var array = getStringsBetweenXandY(html);
You need to make sure that strings x and y contain backslashes where necessary.
matches will contain an array or an array-like object containing all of the html fragments you are looking for

Current Alternative To .fontcolor() method in Javascript

I was given this task with some existing code to change the string color of each of three selector.value(s) that is output onto an input element to three different colors. The code boils the three selectors into a single output variable. Without destroying the code, I cannot figure out how to select each individual variables prior to condensing them.
If I could use the fontcolor() method, my life would be great but it's 2018 and I can't. Is there any way you can think of to solve this issue?To clarify, I need to alter the colors of the strings that belong to output(red), select1.value(blue) and select2.value(black.
Most of the action for this is happening in the parseOutput() function but I'm just stuck and don't think it's possible without rewriting the entire program.
function updateSelector(result){
var options = result.options;
var elementId = "select" + result.element;
var logger = document.getElementById('logger');
var selector = document.getElementById(elementId);
//logger.innerHTML = JSON.stringify(elementId);
selector.innerHTML = options;
selector.disabled = false;
}
google.script.run.withSuccessHandler(updateSelector).processOptions(0);
plate();
function resetAll(){
for (var i = 0;i<3;i++){
var selector = document.getElementById('select' + i);
selector.disabled = true;
selector.innerHTML = "";
}
google.script.run.withSuccessHandler(updateSelector).processOptions(0);
}
function finalSelection(){
var output = document.getElementById('out');
//output.focus();
output.select();
}
function plate(){
var plate = document.getElementById('plate');
plate.innerHTML = atob('Q3JhZnRlZCBieTogWmFjaGFyeSBTdGFjaG93aWFr');
}
//Adds the location as initial output, followed by divider, application, and issue if select1 is selected
//else statement added so if select0 is [Costco Website Name], to ommit the " - "
function parseOutput(){
var output = "";
if (select1.value.length > 0 && select0.value !== "[Costco Website Name]"){
output = output + ' - ' + select1.value + ' // ' + select2.value;
} else{
output = output + select1.value + ' // ' + select2.value;
}
out.value=output.trim();
}
And this is the Div that displays the output:
<div class="wide"><p><input class="wide" type="readonly" id="out" onfocus="this.select();"></p></div>
A modern replacement for fontcolor would use a span and a style (or class), e.g.:
function modernFontColor(str, color) {
return '<span style="color: ' + color + '">' + str + '</span>';
}
or
function modernFontClass(str, cls) {
return '<span class="' + cls + '">' + str + '</span>';
}
...where the class defines the styling.

Unpack array of objects into strings to display on a template in meteor

I have a collection that has within it an object that holds an array of yet more objects that need to be unpacked to display in a template eventually.
The item in the sub-object is an order, and the order contains an array of line items.
I can get the order out fine, and see the array of line items no problem, but that's where I come unstuck.
I thought the following would work (using js to convert them into an array of strings to then display somehow)
Template.editEvent.helpers({
lineItems: function(req) {
var order = req.order;
console.log(order);
var lines;
var count = 1;
_.each(order, function(item) {
var string;
string +count++ + '. ';
if(item.age) { // we have a cloathing string
string += item.age + " " + item.sex + " " + item.Season + " " + "Number: " + item.Number;
lines.push(string);
}
else if(item.pushers) {
string += "Pushers needed: " + item.pushers;
lines.push(string);
}
else if(item.cots) {
string += "Cots needed: " + item.pushers;
lines.push(string);
}
else if(items.extra) {
string = "Extra info: " + item.extra;
lines.push(string);
}
else {
string = "Don't know this field";
lines.push(string);
}
console.log(lines);
});
return lines;
}
})
Where the tests are to see if the line item starts with the field shown (because the line items can be different).
However, the _.each is throwing up on the client, (it works fine in the startup code, so I guess from that its server only?)
Am I barking up the wrong tree here, should this embedded object be a new collection? If I am right, how do I go about displaying the returned string array (only just thought of this) in the template anway?
You are not initializing lines. Use:
var lines = [];
also, what is: string +count++ + '. '? did you mean string += count++ + '. '? If so then you also need to initialize string, e.g., var string = "";
From your comment, I get the sense that what you really want is to show the list reactively in the template. For that, you'd probably want to directly use a transform. Here is how that could work. Alternatively you could wrap your code into a Deps.autorun.
HTML (e.g., edit_event.html):
<template name="editEvent">
{{lines}}
</template>
Javascript (e.g., edit_event.js):
Template.editEvent.lines = function() {
var order = Orders.find(
{id: Session.get('currentOrder')},
{limit: 1,
transform: function(order) {
console.log(order);
var lines;
var count = 1;
_.each(order, function(item) {
var string = count++ + '. ';
if(item.age) { // we have a cloathing string
string += item.age + " " + item.sex + " "
+ item.Season + " " + "Number: " + item.Number;
lines.push(string);
}
else if(item.pushers) {
string += "Pushers needed: " + item.pushers;
lines.push(string);
}
else if(item.cots) {
string += "Cots needed: " + item.pushers;
lines.push(string);
}
else if(items.extra) {
string = "Extra info: " + item.extra;
lines.push(string);
}
else {
string = "Don't know this field";
lines.push(string);
}
console.log(lines);
});
return lines;
}
})
}

Javascript won't filter eBay API results by price/listing type

After following eBay's API guidelines for displaying fixed price items that fall within a specified price range, results are still showing auction based items of varying prices outside the range. I followed their tutorial word for word, so I'm not sure what I'm doing wrong.
Code:
<div id="api"></div>
<script>
function _cb_findItemsByKeywords(root)
{
var items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
var html = [];
html.push('<table width="100%" border="0" cellspacing="0" cellpadding="3"><tbody>');
for (var i = 0; i < items.length; ++i)
{
var item = items[i];
var title = item.title;
var pic = item.galleryURL;
var viewitem = item.viewItemURL;
if (null != title && null != viewitem)
{
html.push(
'<tr id="api_microposts"><td>'
+ '<img src="' + pic + '" border="0" width="190">' + '<a href="' + viewitem + '" target="_blank">' + title +
'</a></td></tr>');
}
}
html.push('</tbody></table>');
document.getElementById("api").innerHTML = html.join("");
// Create a JavaScript array of the item filters you want to use in your request
var filterarray = [
{"name":"MaxPrice",
"value":"500",
"paramName":"Currency",
"paramValue":"USD"},
{"name":"MinPrice",
"value":"200",
"paramName":"Currency",
"paramValue":"USD"},
{"name":"FreeShippingOnly",
"value":"true",
"paramName":"",
"paramValue":""},
{"name":"ListingType",
"value":["FixedPrice"],
"paramName":"",
"paramValue":""},
];
// Define global variable for the URL filter
var urlfilter = "";
// Generates an indexed URL snippet from the array of item filters
function buildURLArray() {
// Iterate through each filter in the array
for(var i=0; i<filterarray.length; i++) {
//Index each item filter in filterarray
var itemfilter = filterarray[i];
// Iterate through each parameter in each item filter
for(var index in itemfilter) {
// Check to see if the parameter has a value (some don't)
if (itemfilter[index] !== "") {
if (itemfilter[index] instanceof Array) {
for(var r=0; r<itemfilter[index].length; r++) {
var value = itemfilter[index][r];
urlfilter += "&itemFilter\(" + i + "\)." + index + "\(" + r + "\)=" + value ;
}
}
else {
urlfilter += "&itemFilter\(" + i + "\)." + index + "=" + itemfilter[index];
}
}
}
}
} // End buildURLArray() function
// Execute the function to build the URL filter
buildURLArray(filterarray);
url += urlfilter;
}
</script>
<!--
Use the value of your appid for the appid parameter below.
-->
<script src=http://svcs.ebay.com/services/search/FindingService/v1?SECURITY-APPNAME=*App ID*&OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=iphone%205%2016gb%20unlocked&paginationInput.entriesPerPage=3>
</script>
The specifications come from this page. I would tackle this problem in two steps:
Check to see if you get the same results even if you comment out this line:
url += urlfilter;
If that happens then your problem is the way you make the request and the parameters you set are not yet relevant. If it does change then the request is going through well enough and you need to fiddle what you pass in.
In that case the parameters need some fiddling. If you are getting any results then one issue could be with the ListingType filter. The specifications say that ListingType takes a string OR can take multiple values. It might be that you want to use:
{"name":"ListingType",
"value": "FixedPrice",
"paramName":"",
"paramValue":""}

conditional statements in jquery shortcode generation

I want to convert this shortcode generating form into one that will generate either of two different shortcodes depending on a value selected in the form. So, a radio button says, "Which shortcode do you want to build?" Then they choose it, then they go on with the other fields to fill out the attribute values. Then when it comes time to generate the code, the JS will condition its output based on the radio button question. I've tried to modify it myself, but the problem is, this script generates the attributes from the options index, so I don't know how to include an option that doesn't go into the index:
var table = form.find('table');
form.appendTo('body').hide();
form.find('#myshortcodeidstem-submit').click(function(){
var options = {
'shortcodename' : '', \\ THIS IS THE ONE TO DETERMINE THE SHORTCODE NAME
'attribute' : '', \\ THIS IS THE ATTRIBUTE THAT BOTH SHORTCODES SHARE
};
var shortcode = '[myshortcode'; \\ THIS LINE NEEDS TO BE CONDITIONAL ON OPTION 1
for( var index in options) {
var value = table.find('#myshortcodeidstem-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
shortcode += '] Content Here [/myshortcode]'; \\ THIS LINE CONDITIONAL ON OP1
--- UPDATE ---
Barmar pointed me in the right direction, and I got it to work, but I'd like to know if there's a more economical way to do it. Here's what I have:
var table = form.find('table');
form.appendTo('body').hide();
form.find('#myshortcodeid-submit').click(function(){
var codeselector = table.find('#myshortcodeid-codeselector').val();
if (codeselector === '1'){
var options = {
'attribute' : '',
};
var shortcode = '[shortcode_one';
for( var index in options) {
var value = table.find('#myshortcodeid-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
shortcode += '] Content Here [/shortcode_one]';
}
if (codeselector === '2'){
var options = {
'attribute' : '',
};
var shortcode = '[shortcode_two';
for( var index in options) {
var value = table.find('#myshortcodeid-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
shortcode += '] Content Here [/shortcode_two]';
}
--- UPDATE ---
Found a more economical way, without repeating the options index. See the answer below.
Here's the most economic way I could come up with. Doesn't repeat the options index this way. Working good. Just had to create a var for the dropdown field that chooses the shortcode, then do if statements referencing that var's value.
var codeselector = table.find('#myid-codeselector').val();
if (codeselector === '1'){
var shortcode = '[shortcode_one';
}
if (codeselector === '2'){
var shortcode = '[shortcode_two';
}
var options = {
'attribute' : '',
};
for( var index in options) {
var value = table.find('#myid-' + index).val();
if ( value !== options[index] && value != null )
shortcode += ' ' + index + '="' + value + '"';
}
if (codeselector === '1'){
shortcode += '] Content Here [/shortcode_one]';
}
if (codeselector === '2'){
shortcode += '] Content Here [/shortcode_two]';
}

Categories

Resources