AngularJS and Laravel Foreach - angularjs

I do have a problem with using Angular with Laravel's foreach loop, i tried to be as detailed as possible :)
<div style="padding:15px;" id="table-scroll" ng-app>
<table class="table table-responsive tblProducts" id="tblProducts">
<thead>
<tr>
<th>Description</th>
<th>Prices</th>
<th></th>
<th></th>
<th>Action</th>
</tr>
</thead>
<tbody>
//foreach loop here
</tbody>
</table>
</div>
this is my foreach loop
#foreach($products as $product)
{{ $product->product_description }}
product_price }}" ng-model="price">
#{{price*qty}}
#endforeach
Problem:
-When I use "ng-model" the prices/quantity are not displayed, but when i use "ng-bind" the prices/quantity are displayed but the subtotal column displays NaN (i have no idea why).
Flow:
-Each row of that table displays a list of grocery items, when the checkbox is clicked, it means that the item is selected and transferred to another table for calculating the grandtotal.
Reference:
https://ibb.co/hCddLv (snap from list of grocery items)
https://ibb.co/e0jk0v (when that product is transferred, this happens)
*im using "ng-bind" to display the price and quantity...
Thanks for the answer in advance guys...
I have updated this with my controller code in laravel
public function create()
{
$rooms = Room::where('status','=',0)->orderBy('room_length_of_stay')->get();
$products = DB::table('classifications')
->join('products', 'classifications.id', '=', 'products.classification_id')
->select('classifications.*', 'products.*')
->get();
//$scope.products = $products;
return View::make('frontdesk.transactions.create', ['rooms' => $rooms, 'products'=>$products]);
}

ng-model works by using a property on the scope to read/write a value as an input changes so you can't just assign it some value hence the problem. Ideally I only use Angular for the front end and template handling and would do the looping with an ng-repeat over an array that is retrieved in JS from the backend (could be laravel based but would keep it just serving JSON data not doing anything with the view, lumen is good for this). In the short term you can just set the value attribute on the input that would be the most direct way to put your data into the form that may not work with ng-model though (assuming you pointed that at some JS property) since it's expected the ng-model will be used for reading/writing the value.

Instead of using the foreach in blade use a ng-repeat directive. Get the data in the foreach in a json and iterate it in the template.
Before the render of the angular controller make a script:
<script>
var products = "{{ json_encode($products) }}";
</script>
Then in the controller store it as:
$scope.products = products;
Then iterate it:
<p ng-repeat="product in products">
#{{ product.product_description }}
#{{ product.price*product.qty}}
</p>

Related

How can i conditionally display an element using AngularJS

I want to display an element conditionally based on the value of another parameter PaymentTypeid. After setting the condition as below the element Payment Channel is not rendering in the UI:
<tr ng-init="paymentMode='BANK CABS'" ng-if="json.name == 'paymentTypeId' && json.property == '1'">
<td><strong>{{ 'label.heading.paymentchannel' | translate }}:</strong></td>
<td ><span >{{paymentMode}} </span></td>
</tr>
However when i refactor the markup as below the element is showing as :
<tr ng-init="paymentMode='BANK CABS'">
<td><strong>{{ 'label.heading.paymentchannel' | translate }}:</strong></td>
<td ><span >{{paymentMode}} </span></td>
</tr>
PaymentTypeId is in a json array defined as follows in the controller:
scope.details = {};
resourceFactory.auditResource.get({templateResource: routeParams.id}, function (data) {
scope.details = data;
scope.details.paymentMode="";
scope.commandAsJson = data.commandAsJson;
var obj = JSON.parse(scope.commandAsJson);
scope.jsondata = [];
_.each(obj, function (value, key) {
scope.jsondata.push({name: key, property: value});
});
});
In the view PaymentTypeid renders as :
<table class="table" data-ng-show="details.commandAsJson" data-anchor>
<tbody>
<tr data-ng-repeat="json in jsondata">
<td class="width20"><strong> {{json.name}}</strong></td>
<td class="width80">{{json.property}}</td>
</tr>
</tbody>
</table>
Any insight on what i might be getting wrong. Im not entirely sure between using ng-if/ng-show or whether im setting json.property correctly.
Assuming that you have knowledge of scope in AngularJS.
There is a difference between using ng-if and ng-show. Whenever you use ng-if , it creates it own child scope. and you can manage it in custom directive that deals with its child scope (child scope is not available in controller unless you write your code in a way, that will make it available in controller) and you can hack the scope to use it in controller too. But that is not the case in ng-show.
When you use ng-show it will not remove your HTML from the DOM tree but if you use ng-if it will also remove your html from DOM tree. (To assist your confusion which one to use)
You have a scope issue here , if i'm getting it right. Use ng-show and it will work.
<div ng-show="condition">
your html markup
</div>

