Multiple Data Bindings in Angular JS - angularjs

I am new to Angular and would like to know if something like this is possible:
I'm calling data to each story using JSON. Once the story is clicked I would like it to be sent to Javascript, then passed to a different HTML div, the player div.
Is there a way to do that? Or is that not possible with Angular?
For example:
<body ng-app="app" ng-controller"storyCtrl">
<div id="story-1"
class="play_button"
data-id="{id}"
data-title="{title}"
data-storyurl="{fullUrl}"
data-program="{program}"
data-programurl="{program.fullUrl}"
data-type="audio"
data-src="{soundcloudLink}"
data-item-type="story"
data-pub-date="{addedOn}"
data-excerpt="{excerpt}">
</div>
<div id="story-2"
class="play_button"
data-id="{id}"
data-title="{title}"
data-storyurl="{fullUrl}"
data-program="{program}"
data-programurl="{program.fullUrl}"
data-type="audio"
data-src="{soundcloudLink}"
data-item-type="story"
data-pub-date="{addedOn}"
data-excerpt="{excerpt}">
</div>
<!--Here is where I would like the clicked data passed back to:-->
<div id="player">
{{story.Title}}
{{story.Program}}
</div>
</body>
How would I go about creating the variables so that they display the data from the clicked story? Is it possible using Angular's two way binding? I would like them to display the data-information as follows:
var app = angular.module('app', []);
app.controller('storyCtrl', function($scope) {
var story = [
{
Id: 'data-id',
Title: 'data-title',
Storyurl:'data-storyurl',
Program: 'data-program',
Programurl: 'data-programurl',
Type: 'data-type',
Src: 'data-src',
Pubdate: 'data-pub-date',
Excerpt: 'data-excerpt',
},
];
$scope.story = story;
});

Related

Use VueJs to save a template

My project currently is made with VueJS. Now, we need to process a certain template with the input data, then store the result and use it to send an email (for example).
Can i render a template with the user data and save it? how?
I don't want to use another library for this purpose, unless We can't do with VueJS
I have read about SSR. But i don't want to use a server-side rendering. The idea is only render certain messages. Following a behavior like this:
save: function(){
userNote.user = ...
userNote.message = document.getElementById('message').innerHtml;
saveToServer(userNote);
}
The Message template:
<div id="message"> Dear {{user.name}}, please confirm that {{notes}} before {{date}}</div>
I hope i made me understand.
Thanks in advance.
Assuming your template is stored in a component, you could add an export method :
var templateComponent = Vue.component("template-component", {
template: "<p>Hello {{name}}</p>",
props: ["name"],
methods: {
exportHTML: function() {
return this.$el.outerHTML;
}
}
});
var app = new Vue({
el: '#app',
data: {
name: "David",
html: undefined
},
methods: {
getHTML: function() {
this.html = this.$refs.template.exportHTML();
}
}
});
<script src="https://unpkg.com/vue#2.4.2/dist/vue.min.js"></script>
<div id="app">
<div style="display: none">
<template-component :name="name" ref="template"></template-component>
</div>
<label>Name
<input v-model="name">
</label>
<button #click="getHTML">Get html</button>
<pre>{{ html }}</pre>
</div>
Then you just have to call the exportHTML method on the template component to retrieve the HTML.

AngularJS - How to change another image when principal image change

I'm trying to develop a solution through AngularJS where when the user changes the profile image, all other photos based on their profile are also changed.
How can I start developing this feature?
Thanks in advance!
[Solution]
With the help of the #wolfman6377, I can understand the functionality and develop the solution for what I need. I'll leave an example in CodePen.
CodePen
var myApp = angular.module('myApp',[]);
myApp.controller('myController', function() {
this.myVar = 'https://robohash.org/asd'
this.updatePicture = function() {
this.myVar = 'https://angular.io/resources/images/logos/angular/angular.png';
};
});
Thank you, #wolfman6377.
You are using a jQuery-like strategy. jQuery element selector will not be able to change the value of myVar.
I would recommend going through some basic tutorials on angular1. But in a nutshell, you need to:
Do not grab elements and change attributes
add a module to the ng-app value
Use ng-controller in the template
Add ng-click to the button to update the value of myVar
template
<body ng-app="myApp">
<div id="var" ng-controller="myController as vm">
<img ng-src={{vm.myVar}} />
<button ng-click="vm.updatePicture()">Click me</button>
</div>
</body>
controller:
angular
.module('myApp', [])
.controller('myController', function() {
this.myVar = 'https://www.w3schools.com/angular/pic_angular.jpg'
this.updatePicture = function() {
this.myVar = 'https://angular.io/resources/images/logos/angular/angular.png';
};
});

