How to create <div> with several children in loop - javascript

I created a div with a class name of div class = "postWindow".
html:
<div class = "postWindow">
<div class = "userName">Initial Name</div>
<div class = "postTitle">Init title</div>
</div>
Now, what I am trying to achieve is that I can create upto 10 of these in a single html window. (upto because the amount of posts may vary from 1-10 and the amount is dynamic)
I tried using the appendChild() method but realized it only populated the div as the new element. It did not create a new postWindow
My .js file has the following function:
function createPost(){
var count = 0;
while(count < upLimit){
$.ajax({
url: root + '/posts/'+curr,
type: "GET",
dataType: "JSON",
success: function(response){
postJson = response;
//im lost here
}
});
count++;
}
Using console.log my Json response is something like this
0: Object
title: "First post"
body: "This is a post"
id: 1
userId: 27
.
.
.
100: //same format of data as object 0
Any help would be appreciated! :D

Here's a simple fiddle to demonstrate the above: https://jsfiddle.net/LLceoLwg/
HTML:
<div class="container">
<div class = "postWindow">
<div class = "userName">Initial Name</div>
<div class = "postTitle">Init title</div>
</div>
</div>
jQuery:
$(document).ready(function(){
for(var i=0; i<10; i++){
$(".postWindow").parent().append("<div class='postWindow'><div class='userName'>Initial Name</div><div class='postTitle'>Init title</div></div>");
}
});

Related

Add class/text to a jQuery element

I'm trying to clone the following HTML template and add class/text to it.
<template id="result">
<section>
<div class="alert">
<p class="someText"></p>
</div>
</section>
</template>
So the user first submits a question:
<div id="answer"></div>
<section class="row">
<form id="form" action="/" method="GET">
<div>
<input id="question" />
</div>
</form>
</section>
Then the script executes:
$(document).ready(function () {
$('#form').on('submit', function (event) {
$.ajax({
data: {...},
type: 'GET',
url: '/result'
}).done(myFunction);
});
});
And finally it clones the template (ID #result), add a class to the element containing a class alert and add some text to the element containing a class someText, and appends it to the element containing ID #answer.
function myFunction(result) {
clone = $('#result').clone();
$('.alert', clone).addClass('myClass');
$('.someText', clone).text('myText');
clone.appendTo("#answer");
}
The function executes (I added a console.log() to the end of it to be sure) but nothing is appending.
Consider the following.
function create_message(result) {
var section = $("#result").children().clone();
$('.alert', section).addClass(result.status);
$('.address', section).text(result.address);
$('.extract', section).text(result.extract);
$('.question', section).text(result.question);
section.appendTo("#answer");
}
This creates a clone of all the HTML Elements inside the Template with ID result. It then finds specific classes inside the Object section and makes changes.
You can also do the following.
section.find(".alert").addClass(result.status);
See more: https://api.jquery.com/clone/
Update
Use <template> to hold some content that will be hidden...
So if you Clone the Template and append it, it will still be hidden.
Try the following:
function myFunction(result) {
clone = $('#result > section').clone();
$('.alert', clone).addClass('myClass');
$('.someText', clone).text('myText');
clone.appendTo("#answer");
}
Update 2
I don't use <template>, so I had to re-read some stuff. It has a content portion, so it has an HTML Fragment contained within and is not like other HTML Elements, more like an iFrame. So we need to collect the content versus cloning it.
See: How to use HTML template tag with jQuery?
Here is a working example: https://jsfiddle.net/Twisty/rpd9h0mf/20/
Your code will be something more like the following.
JavaScript
$(function() {
function showResults(results) {
var clone = $($('#result').html());
$('.alert', clone).addClass(results.class);
$('.someText', clone).text(results.answer);
clone.appendTo("#answer");
}
$('#question-form').submit(function(event) {
event.preventDefault();
$.ajax({
data: {
q: $("#question").val()
},
type: 'GET',
url: '/result',
success: showResults
});
});
});
This creates a new jQuery Object based on the HTML Content of the Template. Now you can properly edit it and append it.

How do I replace variables in HTML with an object of variables from jQuery?

I am trying to make a system for my web page that gets the content of a template found in the HTML and then replaces the appropriate variables with the corresponding values which is stored in an object. The problem is that nothing is being replaced. In this example, I am getting the contents of an RSS file that displays forum posts. I use ajax to get the contents, then iterate through each item. I assign the xml tag values to an object whose keys correspond to the variabls in the HTML template. For every post found, it should replace the HTML variable with the contents of the xml tag.
This is my Javascript:
$.ajax({
url: "rsstest.xml",
type: "GET",
dataType: 'xml',
crossDomain: true,
success: function(xml){
var news = $('#news-results');
news.empty();
if($(xml).find('item').length > 0){
$(xml).find('item').each(function(){
var temp_vars = {
news_title: $(this).find('title').text(),
news_body: $(this).find('description').text(),
news_date: $(this).find('pubDate').text(),
news_link: $(this).find('link').text()
}
var template = $('#news-template').contents().clone();
for(const variable in temp_vars){
template.text().replace("{"+variable+"}", temp_vars[variable])
}
news.append(template);
})
} else {
news.append($('<p></p>').text('There is no news to display at this time.'));
}
}
})
This is my HTML:
<h1>Announcements</h1>
<div id="news-results">
</div>
<div id="news-template" style="display: none;">
<div class="media">
<div class="media-body">
<h3>{news_title}</h3>
<p>{news_body}</p>
<div class="media-footer">
<div class="col-left">
<h4>Posted on {news_date}</h4>
</div>
<div class="col-right">
Read More
</div>
</div>
</div>
</div>
</div>
What am I doing wrong?
Code below will only replace the text without assigning it.
template.html().replace("{"+variable+"}", temp_vars[variable])
You have to assign after replacing the text to update the actual value.
template.html(template.html().replace("{"+variable+"}", temp_vars[variable]))

How do i loop through an ajax response and display it in html

I'm a PHP developer and i'm looking for something like a foreach loop for an ajax response
I have a card design in html and i would like the response of the ajax request make a new card for each object in the ajax response
This is my code for far
ajax:
$.ajax({
type:"GET",
url:"http//url_to_api.com/projects/v1" ,
dataType: "json",
success:function(mdata){
var result = '';
$.each(mdata, function (index, element) {
result += + element.project_name ;
console.log(element.project_name); // alert the values
});
$('.cho-card-title').html(result);
}
});
html that i want my ajax response to populate for each object in the response data
<div class="card-row">
<div class="card">
<div class="card-img">
//image.of.ajax.responce
<img src="">
</div>
<div class="card-title">
// title.of.ajax.responce
</div>
<div class="card-description">
// title.of.ajax.description
</div>
<div class="select-card">
Select
</div>
</div>
</div>
currently the code loops through the response and displays everything in one card how do I get every response in its own card.
You can create and append elements inside the .each statement.
This is untested, but something like this might work:
$.each(mdata, function (index, element) {
var div = $('<div />') // Create the div
.addClass('cho-card-title') // Add the class name
.html(element.project_name); // Insert the html
// Append the new div to whatever your container is
$('.container').append(div);
});

JavaScript loop printing a HTML code

I have this HTML code:
<div class="content">
<article class="underline">
<a href="incidente.html"><img id="incidente"
src="img/buraco.jpg" alt="Incidente" /></a>
<h2></h2>
<p id="desc">Esse buraco na rua Montes Claros já está há 1 ano
trazendo transtornos aos moradores</p><p></p>
<div class="date" id="date"></div>
<img class="tick" alt="não resolvido" src="img/no-tick.png">
<img class="apoio" alt="apoiar" src="img/apoio.png">
</article>
And this ajax that receive an array:
$.ajax({
type: "GET",
url: "http://localhost/again/www/index.php",
dataType: "json",
success: function (data) {
var tit = "";
// Loop over each object
for (var $i = 0; $i < data.length; $i++) {
var object = data[$i];
tit+= object.titulo;
}
$('#tit').html(tit);
}
});
</script>
Now, it is inserting everything in the same HTML code(off course,because I don't have a foreach), but I would like to show this HTML for each row(each "tit") that i am receiving...Can someone help me?
What I understand is this: You have an array with text that you want to loop through, and display.
If this was your array:
["Text 1", "Text 2", "Text 3", "Text 4", "Text 5"]
then you want this to be displayed
<element>Text 1</element>
<element>Text 2</element>
<element>Text 3</element>
<element>Text 4</element>
<element>Text 5</element>
The problem in your code
The problem I see in your code is that you are using jquery's .html(arrayItem) which will overwrite any existing text inside of the element.
Instead look at my solution: (http://jsfiddle.net/ProgrammerKid/v6upsLp8/)
HTML
<div id="tit"></div>
JavaScript
$(document).ready(function () {
var tit = ["Text 1", "Text 2", "Text 3", "Text 4", "Text 5"];
for (var i in tit) {
var element = document.createElement("h2");
element.innerHTML = tit[i];
$("#tit").append(element);
}
});
over here we use jQuery's .append, and we create a node and we append the node into the wrapper element.
If you have any questions, please leave a comment below and I will reply ASAP
Your best bet to keep things organised is to use a templating engine like handlebars. I've set up a jsfiddle for you that renders out your articles using the example data you provided (which needed a bit of formatting to get working).
http://jsfiddle.net/4ud6rLfq/10/
// This is what you'll need to get the data via AJAX
var source = $("#template").html();
var template = Handlebars.compile(source);
$.ajax({
type: "GET",
url: "http://localhost/again/www/index.php",
dataType: "json",
success: function (data) {
$.each(data, function(key, value) {
$('#articles').append(template(value));
});
}
});
// A demo using the data you provided (formatted a bit)
var data = [
{
"codigo":"32",
"titulo":"Some title here",
"descricao":"Here is my description",
"data":"2015-10-29 21:48:13"
},{
"codigo":"33",
"titulo":"Title here",
"descricao":"description here",
"data":"2015-10-30 20:45:46"
}
];
var source = $("#template").html();
var template = Handlebars.compile(source);
$.each(data, function(key, value) {
$('#articles').append(template(value));
});
And the HTML you'll need:
<script id="template" type="text/x-handlebars-template">
<article class="underline">
<a href="#">
<img class="incidente" src="" alt="{{titulo}}" />
</a>
<h2>{{titulo}}</h2>
<p class="desc">{{descricao}}</p>
<p></p>
<div class="date" class="date">{{data}}</div>
<img class="tick" alt="não resolvido" src="img/no-tick.png">
<img class="apoio" alt="apoiar" src="img/apoio.png">
</article>
</script>
<div id="articles"></div>
There's an example using your $.ajax function commented out and another example below it using the data variable - all you need to do is include handlebars in your page after jQuery and it should be good to go. You can edit the variables in the template to match whatever you pass back to your script via ajax.
Basically what's happening is your setting up the template for your data first, then you loop over your data and bind each item to the template, the item template is then appended to the #articles container as HTML and it moves on to the next item until it's finished.
If I understand you, you have multiple articles and you want to change their titles dynamically?
If so, first of all you should remove;
$('#tit').html(tit);
Then inside the loop put this:
$('#content article:eq('+$i+')').find('#tit').html(object.titulo);
This works only if $i is the same as the elements index relative to their parent.
You can make a function which returns a string with the html-markup. If you need to populate the html-template then you will need to send params to that function. Here is an example of the javascript:
http://jsfiddle.net/fnLjcfvr/1/
function getHtml(title){
var html = "";
html += '<div class="content">';
html += '';
html += '<article class="underline">';
html += '<a href="incidente.html"><img id="incidente"';
html += 'src="img/buraco.jpg" alt="Incidente" /></a>';
html += '<h2> + ' title ' + </h2>';
html += '<p id="desc">Esse buraco na rua Montes Claros já está há 1 ano trazendo transtornos aos moradores</p><p></p>';
html += '<div class="date" id="date"></div>';
html += '<img class="tick" alt="não resolvido" src="img/no-tick.png">';
html += '<img class="apoio" alt="apoiar" src="img/apoio.png">';
html += '';
html += '</article>';
return html;
}

Unable to remove css class and add a new one

I have this function that goes through each breadcrumb in a navbar and I want to change the styling of the breadcrumb depending what page they are on.
Here is the basic HTML of the breadcrumb navbar
<div id="WCBar">
<div class="bc_nav current span" id="bc_main">
<a class="bc_1" id="lnkCrumb" href="javascript:__doPostBack('ctl00$breadcrumbnav1$ctl00$lnkCrumb','')">
<li>Account Info</li></a>
<span class="step-arrow"></span>
<input name="ctl00$breadcrumbnav1$ctl00$hdnPageName" id="hdnPageName" type="hidden" value="WCQuoteMain2.aspx">
</div>
<div class="bc_nav a" id="bc_main">
<a class="aspNetDisabled bc_2" id="lnkCrumb"> <li>Rate</li></a>
<span class="step-arrow"></span>
<input name="ctl00$breadcrumbnav1$ctl01$hdnPageName" id="hdnPageName" type="hidden" value="WCQuoteRatingV4.aspx">
</div>
<div class="bc_nav a" id="bc_main">
<a class="aspNetDisabled bc_3" id="lnkCrumb"><li>Questions</li></a>
<span class="step-arrow"></span>
<input name="ctl00$breadcrumbnav1$ctl02$hdnPageName" id="hdnPageName" type="hidden" value="questions.aspx"></div>
<div class="bc_nav last" id="bc_main">
<a class="aspNetDisabled bc_4" id="lnkCrumb"><li>Final</li></a>
<span class="step-arrow" style="background-image: none;"></span>
<input name="ctl00$breadcrumbnav1$ctl03$hdnPageName" id="hdnPageName" type="hidden" value="managesubmission.aspx"></div>
I then call this function in Javascript:
function WCBar(pagename, iframepagename, currentSet) {
$('.bc_nav', $('#WCBar')).each(function () {
iframepagename = $(this).find('input[id*="hdnPageName"]').attr('value');
var bcMain = $(this).find('div[id*="bc_main"]');
var lnkCrumb = $(this).find('a[id*="lnkCrumb"]');
if (pagename == iframepagename) {
//bcMain.addClass("current span");
bcMain.attr("class", "current span");
currentSet = 1;
// notify server
$.ajax({
type: "POST",
url: window.location.pathname + "/UpdateIFrameBreadcrumb",
data: "{'pagename':'" + iframepagename + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// alert(msg.d);
},
error: function (msg) {
// alert(msg.d);
}
});
}
else {
if (lnkCrumb[0].href.length > 1) { //&& currentSet == 0
//bcMain.attr("class", "bc_nav enabled span");
bcMain.removeClass("bc_nav");
bcMain.addClass("bc_nav enabled span");
}
else {
//bcMain.attr("class", "bc_nav a");
bcMain.removeClass();
bcMain.addClass("bc_nav a");
}
}
});
}
When I mouse over bc_Main during a debugging session, context > className shows the proper class but trying to determine if bc_main has a class results in
?bcMain.hasClass('bc_nav');
false
in Visual Studio's Immediate window.
Furthermore, trying to determine what the values are in class gets me an undefined error.
var x = bcMain.attr('class');
undefined
No class is ever removed from bc_main, no matter if I try .removeClass() and leave it empty or try .removeClass('bc_nav');
I have checked to make sure nothing is defaulting elsewhere and can't find anything.
Thanks for your help.
It looks like a scope issue. You are using THIS to perform your find which shouldn't find itself. Your .bc_nav elis actually your #bc_main el, so you might as well just treat $(this) as bcMain. I don't know why you are iterating on both .bc_nav and #WCBar, seems like you should only use .bc_nav.
$('.bc_nav', $('#WCBar')).each(function () {
...
var bcMain = $(this).find('div[id*="bc_main"]');
saying $(this) in this instance is the same as saying $('.bc_nav') so you are essentially doing $('.bc_nav').find('div[id*="bc_main"]'); which won't work since #bc_main isnt' a child of .bc_nav.
If you are trying to empty the class attribute use:
$('#myElementID').removeAttr('class');
or this
$('#myElementID').attr('class', '');
To remove a specific class, you have to use the class name:
$('#myElementID').removeClass('myClassName');
Also, FWIW, in the else statement, this line
bcMain.removeClass("bc_nav");
is pointless, being that it's followed by this one
bcMain.addClass("bc_nav enabled span");

Categories

Resources