Generate multiple unique sets of divs in jQuery - javascript

I am trying to generate multiple unique sets of divs within the existing div with an id of row. I would like the output to be this:
<div id="row">
<div>fluffy</div>
<div>soft</div>
<div>green</div>
<div>mittens</div>
<div>coarse</div>
<div>fire</div>
<div>whiskers</div>
<div>none</div>
<div>grey</div>
</div>
However my output is currently this:
<div id="row">
<div>fluffy, soft, green</div>
<div>mittens, coarse, fire</div>
<div>whiskers, none, grey</div>
</div>
I am using the following jquery:
function cats(catName, catFur, catEyes) {
$("#row").html('<div>' + catName + '</div>' + '<div>' + catFur + '</div>' + '<div>' + catEyes + '</div>');
}
$cat1 = ["fluffy", "soft", "green"];
$cat2 = ["mittens", "coarse", "fire"];
$cat3 = ["whiskers", "none", "grey"];
jQuery(document).ready(function() {
function catGenerator() {
$catVars = [$cat1, $cat2, $cat3];
cats($catVars[0], $catVars[1], $catVars[2] );
}
catGenerator();
});
My overall goal is to be able to automate the number div sets to be generated, for example, there are 3 div sets to be generated here, so instead of listing every cat array under the catGenerator function, it would automatically know how many sets to generate. I believe this would be implemented with a for loop, but I haven't been able to figure it out.
I feel overall I am missing a bigger concept here, and I would love to know if anyone has a better way of going about this overall problem, a more best practices approach. Thanks!
codepen:
http://codepen.io/anon/pen/IfKek

Try this.
function catGenerator() {
$catVars = [$cat1, $cat2, $cat3];
for (var i = 0; i < $catVars.length; i++) {
cats($catVars[i][0], $catVars[i][1], $catVars[i][2]);
}
}
Actually "$catVars" is a two dimensional array.
$catVars[0][0] = "fluffy";
$catVars[0][1] = "soft";
$catVars[0][2] = "green";
$catVars[1] = ["mittens", "coarse", "fire"]
$catVars[2] = ["whiskers", "none", "grey"];

Related

Need help to add javascript array contents to an existing piece of HTML code

My front-end skills are fairly limited. I have a trained language model which generates 'tweets'.
I have this javascript function which currently displays the tweets as a paragraph.
function addResponse(msg) {
document.getElementById("results").textContent = ""
var para = document.createElement("div");
var s = "<div class='center' id='gpt2'> <b> Here what our BOT has to say... </b> </br></br>"
i = 1
for (var key in msg){
var value = msg[key];
console.log(value);
s = s + i + ") " + " <b>" + value + "</b> </br></br>"
i = i + 1
}
para.innerHTML = s + "</div>";
document.getElementById('append').appendChild(para);
}
Instead of displaying in a paragraph, I want to display as a proper tweet.
Here is a tailwind CSS implementation to create the UI of the tweet: https://codepen.io/webcrunchblog/pen/xedQVv
Currently this displays a fixed string "Starhopper". What I want to do is, loop through my array object 'msg' and display all the tweets with the proper UI .
Currently the addResponse() is called as part of ajax callback for successful response. From there how can I include the tailwind CSS code so that I can display every array element in its own tweet UI?
Hope the question is clear.
EDIT: Created this codepen if anyone wants to try it out: https://codepen.io/nikhilno1/pen/RwPBWvb
In the output, there is a tweet and three sentences. I want 3 tweets to be created for each of the sentence.
I've updated a bit of your code here: https://codepen.io/rxna/pen/OJVwMOm
The idea is to:
Clone the tweet element, have added a custom class for that:
var articleNode = document.querySelector(".tweet-body");
var clone = articleNode.cloneNode(true);
Update the text within each element:
var title = clone.querySelector(".tweet-text");
title.innerText = value;
And lastly append within the DOM:
document.getElementById("append").appendChild(clone);
It's not perfect but hopefully you'd get the idea.

Converting HTML to JavaScript string in PhpStorm

