How to pass data from AngularJS list to Bootstrap modal? - javascript

At my view I have a list of items:
<li ng-repeat="fruit in items">
{{fruit.name}} / {{fruit.price}}
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">EDIT</button>
</li>
And I'd like to edit each product using bootstrap modal. That's why I need to pass data of specific product to modal. After this I'll simply pass this data to angular script using ng-click="saveFruit(dataFruit)" and saveFruit will save data.
Here is my fiddle:
http://jsfiddle.net/czus6s3a/

EDIT: Changed answer entirely.
Click here for a working fiddle: http://jsfiddle.net/sn8u7kqe/1/.
Changes made:
In the controller, I created a $scope.dataFruit = null, just to ensure the variable is initialized. I also created a function as follows:
$scope.setDataFruit = function(fruit) {
$scope.dataFruit = fruit;
};
This was to ensure that we were assigning our fruit to the right $scope.
Finally, I had you move your <div class="modal"> to INSIDE the div which had the ng-controller directive.
The controller will only apply it's model (variables, and functions, etc), to the elements that it has visibility of. As per your original example, the modal was OUTSIDE of the div, so the data binding would not have applied there.

Related

I can't edit a object in an array, ng-model doesn't change with ng-click

I am making a movie library. I use ng-repeat to show the movies and, for each movie there is a button to edit it and another one to remove it. The remove button works just fine, but the edit button doesn't.
It should open a panel and fill it with the movie data, but it only opens the panel with the first value I defined for the index.
button
<i class="glyphicon glyphicon-pencil small btnEdit" ng-click="i =(movies.indexOf(movie));"></i>
input
<input type="text" class="form-control" placeholder="Title" id="title" ng-model="movies[i].title">
the whole code is here: https://jsfiddle.net/victoorns/mwgcnsno/2/
Your controller's $scope property 'i' is being hidden via the rules behind scope inheritance. Ng-repeat creates its own isolate scope and since 'i' is a primitive (its just an integer), 'i' is only being set on that child $scope, as opposed to the main parent controller's scope.
<input type="text" class="form-control" placeholder="Title" id="title"
ng-model="movies[selected.movieIndex].title">
<i class="glyphicon glyphicon-pencil small btnEdit"
ng-click="selected.movieIndex =(movies.indexOf(movie));"></i>
Heres an updated jsfiddle here.
Notice how I am using an object (selected.movieIndex) so that is correctly updating the right property.
Heres more on understanding the exact behavior going on with the scope here
Approach is putting too much business logic in the view.
Pass whole object back to controller when you do things like this. Then do any splicing, copying etc in controller:
Simplified example:
<div ng-repeat="movie in movies">
<button ng-click="edit(movie)">
<button ng-click="delete(movie)">
</div>
In controller:
$scope.delete = function(movie){
var idx = $scope.movies.indexOf(movie);
if(idx !=-1){
$scope.movies.splice(idx,1)
}
}
$scope.edit = function(movie){
$scope.selectedMovie = movie;
}
Also get rid of all the jQuery and get rid of bootstrap.js and replace with angular-ui-bootstrap

Access Data from ng-repeat

i would like to use templates for a NetBanking app.
Therefore i constructed a basic service to get Objects filled with some Names and IBAN (unique key for banking transactions) in my service.js:
.factory('templateData', function(){
var savedTemplates = [
{name:"Adam Müller", iban:"AT29100020003000",img:"adam"},
{name:"Ben Streicher",iban:"AT34900080007000",img:"ben"},
{name:"Max Krossmann",iban:"AT23400050006000",img:"max"}
];
var getTemplates = function(){
return savedTemplates;
};
return {
getTemplates:getTemplates,
};
})
The controller saves this data via the .getTemplates() statement in a variable and the template view accesses mentioned variable with ng-repeat.
template.hmtl:
<div class="list" ng-model="chosentemplate">
<a
class="item item-thumbnail-left"
ng-repeat="template in Templatelist">
<img src="img/{{template.img}}.jpg">
<h2><b>{{template.name}}</b></h2>
<button
style="float: right;"
class="button button-positive pull-right"
ng-click="onTemplateClick(chosentemplate.iban)"
ui-sref="tab.transactions">Vorlage auswählen</button>
<p ><b>IBAN</b> {{template.iban}}</p>
</a>
Now, I'd like to save the chosen object in the service to use it later when filling it into the transactions form.
I'm struggling to access the used data from ng-repeat, when the button is clicked.
Some weeks ago i've done something quite similar, but just one child element of the object. I could access it with the equivalent to chosentemplate.name.
I would be very grateful for any suggestions!
You are iterating the Templatelist with the template variable.
So, simply use :
ng-click="onTemplateClick(template.iban)"

How to show the details of a particular row in a modal when row is clicked in AngularJS

