How to get current year with coffeescript - ruby-on-rails

I am working with Angular/CoffeeScript/Rails and I am trying to place the copyright with the current year in the footer.
With JavaScript, I used to do something like this:
<script type="text/javascript">
<!--
var theDate = new Date();
$('.mDate').html('© ' + theDate.getFullYear());
-->
</script>
<span class="mDate"></span>
Here is what I have tried in CoffeeScript - within the mainController.coffee:
# mCopyRight
# ------------------------------------------------------------
$scope.mCopyRight = ->
$scope.theDate = new Date();
$scope.mFullYear = '© ' + theDate.getFullYear();
Within the application.html.erb
<span class="mDate">{{mFullYear}}</span>
But nothing is showing up.
It is like new Date is not working and/or .getFullYear(); either
The only thing that I can think of, would be to make a regular js file and require it in the application.js file:
//= require user-defined/mDate
With a file named mDate.js being in the vendor/assets/javascripts/user-defined/ directory.
Thanks in advance

You have assigned theDate to be a property of $scope. Either read it from there:
$scope.mCopyRight = ->
$scope.theDate = new Date
$scope.mFullYear = '© ' + $scope.theDate.getFullYear()
Or if that value is only needed by this function, don't use $scope:
$scope.mCopyRight = ->
theDate = new Date
$scope.mFullYear = '© ' + theDate.getFullYear()

Related

using katex, '&' alignment symbol displays as 'amp;'

I am using katex to render math.
https://github.com/Khan/KaTeX
Generally, to get this to work I link to the files katex.min.js and katex.min.css from a cdn, which is one of the ways the directions suggest.
I wrap what needs to be rendered in tags and give all the same class. For example:
<span class='math'>\begin{bmatrix}a & b \\c & d\end{bmatrix}</span>
And inside a script tag I apply the following:
var math = document.getElementsByClassName('math');
for (var i = 0; i < math.length; i++) {
katex.render(math[i].innerHTML, math[i]);
}
So, my implementation works but there is a problem in what katex returns. The output of the above gives me:
This exact same question is asked here:
https://github.com/j13z/reveal.js-math-katex-plugin/issues/2
But I can't understand any of it.
The solution is to use element.textContent, not element.innerHTML.
If I use a form like what follows, the matrix will be rendered properly.
var math = document.getElementsByClassName('math');
for (var i = 0; i < math.length; i++) {
katex.render(math[i].textContent, math[i]); // <--element.textContent
}
A solution that works for me is the following (it is more of a hack rather than a fix):
<script type="text/javascript">
//first we define a function
function replaceAmp(str,replaceWhat,replaceTo){
replaceWhat = replaceWhat.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp(replaceWhat, 'g');
return str.replace(re,replaceTo);
}
//next we use this function to replace all occurences of 'amp;' with ""
var katexText = $(this).html();
var html = katex.renderToString(String.raw``+katexText+``, {
throwOnError: false
});
//hack to fix amp; error
var amp = '<span class="mord mathdefault">a</span><span class="mord mathdefault">m</span><span class="mord mathdefault">p</span><span class="mpunct">;</span>';
var html = replaceAmp(html, amp, "");
</script>
function convert(input) {
var input = input.replace(/amp;/g, '&'); //Find all 'amp;' and replace with '&'
input=input.replace(/&&/g, '&'); //Find all '&&' and replace with '&'. For leveling 10&x+ &3&y+&125&z = 34232
var html = katex.renderToString(input, {
throwOnError: false});
return html
}
Which version are you using?
Edit the src/utils.js and comment line number 51 to 55 after updated run in terminal npm run build command.

How do I call a JavaScript function from an html.erb