I'd like to convert some html easily into concatenated JS strings in PhpStorm.
From:
<div class="spa-shell-head">
<div class="spa-shell-head-logo"></div>
<div class="spa-shell-head-acct"></div>
<div class="spa-shell-head-search"></div>
</div>
To:
var main_html = ''
+ '<div class="spa-shell-head">'
+ ' <div class="spa-shell-head-logo"></div>'
+ ' <div class="spa-shell-head-acct"></div>'
+ ' <div class="spa-shell-head-search"></div>'
+ '</div>';
Ideally into the other direction as well. Is there any chance to achieve this? With a plugin? I could imagine that a macro with some regex could do it. Is it possbile?
Same question for other IDE can be found here. Or here.
Using only PHPStorm, you can use the Extra Actions plugin:
Select all your lines
Split the selection into lines (ctrl + shift + L)
Go to the beginning of the line (home)
Add a plus sign and a quote
Go to the end of the line (end)
Add a quote
Rather than converting HTML to a JS string, you should really create your elements in JS and then insert them into the DOM. This would give you much more control, not create such a difficult to maintain/read code, cause less problems, and be much faster to boot:
var outerDiv = document.createElement("div"); // Create a div
outerDiv.className = "spa-shell-head"; // Give it a class
var innerDivLogo = document.createElement("div");
innerDivLogo.className = "spa-shell-head-logo";
var innerDivAcct = document.createElement("div");
innerDivAcct.className = "spa-shell-head-acct";
var innerDivSearch = document.createElement("div");
innerDivSearch.className = "spa-shell-head-search";
outerDiv.appendChild(innerDivLogo); // Append into original div
outerDiv.appendChild(innerDivAcct);
outerDiv.appendChild(innerDivSearch);
document.body.appendChild(outerDiv); // Add to page
The above creates the following:
https://jsfiddle.net/yfeLbhe4/

How to get the total of the list ordered, with Javascript

I'm making a code of a online delivery webpage, and I having a hard time trying to figure out how to output the total of the list ordered by the user.
function ListOrder(){
document.getElementById('order').innerHTML += "<div id=\"YourOrders\">" + + document.getElementById('FoodName').value + document.getElementById('quantity').value + document.getElementById('Totality').value + "</div><br>";}
Edited: I want to know how I can get the sum of the total price. So, I placed a parseInt between the document.getElementById('Totality').value . It looks like this now,
function ListOrder(){
document.getElementById('order').innerHTML += "<div id=\"YourOrders\">" + + document.getElementById('FoodName').value + document.getElementById('quantity').value + parseInt(document.getElementById('Totality').value) + "</div><br>";}
Can someone help me make a function or something for that? Javascript only, please. I'm still kinda new at it.
function ListOrder(){
document.getElementById('order').innerHTML +=
"<div id=\"YourOrders\">" +
parseInt(document.getElementById('FoodName').value) +
parseInt(document.getElementById('quantity').value) +
parseInt(document.getElementById('Totality').value) +
"</div><br>";
}
the kernel of your code should look like the following (double + operator deleted, reformatted):
function ListOrder(){
document.getElementById('order').innerHTML +=
"<div id=\"YourOrders\">" + (
document.getElementById('FoodName').value
+ document.getElementById('quantity').value
+ document.getElementById('Totality').value
)
+ "</div><br>"
;
}
You've phrased your question in a way that suggests you wish to output an order list assembled from the content of all (html) elements with certain ids.
this won't work reliably:
Ids should be document unique.
The Js functions you use do not iterate over lists.
instead, proceed along the following lines (which assume that you import jquery, a cross-browser dom-handling and ajax library (which you should use anyway :)):
function ListOrder(){
var e_orders = $("<div id=\"YourOrders\">");
$("#order").append(e_orders);
$(".FoodName").each ( function ( idx_fn, e_fn ) {
$(e_orders).append(
$("<div/>").append(
$(e_fn).val()
+ $(e_fn).nextAll('.quantity').val()
+ $(e_fn).nextAll('.Totality').val()
);
);
$(e_orders).append("<br>");
});
return e_orders;
}
The code template assumes that the source data are elements with value attributes being marked with css classes quantity, Totality and 'FoodName``, that these elements are siblings and unique within a container element for each item incl. quantity information. It should be flexible enough to be tailored to your actual needs and html structure.

How can I reduce this Javascript/HTML/jQuery code?

