Angular modal window depenging on server answer - angularjs

Good day! I am rather new to angular and I need help in creating a directive or, maybe, some other solution. I have got a list of news, which are displayed one after another. It is done by ng-repeat. Inside each new there are a things like creationDate, post.media and etc. I would a new to appear in a modal window, when user clicks directly on the div with a new text. But, i would to make a request to the server after click to get the most recent version of the new.
So, this is what I want briefly:
1) User clicks on new's text.
2) The id is sent to the server.
3) Server responds with all post information
4) Some specified template loads with all information got from server and appears in a modal window.
What i tried to do:
I tried to create a directive and placed it on new's text. I created an isolated scope, which expects to have one more attribute, so I could get a postId.
scope: {
postId: '#'
}
I created a template and specified a link to it as templateURL.
Then i created a link function and inside it i created smth like this :
element.on('click', function() {
scope.postInfo = scope.findPostById(postId);
});
But for now, this directive just replaces its innerHTML :))
Some requirments:
Modal window should appear only after server receives all the information.
Thank you :)

Basically ng-repeat creates scope for every single element. So you just need to create a function i.e.
$scope.fetchNews = function(news){
newsRepository.find(news).then(function(result){
$modal.open({
templateUrl:...
controller:...
resolve:{
news:function(){
return result;
}
}
})
})
}
And in the controller of the model you inject as depenency news and after that you are done :)

Related

communicating between two controller in angularjs using factory

I have created a plunker that communicates between two different controller in nested views using factory. Below is the url of plunker.
https://plnkr.co/edit/fWA2Xugjbkf3QvHKfTa0?p=preview .
Here is the factory.
routerApp.factory("widgetService",function($state){
var callbackFunctions=[];
var counter=0;
var addWidget=function(name){
callbackFunctions[0](name);
}
var addCallback=function(callback){
if (callbackFunctions.length===0) {
callbackFunctions.push(callback);
}
}
return{
addCallback: addCallback,
addWidget: addWidget
}
})
Scenario 1:
1. Click on "List" menu under the home page.
2. Click on "verify" button. notice the change in highlighted area with yellow. Text changes from "Chandan" to "singh1".
3. Click again on verify button. Text changes from "singh1" to "singh2". So i am able to communicate between two controller in this.
Scenario 2:
1. Repeat the scenario 1 till step 2.
2. Click on "PARAGRAPH" menu under home page.
3. Click on "List" menu under home page. Click verify button. The text wont change. It will remain "chandan".
Communication is not working as we change the state.
Also i have observed that the model is changing but same is not getting reflected in view. Moreover if we bind the view to rootscope, view is getting updated.
Please clarify.
When you switch between list and paragraph states, your list controller is destroyed (and recreated next time you go to list). So when it is recreated it gets a new scope.
The callbackFunction that is registered in your service, refers to the changeMyName() function on the old controller scope, so whenever you call addWidget() in your service, you're actually calling the callback in your old scope.
To make this work as expected (at least in your sample code here), you would have to change your service to allow changing the old callback in the addCallback()-function. Something like this:
var addCallback=function(callback){
callbackFunctions[0] = callback;
}

Retain Tab number in Navigation AngularJs