How do I call a JavaScript function from html.erb
in application.js
function displayClock() {
var digital = new Date();
var hours = digital.getHours();
var minutes = digital.getMinutes();
var seconds = digital.getSeconds();
var amOrPm = 'AM';
if (hours > 11) amOrPm = 'PM';
if (hours > 12) hours = hours - 12;
if (hours == 0) hours = 12;
if (minutes <= 9) minutes = '0' + minutes;
if (seconds <= 9) seconds = '0' + seconds;
dispTime = '<b>'+hours + ':' + minutes + ':' + seconds + ' ' + amOrPm+'</b>';
document.getElementById('time').innerHTML = dispTime;
setTimeout('displayClock()', 1000);
}
and in home.html.erb
displayClock();
but it's not calling function!
You probably need to use proper tag to indicate that you're writing JS code:
<script type="text/javascript">
displayClock();
</script>
Plus, since you probably use jQuery (it's default in Rails), you may want to make sure the function is called after whole document is loaded:
<script type="text/javascript">
$(document).load(function(){
displayClock();
});
</script>
I'd also advice you not to write your JS in application.js and use this file only as a manifest file, which includes your other scripts through Rails asset pipeline.
Also you can take advantage of the javascript helper javascript_tag in your html.erb file
<%= javascript_tag "displayClock()" %>

Angular pagination not updating when bound list changes due to filtering on an input text box

Here's the scenario:
I am using an ASP.NET MVC site with Angular JS and Boostrap UI. I have a dynamic ul list populated by data fed through a controller call to AngularJS, filtering on that list through an input search box. The list is also controlled through pagination (UI Bootstrap control) that I've setup to show 10 results per page for the list of 100 or so items. This list is filtered as the user types in the search box, however I would like the pagination to update as well so consider the following example:
The list has 10 pages of items (100 items), the user types some text in the input search box which filters the list down to 20 or so items, so the pagination should be updated from 10 pages to two pages.
I figure there must be a $watch setup somewhere, perhaps on the list items after it has been filtered and then update the pagination page count, however I'm pretty new to AngularJS so can someone please explain to me how this could be done?
Thanks very much. I have posted my code below:
<div data-ng-app="dealsPage">
<input type="text" data-ng-model="cityName" />
<div data-ng-controller="DestinationController">
<ul>
<li data-ng-repeat="deals in destinations | filter: cityName |
startFrom:currentPage*pageSize | limitTo:pageSize">{{deals.Location}}</li>
</ul>
<br />
<pagination rotate="true" num-pages="noOfPages" current-page="currentPage"
max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
</div>
var destApp = angular.module('dealsPage', ['ui.bootstrap', 'uiSlider']);
destApp.controller('DestinationController', function ($scope, $http) {
$scope.destinations = {};
$scope.currentPage = 1;
$scope.pageSize = 10;
$http.get('/Deals/GetDeals').success(function (data) {
$scope.destinations = data;
$scope.noOfPages = data.length / 10;
$scope.maxSize = 5;
});
});
destApp.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
};
});
Because your pagination is a combination of chained filters, Angular has no idea that when cityName changes, it should reset currentPage to 1. You'll need to handle that yourself with your own $watch.
You'll also want to adjust your startFrom filter to say (currentPage - 1) * pageSize, otherwise, you always start at page 2.
Once you get that going, you'll notice that your pagination is not accurate, because it's still based on destination.length, and not the filtered sub-set of destinations. For that, you're going to need to move your filtering logic from your view to your controller like so:
http://jsfiddle.net/jNYfd/
HTML
<div data-ng-app="dealsPage">
<input type="text" data-ng-model="cityName" />
<div data-ng-controller="DestinationController">
<ul>
<li data-ng-repeat="deals in filteredDestinations | startFrom:(currentPage - 1)*pageSize | limitTo:pageSize">{{deals.Location}}</li>
</ul>
<br />
<pagination rotate="true" num-pages="noOfPages" current-page="currentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
</div>
JavaScript
var destApp = angular.module('dealsPage', ['ui.bootstrap']);
destApp.controller('DestinationController', function ($scope, $http, $filter) {
$scope.destinations = [];
$scope.filteredDestinations = [];
for (var i = 0; i < 1000; i += 1) {
$scope.destinations.push({
Location: 'city ' + (i + 1)
});
}
$scope.pageSize = 10;
$scope.maxSize = 5;
$scope.$watch('cityName', function (newCityName) {
$scope.currentPage = 1;
$scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.cityName);
$scope.noOfPages = $scope.filteredDestinations.length / 10;
});
});
destApp.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
};
});
The version shared on jsfiddle is compatible with ui-bootstrap 0.5.0 but from 0.6.0 onwards there have been breaking changes.
Here is a version that uses the following libraries:
angular 1.2.11
angular-ui-bootstrap 0.10.0
bootstrap 3.1.0
Here is a plunker for the same:
Angular UI Bootstrap Pagination
Hello I tried to hook this up with Firebase using Angular Fire and it only works after I type something in the search input. In the $scope.$watch method, I used Angular Fire's orderByPriorityFilter to convert the object to an array.
$scope.$watch('search', function(oldTerm, newTerm) {
$scope.page = 1;
// Use orderByPriorityFilter to convert Firebase Object into Array
$scope.filtered = filterFilter(orderByPriorityFilter($scope.contacts), $scope.search);
$scope.lastSearch.search = oldTerm;
$scope.contactsCount = $scope.filtered.length;
});
Initial load doesn't load any contacts. It's only after I start typing in the input search field.