I have hundreds, maybe thousands of charts for stores. The only difference is the name of the store and the product. The HTML code is dynamically generated once/day. Even minified, it takes forever to load (at least it feels like an eternity). If I use Firebug, then loading the file does take a very, very long time to load.
The stores and products are created from a table that's generated each morning. Since each table has a title (e.g., "JohnsMarket"), the ids cannot be reduced to numbers (e.g., 'store1', 'store2').
All of the other SO solutions to repetitive code use numbered ids.
For each store/product, I have to repeat the following 3 snippets.
<div id="JohnsMarket_Soup" class="frmStep">
<div id="JohnsMarket_soup_chart" ></div>
<div class="layout">
<div class="layout_slider-settings">
<div class="loading" id="JohnsMarket_soup_loading"></div>
</div>
<div class="layout_slider"><input id="JohnsMarket_soup_slider" name="area" value="1" ></div>
<div class="layout_slider-settings"> </div>
</div>
</div>
if ( ui.panel.id==='JohnsMarket' )
{
if( typeof JohnsMarket_soup_chart_data === 'undefined' )
{
$('.loading_graph_msg').show();
window.setTimeout(function() { JohnsMarket_soup_data=checkData( JohnsMarket_soup_data,'JohnsMarket' );
JohnsMarket_soup_chart_data = createChart(JohnsMarket_soup_data, 'JohnsMarket_soup_chart', 'JohnsMarket Soup', 50, 7, -1); },50 );
$('.loading_graph_msg').hide('fast');
}
}
});
jQuery('#JohnsMarket_soup_slider').slider({}
$('#JohnsMarket_soup_loading').show();
var x = this.getValue();
window.setTimeout(function() {
JohnsMarket_soup_chart_data.replot();
JohnsMarket_soup_chart_data.destroy();
JohnsMarket_soup_chart_data = createChart(JohnsMarket_soup_data, 'JohnsMarket_soup_chart_data', 'JohnsMarket Soup', 5, x*7, -1);
},20 );
}
});
I can't say I fully understand what your whole problem statement looks like, but you can drastically compress all your code into one function that is used over and over again. This will, at least trim the size of the code down. Since you only showed one example of the data, I can't be sure what exactly is common from one data set to the next, but I made an assumption in order to show you how it can all be procedurized. You could collapse all the code to this:
function checkItem(idStr) {
if ( ui.panel.id == idStr) {
// generate derived names
var soupChartDataName = idStr + "_soup_chart_data";
var soupDataName = idStr + "_soup_data";
var soupChartData = idStr + "_soup_chart_data";
var soupChart = idStr + "_soup_chart";
var soup = idStr + " Soup";
var soupSlider = idStr + "_soup_slider";
var soupLoading = idStr + "_soup_loading";
if (typeof window[soupChartDataName] === 'undefined') {
$('.loading_graph_msg').show();
window.setTimeout(function() {
window[soupDataName] = checkData(window[soupDataName], idStr );
window[soupChartData] = createChart(window[soupChartData], soupChart, soup, 50, 7, -1);
}, 50);
$('.loading_graph_msg').hide('fast');
}
$("#" + soupSlider).slider({});
$("#" + soupLoading).show();
var x = this.getValue();
window.setTimeout(function() {
window[soupChartDataName].replot();
window[soupChartDataName].destroy();
window[soupChartDataName] = createChart(soupDataName, soupChartData, soup, 5, x*7, -1);
}, 20);
}
}
checkItem("JohnsMarket");
Then, for all the other items just call checkItem() with a different idString and no additional code. If I didn't guess the commonality among them quite correctly, you should be able to get the idea for how you can generate all the names being used from one or two common roots. For example, if "soup" isn't common among all the derived names, then maybe you need to pas that root into checkItem too so it can vary from one name to the next. If this were my code, I wouldn't be using so many global variables and I'd hang them off some object in my page, but that's your choice.
Note - for global variables, we access them off the windowobject so we can use the derived variable names as indexes.
And, you could create the HTML from a string template like this:
function createItem(idStr) {
var template = '<div id="xxxx_soup_chart" ></div><div class="layout"><div class="layout_slider-settings"><div class="loading" id="xxxx_soup_loading"></div></div><div class="layout_slider"><input id="xxxx_soup_slider" name="area" value="1" ></div><div class="layout_slider-settings"> </div></div>';
var o = document.createElement("div");
o.id = idStr + "_Soup";
o.className = "frmStep";
o.innerHTML = template.replace(/xxxx/g, idStr);
document.body.append(o); // change this to append the item wherever it's supposed to go
}
createItem("JohnsMarket");
Any of that data seems like it could be stored in a hash keyed on the store name, including the chart itself; the rest is just string concatenation. But I agree, I'd try to move some of that onto the server side, even if it's just to retrieve the data used to create the charts.