So I am relatively new to AngularJs and I am trying to figure out the best way for a tabController to remember what tab was previously clicked when switching to a new controller. So the situation would be I have 3 tabs. I click on tab 3 and then I click on something inside of it bringing me to a new controller and HTML template... What is the best way if I hit a "back" Button I created in that controller to remember exactly the state of it being the 3 tab.
I tried using $rootScope and then in each controller setting the tab number and setting the tabcontroller = $rootScope... but that was chaotic and too repetitive, and its not the right way.
This is not about $windoe.back(), this refers to coming up with a way that no matter where the navigation is the tab number is retained.
You can use a factory for this. In angular, a factory is a singleton, meaning only one instance of it exists for the whole project. Thus, by making something with it in one controller (and saving what you've did), you can access your changes in another controller.
angular.module('awesomeApp')
.factory('tabHistoryFactory', function () {
var tabHistory = {
setPrevTab: function(tab) { tabHistory.prevTab = tab; },
getPrevTab: function() { return tabHistory.prevTab; }
};
return tabHistory;
});
Then, in your first controller you'll have to inject this factory and before changing to another tab, just save the tab you're on using tabHistoryFactory.setPrevTab(tab). Then, in your second controller, you can access your previous tab by using tabHistoryFactory.getPrevTab(). Similarly, you can customize the behavior of your tab history by implementing other functions alongside those two.
Good luck!

How to design angular app with multiple models and select fields

What I'm trying to build is a SPA containing multiple selects on one page, where each select has it's own model. Choosing different options in the select boxes may show/hide other fields on the page and modify data for other selects (load different sets). Finally options in two selects may change the url (so when page is loaded with a proper address, those two options will be preselected).
Now I'm wondering what'll be the best approach here.
First. Is it worth to switch to ui-router in this case ?
Second. I need to write a custom directive for this select, that will have the following functionality
load data collection
display data and remember selection
reload it's data collection when other select triggered it
reload data for other selects
Now I've written directives before but never anything this (I think) complex. That's why few questions come to my mind.
How can I bind different data to my directive ?
Should this be just a single massive complex directive or divide it to smaller parts (like one directive for showing closed select box and another one to show the list and so on) ?
How can I trigger event when data should be changed and listen to a similar event from another select. Via controller ?
Thanks in advance for all your help.
What I can suggest is keep it MVC. Here is one of the solution -
Create a controller to store model data (here $scope.selectOptions inside controller)
Pass this values to 'select directive' instance to display
Whenever user select the value in directive, pass that selected value to controller (lets say in controller $scope.selectedValue is holding that value)
In controller add $watch on $scope.selectedValue and in its callback call for different data set for another select option. (lets say storing that data set in $scope.anotherSelectOption )
Pass this $scope.anotherSelectOption to '2nd directive' instance
Whenever user select the value in 2nd directive, pass that selected value to controller (lets say in controller $scope.anotherSelectedValue is holding that value)
In controller add $watch on $scope.anotherSelectedValue and in its callback change url thing you want to do
Here's your HTML will look like -
<div ng-controller="MyCtrl">
<select-directive selection-option="selectOptions", selected-option="selectedValue"> </select-directive>
<select-directive selection-option="anotherSelectOptions", selected-option="anotherSelectedValue"> </select-directive>
</div>
Here's your controller, it will look something like this -
yourApp.controller('MyCtrl', function($scope) {
$scope.selectOptions = []; // add init objects for select
$scope.selectedValue = null;
$scope.$watch('selectedValue', function() {
// here load new values for $scope.anotherSelectOptions
$scope.anotherSelectOptions = [] // add init objects for select
$scope.anotherSelectedValue = null;
});
$scope.$watch('anotherSelectedValue', function() {
// here add code for change URL
});
});
Here's your directive scope is
yourApp.directive('selectDirective', function() {
return {
templateUrl: 'views/directives/select.html',
restrict: 'E',
scope: {
selectionOption: '=',
selectedOption: '='
}
};
});

Opening angular-ui-bootstrap modal from javascript

I am trying to open the modal dialog from javascript when a certain condition is met. The example shown here http://angular-ui.github.io/bootstrap/ invokes the modal on ng-click.
How do I achieve showing modal when a certain condition is met?
Thanks
Additional Info
Sorry didn't mean to create confusion. I am going to clarify a little bit more by saying what I meant by "certain condition". The scenario is the user will search for customer by name and will get a list of customers back matching with the search string. The user then clicks on any one of the customer row to get more detail information.
When clicked the code control is handed off to Controller (It's an ASP.Net MVC app) which will then go through other classes and finally get data of the customer from database. It will then populate a boolean property called spouseNotFound. It then returns the JSON back to angularjs controller. Now assume that if this particular customer does not have spouse I want to show a modal saying that "Spouse not found".
So, no, I don't want the modal to be invoked on an event, rather than on business rule condition.
Hope that helps to understand things clearly.
Straight from the documentation.
$modal is a service to quickly create AngularJS-powered modal windows. Creating custom modals is straightforward: create a partial view, its controller and reference them when using the service.
Example plnkr. (http://plnkr.co/edit/?p=preview)
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
If anyone needs an easy approach to showing Bootstrap Modals with AngularJS, then you can simply use the following approach. It worked well for me:
var element = angular.element('#myModal');
// Open dialog
element.modal('show');
// Close dialog
element.modal('hide');
What you may be looking for is a $watch on your scope. This will allow you to monitor a variable, and when the value is what you want, then launch the modal as Nix describes.
$scope.$watch('entities', function(){
if($scope.entities[0].checked && $scope.entities[1].checked){
alert("If I were bootstrap, I'd be launching a modal right now!");
};
}, true);
A jsfiddle: http://jsfiddle.net/HB7LU/1636/

Interactive html from server

somewhere in my application I get a formatted html from server to be displayed to user:
me.myPanel().update(response.responseText);
Now, I want to put in this html some links (like "add comment") in every record. I get this in the server!
But how to capture this links in extjs to act like a button or so ?
I would use a delegate for this.
me.myPanel.el.on('click', me._click, me.myPanel, {
delegate: 'a.linkclass'
});
In the code above you would have a couple of < a > tags in the body of your panel. delegate will make sure that the click only applies to your a tags with only linkclass on them.
Here's a fiddle: http://jsfiddle.net/N9MSC/
I recommend to use the answer of Johan Haest
One other way would be to give unique ID's to the buttons. You can the use Ext.get('id') to fetch a Ext.dom.Element to which you can bind event like so
domElementRef.on('click', function() { alert('hit') })
You need to do this after the update is done.
Here's a JSFiddle

Resources