I'm new to AngularJS. I'm converting some pages to AngularJS. I just displayed rows of information. However I'm having trouble converting the button onclick part to AngularJS. Can someone please help me. Below is the code that I'm working with.
<div ng-repeat="i in data">
<p>{{i.name}}</p>
<button class="btn btn-xs btn-default" data-toggle="modal" data-target=".show-ticket-details-modal" onclick="show_details(10)">
<i class="fa fa-info"></i>
</button>
</div>
Just pass the model to show_details method
show_details(i)
Regards,
Try using ng-click (https://docs.angularjs.org/api/ng/directive/ngClick). This runs a function in your angular controller when you click an element. All you've got to do is add the ng-click directive to your element, and then build a function with the same name in your angular controller to handle the data.
IE, replace onclick="show_details(10)" with: ng-click="show_details(10)".
Then, in your controller, build a function with the same name that will handle the data show_details(10), like:
$scope.show_details = function(index) {
console.log(index); // will log 10 in the example above
// do stuff with your index here,
// pass data to your angular factory, etc.
};
Note: For <form> elements, you can use the ng-submit directive instead (https://docs.angularjs.org/api/ng/directive/ngSubmit). Just use ng-submit="someFunction()" instead of ng-click.
Another Idea:
Instead of passing in the number 10, you could also use track by $index (https://docs.angularjs.org/api/ng/directive/ngRepeat#), for example, in your ng-repeat, you could:
ng-repeat="i in data track by $index"
Now, you can actually just pass $index into your ng-click function, instead of the number 10:
ng-click="show_details($index)" // $index will be 10, if the index of `i` was 10 in `data`
Hope this helps somewhat, let me know if you have any questions! The links included show more examples of their usage!

Combine ng-repeat and ng-click

I am building an angularJS app using ng-repeat and ng-click on the same element.
I have an array of items which I run through to create a list of buttons. Each one of these items has a property category which I'd like to pass as an argument for an ng-click action.
So far I have used the following code:
<button type="button" class="btn btn-default" ng-repeat="job in jobs" ng-click="filterJobListings(job.category)">
{{ job.category }}
</button>
However, the generated HTML is as follows:
<button type="button" class="btn btn-default ng-scope ng-binding" ng-repeat="job in jobs" ng-click="filterJobListings(job.category)">Design</button>
How can I pass the argument correctly here?
Thanks a lot,
Cheers
EDIT
I was wrong, ng-click="filterJobListings({{job.category}})" is not the solution
I believe you're doing it correctly. This could be an issue with prototypical inheritance. Remember, that ng-repeat creates its own scopes that might not apply their changes to the parent scope(s).
See my fiddle that works. Notice I'm using and object to store the selected category $scope.obj.cat=i;. It wouldn't work if I used a primitive.
http://jsfiddle.net/nicolasmoise/hwH64/

Most Angular way to add class on click

I'm building an interface with a lot of toggles to control what data is being filtered in a different part of an App's search results. Here is a codepen of it: Here
Coming from a jQuery/Backbone background, what is the most Angular way of toggling the 'active' state of any/all of the filter items? Essentially, almost any <li> tag presented here is a toggle-able feature.
In jQuery, I would put a listener on the view and wait for any click events to bubble up and toggle an 'active' class on the event.target. I want to do it the best way with Angular.
(Also, this is my first Angular project.. I am probably doing all sorts of things the wrong way. Apologies in advance.)
Edit: To clarify the question, I have an App Interface with 20+ possible filter attributes to control a separate module on the page. Every time someone toggles one of these filter attributes, I want to add/remove an 'active' class. Do I put an 'ng-click="function(...)"' in the ng-repeat for each controller? Or is there an easier way to manage this module-wide behavior (a la event bubbling, like in Backbone/jQuery) ?
Thanks!
You can do something like this:
<section ng-init="active = 'areaFoo'">
<div ng-class="{active:active == 'areaFoo'}" ng-click="active = 'areaFoo'"></div>
<div ng-class="{active:active == 'areaBar'}" ng-click="active = 'areaBar'"></div>
</section>
It will populate $scope.active for you, and is very angular as it leverages existing directives, manages the state on scope, and does not leverage dom api's or events outside of directives. There is really no need to involve the controller here, as its display logic.
Learn more about ng-class here.
Multiple active elements
<section>
<div ng-class="{active:areaFoo}" ng-init="areaFoo = true">
<button ng-click="areaFoo = true">activate</button>
<button ng-click="areaFoo = false">de activate</button>
</div>
<div ng-class="{active:areaBar}" ng-init="areaBar = false">
<button ng-click="areaBar = true">activate</button>
<button ng-click="areaBar = false">de activate</button>
</div>
<div ng-class="{active:areaBar}" ng-init="areaBaz = false">
<button ng-click="areaBaz = true">activate</button>
<button ng-click="areaBaz = false">de activate</button>
</div>
</section>
you could also toggle with something like this ng-click="areaFoo = !areaFoo"
I was able to come up with a solution I'm ok with, for anyone curious you can see a demo Here.
Here are the relevant code snippets:
<li ng-repeat='category in data' ng-class='{active: category.isActive}' ng-click='toggleActive(category)' >
<span class='solr-facets-filter-title'>{{category.catTitle}}</span>
<span class='solr-facets-filter-count'>{{category.catResults}}</span>
</li>
An ng-click calls a method on the Controller, toggleActive(category). The current data model gets sent to the method. In the JS:
$scope.toggleActive = function(category){
category.isActive = !category.isActive;
}
The function returns the opposite of the isActive attribute back to the li in question: an ng-class adds the active class for a truthy state of isActive.
I'm not a huge fan of how I have to adjust the data model with flags for active/inactive states like this, but it ends up working out for the best in this case. I can push those isActive states back to the $scope so that other parts of the App can run queries based on that information.

Categories