mobiscroll for jquery: how to use language module - mobiscroll

How do I use the language module for mobiscroll? I am missing some "link" between the initialization and the extended language function.
(function ($) {
$.mobiscroll.i18n.de = $.extend($.mobiscroll.i18n.de, {
setText: 'OK',
cancelText: 'Abbrechen'
});
})(jQuery);
(function ($) {
$.mobiscroll.i18n.de = $.extend($.mobiscroll.i18n.de, {
dateFormat: 'dd.mm.yy',
...
yearText: 'Jahr'
});
})(jQuery);
$(function(){
$("#scroller").mobiscroll().date();
});
(And, I'm open to suggestions for other good pop-up calendars for mobile devices. jquery datepicker was too slow and the plain calendar for mobiscroll costs money)

I ended up doing it like so:
mob_dict = {dateFormat: 'dd.mm.yy', ...}
$(function(){
$("#scroller").mobiscroll().date(mobi_dict);
});

If you're looking for a German Language pack, it can be selected from the download package builder. No need for a custom one.

Related

ng-click doesn't work with external JavaScript

I am creating an ionic project and I am trying to integrate with Algolia autocomplete.js. I managed to make the search system work, however I added a ng-click on my search results and this function is not working as presented in this codepen that I did as example below:
http://codepen.io/marcos_arata/pen/VKVOky
Inside my algolia's result template:
<a ng-click="add_name({{{ name }}})">
Function that should be run when clicked:
$scope.add_name = function(name) {
alert('User added!');
console.log(name);
}
I tried to inject the results inside the scope but didn't work as well:
autocomplete('#search_name', { hint: false, debug: true, openOnFocus: true },[{
source: index.ttAdapter({ hitsPerPage: 15 }),
templates: {
header: '',
suggestion: function(hit) {
$scope.hit = hit;
return template.render(hit);
}
}
}]);
http://codepen.io/marcos_arata/pen/VKVOky
---- SOLVED ----
Instead of creating a ng-click function inside your templates, you can handle the event click of your search inside your "autocomplete:selected" function and use the dataset and suggestion results.
.on('autocomplete:selected', function(event, suggestion, dataset) {
$scope.name = suggestion.name;
console.log($scope.name);
## create any functions with the suggestion and dataset results inside
});
EDITING THE ANSWER:
Here is the codepen:
Apparently the suggestion keep the name clicked, so you dont need an extra function:
.on('autocomplete:selected', function(event, suggestion, dataset) {
$scope.name = suggestion.name;
console.log($scope.name);
});

How would I add a swipe action in Javascript using Angular Material

I am interested in using ngMaterial's swipe since I get the warning...
You are using the ngTouch module.
Angular Material already has mobile click, tap, and swipe support...
ngTouch is not supported with Angular Material!
Problem is for now this element is not under a directive. Instead I currently use angular.element to grab it then using ngTouch publish a global event...
$rootScope.$broadcast('gesture', gestures);
I know it may not be the material-way but I would just like to attach the swipe events manually.
Update
This look promising, although undocumented...
$mdGesture.register(myElement, 'drag', { minDistance: 20, horziontal: false })
Here is my working version
function TouchService($mdGesture, $rootScope){
this.setElement = function (selector) {
var element = angular.element(selector);
$mdGesture.register(element,'swipe', { minDistance: 20, horziontal: false });
element.on("$md.swipeleft", function(){
$rootScope.$broadcast('gesture', {direction: 'left'});
});
element.on("$md.swiperight", function(){
$rootScope.$broadcast('gesture', {direction: 'right'});
});
element.on("$md.swipeup", function(){
$rootScope.$broadcast('gesture', {direction: 'up'});
});
element.on("$md.swipedown", function(){
$rootScope.$broadcast('gesture', {direction: 'down'});
});
};
}

angular-translate service is not translating for first time

I´m using angular-translate $translate service to translate the title and meta description tags content dinamically according to the page (for SEO purposes).
I have a function that is called when a select combobox component with the language changes:
$scope.changeLanguage = function (langKey) {
$scope.langKey = langKey;
$translate.uses(langKey);
$rootScope.title = $translate('PAGE_TITLE');
tmhDynamicLocale.set(langKey).then(function (){
LocationService.setLangKey($scope.langKey);
$window.moment.lang(langKey);
});
};
All my application content is translated but the title.
My application default language is english. When I change to spanish (for first time) it´s not translating. After that, if I change to english and then to spanish again it works. All next times will work.
the translate service returns a promise
$translate('PAGE_TITLE').then(function(result) {
$rootScope.title = result
});
I think I have fixed it this way:
$translate.uses(langKey).then(function() {
$rootScope.title = $translate('PAGE_TITLE');
});

Understanding Backbone architecture base concepts

I'm trying to working with backbone but I'm missing it's base concepts because this is the first JavaScript MVVM Framework I try.
I've taken a look to some guide but I think I still missing how it should be used.
I'll show my app to get some direction:
// Search.js
var Search = {
Models: {},
Collections: {},
Views: {},
Templates:{}
};
Search.Models.Product = Backbone.Model.extend({
defaults: search.product.defaults || {},
toUrl:function (url) {
// an example method
return url.replace(" ", "-").toLowerCase();
},
initialize:function () {
console.log("initialize Search.Models.Product");
}
});
Search.Views.Product = Backbone.View.extend({
initialize:function () {
console.log("initialize Search.Views.Product");
},
render:function (response) {
console.log("render Search.Views.Product");
console.log(this.model.toJSON());
// do default behavior here
}
});
Search.Models.Manufacturer = Backbone.Model.etc...
Search.Views.Manufacturer = Backbone.View.etc...
then in my web application view:
<head>
<script src="js/jquery.min.js"></script>
<script src="js/underscore.min.js"></script>
<script src="js/backbone/backbone.min.js"></script>
<script src="js/backbone/Search.js"></script>
</head>
<body>
<script>
var search = {};
search.product = {};
search.product.defaults = {
id:0,
container:"#search-results",
type:"product",
text:"<?php echo __('No result');?>",
image:"<?php echo $this->webroot;?>files/product/default.png"
};
$(function(){
var ProductModel = new Search.Models.Product();
var ProductView = new Search.Views.Product({
model:ProductModel,
template:$("#results-product-template"),
render:function (response) {
// do specific view behavior here if needed
console.log('render ProductView override Search.Views.Product');
}
});
function onServerResponse (ajax_data) {
// let's assume there is some callback set for onServerResponse method
ProductView.render(ajax_data);
}
});
</script>
</body>
I think I missing how Backbone new instances are intended to be used for, I thought with Backbone Search.js I should build the base app like Search.Views.Product and extend it in the view due to the situation with ProductView.
So in my example, with render method, use it with a default behavior in the Search.js and with specific behavior in my html view.
After some try, it seems ProductModel and ProductView are just instances and you have to do all the code in the Search.js without creating specific behaviors.
I understand doing it in this way make everything easiest to be kept up to date, but what if I use this app in different views and relative places?
I'm sure I'm missing the way it should be used.
In this guides there is no code used inside the html view, so should I write all the code in the app without insert specific situations?
If not, how I should write the code for specific situations of the html view?
Is it permitted to override methods of my Backbone application?
Basically, you should think of the different parts like this:
templates indicate what should be displayed and where. They are writtent in HTML
views dictate how the display should react to changes in the environment (user clicks, data changing). They are written in javascript
models and collections hold the data and make it easier to work with. For example, if a model is displayed in a view, you can tell the view to refresh when the model's data changes
then, you have javascript code that will create new instances of views with the proper model/collection and display them in the browser
I'm writing a book on Marionette.js, which is a framework to make working with Backbone easier. The first chapters are available in a free sample, and explain the above points in more detail: http://samples.leanpub.com/marionette-gentle-introduction-sample.pdf

backbone events not triggering in Safari

For a learning exercise I converted a sinatra/backbone app to the Rails environment. I got it working on Chrome and Firefox but it doesn't work on Safari. It turns out that the original app http://backbone-hangman.heroku.com doesn't work on Safari either. When you click "new game" it doesn't seem to fire an event. The Safari console doesn't show any errors (although I'm not that experienced with Safari's developer tools as I never use them).
Since there is a live version of the app available here http://backbone-hangman.heroku.com I won't post a lot of code, but this is the view code that sets an event on click #new_game, triggering the startNewGame function. Nothing happens in Safari. Source code for the original is here https://github.com/trivektor/Backbone-Hangman
I googled a bit and found some mention of Safari treating events differently but couldn't find a solution. Can any recommend anything?
$(function() {
window.OptionsView = Backbone.View.extend({
el: $("#options"),
initialize: function() {
this.model.bind("gameStartedEvent", this.removeGetAnswerButton, this);
this.model.bind("guessCheckedEvent", this.showGetAnswerButton, this);
},
events: {
'click #new_game': 'startNewGame',
'click #show_answer': 'showAnswer'
},
startNewGame: function() {
this.model.new();
},
removeGetAnswerButton: function() {
$("#show_answer").remove();
},
showGetAnswerButton: function(response) {
console.log("showGetAnswerButton");
console.log(response);
var threshold = this.model.get("threshold");
console.log(threshold);
if (response.incorrect_guesses == this.model.get("threshold")) {
$(this.el).append('<input type="button" id="show_answer" class="action_button" value="Show answer" />');
}
},
showAnswer: function() {
this.model.get_answer();
}
})
})
Update
Based on one of the comments below the OP, I'm posting more code. This is hangman.js where the objects are instantiated
var game = new Game
var options_view = new OptionsView({model: game});
var characters_view = new CharactersView({model: game});
var hint_view = new HintView({model: game});
var word_view = new WordView({model: game});
var hangman_view = new HangmanView({model: game});
var answer_view = new AnswerView({model: game});
var stage_view = new StageView({model: game});
The views and models are attached to the window like this
window.AnswerView = Backbone.View.extend({ ...
Update
Aside from Backbone, jQuery and Underscore which are loaded sitewide, the following files are loaded for this specific app in the Rails system.
This is jQuery + Safari issue (document.ready)
You can just move your scripts inside the body tag and remove $(function(){ /**/ }) wrapper in every file.
Also I added requirejs support and made pull request
EDIT:
First of all sorry for my English :)
File views/index.haml:
We should embed js at the bottom of the page (to avoid Safari error)
= javascript_include_tag "javascript/require.js", :"data-main" => "javascript/config"
Here javascript/config is the path to requirejs config.
File public/javascript/config.js:
"deps" : ["hangman"]
This means that application will start with hangman.js
File public/javascript/hangman.js:
We don't need $(function() { wrapper because our script initialized from the body and document is already 'ready'
define([
'models/game',
'views/answerView',
/* ... */
],
function(Game, OptionsView, /* ... */) {
// ...
}
Here we load our modules (first array element will be available in the first function argument and so on)
Other files
We just replace $(function() { with define(['backbone'], function(Backbone) {
In the first line we load backbone module. When it will be fetched it will be available inside anonymous function (first parameter - Backbone)
Next we should return the view to avoid undefined module value (public/javascript/hangman.js file should initialize a lot views. It can't initialize undefined it should initialize Backbone.View that we should return)
To learn more you should read requirejs documentation.
I recomend you to start with this article
Try this instead.
var OptionsView = Backbone.View.extend({
el: $("#options"),
initialize: function() {
this.model.bind("gameStartedEvent", this.removeGetAnswerButton, this);
this.model.bind("guessCheckedEvent", this.showGetAnswerButton, this);
},
events: {
'click #new_game': 'startNewGame',
'click #show_answer': 'showAnswer'
},
startNewGame: function() {
this.model.new();
},
removeGetAnswerButton: function() {
$("#show_answer").remove();
},
showGetAnswerButton: function(response) {
console.log("showGetAnswerButton");
console.log(response);
var threshold = this.model.get("threshold");
console.log(threshold);
if (response.incorrect_guesses == this.model.get("threshold")) {
$(this.el).append('<input type="button" id="show_answer" class="action_button" value="Show answer" />');
}
},
showAnswer: function() {
this.model.get_answer();
}
});
Your code dosen't need to be in a document ready (it's not directly manipulating DOM, it's just declaring an object);
Make sure game.js goes after all your declarations though.
It looks like a problem Safari has in adding variables to the Global Object. Using var in the global context makes sure window.OptionsView exists. You might want to consider using require.js in the future to manage all of these global object problems.

Resources