Materialize getInstance(elem) inside AngularJS component's controller - javascript

I'm trying to use the .open() method of materialize to open a modal component within AngularJS on the page load.
So my component file (loginModal.js) has the following code:
angular.module('my-app').component('loginModal', {
templateUrl:'app/components/templates/loginModal.html',
controller: loginModalController
})
function loginModalController()
{
angular.element(document).ready( function(){
var loginModal = document.querySelectorAll('.modal');
var loginModal_options = {};
var loginModal_instance = M.Modal.init( loginModal, loginModal_options);
console.log(loginModal_instance);
loginModal_instance.open();
var instance = M.Modal.getInstance(loginModal);
instance.open();
});
}
While the initialization is happening as expected when I'm trying to trigger the open method, through the loginModal_instance variable I'm getting
loginModal_instance.open is not a function
while through instance variable I'm getting
Cannot read property 'open' of undefined
Instead, If I'm going to use JQuery, its working
function loginModalController()
{
$(document).ready(function(){
$('.modal').modal();
$('#login-modal').modal('open');
});
}
Any ideas? Am I doing anything wrong?

Actually by using querySelector() instead of querySelectorAll() did the trick.

Related

How to override action_registry js in odoo [12.0]

I have the following js file that handles a widget and I would like to overwrite and add code for custom events function, but when I tried to instantiate, nothing seems to be on the object:
This a reference for the script that I want to overwrite
odoo.define('my_module.my_report', function (require) {
'use strict';
var myWidget = AbstractAction.extend(ControlPanelMixin, {
custom_events: {
},
}
core.action_registry.add('my_report', myWidget );
return myWidget
});
});
I have tried inheriting using the following:
var InheritedWidget = require('my_module.my_report);
and also:
var InheritedWidget = core.action_registry.get('my_report');
and when I tried to override, nothing seems to happen:
InheritedWidget.include({
custom_events: {
//My custom code goes here
}
})
Do you know how to override this widget or method?
You need to extend the custom_events of an existing widget.
var InheritedWidget = require('my_module.my_report');
InheritedWidget.include({
custom_events: _.extend({}, InheritedWidget.prototype.custom_events, {
//My custom code goes here
}),
});
For more details refer to the event system documentation.

backbone js rigth initialization process

This javascript present on all site pages.
var CategoriesView = Backbone.View.extend({
el: $('.js-categories-view'),
initialize: function () {
...
}
...
templates: {
'category-template': _.template($('#js-category-template').html())
},
});
And if page haven't element $('.js-categories-view'), code like: new CategoriesView(); it will not be called and initialize not be called too.
But what about templates section?
_.template($('#js-category-template').html()) always called and I get the error:
Uncaught TypeError: Cannot read property 'length' of undefined
Because $('#js-category-template') doesn't present on page and and I don't want store template html on page where this View not needed?
You can check if the needed element present on the current page like this:
if( $('.js-categories-view').length ){
new CategoriesView();
}
And if you want to prevent error when calling the _.template() function, you also need to move the definition of the templates object into the initialize method of the view like follows:
var CategoriesView = Backbone.View.extend({
el: $('.js-categories-view'),
initialize: function () {
this.templates = {
'category-template': _.template($('#js-category-template').html())
};
...
}
});
Thanks all! It's good solution. But eventually I implement this:
$(function () {
if (!$('.js-categories-view').length) {
return;
}
var CategoriesPageModel = Backbone.Model.extend({
...
to not to think about issues like this. But I think thant better solution can be found

Pass data between controllers while pageload without using $rootscope in angularjs

I have 2 controllers like below,
app.controller('ParentMenuController',
function ($scope,MenuService) {
$scope.contentLoaded = false;
$scope.showButton = false;
$scope.showButton = MenuService.getStatus();
});
Controller2:
app.controller('ChildMenuController',
function ($scope,MenuService) {
MenuService.setStatus(true);
});
Service:
app.factory('MenuService', function ($q,$http) {
var status= false;
var setStatus=function(newObj){
status=newObj;
};
var getStatus=function(){
return status;
};
return {
getStatus:getStatus,
setStatus:setStatus
};
});
I am not able to set the status to true, but the below line of coding is not at all executing, so the status is always false.
$scope.showButton = MenuService.getStatus();
On button click or any action from user i can trigger the event, but my requirement is while page load, the button should not be visible. When childMenu controller executes, then parent controller button should be visible. I dont want to use $broadcast which requires $rootscope.
Note: My controller and html has hundereds of lines. I just pasted here required code for this functionality. ChildMenuController(childMenu.html) has separate html and ParentMenuController(parentMenu.html) has separete html.
So $scope.showButton is not available in ChildMenucontroller. Both html is used as directive. Main html is index.html.
See this sample:
http://plnkr.co/edit/TepAZGOAZZzQgjUdSpVF?p=preview
You need to use a wrapper object so that it's properties are changed instead of the main object.
app.controller('ParentMenuController',
function ($scope,MenuService) {
$scope.contentLoaded = false;
$scope.showButton = MenuService.getStatus();
});
app.controller('ChildMenuController',
function ($scope,MenuService) {
MenuService.setStatus(true);
});
app.factory('MenuService', function ($q,$http) {
var status= {value:false};
var setStatus=function(newObj){
status.value=newObj;
};
var getStatus=function(){
return status;
};
return {
getStatus:getStatus,
setStatus:setStatus
};
});
It's exactly the same as your code, but state is now an object with a value property. The state object is always the same one so that when the value is changed in the service the changes are propagated to everyone that has ever requested that object.
Actually your service is getting called and this piece of line is executing
$scope.showButton = MenuService.getStatus();
but once your child controller got loaded you are only setting the status but in order to show button you should getStatus after setting it
Like this,
app.controller('ChildMenuController', function($scope, MenuService) {
MenuService.setStatus(true);
$scope.$parent.showButton = MenuService.getStatus();
});
this will set the button to true and it will be shown.
I have done a sample with your code please take a look into it
DEMO

How to get angular variable to javascript when using scope() method

This is how I get my input. sql table -> php slim -> angularjs -> website.
I need to GET a variable in javascript that php slim is returning to angular.
Right now I'm using this in $( document ).ready(function() {.
var $element = $('div[ng-show="game"]');
var scope = angular.element($element).scope();
console.log(scope);
It returns this in console.
Any ideas how to achieve this?
In your Angular controller just create your JQuery method there.
//Controller
function someController($scope) {
$scope.game = GetFromSlim();
$scope.yourMethod = function(){
$('#someDiv').innerHtml($scope.game.total_rating);
}
}
Then you can just call your method from the view using angular.
//View
<div ng-controller="someController" ng-app>
<div id="someDiv"></div>
<button ng-click="yourMethod()">Just do it</button>
</div>
Angular 2 or AngularJS 2 ++
Without scope method also can be passed as below. You have to write somecodes inside angular page(Declare, define and redefine) and some in javascript.
A. In angular (i used in common angular page) write below code
//Declare and Define of variables
environmentStringify = {
'project_url':'172.23.77.82:4200/myangularproject/',
'testMode':true
};
declare var environmentStringify: any;
environmentStringify = JSON.stringify(environment);
B. in html page (i used index.html inside head and script tags) write below codes
<script type="text/javascript">
var environmentStringify = "{{environmentStringify}}";
var environment = null;
function isJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function setJSEnvironmentVariable(){
if(isJsonString(environmentStringify)){
environment = JSON.parse(environmentStringify);
} else {
setTimeout(function(){
setJSEnvironmentVariable();
}, 500);
}
}
setJSEnvironmentVariable();
</script>

Why cant my anchor fire this javascript object?

I have a page with a linked javascript object:
//the constructor function
function NewsScroller() {
}
//now put some config objects using the JSON structure
NewsScroller.prototype.config = {
serviceUrl : '/NewsProvider.svc/rest/GetNews/',
pageIndex : 0
}
//the argumented constuctor for this object
NewsScroller.prototype.init = function () {
this.getNews(this.config.pageIndex);
console.log(this.config.pageIndex);
}
NewsScroller.prototype.decreasePage = function () {
console.log('current page index ' + this.config.pageIndex);
}
Then I have the page ready declaration:
<script>
$(document).ready(function () {
var newsScrollerForPage = new NewsScroller();
newsScrollerForPage.init();
newsScrollerForPage.decreasePage();
});
</script>
Which produces the result:
current page index 0
I want to call the function from an anchor tag so I have:
<div class="scroller-left">
<a id="scroller-left-a" href="javascript:newsScrollerForPage.decreasePage();">
<img src="/Images/Left-Scroller.jpg"/>
</a>
</div>
But when I click the anchor I get:
newsScrollerForPage is not defined
Why is this? Surely I should be able to call the object and function just like I did in the .ready method?
You define the newsScrollerForPage inside the ready function with local scope (by using "var"), you can't use it outside of there except if you define a function in the same scope which uses it (scope is evaluated from where functions are defined, not from where they are called).
You can quickly fix the issue by taking away the var from before it (making it more global rather than local in scope) but I wouldn't suggest this as the best solution.
Better would be to link up the anchor like this:
$(document).ready(function () {
var newsScrollerForPage = new NewsScroller();
newsScrollerForPage.init();
newsScrollerForPage.decreasePage();
document.getElementById("scroller-left-a").onclick=function()
{
newsScrollerForPage.decreasePage();
return false;
}
});
and removing the href from the HTML element.

Categories

Resources