InnerHTML not rendering as expected - javascript

I am currently making an Ajax call which returns an array of different projects in a portfolio.
Once the call is successful, I want to loop through the array and create a bootstrap carousel displaying each project name and details as a carousel item.
The issue that I'm having is that when I try to add HTML-code to the #project-carousel and #project-carousel-indicators, nothing shows up.
<div class="row" id="project-section">
<div class="col-lg-12">
<div class="carousel slide" data-ride="carousel" id="project-carousel">
<ol class="carousel-indicators" id="project-carousel-indicators">
<!-- loop -->
</ol>
<div class="carousel-inner" id="inner-project-carousel">
<!-- loop -->
</div>
</div>
</div>
</div>
document.addEventListener('DOMContentLoaded', getProjects(), false);
function getProjects() {
$.ajax({
url: '/Portfolio/getProjects',
type: 'POST',
async: false,
success: function(result) {
var innerCarousel = document.getElementById('inner-project-carousel');
var carouselIndicators = document.getElementById('project-carousel-indicators');
for (var i = 0; i < result.length; i++) {
if (i === 0) {
//This is being hit but it doesn't render the innerHTML
carouselIndicators.innerHTML = `<li data-target="#project-carousel" data-slide-to="${i}" class="active"></li>`;
innerCarousel.innerHTML =
`<div class="item active">
<div class="row item-wrapper">
<div class="col-lg-5">
<h3>${result[i].Client}</h3>
<p>${ result[i].Description}</p>
</div>
</div>
</div>`;
} else {
//this is also being hit but it doesn't render the innerHTML
carouselIndicators.innerHTML = `<li data-target="#project-carousel" data-slide-to="${i}"></li>`;
innerCarousel.innerHTML =
`<div class="item">
<div class="row item-wrapper">
<div class="col-lg-5">
<h3>${result[i].Client}</h3>
<p>${ result[i].Description}</p>
</div>
</div>
</div>`;
}
}
},
error: function(event, jqxhr, settings, excpetion) {
showError(event, jqxhr, settings, excpetion);
}
});
}

Call carousel manually after you append the html content.
$('.inner-project-carousel').carousel();

Related

Ajax status update in one page with one button