using local storage to store and retrieve current clicked item on listview jquery mobile

I have a dynamic list view and what I am trying to do is store the list that is CURRENTLY being clicked to local storage and retrieve it. I have the following code, it seems to work but I'm not sure so could someone give me a heads up if it's correct as I need to be doing more things with the data.
The html for list view:
<ul data-role="listview" id="newsfeedposts" data-theme="a" data-overlay-theme="a" data-inline="true"data-inset="true"></ul>
the markup for each list item:
markup += '<li><img src="' + thumb_url + '">' +'<h4>' + name + '</h4><p>' +'posted this photo....</p><p>'+likes+'<img src="images/facebook-like-16.png"></p></li>';
$('#newsfeedposts').append(markup);
addPostToLocalStorage(posts);
$('#newsfeedposts').listview("refresh");
The method to add the item to storage and retrieve it;
function addPostToLocalStorage(facebookPost){
$(".item").on('click', function (){
var i = $('.item').index(this);
console.log(i);
localStorage['results'] = JSON.stringify(facebookPost[i]);
storedItem = (localStorage['results']) ;
console.log(storedItem);
alert("this post was added to local storage");
//retrieve list item
var retrievedItem = localStorage.getItem(['results']);
console.log( 'retrieved: ' + retrievedItem);
});

Newline in text file created in jscript via activeXObject

Okay from the top:
Using the following code I can create a text file using jscript in an htm file from Internet Explorer via an ActiveX object. Yay!
However, opening the text file in Notepad I noticed new lines appear as mojibake characters (rectangular character) instead of newlines . It's fine in Sublime 2.
<html>
<head>
</head>
<script type="text/javascript">
var myStr = "The self same moment I could pray;\nAnd from my neck so free\nThe Albatross fell off, and sank\nLike lead into the sea.";
var myPath = "C:\\temp\\";
var myTextfile = "Rime.txt"
writeFile(myPath, myTextfile, myStr)
function writeFile(apath, afilename, str)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var outFile = fso.CreateTextFile(apath + afilename, true);
outFile.WriteLine(str);
outFile.Close();
}
</script>
</body>
</html>
I also noticed that it doesn't occur when using the following from Photoshop environment (where I normally script from)
var txtFile = new File(apath + "/" + afilename);
outFile.open('w');
outFile.writeln(str);
outFile.close();
Is this just a quirk (or bonus) of ActiveX? Can I change it so it writes new lines that can be viewed properly in Notepad?
And, yes my Mother did warn me about the dangers of getting involved with ActiveX objects.
Looks like there's something wrong with character encoding. Try this instead of CreateTextFile():
var outFile = fso.OpenTextFile(apath + afilename, 2, true, 0);
2nd arg: 1 = reading, 2 = writing, 8 = appending.
3rd arg: true if non-existing file is created, false if non-existing file is not created. [optional, default = false]
4th arg: 0 = ASCII, -1 = Unicode, -2 = system default. [optional, default = 0]

Resources