Update html meteor? - javascript

I am trying to output an estimated time based off the number of items (people) within my database (this is a wait list). Currently I save a value in the quick form called countNumber. This is just set to 1 everytime. I then get the count of all the items by finding the all items that have countNumber = 1 (all of them). I then try updating the html using getElementById().
The problem I am having is that when I add a person to the database the estimated time will go up appropriately. However when I refresh the page the html resets to 0 like the initial html that is put in.
How do I fix this so that the html will always display the appropriate time even when the page is refreshed?
Html code:
<head>
<title>Wait List</title>
</head>
<template name= "home">
<body>
<h2 id="insert">Approximate Wait Time: 0 Minutes</h2>
<div class="col-lg-6 col-lg-offset-3">
{{>quickForm id="studentForm" collection="Students" type="insert" template="bootstrap3-horizontal" label-class="col-sm-3" input-col-class="col-sm-9"}}
</div>
</body>
</template>
js code:
AutoForm.hooks({
studentForm:
{
onSuccess: function (insert,result) {
var totalCount = Students.find({countNumber:1}).count();
var waitTime = "Approximate Wait Time: " + totalCount*15 +" Minutes";
document.getElementById("insert").innerHTML = waitTime;
...
},
}
});

You should put this into a helper instead of a hook.
Template.home.helpers({
waitTime: function(){
var totalCount = Students.find({countNumber:1}).count();
var waitTime = totalCount*15;
return waitTime;
}
});
and change the <h2> line in the html to this.
<h2 id="insert">Approximate Wait Time: {{waitTIme}} Minutes</h2>

Related

My heading tags aren't loading the way I want them to in Vue JS

My goal is to load a message wrapped inside (working) heading tags of different sizes a la
<h1>message 1</h1>
<h2>message 2</h2>
<h3>message 3</h3>
based on a random integer I generate in my code and using mustaches {{ }} to load the message from the Computed Property into the browser. But my attempts to load different headings into the browser have failed.
Instead of the heading tag loading up as I expect in big font, it just sits there as if it was typed as regular text.
I receive no error messages about it.
I've tried removing the <p></p> tags around the mustaches in case that was disrupting the <h1> tags within. That didn't work.
I've tried adding separate mustaches to load just the heading tags around the message I want to turn into a heading. That didn't work.
So here is my code...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>App</title>
</head>
<body>
<div id="root">
<input type="text" id="input" v-model="someNumber"></input>
<p> the value is: {{ someNumber }}</p>
<button #click="randomNum">random a new number</button>
<p>Result: {{ sleepyTime }} </p>
</div>
<script src="https://unpkg.com/vue#2.1.3/dist/vue.js"></script>
<script>
new Vue({
el: "#root",
data: {
goToBed: false,
someNumber: 0
},
methods: {
randomNum() {
this.someNumber = Math.random() * 10
}
},
computed: {
sleepyTime: function () {
if (this.someNumber < 5) {
return "<h1>It's okay to go back to bed.</h1>"
} else if (5 < this.someNumber && this.someNumber < 7) {
return "<h3>One more hours plus a cup of coffee</h3>"
} else if (7 < this.someNumber && this.someNumber < 9) {
return "<h2>2 more hours and 2 cups of coffee.</h2>"
} else if (this.someNumber > 9) {
return "<h1>Drill 3 cups of coffee. And just stay up.</h1>"
}
}
}
});
</script>
</body>
</html>
The result I want is: For example, "It's okay to go back to bed." loading as it does on the page here in big lettering.
Instead I get the text loading like:
<h1>It's okay to go back to bed.</h1>
with the h1 tags displayed in the browser as text.
What to do?
p.s. I am about to leave for work so I'll be back to check on this thread at about 11:40 PM Pacific time.
The value output using {{ ... }} we be escaped. There is no way to disable this.
To output HTML you can use v-html. However, that is not equivalent to {{ ... }} as v-html needs to be hung off an element and cannot be used to create partial content.
So you can write this:
<p v-html="'Result: ' + sleepyTime"></p>
The other option, and usually the preferred option, is to keep the markup in the template. That would look something like this:
<p>Result:
<h1 v-if="someNumber < 5">It's okay to go back to bed.</h1>
<h3 v-else-if="someNumber < 7">One more hours plus a cup of coffee</h3>
<h2 v-else-if="someNumber < 9">2 more hours and 2 cups of coffee.</h2>
<h1 v-else>Drill 3 cups of coffee. And just stay up.</h1>
</p>
You could also do it something like this:
<p>Result:
<component :is="headingSize">{{ content }}</component>
</p>
Here headingSize and content would be computed properties that set the tag name and content respectively. You could implement them using a single property that returns an object, e.g.:
computed: {
heading () {
if (this.someNumber < 5) {
return { tag: 'h1', content: "It's okay to go back to bed." }
}
// etc.
}
}
with:
<p>Result:
<component :is="heading.tag">{{ heading.content }}</component>
</p>