How to Redraw Tables using Angular UI Tabs and UI Grid?

I'm trying to migrate from jQuery Data Tables to Angular UI. My app uses the MySQL World schema and displays the data in 3 different tables. In jQuery, I'd 3 different pages, each launched from a home page. Here's a live example.
In Angular, I created 3 tabs, clicking on each of which is supposed to reload the page with a new grid and populate it with data. Problem is, the grid gets displayed alright on page load with the content on the first tab. On clicking the other tabs, page goes empty and nothing is rendered. Now the data returned is not insignificant, sometimes around 4k rows. However, the problem isn't a latency issue as I've confirmed by waiting several minutes.
I'm not a JS/CSS/HTML guy so most likely I'm missing something. That's why this question.
Edit:
Plnkr
Following is the code:
HTML:
<body>
<div id="selection-panel" class="selection-panel" ng-controller="HelloWorldCtrl">
<div>
<uib-tabset type="pills" justified="true">
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)">
<div id="data-panel" class="data-panel" ui-grid="gridOptions"></div>
</uib-tab>
</uib-tabset>
</div>
</div>
<script src="js/app.js"></script>
</body>
JS:
(function() {
var app = angular.module('helloWorld', ['ui.bootstrap', 'ui.grid']);
app.controller('HelloWorldCtrl', ['$http', '$scope', function ($http, $scope) {
$scope.tabs = [
{ title: 'Countries' },
{ title: 'Cities' },
{ title: 'Languages' }
];
$scope.gridOptions = {};
$scope.gridOptions.data = [];
$scope.gridOptionsCountries = {
columnDefs: [
{ name: 'code'},
{ name: 'name'},
{ name: 'continent'},
{ name: 'region'},
{ name: 'population'}
]
};
$scope.gridOptionsCities = {
columnDefs: [
{ name: 'id'},
{ name: 'name'},
{ name: 'country'},
{ name: 'population'}
]
};
$scope.gridOptionsLanguages = {
columnDefs: [
{ name: 'country'},
{ name: 'language'}
]
};
$scope.update = function(title) {
if (title === "Countries") {
$scope.gridOptions = angular.copy($scope.gridOptionsCountries);
} else if (title === "Cities") {
$scope.gridOptions = angular.copy($scope.gridOptionsCities);
} else if (title === "Languages") {
$scope.gridOptions = angular.copy($scope.gridOptionsLanguages);
}
$http.get(title.toLowerCase()).success(function(data) {
$scope.gridOptions.data = data;
});
};
}]);
})();
I see 2 problems here:
You are creating/changing gridOptions dinamically. This is not the usual way of doing things and can bring many problems.
You are using grids inside of uib-tabs and this, like uib-modals, can have some annoying side effects.
I'd suggest you to address the first issue using different gridOptions (as you do when you create them) and then putting them inside your tabs array children, this way you can refer them from the html this whay:
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)">
<div id="data-panel" class="data-panel" ui-grid="tab.gridOptions"></div>
</uib-tab>
The second problem is quite known and inside this tutorial they explain how to address it: you should add a $interval instruction to refresh the grid for some time after it's updated in order to let the tab take its time to load and render.
The code should be as follows:
$scope.tabs[0].gridOptions.data = data;
$interval( function() {
$scope.gridCountriesApi.core.handleWindowResize();
}, 10, 500);
Where gridCountriesApi are created inside of a regular onRegisterApi method.
I edited your plunkr, so you can see the whole code.
I can not get this to work in tabs, my guess is because you first use ng-repeat which creates a scope for each iteration, and then maybe the tabs itself creates a new scope and this causes a lot of headache with updates.
The quickest solution is just to move the grid outside of the tabs.
Here is the updated html.
HTML
<body>
<div id="selection-panel" class="selection-panel" ng-controller="HelloWorldCtrl">
<div>
<uib-tabset type="pills" justified="true">
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)"></div>
</uib-tab>
</uib-tabset>
<!-- This is moved outside -->
<div id="data-panel" class="data-panel" ui-grid="gridOptions">
</div>
</div>
<script src="js/app.js"></script>
</body>
In my situation tab contents consume important time to be loaded. So if your case is that you don't want to update tab content everytime the tab is clicked, you can use this workaround:
In the HTML part I use select property to indicate which tab is pressed:
<tabset justified="true">
<tab heading="Tab 1" select="setFlag('showTab1')">
<div ng-if="showTab1">
...
</div>
</tab>
</tabset>
In the tab (*) container I used a switch to recognize which tab is pressed and broadcast the press action:
case 'showTab1':
$scope.$broadcast('tab1Selected');
break;
And in the controller part I listen the event and handle resizing:
// The timeout 0 function ensures that the code is run zero milliseconds after angular has finished processing the document.
$scope.$on('tab1Selected', function () {
$timeout(function() {
$scope.gridApi1.core.handleWindowResize();
}, 0);
});
Here is my Plunkr. Hope it helps.
(*) For current bootstrap version you should use and

