How to take the amount from an input and add(+) to the amount table in db? (Laravel)
I have this view :
enter image description here
and i have a table named Collaborators (which has an column named istoric_proiecte_sum_suma(made with withSum() function from laravel, in relationship with another table ProjectHistory that contains details about what collaborator works in any project and how much the owner paid him. and if the collab work on multiple projects the owners has to pay him multiple times, and if that, we have multiple inserts in ProjectHistory table with sums and withSum() function makes the relation between those and add the sum and display it to me) which contains the expenses, payments from the owner of the company to a collaborator) like you see in "suma" column in first image (suma = amount). So if i have a - amount the owner of the company needs to pay the collaborator and he pay him from completing that input and press "realizeaza plata" (translated -> make the payment).
So when he press "make payment" -> realizeaza plata, i need to add (+ sign operator) the amount that i typed in "suma" input to the "suma" (amount) column in first image(which is column istoric_proiecte_sum_suma).
My question is how do i resolve this problem because i have no idea. Look what i've tried:
CollaboratorController.php
public function realizeazaPlata(Request $request, Colaboratori $colaborator, $id)
{
$colaboratori1 = Colaboratori::findOrFail($id);
$suma = $request->input('introduSuma');
dd($suma);
DB::update('UPDATE Colaboratori SET istoric_proiecte_sum_suma=? WHERE id=?', [($colaborator->istoric_proiecte_sum_suma + $suma), $colaboratori1->id]);
return back();
}
ColabsView.blade
<form action="{{ url('colaboratori') }}" method="POST">
#csrf
#method('GET')
<td>
<input type="text" name='introduSuma' placeholder="Suma">
<button type="submit" class="btn btn-primary">Realizeaza plata</button>
</td>
</form>
web.php
Route::get('colaboratori', [App\Http\Controllers\ColaboratoriController::class, 'realizeazaPlata'])->name('realizeazaPlata');
Can someone help me please. Thanks
Do you mean you need to convert negative number to positive and then SUM it?
You could use abs() function:
$suma = abs($request->input('introduSuma'));
You should use type=number, to prevent users from entering characters:
<input type="number" name='introduSuma' placeholder="Suma">
You can do it like the following:
$colaboratori1 = Colaboratori::findOrFail($id);
$suma = $request->input('introduSuma');
$colaboratori1->istoric_proiecte_sum_suma = $colaboratori1->istoric_proiecte_sum_suma + $suma;
$colaboratori1->save();
I have a simple application which sum amount of my orders and payments only per same day and submit them in table. I have a drawer which starting every day and when finish the day I can submit total sum of day (orders,pay in/out) and at the next day I'm starting from begining with 0 cash again.
My question: Is that a possible to end my drawer and start it again in the same day with 0 cash multiple times per day?
Now if I start again I'm seeing all orders whose are already maked today.
My controller:
public function show($id)
{
$locations = Location::find($id)->orders()->whereDate('created_at', '=', Carbon::today()->toDateString()); //show orders
$wallets = Location::find($id)->locsales()->whereDate('created_at', '=', Carbon::today()->toDateString()); //show payments
$loc = Location::find($id); //to show location name
return view('location')
->with('locations', $locations)
->with('wallets', $wallets)
->with('loc', $loc);
}
Part of my view:
<div class="card-body">
<div class="form-group">
<div class="list-group-item">
<label for="location">Location: {{$loc->location_id}}</label>
<form method="post" action="/post_drawer">
#csrf
<input type="number" class="form-control" name="start_cash" id="start_cash" value="{{$wallets->sum('start_cash')}}" readonly>
<label for="info">Amount of orders(today):</label>
<input type="number" class="form-control" name="amount" id="amount" value="{{$locations->sum('total')}}" readonly>
Update 1: I added to orders table and to my view option to submit added_to_drawer field with boolean and now my controller is like that:
$locations = Location::find($id)->orders()->whereDate('created_at', '=', Carbon::today()->toDateString())->whereNull('added_to_drawer');
May be I'm doing something wrong but it doesn't work.
Update 2:I maked my controller to show only records with value 1 and now it's working correct.
$locations = Location::find($id)->orders()
->where('added_to_drawer', 1)
$affected = DB::table('orders')->whereid('location', $id)->update(array('added_to_drawer' => 0));
$affected = DB::table('wallets')->where('location_id', $id)->update(array('added_to_drawer' => 0));
But I have another problem. When I close my drawer he update(reset) all locations
drawer to 0.
For example - I want to update only this locations where name is New York but to be dynamically. Not like that: where('location','=','New York')
I tried it like this: where('location','=' $id) but it's doesn't work.
I am trying to write a function that enables me to remove an item when the button is clicked but I think I am getting confused with the function - do I use $digest?
HTML & app.js:
<ul ng-repeat="bday in bdays">
<li>
<span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
<form ng-show="editing" ng-submit="editing = false">
<label>Name:</label>
<input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
<label>Date:</label>
<input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
<br/>
<button class="btn" type="submit">Save</button>
<a class="btn" ng-click="remove()">Delete</a>
</form>
</li>
</ul>
$scope.remove = function(){
$scope.newBirthday = $scope.$digest();
};
To remove item you need to remove it from array and can pass bday item to your remove function in markup. Then in controller look up the index of item and remove from array
<a class="btn" ng-click="remove(item)">Delete</a>
Then in controller:
$scope.remove = function(item) {
var index = $scope.bdays.indexOf(item);
$scope.bdays.splice(index, 1);
}
Angular will automatically detect the change to the bdays array and do the update of ng-repeat
DEMO: http://plnkr.co/edit/ZdShIA?p=preview
EDIT: If doing live updates with server would use a service you create using $resource to manage the array updates at same time it updates server
This is a correct answer:
<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove=function($index){
$scope.bdays.splice($index,1);
}
In #charlietfl's answer. I think it's wrong since you pass $index as paramter but you use the wish instead in controller. Correct me if I'm wrong :)
In case you're inside an ng-repeat
you could use a one liner option
<div ng-repeat="key in keywords">
<button ng-click="keywords.splice($index, 1)">
{{key.name}}
</button>
</div>
$index is used by angular to show current index of the array inside ng-repeat
Using $index works perfectly well in basic cases, and #charlietfl's answer is great. But sometimes, $index isn't enough.
Imagine you have a single array, which you're presenting in two different ng-repeat's. One of those ng-repeat's is filtered for objects that have a truthy property, and the other is filtered for a falsy property. Two different filtered arrays are being presented, which derive from a single original array. (Or, if it helps to visualize: perhaps you have a single array of people, and you want one ng-repeat for the women in that array, and another for the men in that same array.) Your goal: delete reliably from the original array, using information from the members of the filtered arrays.
In each of those filtered arrays, $index won't be the index of the item within the original array. It'll be the index in the filtered sub-array. So, you won't be able to tell the person's index in the original people array, you'll only know the $index from the women or men sub-array. Try to delete using that, and you'll have items disappearing from everywhere except where you wanted. What to do?
If you're lucky enough be using a data model includes a unique identifier for each object, then use that instead of $index, to find the object and splice it out of the main array. (Use my example below, but with that unique identifier.) But if you're not so lucky?
Angular actually augments each item in an ng-repeated array (in the main, original array) with a unique property called $$hashKey. You can search the original array for a match on the $$hashKey of the item you want to delete, and get rid of it that way.
Note that $$hashKey is an implementation detail, not included in the published API for ng-repeat. They could remove support for that property at any time. But probably not. :-)
$scope.deleteFilteredItem = function(hashKey, sourceArray){
angular.forEach(sourceArray, function(obj, index){
// sourceArray is a reference to the original array passed to ng-repeat,
// rather than the filtered version.
// 1. compare the target object's hashKey to the current member of the iterable:
if (obj.$$hashKey === hashKey) {
// remove the matching item from the array
sourceArray.splice(index, 1);
// and exit the loop right away
return;
};
});
}
Invoke with:
ng-click="deleteFilteredItem(item.$$hashKey, refToSourceArray)"
EDIT: Using a function like this, which keys on the $$hashKey instead of a model-specific property name, also has the significant added advantage of making this function reusable across different models and contexts. Provide it with your array reference, and your item reference, and it should just work.
I usually write in such style :
<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove = function(index){
$scope.[yourArray].splice(index, 1)
};
Hope this will help
You have to use a dot(.) between $scope and [yourArray]
Building on the accepted answer, this will work with ngRepeat, filterand handle expections better:
Controller:
vm.remove = function(item, array) {
var index = array.indexOf(item);
if(index>=0)
array.splice(index, 1);
}
View:
ng-click="vm.remove(item,$scope.bdays)"
implementation Without a Controller.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<script>
var app = angular.module("myShoppingList", []);
</script>
<div ng-app="myShoppingList" ng-init="products = ['Milk','Bread','Cheese']">
<ul>
<li ng-repeat="x in products track by $index">{{x}}
<span ng-click="products.splice($index,1)">×</span>
</li>
</ul>
<input ng-model="addItem">
<button ng-click="products.push(addItem)">Add</button>
</div>
<p>Click the little x to remove an item from the shopping list.</p>
</body>
</html>
The splice() method adds/removes items to/from an array.
array.splice(index, howmanyitem(s), item_1, ....., item_n)
index:
Required. An integer that specifies at what position to add/remove items, Use negative values to specify the position from the end of the array.
howmanyitem(s): Optional. The number of items to be removed. If set to 0, no items will be removed.
item_1, ..., item_n: Optional. The new item(s) to be added to the array
I disagree that you should be calling a method on your controller. You should be using a service for any actual functionality, and you should be defining directives for any functionality for scalability and modularity, as well as assigning a click event which contains a call to the service which you inject into your directive.
So, for instance, on your HTML...
<a class="btn" ng-remove-birthday="$index">Delete</a>
Then, create a directive...
angular.module('myApp').directive('ngRemoveBirthday', ['myService', function(myService){
return function(scope, element, attrs){
angular.element(element.bind('click', function(){
myService.removeBirthday(scope.$eval(attrs.ngRemoveBirthday), scope);
};
};
}])
Then in your service...
angular.module('myApp').factory('myService', [function(){
return {
removeBirthday: function(birthdayIndex, scope){
scope.bdays.splice(birthdayIndex);
scope.$apply();
}
};
}]);
When you write your code properly like this, you will make it very easy to write future changes without having to restructure your code. It's organized properly, and you're handling custom click events correctly by binding using custom directives.
For instance, if your client says, "hey, now let's make it call the server and make bread, and then popup a modal." You will be able to easily just go to the service itself without having to add or change any of the HTML, and/or controller method code. If you had just the one line on the controller, you'd eventually need to use a service, for extending the functionality to the heavier lifting the client is asking for.
Also, if you need another 'Delete' button elsewhere, you now have a directive attribute ('ng-remove-birthday') you can easily assign to any element on the page. This now makes it modular and reusable. This will come in handy when dealing with the HEAVY web components paradigm of Angular 2.0. There IS no controller in 2.0. :)
Happy Developing!!!
Here is another answer. I hope it will help.
<a class="btn" ng-click="delete(item)">Delete</a>
$scope.delete(item){
var index = this.list.indexOf(item);
this.list.splice(index, 1);
}
array.splice(start)
array.splice(start, deleteCount)
array.splice(start, deleteCount, item1, item2, ...)
Full source is here
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
if you have ID or any specific field in your item, you can use filter(). its act like Where().
<a class="btn" ng-click="remove(item)">Delete</a>
in controller:
$scope.remove = function(item) {
$scope.bdays = $scope.bdays.filter(function (element) {
return element.ID!=item.ID
});
}
Pass the id that you want to remove from the array to the given function
from the controller( Function can be in the same controller but prefer
to keep it in a service)
function removeInfo(id) {
let item = bdays.filter(function(item) {
return bdays.id=== id;
})[0];
let index = bdays.indexOf(item);
data.device.splice(indexOfTabDetails, 1);
}
An inline simple way is just add bdays.splice($index, 1) in your delete button.
<ul ng-repeat="bday in bdays">
<li>
<span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
<form ng-show="editing" ng-submit="editing = false">
<label>Name:</label>
<input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
<label>Date:</label>
<input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
<br/>
<button class="btn" type="submit">Save</button>
<a class="btn" ng-click="bdays.splice($index, 1)">Delete</a>
</form>
</li>
</ul>
Hi I have a relatioship between client and phones.
Using an array name in the form I managed to save all numbers to a client:
form:
<input type="text" class="form-control phone-number" name="phoneNumbers[work][]" value="">
controller:
$numbers = [];
foreach(Input::get('phoneNumbers') as $phone_type => $array){
foreach($array as $index => $phone_number ){
$phone = new Phone(array(
'name' => $phone_type,
'number' => $phone_number
));
array_push($numbers, $phone);
}
}
$client->phones()->saveMany($numbers);
But now on to updating... Wouldn't it be better to just remove all phones and recreate them with the new ones? As I'm not sure how to write the script to update the phones.
Delete and re-create, easiest way to achieve this (works pretty well, I did it a couple of times for an admin panel).
When the phones/numbers are saved to the model, each would receive an id. When you output this to your update form, tag each one with the appropriate id. The input can then update the correct phones. Loop through them same way, finding and updating each.
I am working on a Laravel 4 project and I am trying to add a bunch of services to the services column in a simple service table. the columns are formatted as:
id userID services price
What I would like it to do is when a user selects the services all the services that user selects get's put into the services column to look like:
id userID services price
1 5 clean $4.95
2 5 unload $7.95
3 5 dance $1.95
4 5 vacuum $12.95
5 5 clean $4.95
basically all the services are in different input fields. So they aren't related.
I tried adding an array to the model but it gives an error:
Array to String conversion
Part of my Controller
$service = new Service();
$service->userID = $user->id;
$service->services = array(
Input::get('rooms'),
Input::get('pr_deodorizer'),
Input::get('pr_protectant') .
Input::get('pr_sanitzer'),
Input::get('fr_couch'),
Input::get('fr_chair'),
Input::get('fr_sectional'),
Input::get('fr_ottoman')
);
var_dump($service->services);die;
$service->save();
Laravel won't understand that you want to create various new instances of the model from just the array, so for each of the services, you'll have to create a separate instance of the Service model for each, eg.
$service = new Service();
$service->userID = $user->id;
$service->services = Input::get('rooms');
$service->save();
One idea.. perhaps you could group your services into a PHP array on your form using the square bracket notation:
<div>
<label for="room">Room</label>
<input type="text" id="room" name="services[]">
</div>
<div>
<label for="pr_deodorizer">Deodorizer</label>
<input type="text" id="pr_deodorizer" name="services[]">
</div>
<div>
<label for="pr_protectant">Protectant</label>
<input type="text" id="pr_protectant" name="services[]">
</div>
and then loop through the selected services in your Controller:
foreach(Input::get('services') as $service)
{
$service = new Service();
$service->userID = $user->id;
$service->services = $service;
$service->save();
}
... That's not tested, and I don't know what the format of your data is, but should give you a start on the problem..