Datatables search, filter, and export with Firebase

I have a CRUD app powered by angular. Recently I added datatables to it in order to search, filter, sort,export and hide columns using the power of datatables. Unfortunately it returns the Firebase references in the various columns {{contact.name}} {{contact.email}} (There are 4 more columns) when I use any datatables feature such as search it returns the Firebase reference instead of a field. Is there a way to fix this? I really need those datatable features at the same time use Firebase.
$(document).ready(function() {
$('#contacts').DataTable( {
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5'
]
} );
} );
<table id="contacts" class="table table-striped table-hover" >
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Area</th>
<th>Occupation</th>
<th>E-mail</th>
<th> Actions </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="contact in contacts">
<td>{{contact.name}}</td>
<td>{{contact.phone}}</td>
<td>{{contact.area}}</td>
<td>{{contact.work}}</td>
<td>{{contact.email}}</td>
<td>Edit <a class="btn btn-raised btn-xs btn-danger" ng-click="removeContact(contact.$id)">Delete</a></td>
</tr>
</tbody>
</table>
EDIT
Will sourcing the data via ajax sort this out. This is the json format i get from the ajax GET request
{"-KIZ6VnucsKbKjlaE8aq":{"area":"Parklands","email":"tttt","name":"Mohammed Sohail","phone":"+254700000000","work":"ttt"},"-KId6OC2gOwiacUid9yK":{"area":"dfgdfg","email":"dfgdf","name":"dfg","phone":"dfgdfg","work":"fdfffffff"},"-KId6Rqo0B6w0jACHhWM":{"area":"dfgdfgdfgdf","email":"dfgdfgdfgdfg","name":"dfgfdgdf","phone":"gdfgdfgdfg","work":"gdfgdfgdfgdfg"},"-KIqmYZubPYhAqDqEyWo":{"area":"dfgfdg","email":"fgfdgfdgdf","name":"fgfg","phone":"fdgdg","work":"fgdfgdf"},"-KIqn5QABMXrTGoVgQv1":{"area":"bla","email":"weadasda","name":"bla","phone":"bla","work":"bla"}}
And this is how the data looks like on the console.
Any help to use data tables will be appriciated.
FireBase database image
So, this question is really about turning a (firebase) JSON object of objects with unknown object entry names such as KId6Rqo0B6w0jACHhWM into a more plain structure that can be used along with dataTables and ng-repeat?
You can format contacts into an array of plain objects this way :
$http.get('firebase.json').then(function(json) { //faked response from firebase
$scope.contacts = []
for (var item in json.data) {
$scope.contacts.push(json.data[item])
}
})
Now the ng-repeat will work and the markup (or contacts data) is understandable for dataTables. To turn this into angular-datatables (angular directives for jQuery dataTables) the only thing you need to do is to include the datatables dependency and include the datatable directive in the markup :
<table datatable="ng" class="table table-striped table-hover" >
demo -> http://plnkr.co/edit/tn9cuKa46vs4x8cHebjB?p=preview

Ng-click does not work outside of my tr tag AngularJS