multiple inputs based on array

My angular experience is basically about 3 days part time, so there's probably something simple I'm missing here.
I'm trying to create a dynamic list of multiple inputs based on an array, which I then want to reference from elsewhere in the app. What I've tried is loading a template from a custom directive, then $compile-ing it.
<input data-ng-repeat="term in query" data-ng-model="term">
My controller contains $scope.query = [""] which successfully creates the first empty input box. But the input box doesn't seem to update $scope.query[0] when I modify it. This means that when I try to create another empty input box with $scope.query.push(""); (from a keypress listener looking for the "/" key) I get a "duplicates not allowed" error.
I've tried manually listening to the inputs and updating scope.$query based on their value, but that doesn't feel very "angular", and results in weird behaviour.
What do I need to do to link these values. Am I along the right lines or way off?
I made a simple jsfiddle showing how to use an angular model (service) to store the data. Modifying the text inputs will also modify the model. In order to reference them somewhere else in your app, you can include TestModel in your other controllers.
http://jsfiddle.net/o63ubdnL/
html:
<body ng-app="TestApp">
<div ng-controller="TestController">
<div ng-repeat="item in queries track by $index">
<input type="text" ng-model="queries[$index]" />
</div>
<br/><br/>
<button ng-click="getVal()">Get Values</button>
</div>
</body>
javascript:
var app = angular.module('TestApp',[]);
app.controller('TestController', function($scope, TestModel)
{
$scope.queries = TestModel.get();
$scope.getVal = function()
{
console.log(TestModel.get());
alert(TestModel.get());
}
});
app.service('TestModel', function()
{
var queries = ['box1','box2','box3'];
return {
get: function()
{
return queries;
}
}
});

Angularjs - Using controller

I am new to Angular.js. I currently have the following html code, where I define my div with my file html ( ng-include ) and my controller ( ng-controller ):
<div id="customerinformation-maxi" ng-include="'pages/customerinformation-maxi.html'" ng-controller="customerInformationMaxiController" class="col-md-12"></div>
This is the html code for the called html in directive ng-include ( customer-information.html ):
<div class="row">
<div class="col-md-2">
<span>Customer Number</span>
<span>{{customer.number}}</span>
</div>
<div class="col-md-2">
<span>Portfolio</span>
<span>{{custom.portfolio}}</span>
</div>
</div>
This is the js controller:
angularRoutingApp.controller('customerInformationMaxiController', function($scope, $http) {
//Here i need to load the model variable with a literal text {{customer.number}} and {{customer.portfolio}}, how could do it? using scope object? with a json file?
});
Here I need to load the model variable with a literal text {{customer.number}} and {{customer.portfolio}}.
How could do it? Using scope object? With a json file?
Thanks for any help.
Yes, you should do it using the $scope object.
To get a general overview, here is a hello-world example:
<div ng-controller="HelloController">
{{ helloMessage }}
</div>
And in you controller's code (js file or script tag into the html):
var myApp = angular.module('myApp',[]);
myApp.controller('HelloController', ['$scope', function($scope) {
$scope.helloMessage= 'Hello World!';
}]);
But I foresee some nesting in the provided snippet of your question, so you 're probably dealing with a collection of objects which means that you have to iterate through it, in the html part, using the ng-repeat directive, like:
<tr ng-repeat="customer in customers>
<td>{{customer.number}}</td>
<td>{{customer.portfolio}}</td>
</tr>
So, your controller's functionality should contain the customers object, like:
angularRoutingApp.controller('customerInformationMaxiController', function($scope, $http) {
var customers=[
{
number:'123',
portfolio: 'blah blah'
},
{
number:'124',
portfolio: 'blah blah'
},
{
number:'125',
portfolio: 'blah blah'
}
];
});
For further reference, you could read two respective example I have written:
Angular.js Controller Example
Angular.js JSON Fetching Example
The second one is only to see a sample usage of traversing collections, it is not meant that you have to use json, as you stated in your question; but I see that you also defined the $http service in your controller, so if it's about data that are going to be fetched from a remote destination, the JSON Fetching Example should probably help you better).
You should use scope objects to give values to your modal variables.
angularRoutingApp.controller('customerInformationMaxiController', function($scope, $http) {
$scope.customer.number = 'sample number';
$scope.customer.portfolio = 'sample portfolio';
});

Resources