How to call a method in the child window in Angular JS - angularjs

My angular JS application has a view button. When clicking on the view button, it will call method and that method changes the content in the same page. Now I have a request that when clicking on the view button, it has to open in a new tab and display the contents.
Previous code:
HTML:
<md-button ng-click="ctrl.ViewClick(item)">View</md-button>
Controller:
vm.ViewClick = function(item) {
// The browser URL is same but it is a new page with the new contents.
// Calls a angular js service and loads the contents
}
Now, I need to call that function in new browser tab.
I made the following changes but didn't worked. Can you please help me on this.
HTML:
<md-button ng-click="ctrl.NewTabClick(item)">View</md-button>
Controller:
vm.newTabClick = function(item){
$Window.open($location.absURL(), 'blank');
// How do I call vm.ViewClick function after opening the new browser window?
};
This is the old angular JS. Thanks for helping on this.

On workaround you can do in this case is, While opening the page pass query parameter in the URL.
vm.newTabClick = function(item){
// Add `viewLink=true` query parameter with true value
$Window.open($location.absURL() + '&viewLink=true', 'blank');
// Store item in sessionStorage
window.sessionStorage.setItem('item', JSON.stringify(item));
}
And then from the component where you want to call the parameter. You can write below code on $onInit lifecycle hook.
vm.$onInit = function () {
// Inject $routeParams in dependency areay
const storedItem = sessionStorage.getItem('item')
if ($routeParams.viewLink == 'true' && storedItem && storedItem != 'null') {
vm.viewLink(JSON.parse(storedItem));
}
}

Related

How to get ui-sref working inside trustAsHtml?