jQuery/JavaScript: Avoid unique ID's for each row in a table?

I'm not sure if I'm doing this the right way. I have table which I fill with rows that each represent a song in a playlist. Right now, I assign a unique ID per row, and also assign som jQuery.data() to each ID.
html += '\
<tr id="track-' + i + '" class="tracks-row"> \
<td class="track"><a id="play-'+ i +'" class="play"></a><a id="play2-' + i + '">' + song.song_track + '<span class="mix-style">' + song_mix + '</span></a></td> \
<td class="artist">' + song.song_artist + '</td> \
<td class="favourites-holder"><a id="favourite-' + i + '" class="favourites"></a></td> \
' + delete_holder + ' \
</tr> \
';
So as you can see, each row has an ID like track-1, track-2 etc.
Is there another way to populate a playlist like this without assigning unique ID's to each track, or is this how it's supposed to be done? Each track has some properties like this:
$("#track-" + i).data("song_id", song.song_id);
$("#track-" + i).data("song_artist", song.song_artist);
$("#track-" + i).data("song_track", song.song_track);
$("#track-" + i).data("song_mix", song.song_mix);
$("#track-" + i).data("ps_id", song.ps_id);
... and also .click events for each track, which allows the user to play, sort, drag etc... It just feels like I'm doing it wrong :)?
You could store a reference to each generated row in your loop (assuming html only contains the HTML for a single row):
var row = $(html).appendTo("#table");
var data = row.data();
data["song_id"] = song.song_id;
data["song_artist"] = song.song_artist;
data["song_track"] = song.song_track;
data["song_mix"] = song.song_mix;
data["ps_id"] = song.ps_id;
row.click(function(){...});
It is not bad to have an ID for an element. But is definitely faster to make use of a reference if you have one and not use jQuery's selector engine over and over again.
Also if you attach the same click handler to every row, it is probably better to just attach one to the table and delegate it, e.g.
$('#table').delegate('tr', 'click', function(){...});
Unique id's makes sense or use the Metadata plugin to store all the extra data related to each row. http://plugins.jquery.com/project/metadata
It will store the data like:
<li class='someclass' data="{some:'random', json: 'data'}">...</li>
And you can query this like this:
var data = $('li.someclass').metadata();
if ( data.some && data.some == 'data' )
alert('It Worked!');
Whether the tr needs a unique id or simply a generic class is going to depend a lot on what you intend to do with either javascript (for targeting the rows) or css (also for targeting the rows). If you need to specifically target one row for styling or script effects, a unique id can be an effective way of doing it. If not, then it may be extra "mark-up" that is unnecessary.
In any case, if you do use id's, do make sure they are unique :-)
May be something like this with jquery:
var songs = function(songList){
this.songs = songlist;
this.init();
}
$.extend(songs.prototype, {
init: function(){
var self = this;
var table = $('#myTableID');
for(var i = 0; i < this.songs.length; i++){
var song = this.songs[i];
var songData = $('<tr><td class="track">'+song.track+'</td><td class="artist">'+song.artist + '</td></tr>');
table.append(songData);
songData.find('td.track:first')click(function){
self.SongClick(song.track);
});
//add other events here
}
}
},
SongClick : function(track){
//add here you click event
},
otherEvent : function(track){
//add otherEvent code
}
});
Like this you can create your javascript object and attach events to the dom elements directly as you parse them. You will not need any id's.
This approach will create a js object with its constructor
so you can say
var so = new songs(mySongList)
when it initializes it will retrieve a table with an id of myTableID and foreach song in the list, it will attach elements to it, and will attach the events directly to those elements.

Categories

Resources