'Laravel pass view field input data to controller and then return calculated value in disabled field

So what i want to do is take values from user input, then do some calculation with it inside the controller with method and that method return value to be displayed in field below with disabled attribute that will on form submit be passed to database. So what i have in view is:

            <input class="form-control {{ $errors->has('price') ? 'is-invalid' : '' }}" type="number" name="price" id="price" value="{{ old('price', '') }}" step="0.001" required>
            <input class="form-control {{ $errors->has('quantity') ? 'is-invalid' : '' }}" type="number" name="quantity" id="quantity" value="{{ old('quantity', '') }}" step="0.001" required>
            <input class="form-control {{ $errors->has('other_expenses') ? 'is-invalid' : '' }}" type="number" name="other_expenses" id="other_expenses" value="{{ old('other_expenses', '') }}" step="0.01" required>
            <input class="form-control {{ $errors->has('coefficient') ? 'is-invalid' : '' }}" type="number" name="coefficient" id="coefficient" value="{{ old('coefficient', '') }}" step="0.001" required>
            <input class="form-control {{ $errors->has('total') ? 'is-invalid' : '' }}" type="number" name="total" id="total" value="{{ old('total', '') }}" step="0.001" disabled>

And then i want to do some calculation through controller and return some value in "total" field. So in my controller i should accept that tada and then calculate something like: total = (pricequantityother_expenses)*coefficient



Solution 1:[1]

From your code above, it looks like everything you need for the calculation is there on the form. Is there a particular action that happens on the controller?

For example, if all you need you intend to calculate is total = (price * quantity * other_expenses ) * coefficient, you may not necessarily need to send the data to the controller.

You can use Alpine js to perform the calculation right on the page.

Follow the step below:

  1. Include alpine in your layout
    <script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>

<script src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>
<div x-data="{
              price: parseInt( '120'), 
              quantity: parseInt( '5'), 
              other_expenses: parseInt( '50'),
              coefficient: parseInt( '2') 
            }">
    <input type="number" name="price" x-model.number="price"  />
    <input type="number" name="quantity" x-model.number="quantity" />
    <input type="number" name="other_expenses" x-model.number="other_expenses" />
    <input type="number" name="coefficient" x-model.number="coefficient" />
    <input type="text" x-bind:value="price * quantity * other_expenses * coefficient" name="total" disabled />
</div>

Note: You can pass the old values like so price: parseInt( '{{ old('price') }}')

You can submit and the total should be submitted.

If you must use the controller for the calculations, you may have to use ajax with vuejs or jquery.

UPDATE: For the ajax implementation, you can use alpine 'fetch' to make API call to the backend for any validation.

<div x-data="{
    price: parseInt( '120'), 
    quantity: parseInt( '5'), 
    other_expenses: parseInt( '50'),
    coefficient: parseInt( '2') ,
    data: null,
    calculateTotal() {
            fetch('/calculateTotal/route/url',{
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    price: this.price,
                    quantity: this.quantity,
                    other_expenses:this.other_expenses,
                    coefficient:this.coefficient
                }),
            })
            .then(response => response.json())
            .then(data => {
                    this.data = data
                    console.log(data)

            })
            .catch(error => {
                    console.log({ error })
                });
    }">
<input type="number" name="price" x-model.number="price"  @keyup.debounce.750ms="calculateTotal()"  />
<input type="number" name="quantity" x-model.number="quantity" @keyup.debounce.750ms="calculateTotal()" />
<input type="number" name="other_expenses" x-model.number="other_expenses" @keyup.debounce.750ms="calculateTotal()" />
<input type="number" name="coefficient" x-model.number="coefficient" @keyup.debounce.750ms="calculateTotal()" />

<input type="text" x-bind:value="data.total" name="total" readonly />

//Your web.php or api.php depending on where the 
Route::post('gettotal', 'ProductController@getTotal');

//Controller
public function getTotal(Request $request)
{
    $data = [
        'total' => $request->price * $request->quantity * $request->other_expenses * $request->coefficient; //You can include any validation here
    ];
    return response()->json($data)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1