I have a activity state, and when there are no activities I would like to display a message. So I created a if/else statement that checks if the $scope activities has any content, if not it injects a certain code into the template.
if(!$scope.activities.length){
var empty = function(){
$scope.renderHtml = function (htmlCode) {
return $sce.trustAsHtml(htmlCode);
};
$scope.body = '<div>There are no activities yet, <a ui-sref="home.users">click here to start following some friends!</a></div>';
}
empty()
}
The problem is that ui-sref doesn't work, a normal 'a href` does work though. Are there any solid work arounds for this problem?
To get this work I created a element with ng-show,
%div{"ng-show" => "activitiesHide"}
And this js,
activitiesService.loadActivities().then(function(response) {
$scope.activities = response.data;
if(!$scope.activities.length){
$scope.activitiesHide = response.data
}
})
I place the results from the service in the activities scope, and then check in the js if it has content. If not activate the activitesHide show.

$scope is updated, but the view is not

I have 2 states. A home state and a child of the home state called, suggestions. The home state loads a template into a ui-view element.
Inside my home template, and my suggestions template I have this link,
.addmovie{"ng-click" => "addMovie(movie)"}
This link fires the .addMovie function. This places a new value in my database and after that's done reloads all the data with this,
var init = function(){
movieService.loadMovies().then(function(response) {
$scope.movies = response.data;
var orderBy = $filter('orderBy');
$scope.orderedMovies = orderBy($scope.movies, "release_date", false);
var movies = $scope.orderedMovies
var i,j,temparray,chunk = 8, movieGroups=[];
for (i=0,j=movies.length; i<j; i+=chunk) {
temparray = movies.slice(i,i+chunk);
movieGroups.push(temparray);
}
$scope.movieGroups = movieGroups
})
$(".search_results").fadeOut(250);
$('body').find('#search_input').val("");
movieTrailers.loadTrailers().then(function(response) {
$scope.trailers = response.data;
})
movieSuggestions.loadSuggestions().then(function(response) {
$scope.suggestions = response.data;
})
console.log ('init end')
}
So if I add a movie from within my home template, the view updates with the new data.
In this home template I also have a button that loads the suggestions state,
#suggestions
%a{"ui-sref" => ".suggestions"}
%h1
Suggestions
%div{"ui-view" => "suggestions"}
This loads the suggestions template inside the suggestions view inside the home state.
In my suggestions template I have the same button as in the home state.
.addmovie{"ng-click" => "addMovie(movie)"}
And when I click that it does do the addMovie function because I get the console logs in my console, and also it reloads all the data (with use of the init function) because when I check the network tab and view the movies.json it has the new data. But it does not update my home template view. To see the new data in my home template I have to refresh the page.

when i click on update button i got data to be updated but it gets cleared when i move to update page in angularjs

$scope.fetchDataForEditInvoice = function (row)
{
var index = $scope.gridOptions.data.indexOf(row.entity);
var InvoiceId = $scope.gridOptions.data[index].InvoiceId;
var status = angularService.FetchDataForEditInvoice(InvoiceId);
status.then(function (invoiceData) {
console.log(invoiceData);
window.location.href = "/Invoice/AddInvoice";
$scope.InvoiceDetails = invoiceData.data.InvoiceDetails;
},
function () {
alert('Error in fetching record.');
})
}
on click of update button i call following function and i got data but how i can assign it to controls on update page
save invoiceData.data.InvoiceDetails in a $rootScope variable. So it will available in all controllers.
$rootScope.InvoiceDetails=invoiceData.data.InvoiceDetails;
inject $rootScope to your controller before using it.
Use routers traversing next page.Refer Single Page Apps with AngularJS Routing]1

Getting access to a DOM element after closing Angular-Bootstrap $modal instance

I'm using Malhar Dashboard widget framework at the moment, and struggling with an issue in the close event of the Bootstrap Modal.
FYI: https://github.com/DataTorrent/malhar-angular-dashboard
Specifically, when I close the modal and arrive back to the $modalInstance.result.then function, I need to have access to the parent container which launched the modal in the first place. This proves to be difficult.
For example, when certain click events are triggered, I can get access to the Kendo UI chart element as follows :
var chart = widget.find('.k-chart').data("kendoChart");
chart.resize($(".k-chart"));
But after having launched the $modal like this :
var modalInstance = $modal.open(options);
I want to close the $modal, and still get access to that Kendo chart widget in the modalInstance.result.then() section - but widget is undefined:
modalInstance.result.then(
function (result) {
var chart = widget.find('.k-chart').data("kendoChart"); // widget UNDEFINED !!!
}
)
**** UPDATE - Two things: ****
1) On a positive note, I can get access to the parent node of .modal-body; however, I don't think my solution is very elegenant with the use of el.parent().parent().parent().parent().find() .
2) On the downside, although I can call the kendo.resize() function, it has no effect.
Help is appreciated.
// Set resolve and reject callbacks for the result promise
modalInstance.result.then(
function (result) {
// Call the close callback
onClose(result, widget, scope);
if (!widget.gadgetConfigured) {
widget.gadgetConfigured = true;
widget.setHeight(widget.fixedSize.height);
widget.setWidth(widget.fixedSize.width);
}
scope.$broadcast('widgetSettingsClosed', widget, result);
// attempt to refresh kendo chart - 04/30/2015 BM:
var el = $('.modal-body');
var chartElem = el.parent().parent().parent().parent().find('.k-chart').data("kendoChart");
if (chartElem != undefined) {
chartElem.setOptions({ chartArea: { width: chartElem.getSize().width * .95, height: chartElem.getSize().height * .90 } });
chartElem.resize($(".k-chart"));
}
scope.$emit('widgetChanged', widget);
},
function (reason) {
// Call the dismiss callback
onDismiss(reason, scope);
}
);

Backbonejs - Back button doesn't work if page transition on same page

Short description of my program and finally the problem:
I have got two pages. The first page list products in rows with a short description. If you click on one you will land on a detail page.
The detail page lists the product details and underneath a couple of related products. If you click on one of the releated products the same page is rendered again with the new information fetched from a REST interface.
If I want to use the browser-back-button or the own back-button to get to the previous product-detail-page a blank page appears. This only happens on my iPad. Using Chrome on a desktop browser works fine. I debugged the application and I figured out, that the backbonejs route is never called. I have no idea why.
Here is my code of the details page:
define([
"jquery",
"lib/backbone",
"lib/text!/de/productDetails.html"
],
function(
$,
Backbone,
ContentTemplate
){
var PageView = Backbone.View.extend({
// product details template
template: _.template(ContentTemplate),
// back-button clicked
events:{
'click a#ac-back-button':'backInHistory',
},
// init
initialize: function(options){
this.options=options;
// bind functions
_.bindAll(this,
'render',
'renderRelatedSeriePlainproduct',
'backInHistory'
);
// listen for collection
this.listenTo(this.options.relatedCollectionPlainproduct, 'reset',this.renderRelatedSeriePlainproduct);
},
// back button
backInHistory: function(e){
e.preventDefault();
window.history.back();
},
// render template
render: function(){
// render template
this.$el.html(this.template(this.model.models[0].attributes));
return this;
},
// render related products
renderRelatedSeriePlainproduct: function (){
var models = this.options.relatedCollectionPlainproduct.models;
if(models.length==0){
$('.ac-plainproduct').hide();
} else{
var elem = $('#ac-related-listing-plainproduct');
var ct="";
ct+='<ul id="ac-list-related-plainproduct">';
$.each(models, function(key, value){
ct+='<li>';
ct+='<a href="index.html?article_id='+value.get('article_id')+'&type='+value.get('type')+'&serie='+value.get('series')+'#product-detail">Link';
ct+='</a>';
ct+='</li>';
});
ct+='</ul>';
elem.append(ct);
}
}
});
// Returns the View class
return PageView;
});
I follow one of the links from renderRelatedSeriePlainproduct.If I click on the back button on the new page the backInHistory function is called, but the window.history.back(); does not call the backbone router.
Maybe the problem is the #hash in the URL, that is not changed during page transition. But this would not explain, why it works perfectly with my Chrome on my desktop machine. For me it seemed to be a problem of asynchronous calls but even there I could not find a problem.
Maybe it helps to list my router code as well. First of all I was thinking it is an zombie issue in backbone, but I remove all events and views while making the transition.
// function called by the route
// details page
productdetail: function() {
$.mobile.loading("show");
_self = this;
// lazy loading
require([
'collection/ProductDetailCollection',
'collection/RelatedCollection',
'view/ProductDetailView'
],
function(ProductDetailCollection, RelatedCollection, ProductDetailView){
// get URL parameters
var articleID = _self.URLParameter('article_id');
var type = _self.URLParameter('type');
var serie = _self.URLParameter('serie');
// product - details
var productDetail = new ProductDetailCollection.ProductDetail({id: articleID});
// related products
_self.relatedCollectionPlainproduct = new RelatedCollection({serie:serie, type:"Electronics", article_id:articleID});
// assign binded context
productDetail.fetch({
// data fetched
success: function (data) {
// page transition
_self.changePage(new ProductDetailView({
model:data,
relatedCollectionPlainproduct:_self.relatedCollectionPlainproduct
}));
// fetch data
_self.relatedCollectionPlainproduct.fetch({reset:true});
}
});
});
},
// page transition
changePage:function (page) {
// remove previous page from DOM
this.page && this.page.remove() && this.page.unbind();
// assign
this.page = page;
// assign page tag to DOM
$(page.el).attr('data-role', 'page');
// render template
page.render();
// append template to dom
$('body').append($(page.el));
// set transition
var transition = "fade";
// we want to slide the first page different
if (this.firstPage) {
transition = "fade";
this.firstPage = false;
}
// make transition by jquery mobile
$.mobile.changePage($(page.el), {changeHash:true, transition: transition});
// page was rendered - trigger event
page.trigger('render');
$.mobile.loading("hide");
},
I tried to use allowSamePageTransition but with no success. Maybe someone could give me a hint. Thanks!
Looks like jQuery Mobile and Backbone's routers are conflicting. Take a look here:
http://coenraets.org/blog/2012/03/using-backbone-js-with-jquery-mobile/
Thats not the reason. I disabled the routing of jquery mobile.
// Prevents all anchor click handling
$.mobile.linkBindingEnabled = false;
// Disabling this will prevent jQuery Mobile from handling hash changes
$.mobile.hashListeningEnabled = false;

Resources