I am working on an app and I cant seem to figure out why my ng-click only works inside of my (single) tr tag but as soon as I put it into another tr tag it stop working. Keep in mind it was working before I used the ng-repeat within the first tr tag. Here is what my code looks like, any advice would greatly help!
<table>
<tbody>
<tr>
<td ng-click="commentOpen = !commentOpen">
<div class="iconsize">Comment Closed</div>
</td>
<td ng-click="switchOpen = !switchOpen">
<div class="iconsize">Switch Closed</div>
</td>
</tr>
<tr>
<td>
<div ng-show="commentOpen == true">
<textarea>Comment Open</textarea>
</div>
<div ng-show="switchOpen == true">
<p>Switch On</p>
</div>
</td>
</tr>
</tbody>
</table>
I had the ng-repeat on the tag which was causing my ng-click to not fire. I ended up moving my ng-repeat to the tbody and the ng-click and ng-show started working again.
ngRepeat creates new scopes for its children, it just usually seems like it's accessing the same scope because this new scope inherits from its parent.
Meaning, commentOpen is actually referring to a property on the wrong scope.
Below are three potential ways for you to fix this:
1) controller as, and always refer to the controller you're after by name
2) $parent.commentOpen (Don't do this! It becomes very confusing as you nest)
3) Instead of commentOpen and switchOpen, you can use an Object (e.g. $scope.openControls = { comment: false, switch: false }, and then in the td tags you would write something like ng-click='openControls.comment = !openControls.comment'). This way it's passed inherited by reference (where as a boolean would be by value), and keeps synced.

How do I bind object model within an ng-repeat directive to a single kendo-window popup

Html:
<table>
<thead>
<tr>
<th>Name</th>
<th>DOB</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="member in model.Members" ng-dblclick="Member(member)">
<td>{{member.Name}}</td>
<td>{{member.DOB | date:'yyyy-MM-dd'}}</td>
</tr>
</tbody>
</table>
<div kendo-window="*dialog*" k-title="'Member Profile'" k-visible="false" k-modal="true" k-width="700" k-height="410" k-resizable="false">
<ng-familymember controller="familycontroller"></ng-familymember>
</div>
Controller:
function fooController($scope) {
$scope.Member = function (familyMember) {
$scope.*dialog*.center().open();
}
}
Problem:
I have a collection of objects (i.e. model.Members) used within an ng-repeat directive and I want to be able to double-click on a row and bind the object model to a kendo-window (popup). Inside my controller I'm passing in the model to a function (i.e. Member()) within the controller but I'm not sure how to pass/bind this model to the kendo-window? I could simply move the kendo-window html inside the ng-repeat and use the ng-model directive but that would repeat the kendo-window html (n) times and I don't want that.
Any Suggestions?
I've tried binding the member object to an $scope variable. (i.e. $scope.familyMember = familyMember;). Because the way Prototypal Inheritance works I'm actually creating a copy of the familyMember object and using that in the kendow-window popup.
You should know that I'm also setting up a $watch within the controller on the member object to notify other directives on the page of changes made within the kendo-window.
Any help would be appreciated... I'm a bit lost at this point...

How to get Angular to update the Ui from within the controller

I have the following html.
<div ng-controller="CustCtrl">
<table class="table table-condensed">
<thead>
etc.
</thead>
<tbody>
<tr ng-repeat="customer in customers" data-cust-id="{{customer.Id}}">
<td>
<button ng-model="Id" tracking-{{customer.Tracking}} ng-click="startTrackingCustById(customer.Id)">
</button>
</td>
etc.
</tr>
</tbody>
</table>
So the button has a class that is databound to the customer.Tracking value which is either true or false. When the button is clicked the startTrackingCustById() method is successfully called and the customer object in the customers object is successfully changed like customer.Tracking = true.
But the buttons class is not updated. What am I missing?
Look at using ng-class . For a boolean value in scope you would use:
ng-class="{'classNameToAddIfTrue':customer.Tracking}"
In the CustCtrl I wrapped the call that updated the customers array like this
$scope.$apply($scope.customers[i].Tracking = true);
Based on the suggestion in an answer I will link to when I find it that basically said "If you are having trouble updating the view you most likely need to use $scope.$apply
So that get's it to work. Now I need to figure out why and how.

Resources