Browser get freezed after loading huge data in angularjs (2k rows)

I am fetching data from server its loading time is quite good, But
while rendering all data almost 3k rows to view (angularJs) browser
get freeze and after some time its crashed also.
I tried pagination but after crossing 500 rows its start freezing. Some time its load all data into view but while scrolling or applying some event like click again got freeze.
Here is the code where i am listing all data.
<div class="divRow" ng-repeat="list in campaignDetailListfilterCopy.campaign_items | limitTo:totalDisplayed"">
<div class="divCell">
<div style="float:left;width: 325px;">
<div>
<span ng-if="list.monitor_type == 3">{{list.items.media_id}}</span>
<div class="moImgPreview hoverPreview creativePreview"> <img alt=""ng-src="{{list.items.media_thumbnail}}"/></div>
</span>
</div>
<p><strong class="lang" key="campaign_List_view_text2">Location</strong><span>{{list.items.media_address}}</span> </p>
</div>
</div>
<button class="btn" ng-click="loadMore()">Load more</button>
//the controller
$scope.totalDisplayed = 20;
$scope.loadMore = function () {
$scope.totalDisplayed += 20;
};
$scope.campaignDetailListfilterCopy.campaign_items = data;
you should keep two separate lists one holds all the data and the other one should hold only 20 at first and when you press load more it should add 20 more to the list from the list that has all the data with a loop
$scope.loadMore = function(){
let start = $scope.listToShow.length;
for(let i = start; i<= start + 20; i++){
if(angular.isDefined($scope.campaignDetailListfilterCopy.campaign_items[i]) {
$scope.listToShow.push($scope.campaignDetailListfilterCopy.campaign_items[i]);
}
}
}
$scope.listToShow= []
$scope.campaignDetailListfilterCopy.campaign_items = data;
$scope.loadMore();
And in your html
<div class="divRow" ng-repeat="list in listToShow">
and maybe inside your list you can add a button that calls the loadMore
<button ng-click="loadMore()"> load more</button>

Rateit plugin not working for content appended after page load

I am using rateit plugin by http://gjunge.github.io/rateit.js/examples/
Every thing works fine until i load content with starts on page dynamically after page load. Stars simply don't appear.
My dynamically generated content which is appended to the page looks likes this(form ajax request):
<div class="caption">
<p id="productNameInFeeds"><a href="https://youlense.com/view/IPHONE">
<b>IPHONE</b></a> - I PHONE 6S</p>
<div class="rateit" data-rateit-value="3.00"
data-rateit-ispreset="true" data-rateit-readonly="true" data-rateit-max="10">
</div>
<div>
3.00 Stars | 2 Reviews | 10 Views | 1 Followers
</div>
</div>
my js file looks likes this
$(document).ready(function() {
var page = 1;
$("#load_more_feeds").click(function(){
$.post("my/feeds/more",
{
page: page
},
function(data, status){
if(data != ''){
$("#feedHolder").append(data);
page = page + 1;
}
});
$('div.rateit, span.rateit').rateit();
});
});
Can anyone tell me the solution?
Thanks in advance
Found this: https://stackoverflow.com/a/33071447/3499595
Just after you append the new content, call this:
$('div.rateit, span.rateit').rateit();
This initializes all the rateit elements.

AngularJS Pagination - Get Current Page and Pass to Controller

I am implementing server-side sorting and pagination, and I need to pass the current page that the user is on so that if they sort and are on a page different than the first page (ex. sort by "least votes" on page 5 does not show the resorted results from page 1 on page 5 but shows the resorted results that should be on page 5). Basically, I need in place sorting but can't figure out how to get the current page.
Server side paging is working without issue, and I believe I am missing something simple here.
HTML (please note that I am using this custom directive: https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination)
<tr dir-paginate="article in articles | itemsPerPage:articlesPerPage" total-items="totalArticles" current-page="currentPage">
<td>
<div class="col-md-1 voting well">
<div class="votingButton" ng-click="upVote(articlevote);">
<i class="glyphicon glyphicon-chevron-up"></i>
</div>
<div class="badge badge-inverse">
<div>{{article.articlevotes}}</div>
</div>
<div class="votingButton" ng-click="downVote(articlevote);">
<i class="glyphicon glyphicon-chevron-down"></i>
</div>
</div>
</td>
<td>{{article.articletitle}}</td>
<td>{{article.articlecategoryid}}</td>
<td><a ng-href="#article/{{article.id}}/{{article.articlelink}}">{{article.articletitle}}</a></td>
</tr>
</table>
<dir-pagination-controls on-page-change="pageChanged(newPageNumber)"></dir-pagination-controls>
Controller
$scope.articles = [];
$scope.totalArticles = 0;
$scope.articlesPerPage = 10; // this should match however many results your API puts on one page
$scope.currentPage = 1;
// sort options
$scope.sortoptions = [
{
label: 'Most Votes',
value: 'articlevotes desc',
},
{
label: 'Least Votes',
value: 'articlevotes asc',
}
];
var sortBy = $scope.sortoptions[0].value;
var currPage = $scope.currentPage; // Get current page
console.log(currPage);
// Initial page load
getResultsPage(1, sortBy);
$scope.update = function (articleSortOrder) {
// get value of sort and log it
console.log(articleSortOrder.value);
sortBy = articleSortOrder.value;
// log current page and pass as parameter
console.log(currPage);
getResultsPage(currPage, sortBy); // need to make dynamic so it gets current page
}
$scope.pageChanged = function (newPage) {
getResultsPage(newPage, sortBy);
};
function getResultsPage(pageNumber, sortorder) {
// currently skipping by page number * articles per page
pfcArticles.query({ $skip: (pageNumber - 1) * $scope.articlesPerPage, $top: $scope.articlesPerPage, $orderby: sortorder, $inlinecount: 'allpages' }, function (data) {
$scope.articles = data.results;
$scope.totalArticles = data.count; // Can change to hard number to reduce total items instead of LimitTo
});
}
The problem is that you are assigning:
var currPage = $scope.currentPage;
So currPage is set to 1 as your controller is instantiated, and is then never changed. So when you reference currPage later in the controller, it remains 1.
You should instead directly reference the $scope.currentPage value, which will get updated by the pagination directive.
So try changing the "update" method to this:
$scope.update = function (articleSortOrder) {
sortBy = articleSortOrder.value;
getResultsPage($scope.currentPage, sortBy);
}
This should pass the correct current page value to your service.

Loading specific div based on the results of multiple dropdowns

EDIT: Would the approach be much easier if the Javascript listed was removed completely, and the dropdown menus restyled as <div>'s within <li>'s, and the final div was generated by a Javascript onclick event? e.g.
<a id="click_link">click me</a>
$("#click_link").click(function(){
$('#div').load('http://www.link.com/');
});
Either way, the problem at hand...
My decision to use an elegant-looking javascript solution is highlighting my massive inexperience when it comes to javascript! The problem is, on the face of it, simple...
Once an option has been chosen on each of the dropdown menus, I need a final div to load so that a specific button can be shown (a link to buy the item with the specified options, e.g. choosing Necklace D, with Stone Option B, and Delivery Option A = loading div with 'Buy' Button #17)
The dropdowns are divs that are filled and styled through the Javascript (as opposed to using the simpler <form> and <input> method), giving the flexibility to add two lines of differently styled text for each option etc. - This is where I step into the realm of the unknown and my inexperience shines through.
The isolated section is viewable in its entirity here
Ok, to the code.
Here's the Javascript:
function createByJson() {
var pearlData = [
{description:'Choose your pearl...', value:'Pearls', text:'Pearls'},
{description:'Beautiful black stone', value:'Black Pearl', text:'Black Pearl'},
{description:'Classic white stone', value:'White Pearl', text:'White Pearl'}
];
$("#DropItPearls").msDropDown({byJson:{data:pearlData, name:'pearls', width: 200}}).data("dd");
var blodeuweddData = [
{description:'Choose your item...', value:'Blodeuwedd', text:'the Blodeuwedd Collection'},
{description:'A striking statement', value:'BlodeuweddCelticStatement', text:'Celtic Statement Piece'},
{description:'Gold laced flower and pearl', value:'BlodeuweddBracelet', text:'Bracelet'},
];
$("#DropItBlodeuwedd").msDropDown({byJson:{data:blodeuweddData, name:'blodeuwedd', width: 250}})
.msDropDown({on:{change:function(data, ui) {
var val = data.value;
if(val!="")
window.location = val;
}}}).data("dd");
var deliveryData = [
{description:'Choose your method...', value:'Delivery', text:'Delivery Options'},
{description:'4-6 weeks delivery', value:'Four Weeks', text:'Made To Order'},
{description:'(unavailable on this item)', value:'Rush', text:'Express Delivery', disabled:true}
];
$("#DropItDelivery").msDropDown({byJson:{data:deliveryData, name:'delivery', width: 200, selectedIndex: 1}}).data("dd");
paymentData = [
{ description:'How would you like to pay?', value:'Payment', text:'Payment Method'},
{image:'images/msdropdown/icons/Visa-56.png', description:'Secure online payment', value:'Visa', text:'Visa'},
{image:'images/msdropdown/icons/Paypal-56.png', description:'Secure online payment', value:'Paypal', text:'Paypal'},
{image:'images/msdropdown/icons/EmailPay-56.png', description:'Order by email', value:'Email Payment', text:'Send Your Details'},
{image:'images/msdropdown/icons/Mastercard-56.png', description:'(coming soon)', value:'Mastercard', text:'Mastercard', disabled:true},
{image:'images/msdropdown/icons/Collect-56.png', description:'(coming soon)', value:'Collection', text:'Order and Collect', disabled:true},
{image:'images/msdropdown/icons/Email-56.png', description:'email Menna', value:'Other Method', text:'Alternatives'}
];
$("#DropItPayments").msDropDown({byJson:{data:paymentData, name:'payments', width: 250}}).data("dd");
}
$(document).ready(function(e) {
//no use
try {
var pages = $("#pages").msDropdown({on:{change:function(data, ui) {
var val = data.value;
if(val!="")
window.location = val;
}}}).data("dd");
var pagename = document.location.pathname.toString();
pagename = pagename.split("/");
pages.setIndexByValue(pagename[pagename.length-1]);
$("#ver").html(msBeautify.version.msDropdown);
} catch(e) {
//console.log(e);
}
$("#ver").html(msBeautify.version.msDropdown);
//convert
$("select").msDropdown();
createByJson();
$("#tech").data("dd");
});
function showValue(h) {
console.log(h.name, h.value);
}
$("#tech").change(function() {
console.log("by jquery: ", this.value);
})
//
And the html:
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Item</p></div>
<div id="DropItBlodeuwedd"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Precious Stones</p></div>
<div id="DropItPearls"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Payment</p></div>
<div id="DropItPayments"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Delivery</p></div>
<div id="DropItDelivery"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Buy Now!</p></div>
<div id="DropItBuy"></div>
</div>
Again, working version viewable here
Many thanks in advance!
What I think you want is for your Buy button to dynamically read what the dropdowns currently say and build a link for redirection based on that, rather than trying to update the Buy button every time a dropdown changes.
From your code I can't see what the form of the final URL is supposed to be. For example, to get the current value of the delivery option, you can check $('#DropItDelivery :selected').text() which will be something like "Made To Order".
Your Buy Now! could be a button with a click event that reads these values and constructs the URL with basic string concatenation, e.g.:
window.location = "buynow.html?delivery=" + $('#DropItDelivery :selected').text() +
"&payment=" + $('#DropItPayments :selected').text()
// etc.
Of course you'd have to handle these options on the server.
In case you want to redirect to the payment page of the processor, you can just branch based on the payment method and give them the URL you want based on that.
var pm = $('#DropItPayments :selected').text();
if (pm == "Visa")
{
// Visa payment URL construction
}
else if (pm == "Send Your Details")
{
// Send your details URL construction
}
// etc.

Categories

Resources