I am trying to update the status for my orders on the same page where it's displayed with an ajax HTML.
Displaying works just fine, but I want to set the status the the next one with only one click so I figured to use ajax for it too.
My ajax PUT for the next status
$(function () {
$(document).on('click', 'button#order_update', function (e) {
e.preventDefault();
let newStatus = '';
if ($(this).data('status') == 'pending') {
newStatus = 'confirm';
} else if ($(this).data('status') == 'confirm') {
newStatus = 'processing';
} else if ($(this).data('status') == 'processing') {
newStatus = 'picked';
}
let formStatusData = new FormData();
formStatusData.append('order_id', $(this).data('order'));
$.ajax({
type: 'PUT',
url: '{{ route("update-order-status") }}',
data: formStatusData,
success: (response) => {
console.log(response);
$(this).data('status', newStatus);
$(this).text(newStatus.charAt(0).toUpperCase() + ' order');
}
});
});
});
My ajax for the html
$.ajax({
type: 'GET',
url: '/order/view/all',
dataType: 'json',
cache: false,
success:function(response){
$('#pimage').attr('url','/'+response.product.product_thambnail);
var product_name = $('#pname').text();
var id = $('#product_id').val();
var quantity = $('#qty').val();
var OrderView = ""
$.each(response.orders, function (key,value){
var productsList = '';
$.each(value.product, function (key,value) {
productsList += `
<div class="row gx-4">
<div class="col-lg-3">
<div class="pos-task-product">
<div class="pos-task-product-img">
<div class="cover" style="background-image: url(${value.product_thambnail});"></div>
</div>
<div class="pos-task-product-info">
<div class="flex-1">
<div class="d-flex mb-2">
<div class="h5 mb-0 flex-1">${value.product_name_en}</div>
<div class="h5 mb-0">${value.pivot.qty} DB</div>
</div>
</div>
</div>
<div class="pos-task-product-action">
Complete
Cancel
</div>
</div>
</div>
</div>
`;
});
OrderView += `<div class="pos-task">
<div class="pos-task-info">
<div class="h3 mb-1" id=""><td>Üzenet: ${value.notes}</td></div>
<div><div><button type="button" class="btn btn-outline-theme rounded-0 w-150px data-status="${value.status}" data-order="${value.status}" id="order_update">Confirm Order</button></div></div>
<br>
<!-- You can safely remove this if not needed
<div class="mb-3">${value.product_id}</div>
<div class="h4 mb-8">${value.product_name}</div>
-->
<td> </td>
<div class="mb-2">
<span class="badge bg-success text-black fs-14px">${value.status}</span>
</div>
<div><span class="text">${value.created_at}</span> Beérkezett</div>
</div>
<div class="pos-task-body">
<div class="fs-16px mb-3">
Completed: (1/4)
</div>
${productsList}
</div>
</div>`
});
$('#OrderView').html(OrderView);
}
})
}
OrderView();```
**Im currently trying to use this button inside the HTML ajax**<div><button type="button" class="btn btn-outline-theme rounded-0 w-150px data-status="${value.status}" data-order="${value.status}" id="order_update">Confirm Order</button></div>
I tried using processData: false, but it just kills the process and the button is unusable. Please help.
Your problem is that you have many identifiers # with the same name.
id must be unique.
Replace in code
$(document).on('click', 'button#order_update'
to
$(document).on('click', 'button.order_update'
and
<button type="button" class="btn btn-outline-theme rounded-0 w-150px data-status="${value.status}" data-order="${value.status}" id="order_update">Confirm Order</button>
to
<button type="button" class="btn btn-outline-theme rounded-0 w-150px order_update" data-status="${value.status}" data-order="${value.status}">Confirm Order</button>
You still have the problem that you didn't close the class quote after w-150px, I closed it in the formatted code

How to append an element loaded via ajax to another previously loaded via ajax?

How can I add an HTML element received via AJAX to another HTML element previously added via AJAX? I tried to use .append but not working:
Example:
$.ajax({ (...), success: function() { $('.padding').append('<div id="request">Foo</div>') } });
This above working well, because .padding is initially loaded on the page. But when I try
$.ajax({ (...), success: function(data) { $('#request').append('<div class="description">Bar</div>') } });
not working. Why and how can I do it the right way?
Below, my .padding content:
<div class="padding">
<!-- Below, HTML result from first AJAX -->
<div class="ui attached segments" id="request">
<div class="ui right center aligned segment" id="header">
<h4 class="ui gray header"> P2017003</h4>
</div>
<div class="ui stackable three item menu segment">
<div style="justify-content: flex-start" class="item">
<button class="ui button">
<i class="left chevron icon"></i>
Voltar
</button>
</div>
<div class="item">
<!--Buttons AJAX-->
<div class="two ui red inverted small buttons segment-controller">
<button id="detalhes" class="ui active button">
Detalhes
</button>
<button id="acompanhar" class="ui button">
Acompanhar
</button>
</div>
</div>
<div style="justify-content: flex-end" class="item">
<button class="ui button">Imprimir</button>
</div>
</div>
<div class="ui main segment">
P-2017-003
</div>
</div>
</div>
I've rigged up this setup to simulate your situation. I've never once encountered the situation where the div with id request is not present in the DOM.
function getDataA() {
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1'
}).then(result => {
$('.padding').append('<div id="request">Call A finished</div>');
});
}
function getDataB() {
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/2'
}).then(result => {
if ($('#request').length === 0) {
console.log('no request element found');
}
$('#request').append('<div class="description">Call B finished</div>');
});
}
getDataA()
.then(getDataB);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="padding"></div>
My guess is your second call is done before the first call. Perhaps your code is something like this:
getDataA();
getDataB();
Now you're depending on which call finishes first. When call B finishes first your code breaks and when call A finishes first you're in luck.
You could run both requests in parallel if you want, it will require using $.when().
function getDataA() {
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1'
});
}
function getDataB() {
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/2'
});
}
$.when(getDataA(), getDataB())
.then(function(resultA, resultB) {
$('.padding').append('<div id="request">Call A finished</div>');
$('#request').append('<div class="description">Call B finished</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="padding"></div>
I've tried it with your provided HTML and I still am not able to reproduce the situation.
function getDataA() {
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1'
}).then(result => {
$('.padding').append(`
<!-- Below, HTML result from first AJAX -->
<div class="ui attached segments" id="request">
<div class="ui right center aligned segment" id="header">
<h4 class="ui gray header"> P2017003</h4>
</div>
<div class="ui stackable three item menu segment">
<div style="justify-content: flex-start" class="item">
<button class="ui button">
<i class="left chevron icon"></i>
Voltar
</button>
</div>
<div class="item">
<!--Buttons AJAX-->
<div class="two ui red inverted small buttons segment-controller">
<button id="detalhes" class="ui active button">
Detalhes
</button>
<button id="acompanhar" class="ui button">
Acompanhar
</button>
</div>
</div>
<div style="justify-content: flex-end" class="item">
<button class="ui button">Imprimir</button>
</div>
</div>
<div class="ui main segment">
P-2017-003
</div>
</div>
`);
const
trigger = document.getElementById('detalhes');
trigger.addEventListener('click', getDataB);
});
}
function getDataB() {
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/2'
}).then(result => {
if ($('#request').length === 0) {
console.log('no request element found');
}
$('#request').append('<div class="description">Call B finished</div>');
});
}
const
trigger = document.getElementById('fill-padding');
trigger.addEventListener('click', getDataA);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="fill-padding" type="button">Fill padding</button>
<div class="padding">
</div>
So, the issue is that jQuery hasn't update it's internal structures yet.
Sometimes this happens when appending elements, and trying to find them right away.
Instead do one of the 3:
Use jQuery.find() instead (eg: $("body").find("#id"))
Store the element html as a jQuery object:
var html = 'Hi';
var elem = $(html);
"Accumulate' the html all at once, and append it all at once.
var html = '';
$.ajax({ (...), success: function() {
html += 'Foo';
$.ajax({ (...), success: function(data) {
html += 'Bar';
$('.padding').append(html);
}
});
}
});

How to loop through JavaScript object in HTML?

I want to loop through a JavaScript object and repeat an html script as many times as the object length.
Here, I have the following in a script tag
<script>
var obj;
ipcRenderer.on('requests-results', (event, hosSchema) => {
obj = hosSchema
})
</script>
obj is an array retrieved from Mongo database as the picture below shows:
and I have the following inside <body> tag:
<div class="row">
<div class="col-md-4 col-sm-4">
<div class="card">
<div class="card-content">
<span class="card-title">.1.</span>
<p>.2.</p>
</div>
<div class="card-action">
.3.
.4.
</div>
</div>
</div>
</div>
How can I loop through obj to repeat the code between <div> tag as many times as obj.length?
I would suggest you to use Handlebars as #Amit mentioned.
first move out the code inside <div id="page-inner"> as below:
<div id="page-inner">
</div>
<script id= "requests-template" type="text/x-handlebars-template">
<div class="row">
{{#each requests}}
<div class="col-md-4 col-sm-4">
<div class="card">
<div class="card-content">
<span class="card-title">{{this.fieldName}}</span>
<p>{{this.fieldName}}</p>
</div>
<div class="card-action">
{{this.fieldName}}
{{this.fieldName}}
</div>
</div>
</div>
{{/each}}
</div>
</script>
Then inside another script page of type text/javascript you create the requests and assigned obj/hosSchema to it as below:
<script type="text/javascript">
var requestInfo = document.getElementById('requests-template').innerHTML;
var template = Handlebars.compile(requestInfo);
var requestData = template({
requests: obj
})
$('#page-inner').html(requestData);
</script>
NOTE: you need handlebars package installed (npm install handlebars --save)
Use templating script like Handlebars.js, Mustache.js or underscore.js.
Check below link for more description.
http://www.creativebloq.com/web-design/templating-engines-9134396
Try this:
var divlist = document.getElementsByTagName['div'];
var duplicate = null;
var rowIndex = -1;
var found = false;
for(var i = 0;i<obj.length;i++)
{
if(!found)
for(var p = 0;p<divlist.length;p++)
{
if(rowIndex != -1 && duplicate != null)
{
//set a Boolean to true and break
found = true;
break;
}
if(divlist[p].className == "col-md-4 col-sm-4")
{
//copy the element
duplicate = divlist[p];
}
else if(divlist[p].className == "row")
{
//identify the row's index
rowIndex = p;
}
}
//append the duplicate
divlist[rowIndex].appendChild(duplicate);
}

How can I get specific information from an external api to my ng-repeat

main.html
<div class="row" ng-repeat="post in myBlogPosts.slice().reverse()">
<br>
<div class="col-md-9 text-center">
<a href="#/blog-post/{{post._id}}">
<div class="thumbnail mTextBg customShadow">
<br>
<img class="img-responsive" src="http://placekitten.com/700/400" alt="">
<div class="caption">
<h3>{{post.imdbId}}</h3>
<p>{{post.blogContent}}</p>
</div>
</div>
</a>
</div>
<div class="col-md-3">
// I WANT THIS PART !!
<div class="well sideBars customShadow">
<img class="img-responsive" ng-src="{{film.Poster}}" title="{{film.Title}}">
<h4 class="text-center">{{film.Title}}</h4>
<p class="text-center" style="margin-bottom: 2px;"><b>Year:</b> {{film.Year}}</p>
<p class="text-center"><span class="customMargin">Runtime: {{film.Runtime}}</span></p>
<p class="text-center"><span class="customMargin">Director: {{film.Director}}</span></p>
<p class="text-center"><span class="customMargin">Writer: {{film.Writer}}</span></p>
<p class="text-center"><span class="customMargin">Actors: {{film.Actors}}</span></p>
</div>
</div>
</div>
This is part of my main.html . In h3 and p tags, I get imdbId and blogContent from my database and put it in ng-repeat in order to traverse blog posts in list. I want to be able get other information(under // I WANT THIS PART) for every post in myBlogPost.
MainController.js
var refresh = function() {
$http.get('/myDatabase').success(function(response) {
$scope.myBlogPosts = response;
});
};
refresh();
This part work as expected when page loaded.
I need also these parts in Main Controller ;
var onGetFilmData = function (data) {
$scope.film = data;
};
var onError = function (reason) {
$scope.error = reason;
};
imdb.getImdbInfo(-- need Id --).then(onGetFilmData, onError);
But I need to put each post id somehow in order to get specific data from Imdb api.
Imdb.js
(function(){
var imdb = function($http){
var getImdbInfo = function (id) {
return $http.get('http://www.omdbapi.com/?i=' + id + '&plot=short&r=json')
.then(function(response){
return response.data;
});
};
return{
getImdbInfo: getImdbInfo
};
};
var module = angular.module('myApp');
module.factory('imdb', imdb);
})();
If I delete id part and put a specific id string in getImdbInfo function, all post in main.html fill with just one film information. I want to fetch those data for each film in my database(I am holding imdb id of each film in my database).
MainController
var jsonObj = {};
var refresh = function() {
$http.get('/myDatabase').success(function(response) {
jsonObj = response;
for(var i = 0; i < jsonObj.length ; i++){
jsonObj[i].title = '';
}
for(var i = 0; i < jsonObj.length ; i++){
(function(i) {
imdb.getImdbInfo(jsonObj[i].imdbId).then(function (data) {
jsonObj[i].title = data.Title;
});
})(i);
}
$scope.myBlogPosts = jsonObj;
});
};
refresh();
main.html
<div class="row" ng-repeat="post in myBlogPosts.slice().reverse()">
<br>
<div class="col-md-9 text-center">
<a href="#/blog-post/{{post._id}}">
<div class="thumbnail mTextBg customShadow">
<br>
<img class="img-responsive" src="http://placekitten.com/700/400" alt="">
<div class="caption">
<h3>{{post.imdbId}}</h3>
<p>{{post.blogContent}}</p>
</div>
</div>
</a>
</div>
<div class="col-md-3">
<!-- Side Widget Well -->
<div class="well sideBars customShadow">
<h4 class="text-center">{{post.title}}</h4>
</div>
</div>
</div>
I solve my problem with adding response from Imdb to my json object which is coming from database. So I can easily use them in ng-repeat.

jQuery fade content out and then fade new content in continuously

I want to continuously fade 2 pieces of content in and out of the same position. Currently the fade in fade out works but the content is below the other content and they are both viewable when the document loads.
To put it simply the content will keep switching between #fade1 and #fade2.
HTML:
<section id="text-slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<p id="fade1">"IT WAS SUCH A PLEASURE WORKING WITH STOKES STREET ON SPECTROSPECTIVE. THEY SURPASSED ALL EXPECATIONS. WE WERE GOBSMACKED, FRANKLY."</p>
<p id="fade2" style="opactiy:0">test</p>
</div><!-- col -->
<div class="col-md-4">
<p></p>
</div><!-- col -->
<div class="col-md-4">
<p></p>
</div><!-- col -->
</div><!-- row -->
</div><!-- container -->
</section><!-- text slider -->
JS:
$(document).ready(function () {
// runs fade code for homepage content
fadeThem();
}
// fades content in and out on homepage
function fadeThem() {
$("#fade1").fadeOut(3000, function() {
$("#fade2").fadeIn(2000, fadeThem());
$("#fade2").fadeOut(2000, fadeThem());
$("#fade1").fadeIn(2000, fadeThem());
});
}
Why don't you put your code in : $( window ).load(function() {} ;
Something like this :
$( window ).load(function() {
// -- Snipped -- //
$(".right-image-crm").addClass('right-image-up');
$(".left-image-crm").addClass("left-image-up");
$(".center-image-crm").addClass("center-image-up");
$(".loader").fadeOut(1000,function(){
}
});
Working Code (JS Fiddle): http://jsfiddle.net/nfdebmen/4/
You can have any Number of PlaceHolders in this code. I have made 4.
var _toggle = {
totalNodes: null,
lastNode: 0,
duration: 1000,
init: function () {
_toggle.totalNodes = $(".toggle").length;
_toggle.next();
},
next: function () {
var nextNode = _toggle.lastNode + 1;
if (nextNode >= _toggle.totalNodes) {
nextNode = 0;
}
//
$(".toggle:eq(" + _toggle.lastNode + ")").fadeOut(_toggle.duration, function () {
$(".toggle:eq(" + nextNode + ")").fadeIn(_toggle.duration);
_toggle.next();
});
_toggle.lastNode = nextNode;
}
}
$(document).ready(function () {
_toggle.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="text-slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<p class = "toggle active">"IT WAS SUCH A PLEASURE WORKING WITH STOKES STREET ON SPECTROSPECTIVE. THEY SURPASSED ALL EXPECATIONS. WE WERE GOBSMACKED, FRANKLY."</p>
<p class = "toggle" style = "display: none;">test</p>
<p class = "toggle" style = "display: none;">Ahsan</p>
<p class = "toggle" style = "display: none;">http://aboutahsan.com</p>
</div><!-- col -->
<div class="col-md-4">
<p></p>
</div><!-- col -->
<div class="col-md-4">
<p></p>
</div><!-- col -->
</div><!-- row -->
</div><!-- container -->
</section><!-- text slider -->
Try using .fadeToggle()
$(document).ready(function() {
var p = $("p[id^=fade]");
function fadeThem() {
return p.fadeToggle(3000, function() {
fadeThem()
});
}
fadeThem();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section id="text-slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<p id="fade1">"IT WAS SUCH A PLEASURE WORKING WITH STOKES STREET ON SPECTROSPECTIVE. THEY SURPASSED ALL EXPECATIONS. WE WERE GOBSMACKED, FRANKLY."</p>
<p id="fade2" style="display:none">test</p>
</div>
<!-- col -->
<div class="col-md-4">
<p></p>
</div>
<!-- col -->
<div class="col-md-4">
<p></p>
</div>
<!-- col -->
</div>
<!-- row -->
</div>
<!-- container -->
</section>
<!-- text slider -->

Categories