问:
Laravel - How to ensure that order price is not less than product price in input field
I am using Laravel-5.8 for a web application that involves dynamic input field. The project is based on sales Order.

Model

```<code>class Product extends Model
{
  protected $table = 'products';
  protected $fillable = [
          'name',
          'rate',
          'vat',
      ];
}

class Order extends Model
{
  protected $table = 'orders';
  protected $fillable = [
          'date',
          'customer_id',
          'workOrder_id',
          'details',
          'product_id',
          'rate',
          'vat',
          'quantity',
          'remaining',
      'amount',
      ];

  public function customer(){
    return $this->belongsTo(Customer::class, 'customer_id');
  }

  public function product(){
      return $this->belongsTo(Product::class, 'product_id');
  }
}
</code>```

product_id in products is a foreign key to orders

Controller

```<code>public function create()
{
    $order = null;
    $products = Product::all('id','name');
    $customers = Customer::all('id','name');
    return view('pages.order.create', compact('order','products','customers'));
}

public function store(Request $request)
{
    $request->validate([
        'date'      => 'required',
        'customer_id'  => ['required', Rule::notIn(['','0'])],
        'workOrder_id'     => 'required|unique:orders',
    ]);

    for ($i=0; $i < count($request->product_id) ; $i++) {

        $order =  new Order;

        $order->date = $request->date;
        $order->customer_id = $request->customer_id;
        $order->workOrder_id = $request->workOrder_id;
        $order->details = $request->details;
        $order->product_id = $request->product_id[$i];
        $order->rate = $request->rate[$i];
        $order->vat = $request->vat[$i];
        $order->quantity = $request->quantity[$i];
        $order->remaining = $request->quantity[$i];
        $order->amount = $request->quantity[$i] * $request->rate[$i];

        $order->save();
    }

    return redirect()
                ->route('order.index')
                ->with('success', 'Added Successfully');
}
</code>```

In an order, a customer can have several products

view

```<code><section class="content">
    <div class="container-fluid">
        <div class="card card-warning">
            <div class="card-body">
                <form method="POST" action="{{ route('order.store') }}">
                    @csrf
                    {{-- Date --}}
                    <div class="form-group">
                        <label for="date">
                            Date
                        </label>

                        <input type="text" class="form-control{{ $errors->has('date') ? ' is-invalid' : '' }}" name="date" id="date" value="{{ old('date', optional($order)->date) }}">

                        @if ($errors->has('date'))
                        <span class="invalid-feedback">
                            <strong>{{ $errors->first('date') }}</strong>
                        </span>
                        @endif
                    </div>

                    {{-- customer --}}
                    <div class="form-group">
                        <label for="customer_id">Customer</label>
                        <select name="customer_id" class="form-control{{ $errors->has('customer_id') ? ' is-invalid' : '' }}" id="customer_id">
                            <option value="">Select</option>
                            @foreach($customers as $customer)
                            <option value="{{ $customer->id }}" {{old('customer_id', optional($order)->customer_id) == $customer->id ? 'selected':''}}>{{ $customer->name }}</option>
                            @endforeach
                        </select>
                        @if ($errors->has('customer_id'))
                        <span class="invalid-feedback">
                            <strong>{{ $errors->first('customer_id') }}</strong>
                        </span>
                        @endif
                    </div>

                    <div class="row">
                        <div class="col-md-1">
                            <button id="add_more" class="btn btn-info mt-4"><i class="fa fa-plus" title="Add More Product"></i></button>
                        </div>
                        <div class="col-md-11">
                            <div id="more_product">
                                <div class="row">
                                    <div class="col-md-3">
                                        {{-- Product --}}
                                        <div class="form-group">
                                            <label for="product_id">Select Product</label>
                                            <select name="product_id[]" class="form-control" id="product_id" required="required">
                                                <option value="">Select Product</option>
                                                @forelse($products as $product)
                                                <option value="{{ $product->id }}" >
                                                    {{ $product->name }}
                                                </option>
                                                @empty
                                                <option value="">No Product Found</option>
                                                @endforelse
                                            </select>
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        {{-- Rate --}}
                                        <div class="form-group">
                                            <label for="rate">
                                                Rate
                                            </label>
                                            <input type="number" min="0" step="any" class="form-control" name="rate[]" id="rate" required="required">
                                        </div>
                                    </div>

                                    <div class="col-md-3">
                                        {{-- Quantity --}}
                                        <div class="form-group">
                                            <label for="vat">
                                                Vat
                                            </label>

                                            <input type="number" min="0" step="any" class="form-control" name="vat[]" id="vat" required="required">
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        {{-- Quantity --}}
                                        <div class="form-group">
                                            <label for="quantity">
                                                Quantity
                                            </label>

                                            <input type="number" min="0" class="form-control" name="quantity[]" id="quantity" required="required">
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    {{-- workOrder_id --}}
                    <div class="form-group">
                        <label for="workOrder_id">Work Order No</label>
                        <input type="text" class="form-control{{ $errors->has('workOrder_id') ? ' is-invalid' : '' }}" name="workOrder_id" id="workOrder_id" value="{{ old('workOrder_id', optional($order)->workOrder_id) }}">

                        @if ($errors->has('workOrder_id'))
                        <span class="invalid-feedback">
                            <strong>{{ $errors->first('workOrder_id') }}</strong>
                        </span>
                        @endif
                    </div>

                    {{-- Payment Type --}}

            {{-- <div class="form-group">
                <label for="payment">Payment</label>
                <select name="payment" class="form-control{{ $errors->has('payment') ? ' is-invalid' : '' }}" id="payment">
                    <option value="">Select Payment</option>
                    <option value="1">Cash</option>
                    <option value="2">Due</option>
                </select>
                @if ($errors->has('payment'))
                <span class="invalid-feedback">
                    <strong>{{ $errors->first('payment') }}</strong>
                </span>
                @endif
            </div> --}}

            {{-- Details --}}
            <div class="form-group">
                <label for="details">
                    Remarks
                </label>

                <textarea name="details" class="form-control {{ $errors->has('details') ? ' is-invalid' : '' }}" id="details" cols="30" rows="5">{{ old('details', optional($order)->details) }}</textarea>

                @if( $errors->has('details'))
                <span class="invalid-feedback">
                    <strong>{{ $errors->first('details') }}</strong>
                </span>
                @endif
            </div>

            {{-- Save --}}
            <div class="form-group row mb-0">
                <div class="col-md-12">
                    <button type="submit" class="btn btn-primary">
                        {{ __('Save') }}
                    </button>
                </div>
            </div>
        </form>
    </div>
</div>
</div>
</section>
</code>```

Javascript

```<code><script>
{{-- jquery datepicker --}}
$( function() {
    $( "#date" ).datepicker({
        dateFormat: 'yy-mm-dd',
        changeMonth: true,
        changeYear: true,
    });
});

$('#customer_id').select2({
    placeholder: 'Select Customer',

    ajax: {
        url: '{!!URL::route('customer-autocomplete-search')!!}',
        dataType: 'json',
        delay: 250,
        processResults: function (data) {
            return {
                results: data
            };
        },
        cache: true
    },
    theme: "bootstrap"
});

$('#product_id').select2({
    placeholder: 'Select Product',

    ajax: {
        url: '{!!URL::route('product-autocomplete-search')!!}',
        dataType: 'json',
        delay: 250,
        processResults: function (data) {
            return {
                results: data
            };
        },
        cache: true
    },
    theme: "bootstrap"
});

$(document).ready(function() {
    var max_fields      = 150;
    var wrapper         = $("#more_product");
    var add_button      = $("#add_more");

    var x = 1;
    $(add_button).click(function(e){
        e.preventDefault();
        if(x < max_fields){
            x++;
            $(wrapper).append('<div class="row"><div class="col-md-3">{{-- Product --}}<div class="form-group"><label for="product_id">Select Product</label><select name="product_id[]" class="form-control product_id" id="product_id" required="required"><option value="">Select Product</option>@forelse($products as $product)<option value="{{ $product->id }}" >{{ $product->name }}</option>@empty<option value="">No Product Found</option>@endforelse </select></div></div><div class="col-md-3">{{-- Rate --}}<div class="form-group"><label for="rate">Rate</label><input type="number" min="0" step="any" class="form-control" name="rate[]" id="rate" required="required"></div></div><div class="col-md-2">{{-- vat --}}<div class="form-group"><label for="vat">Vat</label><input type="number" min="0" step="any" class="form-control" name="vat[]" id="vat" required="required"></div></div><div class="col-md-3">{{-- Quantity --}}<div class="form-group"><label for="quantity">Quantity</label><input type="number" min="0" class="form-control" name="quantity[]" id="quantity" required="required"></div></div><div class="col-sm-1"><a href="#" class="remove_field"><button style="margin-top: 30px;" class="btn btn-info"><i class="fa fa-minus" title="Remove Item"></i></button></a></div></div>');

            $('.product_id').select2({
                placeholder: 'Select Product',

                ajax: {
                    url: '{!!URL::route('product-autocomplete-search')!!}',
                    dataType: 'json',
                    delay: 250,
                    processResults: function (data) {
                        return {
                            results: data
                        };
                    },
                    cache: true
                },
                theme: "bootstrap"
            });
        }
    });

    $(wrapper).on("click",".remove_field", function(e){
        e.preventDefault();
        $(this).parent().parent('div').remove();
        x--;
    })
});
</script>
</code>```

I have been on this for days. What I want to achieve is that as the User enter the rate on order on a particular product, the system should compare it with the rate in products.

If the rate on order is less than that in product, the system should display an error message to the user explaining the problem.

How do I achieve this?

Thank you

答:
Ok, so here's what I've come up. As explained earlier, this only provides server side validation as from what I can see you do not have any client side one.

First thing I did was to convert validation in the controller to a Request injected to the store method. I called it StoreOrderRequest

App\Http\Requests\StoreOrderRequest

```<code><?php

namespace App\Http\Requests;

use App\Order;
use App\Product;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;

/**
 * Class StoreOrderRequest
 *
 * @package App\Http\Requests
 *
 * @property string $date
 * @property int $customer_id
 * @property int $workOrder_id
 * @property array $product_id
 * @property array $rate
 * @property array $vat
 * @property array $quantity
 */
class StoreOrderRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'date' => 'required',
            'customer_id' => [
                'required',
                'exists:customers,id',
            ],
            'workOrder_id' => [
                'required',
                'unique:orders',
            ],
            'details' => 'present',
            'product_id' => 'array',
            'rate' => 'array',
            'vat' => 'array',
            'quantity' => 'array',
        ];
    }

    /**
     * Prepare the data for validation.
     *
     * @return void
     */
    protected function prepareForValidation(): void
    {
        $this->redirect = route('order');

        $this->validator = $this->getValidatorInstance();

        $this->validator->after(function (Validator $validator) {

            $products = Product::whereIn('id', $this->product_id)->get();

            foreach ($this->product_id as $key => $id) {

                $rate = $products->firstWhere('id', $id)->rate;

                if ($rate < $this->rate[$key]) {
                    continue;
                }

                $validator->errors()->add(
                    'rate.'.$key,
                    __(
                        'validation.min.numeric',
                        [
                            'attribute' => 'rate',
                            'min' => $rate
                        ]
                    )
                );
            }

        });
    }

    /**
     * Create orders.
     *
     * @return void
     */
    protected function save(): void
    {
        $orders = collect($this->product_id)
            ->map(function (int $product_id, int $index) {
                return array_merge(
                    $this->only([
                        'date',
                        'customer_id',
                        'workOrder_id',
                        'details',
                    ]),
                    [
                        'product_id' => $this->product_id,
                        'rate' => $rate = $this->rate[$index],
                        'vat' => $this->vat[$index],
                        'quantity' => $qty = $this->quantity[$index],
                        'remaining' => $qty,
                        'amount' => $qty * $rate,
                    ]
                );
            });

        Order::insert($orders->toArray());
    }
}
</code>```

You'll see that I've made use of the prepareForValidation method, which allowed us to register the after validation hooks. These check each product rate and if it's less than the corresponding Product record, it will add the error for its index to the error bag.

(Please note I've overriden the default redirect property to work with my test - you probably won't need that line if you're just going back to the previous page).

I've also created the save method that saves all these orders.

With all this, we are now able to skim your OrderController::store method significantly:

OrderController

```<code>/**
 * Store new record.
 *
 * @param  \App\Http\Requests\StoreOrderRequest $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function store(StoreOrderRequest $request): RedirectResponse
{
    $request->save();

    return redirect()
        ->route('order')
        ->with('success', 'Added Successfully');
}
</code>```

And here's the corresponding test to make sure everything above works as expected:

Tests\Feature\ProductOrderTest

```<code><?php

namespace Tests\Feature;

use App\Order;
use App\Product;
use App\Customer;
use Tests\TestCase;

use Illuminate\Foundation\Testing\RefreshDatabase;

class ProductOrderTest extends TestCase
{
    use RefreshDatabase;

    /**
     * @test
     */
    public function validation_fails_with_product_rate_lower_than_original_product_price()
    {
        $customer = factory(Customer::class)->create();

        $product_1 = factory(Product::class)->create(['rate' => 20.50]);
        $product_2 = factory(Product::class)->create(['rate' => 95.67]);

        $this->assertCount(0, Order::all());

        $response = $this->post(route('order.store'), [
            'date' => now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => [
                0 => $product_1->id,
                1 => $product_2->id,
            ],
            'rate' => [
                0 => 20.49,
                1 => 95.66,
            ],
            'vat' => [
                0 => round(20.49 * 0.20),
                1 => round(95.66 * 0.20),
            ],
            'quantity' => [
                0 => 1,
                1 => 1,
            ],
        ]);

        $response->assertRedirect(route('order'));

        $response->assertSessionMissing('success');

        $response->assertSessionHasErrors([
            'rate.0' => __('validation.min.numeric', [
                'attribute' => 'rate',
                'min' => 20.50
            ]),
            'rate.1' => __('validation.min.numeric', [
                'attribute' => 'rate',
                'min' => 95.67
            ]),
        ]);

        $this->assertCount(0, Order::all());
    }

    /**
     * @test
     */
    public function saves_order_with_valid_request()
    {
        $customer = factory(Customer::class)->create();

        $product_1 = factory(Product::class)->create(['rate' => 20.50]);
        $product_2 = factory(Product::class)->create(['rate' => 95.67]);

        $this->assertCount(0, Order::all());

        $response = $this->post(route('order.store'), [
            'date' => $date = now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => [
                0 => $product_1->id,
                1 => $product_2->id,
            ],
            'rate' => [
                0 => 20.50,
                1 => 95.68,
            ],
            'vat' => [
                0 => round(20.50 * 0.20),
                1 => round(95.68 * 0.20),
            ],
            'quantity' => [
                0 => 1,
                1 => 1,
            ],
        ]);

        $response->assertRedirect(route('order'));

        $response->assertSessionHas('success', 'Added Successfully');

        $response->assertSessionDoesntHaveErrors();

        $this->assertCount(2, Order::all());

        $this->assertDatabaseHas('orders', [
            'date' => $date = now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => $product_1->id,
            'rate' => 20.50,
            'vat' => round(20.50 * 0.20),
            'quantity' => 1,
            'remaining' => 1,
            'amount' => 20.50,
        ]);

        $this->assertDatabaseHas('orders', [
            'date' => $date = now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => $product_2->id,
            'rate' => 95.68,
            'vat' => round(95.68 * 0.20),
            'quantity' => 1,
            'remaining' => 1,
            'amount' => 95.68,
        ]);
    }
}
</code>```

Body:
I am using Laravel-5.8 for a web application that involves dynamic input field. The project is based on sales Order.

Model

class Product extends Model
{
  protected $table = 'products';
  protected $fillable = [
          'name',
          'rate',
          'vat',
      ];
}

class Order extends Model
{
  protected $table = 'orders';
  protected $fillable = [
          'date',
          'customer_id',
          'workOrder_id',
          'details',
          'product_id',
          'rate',
          'vat',
          'quantity',
          'remaining',
      'amount',
      ];

  public function customer(){
    return $this->belongsTo(Customer::class, 'customer_id');
  }

  public function product(){
      return $this->belongsTo(Product::class, 'product_id');
  }
}

product_id in products is a foreign key to orders

Controller

public function create()
{
    $order = null;
    $products = Product::all('id','name');
    $customers = Customer::all('id','name');
    return view('pages.order.create', compact('order','products','customers'));
}

public function store(Request $request)
{
    $request->validate([
        'date'      => 'required',
        'customer_id'  => ['required', Rule::notIn(['','0'])],
        'workOrder_id'     => 'required|unique:orders',
    ]);

    for ($i=0; $i < count($request->product_id) ; $i++) {

        $order =  new Order;

        $order->date = $request->date;
        $order->customer_id = $request->customer_id;
        $order->workOrder_id = $request->workOrder_id;
        $order->details = $request->details;
        $order->product_id = $request->product_id[$i];
        $order->rate = $request->rate[$i];
        $order->vat = $request->vat[$i];
        $order->quantity = $request->quantity[$i];
        $order->remaining = $request->quantity[$i];
        $order->amount = $request->quantity[$i] * $request->rate[$i];

        $order->save();
    }

    return redirect()
                ->route('order.index')
                ->with('success', 'Added Successfully');
}

In an order, a customer can have several products

view

                <form method="POST" action="{{ route('order.store') }}">
                    @csrf
                    {{-- Date --}}

                            Date

                        <input type="text" class="form-control{{ $errors->has('date') ? ' is-invalid' : '' }}" name="date" id="date" value="{{ old('date', optional($order)->date) }}">

                        @if ($errors->has('date'))

                            {{ $errors->first('date') }}

                        @endif

                    {{-- customer --}}

                        Customer
                        <select name="customer_id" class="form-control{{ $errors->has('customer_id') ? ' is-invalid' : '' }}" id="customer_id">
                            <option value="">Select</option>
                            @foreach($customers as $customer)
                            <option value="{{ $customer->id }}" {{old('customer_id', optional($order)->customer_id) == $customer->id ? 'selected':''}}>{{ $customer->name }}</option>
                            @endforeach
                        </select>
                        @if ($errors->has('customer_id'))

                            {{ $errors->first('customer_id') }}

                        @endif

                            <button id="add_more" class="btn btn-info mt-4"></button>

                                        {{-- Product --}}

                                            Select Product
                                            <select name="product_id[]" class="form-control" id="product_id" required="required">
                                                <option value="">Select Product</option>
                                                @forelse($products as $product)
                                                <option value="{{ $product->id }}" >
                                                    {{ $product->name }}
                                                </option>
                                                @empty
                                                <option value="">No Product Found</option>
                                                @endforelse
                                            </select>

                                        {{-- Rate --}}

                                                Rate

                                            <input type="number" min="0" step="any" class="form-control" name="rate[]" id="rate" required="required">

                                        {{-- Quantity --}}

                                                Vat

                                            <input type="number" min="0" step="any" class="form-control" name="vat[]" id="vat" required="required">

                                        {{-- Quantity --}}

                                                Quantity

                                            <input type="number" min="0" class="form-control" name="quantity[]" id="quantity" required="required">

                    {{-- workOrder_id --}}

                        Work Order No
                        <input type="text" class="form-control{{ $errors->has('workOrder_id') ? ' is-invalid' : '' }}" name="workOrder_id" id="workOrder_id" value="{{ old('workOrder_id', optional($order)->workOrder_id) }}">

                        @if ($errors->has('workOrder_id'))

                            {{ $errors->first('workOrder_id') }}

                        @endif

                    {{-- Payment Type --}}

            {{--

                Payment
                <select name="payment" class="form-control{{ $errors->has('payment') ? ' is-invalid' : '' }}" id="payment">
                    <option value="">Select Payment</option>
                    <option value="1">Cash</option>
                    <option value="2">Due</option>
                </select>
                @if ($errors->has('payment'))

                    {{ $errors->first('payment') }}

                @endif

 --}}

            {{-- Details --}}

                    Remarks

                <textarea name="details" class="form-control {{ $errors->has('details') ? ' is-invalid' : '' }}" id="details" cols="30" rows="5">{{ old('details', optional($order)->details) }}</textarea>

                @if( $errors->has('details'))

                    {{ $errors->first('details') }}

                @endif

            {{-- Save --}}

                    <button type="submit" class="btn btn-primary">
                        {{ __('Save') }}
                    </button>

        </form>

Javascript

I have been on this for days. What I want to achieve is that as the User enter the rate on order on a particular product, the system should compare it with the rate in products.

If the rate on order is less than that in product, the system should display an error message to the user explaining the problem.

How do I achieve this?

Thank you

Body:
Ok, so here's what I've come up. As explained earlier, this only provides server side validation as from what I can see you do not have any client side one.

First thing I did was to convert validation in the controller to a Request injected to the store method. I called it StoreOrderRequest

App\Http\Requests\StoreOrderRequest

<?php

namespace App\Http\Requests;

use App\Order;
use App\Product;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;

/**
 * Class StoreOrderRequest
 *
 * @package App\Http\Requests
 *
 * @property string $date
 * @property int $customer_id
 * @property int $workOrder_id
 * @property array $product_id
 * @property array $rate
 * @property array $vat
 * @property array $quantity
 */
class StoreOrderRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'date' => 'required',
            'customer_id' => [
                'required',
                'exists:customers,id',
            ],
            'workOrder_id' => [
                'required',
                'unique:orders',
            ],
            'details' => 'present',
            'product_id' => 'array',
            'rate' => 'array',
            'vat' => 'array',
            'quantity' => 'array',
        ];
    }

    /**
     * Prepare the data for validation.
     *
     * @return void
     */
    protected function prepareForValidation(): void
    {
        $this->redirect = route('order');

        $this->validator = $this->getValidatorInstance();

        $this->validator->after(function (Validator $validator) {

            $products = Product::whereIn('id', $this->product_id)->get();

            foreach ($this->product_id as $key => $id) {

                $rate = $products->firstWhere('id', $id)->rate;

                if ($rate < $this->rate[$key]) {
                    continue;
                }

                $validator->errors()->add(
                    'rate.'.$key,
                    __(
                        'validation.min.numeric',
                        [
                            'attribute' => 'rate',
                            'min' => $rate
                        ]
                    )
                );
            }

        });
    }

    /**
     * Create orders.
     *
     * @return void
     */
    protected function save(): void
    {
        $orders = collect($this->product_id)
            ->map(function (int $product_id, int $index) {
                return array_merge(
                    $this->only([
                        'date',
                        'customer_id',
                        'workOrder_id',
                        'details',
                    ]),
                    [
                        'product_id' => $this->product_id,
                        'rate' => $rate = $this->rate[$index],
                        'vat' => $this->vat[$index],
                        'quantity' => $qty = $this->quantity[$index],
                        'remaining' => $qty,
                        'amount' => $qty * $rate,
                    ]
                );
            });

        Order::insert($orders->toArray());
    }
}

You'll see that I've made use of the prepareForValidation method, which allowed us to register the after validation hooks. These check each product rate and if it's less than the corresponding Product record, it will add the error for its index to the error bag.

(Please note I've overriden the default redirect property to work with my test - you probably won't need that line if you're just going back to the previous page).

I've also created the save method that saves all these orders.

With all this, we are now able to skim your OrderController::store method significantly:

OrderController

/**
 * Store new record.
 *
 * @param  \App\Http\Requests\StoreOrderRequest $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function store(StoreOrderRequest $request): RedirectResponse
{
    $request->save();

    return redirect()
        ->route('order')
        ->with('success', 'Added Successfully');
}

And here's the corresponding test to make sure everything above works as expected:

Tests\Feature\ProductOrderTest

<?php

namespace Tests\Feature;

use App\Order;
use App\Product;
use App\Customer;
use Tests\TestCase;

use Illuminate\Foundation\Testing\RefreshDatabase;

class ProductOrderTest extends TestCase
{
    use RefreshDatabase;

    /**
     * @test
     */
    public function validation_fails_with_product_rate_lower_than_original_product_price()
    {
        $customer = factory(Customer::class)->create();

        $product_1 = factory(Product::class)->create(['rate' => 20.50]);
        $product_2 = factory(Product::class)->create(['rate' => 95.67]);

        $this->assertCount(0, Order::all());

        $response = $this->post(route('order.store'), [
            'date' => now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => [
                0 => $product_1->id,
                1 => $product_2->id,
            ],
            'rate' => [
                0 => 20.49,
                1 => 95.66,
            ],
            'vat' => [
                0 => round(20.49 * 0.20),
                1 => round(95.66 * 0.20),
            ],
            'quantity' => [
                0 => 1,
                1 => 1,
            ],
        ]);

        $response->assertRedirect(route('order'));

        $response->assertSessionMissing('success');

        $response->assertSessionHasErrors([
            'rate.0' => __('validation.min.numeric', [
                'attribute' => 'rate',
                'min' => 20.50
            ]),
            'rate.1' => __('validation.min.numeric', [
                'attribute' => 'rate',
                'min' => 95.67
            ]),
        ]);

        $this->assertCount(0, Order::all());
    }

    /**
     * @test
     */
    public function saves_order_with_valid_request()
    {
        $customer = factory(Customer::class)->create();

        $product_1 = factory(Product::class)->create(['rate' => 20.50]);
        $product_2 = factory(Product::class)->create(['rate' => 95.67]);

        $this->assertCount(0, Order::all());

        $response = $this->post(route('order.store'), [
            'date' => $date = now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => [
                0 => $product_1->id,
                1 => $product_2->id,
            ],
            'rate' => [
                0 => 20.50,
                1 => 95.68,
            ],
            'vat' => [
                0 => round(20.50 * 0.20),
                1 => round(95.68 * 0.20),
            ],
            'quantity' => [
                0 => 1,
                1 => 1,
            ],
        ]);

        $response->assertRedirect(route('order'));

        $response->assertSessionHas('success', 'Added Successfully');

        $response->assertSessionDoesntHaveErrors();

        $this->assertCount(2, Order::all());

        $this->assertDatabaseHas('orders', [
            'date' => $date = now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => $product_1->id,
            'rate' => 20.50,
            'vat' => round(20.50 * 0.20),
            'quantity' => 1,
            'remaining' => 1,
            'amount' => 20.50,
        ]);

        $this->assertDatabaseHas('orders', [
            'date' => $date = now(),
            'customer_id' => $customer->id,
            'workOrder_id' => 1,
            'details' => 'Order details',
            'product_id' => $product_2->id,
            'rate' => 95.68,
            'vat' => round(95.68 * 0.20),
            'quantity' => 1,
            'remaining' => 1,
            'amount' => 95.68,
        ]);
    }
}


来源: stackexchange

问:
How to have single view for multiple HTML forms - Django
This is my view.So I want to keep 2 different HTML forms in same view ,But I am unable to do so beacuse whenever I add 1 form , I get the error of other on being none.

```<code>def home(request):
    name = None
    if request.method == 'POST':
        name = request.POST.get('name')
        choices = request.POST.get('choices')
        subtest = request.POST.get('subtest')
        reference = request.POST.get('reference')
        unit = request.POST.get('unit')
        test = Test()
        test.name = name
        test.save()
        subtest = Subtest()
        subtest.test = Test.objects.get(name=choices)
        subtest.name = subtest
        subtest.unit = unit
        subtest.reference_value = reference
        subtest.save()
        # print(name)
        return redirect('home')
    return render(request,'main.html',{})
</code>```

I have got 2 different forms . I didn't use django forms because I wanted to try something new.

MY FIRST FORM

```<code><form method="POST">
        {% csrf_token %}
        <div class="icon-holder">
          <i data-modal-target="test-popup" class="icon-cross"></i>
        </div>
        <div class="input-group">
          <input type="text" name="name" placeholder="Test name" />
        </div>
        <div class="button-group">
          <button type="submit">Submit</button>
        </div>
      </form>
</code>```

MY SECOND FORM

```<code><form method="POST">
        {% csrf_token %}
        <div class="icon-holder">
          <i data-modal-target="menu-test-popup" class="icon-cross"></i>
        </div>
        <div class="input-group">
          <label for="test-select">Test Name:</label>
          <select name="choices" id="test-select">
            {% for test in test %}
            <option value="{{test.name}}" name='choices'>{{test.name|title}}</option>
            {% endfor %}
          </select>
        </div>
        <div class="input-group">
          <input type="text" name="subtest" placeholder="SubTest name" />
        </div>
        <div class="input-group">
          <input type="text" name="reference" placeholder="Reference rate" />
        </div>
        <div class="input-group">
          <input type="text" name="unit" placeholder="Unit" />
        </div>
        <div class="button-group">
          <button type="submit">Submit</button>
        </div>
      </form>
</code>```

答:
first form

```<code><form method="POST">
...
<input name="form_type" value="first-form" type="hidden">
</form>
</code>```

second form

```<code><form method="POST">
...
<input name="form_type" value="second-form" type="hidden">
</form>
</code>```

view function

```<code>def view(request):
  if method == "POST":

    form_type = request.POST.get('form_type')

    if form_type == "first-form":
      # first form's process
    elif form_type == "second-form":
      #second form's process
</code>```

ContentLicense: CC BY-SA 4.0

Body:
This is my view.So I want to keep 2 different HTML forms in same view ,But I am unable to do so beacuse whenever I add 1 form , I get the error of other on being none.

def home(request):
    name = None
    if request.method == 'POST':
        name = request.POST.get('name')
        choices = request.POST.get('choices')
        subtest = request.POST.get('subtest')
        reference = request.POST.get('reference')
        unit = request.POST.get('unit')
        test = Test()
        test.name = name
        test.save()
        subtest = Subtest()
        subtest.test = Test.objects.get(name=choices)
        subtest.name = subtest
        subtest.unit = unit
        subtest.reference_value = reference
        subtest.save()
        # print(name)
        return redirect('home')
    return render(request,'main.html',{})

I have got 2 different forms . I didn't use django forms because I wanted to try something new.

MY FIRST FORM

<form method="POST">
        {% csrf_token %}

          <input type="text" name="name" placeholder="Test name" />

          <button type="submit">Submit</button>

      </form>

MY SECOND FORM

<form method="POST">
        {% csrf_token %}

          Test Name:
          <select name="choices" id="test-select">
            {% for test in test %}
            <option value="{{test.name}}" name='choices'>{{test.name|title}}</option>
            {% endfor %}
          </select>

          <input type="text" name="subtest" placeholder="SubTest name" />

          <input type="text" name="reference" placeholder="Reference rate" />

          <input type="text" name="unit" placeholder="Unit" />

          <button type="submit">Submit</button>

      </form>

Body:
first form

<form method="POST">
...
<input name="form_type" value="first-form" type="hidden">
</form>

second form

<form method="POST">
...
<input name="form_type" value="second-form" type="hidden">
</form>

view function

def view(request):
  if method == "POST":

    form_type = request.POST.get('form_type')

    if form_type == "first-form":
      # first form's process
    elif form_type == "second-form":
      #second form's process


问:
How to use tumbling window to group XML elements by content?
How do I group based on whether there's a match to [0-9] for digits with a tumbling window?

desired output:

```<code>...
<record>
    <name>joe</name>
    <data>phone1</data>
    <data>phone2</data>
</record>
...
</code>```

current output, not grouped:

```<code><xml>
  <record>
    <person key="$s" data="name">phone1</person>
  </record>
  <record>
    <person key="$s" data="name">phone2</person>
  </record>
  <record>
    <person key="$s" data="name">phone3sue</person>
  </record>
  <record>
    <person key="$s" data="name">cell4</person>
  </record>
  <record>
    <person key="$s" data="name">home5alice</person>
  </record>
  <record>
    <person key="$s" data="name">atrib6</person>
  </record>
  <record>
    <person key="$s" data="name">x7</person>
  </record>
  <record>
    <person key="$s" data="name">y9</person>
  </record>
  <record>
    <person key="$s" data="name">z10</person>
  </record>
</xml>
</code>```

input:

```<code><text>
  <line>people</line>
  <line>joe</line>
  <line>phone1</line>
  <line>phone2</line>
  <line>phone3</line>
  <line>sue</line>
  <line>cell4</line>
  <line>home5</line>
  <line>alice</line>
  <line>atrib6</line>
  <line>x7</line>
  <line>y9</line>
  <line>z10</line>
</text>
</code>```

The notion is that each "person" will have a name (no digits) and perhaps additional data.  So looking to read in each line and then group based on where the names are found.

code:

```<code>xquery version "3.0";

<xml>
{
for tumbling window $line in db:open("foo.txt")//text()
start $s when matches($s, '[0-9]')
return
<record>

       <person key='$s' data="name">{$line}</person>

 </record>
}
 </xml>
</code>```

Looking at the output, "phone3sue" is obviously doing some matching and grouping, although not exactly as desired because "phone3" should be in its own element, nested within "joe" rather than "sue".  But, still, there's some matching happening there.

from the saxon mailing list:

On Wed, Feb 19, 2020 at 10:31:37AM -0800, thufir scripsit:

I'll re-read the section on windowing; my impression was that it was more
    for display or report purposes.

Windowing is how you take chunks out of a stream of data.

What you've got is effectively a stream of line elements; you can
  identify the "name" lines, but you don't now how far part they are/how
  much data is between any particular pair of names.

Windows lets you say "I want the chunk of this stream that starts with
  a name line and continues up to (but not including) the next name
  line".

Would you elaborate on what you mean by two steps, a bit more concretely?

You're trying to take some input XML and turn it into different output
  XML.

If this is pure transformation -- change all of the elements named FOO
  to element named BAZ -- XQuery's not the best tool choice. Use XSLT if
  you can.  They're computationally the same but the languages have
  different biases and XSLT does transforms more naturally.

If the output XML is a representation of an abstraction of your input
  -- morally some sort of report -- it helps a lot to have the abstraction, and then present it.

So in your case, what you have is a stream containing an implicit
  association between names and data.  (It's a stream of lines; the only
  way you know these data lines go with that name line is position.  So
  implicit.)  If you turn that into an explicit mapping between names
  and data -- such as by creating a map variable where the keys are the
  contents of the name line (with spaces handled somehow) and the
  entries for each key are the data lines associated with that name --
  you have done the abstraction part.

You can then take that map and produce the XML output you want from
  it, which is much simpler than trying to combine the "create new XML"
  and "do the abstraction steps".  The last thing I posted has an
  example of turning a map into elements, but as a pattern it's just

map:keys($map) ! {.}{$map(.)}

(it gets more complicated if you've got nodes or a sequence in the
  entry, but not much more.)

That make something a little closer to sense?

-- Graydon

_______________________________________________ saxon-help mailing list archived at http://saxon.markmail.org/
  saxon-help@lists.sourceforge.net
  https://lists.sourceforge.net/lists/listinfo/saxon-help

答:
If you're using 3.0 or 3.1, then use the "window" clause of the FLWOR expression. Something like

```<code>for tumbling window $w in line
    start $s when matches($s, '[a-z]')
    return <group key="$s">{$w}</group>
</code>```

Not tested and probably will need correction or adaptation.

Body:
How do I group based on whether there's a match to [0-9] for digits with a tumbling window?

desired output:

...
<record>
    <name>joe</name>
    <data>phone1</data>
    <data>phone2</data>
</record>
...

current output, not grouped:

<xml>
  <record>
    <person key="$s" data="name">phone1</person>
  </record>
  <record>
    <person key="$s" data="name">phone2</person>
  </record>
  <record>
    <person key="$s" data="name">phone3sue</person>
  </record>
  <record>
    <person key="$s" data="name">cell4</person>
  </record>
  <record>
    <person key="$s" data="name">home5alice</person>
  </record>
  <record>
    <person key="$s" data="name">atrib6</person>
  </record>
  <record>
    <person key="$s" data="name">x7</person>
  </record>
  <record>
    <person key="$s" data="name">y9</person>
  </record>
  <record>
    <person key="$s" data="name">z10</person>
  </record>
</xml>

input:

<text>
  <line>people</line>
  <line>joe</line>
  <line>phone1</line>
  <line>phone2</line>
  <line>phone3</line>
  <line>sue</line>
  <line>cell4</line>
  <line>home5</line>
  <line>alice</line>
  <line>atrib6</line>
  <line>x7</line>
  <line>y9</line>
  <line>z10</line>
</text>

The notion is that each "person" will have a name (no digits) and perhaps additional data.  So looking to read in each line and then group based on where the names are found.

code:

xquery version "3.0";

<xml>
{
for tumbling window $line in db:open("foo.txt")//text()
start $s when matches($s, '[0-9]')
return
<record>

       <person key='$s' data="name">{$line}</person>

 </record>
}
 </xml>

Looking at the output, "phone3sue" is obviously doing some matching and grouping, although not exactly as desired because "phone3" should be in its own element, nested within "joe" rather than "sue".  But, still, there's some matching happening there.

from the saxon mailing list:

On Wed, Feb 19, 2020 at 10:31:37AM -0800, thufir scripsit:

I'll re-read the section on windowing; my impression was that it was more
    for display or report purposes.

Windowing is how you take chunks out of a stream of data.

What you've got is effectively a stream of line elements; you can
  identify the "name" lines, but you don't now how far part they are/how
  much data is between any particular pair of names.

Windows lets you say "I want the chunk of this stream that starts with
  a name line and continues up to (but not including) the next name
  line".

Would you elaborate on what you mean by two steps, a bit more concretely?

You're trying to take some input XML and turn it into different output
  XML.

If this is pure transformation -- change all of the elements named FOO
  to element named BAZ -- XQuery's not the best tool choice. Use XSLT if
  you can.  They're computationally the same but the languages have
  different biases and XSLT does transforms more naturally.

If the output XML is a representation of an abstraction of your input
  -- morally some sort of report -- it helps a lot to have the abstraction, and then present it.

So in your case, what you have is a stream containing an implicit
  association between names and data.  (It's a stream of lines; the only
  way you know these data lines go with that name line is position.  So
  implicit.)  If you turn that into an explicit mapping between names
  and data -- such as by creating a map variable where the keys are the
  contents of the name line (with spaces handled somehow) and the
  entries for each key are the data lines associated with that name --
  you have done the abstraction part.

You can then take that map and produce the XML output you want from
  it, which is much simpler than trying to combine the "create new XML"
  and "do the abstraction steps".  The last thing I posted has an
  example of turning a map into elements, but as a pattern it's just

map:keys($map) ! {.}{$map(.)}

(it gets more complicated if you've got nodes or a sequence in the
  entry, but not much more.)

That make something a little closer to sense?

-- Graydon

_______________________________________________ saxon-help mailing list archived at http://saxon.markmail.org/
  saxon-help@lists.sourceforge.net
  https://lists.sourceforge.net/lists/listinfo/saxon-help

Body:
If you're using 3.0 or 3.1, then use the "window" clause of the FLWOR expression. Something like

for tumbling window $w in line
    start $s when matches($s, '[a-z]')
    return <group key="$s">{$w}</group>

Not tested and probably will need correction or adaptation.


问:
How to upload a file from a Flask's HTML form to an S3 bucket using python?
I have an HTML form (implemented in Flask) for uploading files. And I want to store the uploaded files directly to S3.

The relevant part of the Flask implementation is as follows:

```<code>@app.route('/',methods=['GET'])
def index():
    return '<form method="post" action="/upload" enctype="multipart/form-data"><input type="file" name="files" /><button>Upload</button></form>'
</code>```

I then use boto3 to upload the file to S3 as follows:

```<code>file = request.files['files']
s3_resource = boto3.resource(
    's3',
     aws_access_key_id='******',
     aws_secret_access_key='*******')

bucket = s3_resource.Bucket('MY_BUCKET_NAME')

bucket.Object(file.filename).put(Body=file)
</code>```

file is a werkzeug.datastructures.FileStorage object.

But I get the following error when uploading the file to S3:

botocore.exceptions.ClientError: An error occurred (BadDigest) when calling the PutObject operation (reached max retries: 4): The Content-MD5 you specified did not match what we received.

How can I upload the file to S3?

答:
Since you are using Flask web framework, the file variable is of type werkzeug.datastructures.FileStorage.

I think the problem is that the put() method expects a byte sequence or a file-like object as its Body argument. So, it does not know what to do with the Flask's FileStorage object.

A possible solution could be to use file.read() to get a sequence of bytes and then pass it to put():

```<code>bucket.Object(file.filename).put(Body=file.read())
</code>```

Body:
I have an HTML form (implemented in Flask) for uploading files. And I want to store the uploaded files directly to S3.

The relevant part of the Flask implementation is as follows:

@app.route('/',methods=['GET'])
def index():
    return '<form method="post" action="/upload" enctype="multipart/form-data"><input type="file" name="files" /><button>Upload</button></form>'

I then use boto3 to upload the file to S3 as follows:

file = request.files['files']
s3_resource = boto3.resource(
    's3',
     aws_access_key_id='******',
     aws_secret_access_key='*******')

bucket = s3_resource.Bucket('MY_BUCKET_NAME')

bucket.Object(file.filename).put(Body=file)

file is a werkzeug.datastructures.FileStorage object.

But I get the following error when uploading the file to S3:

botocore.exceptions.ClientError: An error occurred (BadDigest) when calling the PutObject operation (reached max retries: 4): The Content-MD5 you specified did not match what we received.

How can I upload the file to S3?

Body:
Since you are using Flask web framework, the file variable is of type werkzeug.datastructures.FileStorage.

I think the problem is that the put() method expects a byte sequence or a file-like object as its Body argument. So, it does not know what to do with the Flask's FileStorage object.

A possible solution could be to use file.read() to get a sequence of bytes and then pass it to put():

bucket.Object(file.filename).put(Body=file.read())


问:
Set all items to a listview from a file .txt (ArrayList) what contains textview value [Android Java]
I want after a button onClick generate1() show all items from my Arraylist(.txt) contains Edittext value.

I am a beginner in android java programming.

This is my onClick Method generate1():

```<code>    public void generate1(View view) throws IOException {

        ArrayAdapter<String> adapter;
        ArrayList<String> ls = new ArrayList<>();
        EditText editText = (EditText) findViewById(R.id.editText);

        BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(getAssets().open("themen.txt")));
        String word;
        while ((word = br.readLine()) != null) {
            ls.add(word);
        }
        br.close();
        ListView listView = (ListView) findViewById(R.id.listView);
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,ls);
        listView.setAdapter(adapter);

        for (String e : ls){
           if (e.toLowerCase().contains(editText.getText().toString())){
              //???? some toDO ???? (if i do here System.out.println(e); its work, but i want the Items to a listview!!
           }
        }
    }
</code>```

答:
public void generate1(View view) throws IOException {

```<code>    ArrayAdapter<String> adapter2;
    ArrayList<String> ls = new ArrayList<>();
    ArrayList<String> ls2 = new ArrayList<>();

    EditText editText = (EditText) findViewById(R.id.editText);

    BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(getAssets().open("themen.txt")));
        String word;
        while ((word = br.readLine()) != null) {
            ls.add(word);
        }
        br.close();
         ListView listView = (ListView) findViewById(R.id.listView);

    for (String e : ls) {

           int i = 0;
            while (i<ls.size()){

               if (e.toLowerCase().contains(editText.getText().toString())) {

                    ls2.add(i,e);
                }
                i++;
            }
        }

        adapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, ls2);
        listView.setAdapter(adapter2);
    }

}
</code>```

i found another way and its worked :D, but the result in the listview is everytime viewed 10 times!!??
I forgot something??

Body:
I want after a button onClick generate1() show all items from my Arraylist(.txt) contains Edittext value.

I am a beginner in android java programming.

This is my onClick Method generate1():

    public void generate1(View view) throws IOException {

        ArrayAdapter<String> adapter;
        ArrayList<String> ls = new ArrayList<>();
        EditText editText = (EditText) findViewById(R.id.editText);

        BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(getAssets().open("themen.txt")));
        String word;
        while ((word = br.readLine()) != null) {
            ls.add(word);
        }
        br.close();
        ListView listView = (ListView) findViewById(R.id.listView);
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,ls);
        listView.setAdapter(adapter);

        for (String e : ls){
           if (e.toLowerCase().contains(editText.getText().toString())){
              //???? some toDO ???? (if i do here System.out.println(e); its work, but i want the Items to a listview!!
           }
        }
    }

Body:
public void generate1(View view) throws IOException {

    ArrayAdapter<String> adapter2;
    ArrayList<String> ls = new ArrayList<>();
    ArrayList<String> ls2 = new ArrayList<>();

    EditText editText = (EditText) findViewById(R.id.editText);

    BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(getAssets().open("themen.txt")));
        String word;
        while ((word = br.readLine()) != null) {
            ls.add(word);
        }
        br.close();
         ListView listView = (ListView) findViewById(R.id.listView);

    for (String e : ls) {

           int i = 0;
            while (i<ls.size()){

               if (e.toLowerCase().contains(editText.getText().toString())) {

                    ls2.add(i,e);
                }
                i++;
            }
        }

        adapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, ls2);
        listView.setAdapter(adapter2);
    }

}

i found another way and its worked :D, but the result in the listview is everytime viewed 10 times!!??
I forgot something??


问:
RabbitMQ Microservices - Parallel processing
I'm working on an application in microservices architecture usingrabbitmq as messaging system.

calls between microservices are asynchronous http requests and each service is subscribed on specific queues

my question is seen that the calls are stateless, how to guarantee the parallelisation of the message commation not by routing-key in rabbitmq queue but by http call itself, that is to say for  n call every service must be able to listen to only needed messages .

Sorry for the ambiguity, I'm trying to explain further:

The scenario is that we are in a micro service architecture, due to huge data response the call service will receive the answer in the listener rabbitmq queue.

So let's imagine that two calls are made simultaneously and both queries start loading data into the same queue, the calling service is waiting for messages and adds the received messages but cannot differentiate between the data of caller 1 and caller 2.

Is there a better implementation for the listener

答:
Not sure I understood the question completely, but here is what I can suggest based on the description:

If each service is hooked to a particular listener and you don't want to associate a Routing-Key for the Queue+Listener integration, then can you try having header arguments. [You can use a QueueBuilder.withArguments API to set specific Header values that the Queue is supposed to listen to]
There needs to be a mechanism through which an exchange will bind to a particular queue and consequently to a Listener service.

Publisher -> Exchange ---> (with headers) binds to Queue -> Listener


问:
How to Parse and Combine More than 10 RSS Feed into one array using Swift on iOS
Im trying to implement a Feature into My Project using Swift that Parses and Combines more than 10 Feed into one array and displaying it into a UITableView. The Array of RSS Links will come from a CoreData Entity that contains all the info about the RSS Feeds like title of the Feed, link, Description,pubDate and enclosure RSS URL. But I Dont know how to parse each RSS URL and Combine them into an Array.</p>

答:
Take a look at

URLSession and URLRequest

JSONDecoder and Codable


问:
How to find the third "." in a string, then changing the value of character behind it
I have two entry widgets where the input is copied from entry_ip to entry_gateway.
entry_gateway is still changeable without affecting entry_ip.

entry_ip the input is users ipv4-address eks: 198.164.65.10

I want the entry_ip to remove the numbers after the last dot. 198.164.65.x and insert "1" instead.

```<code>from tkinter import *

my_window = Tk()
my_window.title("IPV4 Configurator")
my_window.configure(background="#2B7A78")
my_window.geometry("400x375+480+340")
my_window.resizable(0, 0)

# Create labels

Label(my_window, text="IP ADDRESS:", bg="#2B7A78", fg="#17252A", font="Caliban 14 bold") \
    .place(x=35, y=70)

Label(my_window, text="SUBNET MASK:", bg="#2B7A78", fg="#17252A", font="Caliban 14 bold") \
    .place(x=35, y=135)

Label(my_window, text="GATEWAY:", bg="#2B7A78", fg="#17252A", font="Caliban 14 bold") \
    .place(x=35, y=200)

# Create StringVar

var_ip = StringVar()
var_mask = StringVar()
var_gateway = StringVar()

# Break function

def focus_next_widget(event):
    event.widget.tk_focusNext().focus()
    return "break"

# Get entry input

def on_entry_input(event):
    text = event.widget.get()
    entry_gateway.delete(0, 'end')
    entry_gateway.insert('1', text)

def user_input_ip():
    input_ip = entry_ip.get()
    display_ip = input_ip
    var_ip.set(display_ip)

# Create ip entry

entry_ip = Entry(my_window, font="Helvetica 15", textvariable=var_ip)
entry_ip.place(x=35, y=100, width=158, height=30)
entry_ip.bind("<Tab>", focus_next_widget)
entry_ip.bind('<KeyRelease>', on_entry_input)

def user_input_mask():
    input_mask = entry_mask.get()
    display_mask = input_mask
    var_mask.set(display_mask)

# Create mask entry

entry_mask = Entry(my_window, font="Helvetica 15", textvariable=var_mask)
entry_mask.place(x=35, y=165, width=158, height=30)
entry_mask.bind("<Tab>", focus_next_widget)
entry_mask.insert(END, "255.255.255.255")

def user_input_gateway():
    input_gateway = entry_gateway.get()
    display_gateway = input_gateway
    var_gateway.set(display_gateway)

# Create gateway entry

entry_gateway = Entry(my_window, font="Helvetica 15", textvariable=var_gateway)
entry_gateway.place(x=35, y=230, width=158, height=30)
entry_gateway.bind("<Tab>", focus_next_widget)
</code>```

答:
Using regex</p>

```<code>import re
new_ip = re.sub(r"\d+$", "1", entry_ip)
</code>```

Body:
I have two entry widgets where the input is copied from entry_ip to entry_gateway.
entry_gateway is still changeable without affecting entry_ip.

entry_ip the input is users ipv4-address eks: 198.164.65.10

I want the entry_ip to remove the numbers after the last dot. 198.164.65.x and insert "1" instead.

from tkinter import *

my_window = Tk()
my_window.title("IPV4 Configurator")
my_window.configure(background="#2B7A78")
my_window.geometry("400x375+480+340")
my_window.resizable(0, 0)

# Create labels

Label(my_window, text="IP ADDRESS:", bg="#2B7A78", fg="#17252A", font="Caliban 14 bold") \
    .place(x=35, y=70)

Label(my_window, text="SUBNET MASK:", bg="#2B7A78", fg="#17252A", font="Caliban 14 bold") \
    .place(x=35, y=135)

Label(my_window, text="GATEWAY:", bg="#2B7A78", fg="#17252A", font="Caliban 14 bold") \
    .place(x=35, y=200)

# Create StringVar

var_ip = StringVar()
var_mask = StringVar()
var_gateway = StringVar()

# Break function

def focus_next_widget(event):
    event.widget.tk_focusNext().focus()
    return "break"

# Get entry input

def on_entry_input(event):
    text = event.widget.get()
    entry_gateway.delete(0, 'end')
    entry_gateway.insert('1', text)

def user_input_ip():
    input_ip = entry_ip.get()
    display_ip = input_ip
    var_ip.set(display_ip)

# Create ip entry

entry_ip = Entry(my_window, font="Helvetica 15", textvariable=var_ip)
entry_ip.place(x=35, y=100, width=158, height=30)
entry_ip.bind("<Tab>", focus_next_widget)
entry_ip.bind('<KeyRelease>', on_entry_input)

def user_input_mask():
    input_mask = entry_mask.get()
    display_mask = input_mask
    var_mask.set(display_mask)

# Create mask entry

entry_mask = Entry(my_window, font="Helvetica 15", textvariable=var_mask)
entry_mask.place(x=35, y=165, width=158, height=30)
entry_mask.bind("<Tab>", focus_next_widget)
entry_mask.insert(END, "255.255.255.255")

def user_input_gateway():
    input_gateway = entry_gateway.get()
    display_gateway = input_gateway
    var_gateway.set(display_gateway)

# Create gateway entry

entry_gateway = Entry(my_window, font="Helvetica 15", textvariable=var_gateway)
entry_gateway.place(x=35, y=230, width=158, height=30)
entry_gateway.bind("<Tab>", focus_next_widget)

Body:
Using regex

import re
new_ip = re.sub(r"\d+$", "1", entry_ip)


问:
NavigationLink inside a VStack is broken on iPad
Consider this very simple view: just a few links to other pages. If you run this on iPhone, everything works as expected. However, run this on the iPad in landscape, and you will notice that most of the time the links simply don't work. Broken in the sim and real device, which is surprising.

When you change the VStack to a List, everything works fine all of a sudden.

struct ContentView: View {
  var body: some View {
    NavigationView {
      VStack {
        NavigationLink(destination: Text("Link 1")) {
          Text("Link 1")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 2")) {
          Text("Link 2")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 3")) {
          Text("Link 3")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 4")) {
          Text("Link 4")
            .padding(.vertical)
        }
        NavigationLink(destination: Text("Link 5")) {
          Text("Link 5")
            .padding(.vertical)
        }
      }

      Text("Hello iPad")
    }
  }
}
```

Has anyone else run into this problem? Why does it happen, and what is the workaround? Other than the obvious "use a List" :p I am using a grid of VStacks and HStacks to show links in multiple columns, configurable per device size. So changing to a List would not be preferable if not 100% necessary.

答:
I suggest you to read the documentation, before you try to find some "workaround"

```<code> // Creates an instance that presents `destination` when `selection` is set
 // to `tag`.
    public init<V>(destination: Destination, tag: V, selection: Binding<V?>, @ViewBuilder label: () -> Label) where V : Hashable
</code>```

example usage

```<code>struct ContentView: View {
    @State var selection: Int? = 0
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: Text("Link 0"), tag: 0, selection: $selection) {
                    Text("link 0")
                }
                NavigationLink(destination: Text("Link 1"), tag: 1, selection: $selection) {
                    Text("link 1")
                }
                NavigationLink(destination: Text("Link 2"), tag: 2, selection: $selection) {
                    Text("link 2")
                }

            }

            Text("Hello iPad user, swipe from left to continue ...")
        }
    }
}
</code>```

Body:
Consider this very simple view: just a few links to other pages. If you run this on iPhone, everything works as expected. However, run this on the iPad in landscape, and you will notice that most of the time the links simply don't work. Broken in the sim and real device, which is surprising.

When you change the VStack to a List, everything works fine all of a sudden.

struct ContentView: View {
  var body: some View {
    NavigationView {
      VStack {
        NavigationLink(destination: Text("Link 1")) {
          Text("Link 1")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 2")) {
          Text("Link 2")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 3")) {
          Text("Link 3")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 4")) {
          Text("Link 4")
            .padding(.vertical)
        }
        NavigationLink(destination: Text("Link 5")) {
          Text("Link 5")
            .padding(.vertical)
        }
      }

      Text("Hello iPad")
    }
  }
}

Has anyone else run into this problem? Why does it happen, and what is the workaround? Other than the obvious "use a List" :p I am using a grid of VStacks and HStacks to show links in multiple columns, configurable per device size. So changing to a List would not be preferable if not 100% necessary.

Body:
I suggest you to read the documentation, before you try to find some "workaround"

 // Creates an instance that presents `destination` when `selection` is set
 // to `tag`.
    public init<V>(destination: Destination, tag: V, selection: Binding<V?>, @ViewBuilder label: () -> Label) where V : Hashable

example usage

struct ContentView: View {
    @State var selection: Int? = 0
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: Text("Link 0"), tag: 0, selection: $selection) {
                    Text("link 0")
                }
                NavigationLink(destination: Text("Link 1"), tag: 1, selection: $selection) {
                    Text("link 1")
                }
                NavigationLink(destination: Text("Link 2"), tag: 2, selection: $selection) {
                    Text("link 2")
                }

            }

            Text("Hello iPad user, swipe from left to continue ...")
        }
    }
}


问:
jQuery get anchor value
I am trying to get the value of a clicked anchor but I am not sure which anchor is being clicked or how to latch onto it with jquery.  I have a document.ready function

```<code>$(document).ready(function () {
var ActiveBlogStats = $('#BlogSelectList');
$('#BlogSelectList').click(function () {
    alert(ActiveBlogStats.text)
}); })
</code>```

Here is the id that it is working on

```<code><ul class="submenu" id="BlogSelectList">
  <xsl:for-each select="oohru/user/oohblog">
    <li>
      <a>
        <xsl:attribute name="href">#<xsl:value-of select="normalize-space(blogid)"/></xsl:attribute>
        <xsl:value-of select="oohblogurl"/>
      </a>
    </li>
  </xsl:for-each>
<li><a href="AddNewBlog.aspx">+ Create a new oohblog</a></li>
</ul>
</code>```

How can I get the href of the actual anchor being clicked?  I don't see how to make a document.ready even for items that don't exist until after the document is ready.
I suppose I could get the # value from the URL since when they click one it will update the URL but I would rather get it directly from the click.

答:
If your content is dynamically generated, you may want to look into .live() (or delegate()) ( http://api.jquery.com/live/ | http://api.jquery.com/delegate/)

Your code would then look something like:

```<code>    $("#BlogSelectList li a").live('click', function () {
        //do something
    });
</code>```

ContentLicense: CC BY-SA 3.0

Title: jQuery get anchor value

Body:
I am trying to get the value of a clicked anchor but I am not sure which anchor is being clicked or how to latch onto it with jquery.  I have a document.ready function

$(document).ready(function () {
var ActiveBlogStats = $('#BlogSelectList');
$('#BlogSelectList').click(function () {
    alert(ActiveBlogStats.text)
}); })

Here is the id that it is working on

  <xsl:for-each select="oohru/user/oohblog">

        <xsl:attribute name="href">#<xsl:value-of select="normalize-space(blogid)"/></xsl:attribute>
        <xsl:value-of select="oohblogurl"/>

  </xsl:for-each>

+ Create a new oohblog

How can I get the href of the actual anchor being clicked?  I don't see how to make a document.ready even for items that don't exist until after the document is ready.
I suppose I could get the # value from the URL since when they click one it will update the URL but I would rather get it directly from the click.

Body:
If your content is dynamically generated, you may want to look into .live() (or delegate()) ( http://api.jquery.com/live/ | http://api.jquery.com/delegate/)

Your code would then look something like:

    $("#BlogSelectList li a").live('click', function () {
        //do something
    });


问:
Is there a way to get most bought package in php?
I have a web application in php. where users can buy packages and admin can see how many sales each package have.
right now I'm getting total sales by counting the rows from the payments table. to get the most bought package I think I have to count the rows in payments table in the database and return the id of of most bought package. but I don't to go with this?

Current Statement Which Get Package Sales from Id:

```<code>$sql = "SELECT COUNT(*) AS totalSales FROM ph_paypal_payments WHERE packageId = ?";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) die ("Prepare failed: " . mysqli_stmt_error($stmt));

mysqli_stmt_bind_param($stmt, "i", $packageId);
mysqli_stmt_execute($stmt);
return mysqli_fetch_assoc(mysqli_stmt_get_result($stmt))['totalSales'];
</code>```

答:
You can use this

```<code>SELECT
  packageId
FROM
  (SELECT packageId, COUNT(*) AS totalSales FROM ph_paypal_payments
  GROUP BY packageId) t1
ORDER BY totalSales DESC
LIMIT 1;
</code>```

Ir gets you one packageId which has the highest totalSales . Even if there are more it still gets you only one of them.

this is based on the number of rows and not the quantity sold.

```<code>$sql = "SELECT packageId FROM (SELECT packageId, COUNT(*) AS totalSales FROM ph_paypal_payments GROUP BY packageId) t1 ORDER BY totalSales DESC LIMIT 1;";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) die ("Prepare failed: " . mysqli_stmt_error($stmt));

mysqli_stmt_bind_param($stmt, "i", $packageId);
mysqli_stmt_execute($stmt);
return mysqli_fetch_assoc(mysqli_stmt_get_result($stmt))['packageId'];
</code>```

Body:
I have a web application in php. where users can buy packages and admin can see how many sales each package have.
right now I'm getting total sales by counting the rows from the payments table. to get the most bought package I think I have to count the rows in payments table in the database and return the id of of most bought package. but I don't to go with this?

Current Statement Which Get Package Sales from Id:

$sql = "SELECT COUNT(*) AS totalSales FROM ph_paypal_payments WHERE packageId = ?";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) die ("Prepare failed: " . mysqli_stmt_error($stmt));

mysqli_stmt_bind_param($stmt, "i", $packageId);
mysqli_stmt_execute($stmt);
return mysqli_fetch_assoc(mysqli_stmt_get_result($stmt))['totalSales'];

Body:
You can use this

SELECT
  packageId
FROM
  (SELECT packageId, COUNT(*) AS totalSales FROM ph_paypal_payments
  GROUP BY packageId) t1
ORDER BY totalSales DESC
LIMIT 1;

Ir gets you one packageId which has the highest totalSales . Even if there are more it still gets you only one of them.

this is based on the number of rows and not the quantity sold.

$sql = "SELECT packageId FROM (SELECT packageId, COUNT(*) AS totalSales FROM ph_paypal_payments GROUP BY packageId) t1 ORDER BY totalSales DESC LIMIT 1;";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) die ("Prepare failed: " . mysqli_stmt_error($stmt));

mysqli_stmt_bind_param($stmt, "i", $packageId);
mysqli_stmt_execute($stmt);
return mysqli_fetch_assoc(mysqli_stmt_get_result($stmt))['packageId'];


问:
Why is the hostname declared invalid when creating a URI
Running this code with JDK 1.8:

```<code>try {
    System.out.println( new URI(null, null, "5-12-145-35_s-81", 443, null, null, null));
} catch (URISyntaxException e) {
    e.printStackTrace();
}
</code>```

results in this error: java.net.URISyntaxException: Illegal character in hostname at index 13: //5-12-145-35_s-81:443

Where does this error come from, considering all the hostname characters seem legit, according to Types of URI characters?

If I use these URLs: //5-12-145-35_s-81:443 or /5-12-145-35_s-81:443 the error is gone.

From the comments, I understand that, according to RFC-2396, the hostname cannot contain any underscore characters.

The question that still holds is why a hostname starting with slash or double slash is allowed to contain underscores?

答:
Host name must match the following syntax:

```<code>hostname      = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
</code>```

As you can see, only . and - are allowed, _ is not.

You then say that //5-12-145-35_s-81:443 is allowed, and it is, but not for host name.

To see how that pans out:

```<code>URI uriBadHost = URI.create("//5-12-145-35_s-81:443");
System.out.println("uri = " + uriBadHost);
System.out.println("  authority = " + uriBadHost.getAuthority());
System.out.println("  host = " + uriBadHost.getHost());
System.out.println("  port = " + uriBadHost.getPort());
</code>```

```<code>URI uriGoodHost = URI.create("//example.com:443");
System.out.println("uri = " + uriGoodHost);
System.out.println("  authority = " + uriGoodHost.getAuthority());
System.out.println("  host = " + uriGoodHost.getHost());
System.out.println("  port = " + uriGoodHost.getPort());
</code>```

Output

uri = //5-12-145-35_s-81:443
  authority = 5-12-145-35_s-81:443
  host = null
  port = -1
```

<pre class="lang-none prettyprint-override"><code>uri = //example.com:443
  authority = example.com:443
  host = example.com
  port = 443
</code>```

As you can see, when the authority has a valid host name, the host and port are parsed, but when not valid, the authority is treated as freeform text, and not parsed any further.

UPDATE

From comment:

System.out.println( new URI(null, null, "/5-12-145-35_s-81", 443, null, null, null)) outputs: ///5-12-145-35_s-81:443. I'm giving it as hostname

The URI constructor you're calling is a convenience method, and it simple builds a full URI string and then parses that.

Passing "5-12-145-35_s-81", 443 becomes //5-12-145-35_s-81:443.

Passing "/5-12-145-35_s-81", 443 becomes ///5-12-145-35_s-81:443.

In the first, it's a host and port, and fails to parse.

In the second the authority part is empty, and /5-12-145-35_s-81:443 is a path.

```<code>URI uri1 = new URI(null, null, "/5-12-145-35_s-81", 443, null, null, null);
System.out.println("uri = " + uri1);
System.out.println("  authority = " + uri1.getAuthority());
System.out.println("  host = " + uri1.getHost());
System.out.println("  port = " + uri1.getPort());
System.out.println("  path = " + uri1.getPath());
</code>```

Output

uri = ///5-12-145-35_s-81:443
  authority = null
  host = null
  port = -1
  path = /5-12-145-35_s-81:443
```

Body:
Running this code with JDK 1.8:

try {
    System.out.println( new URI(null, null, "5-12-145-35_s-81", 443, null, null, null));
} catch (URISyntaxException e) {
    e.printStackTrace();
}

results in this error: java.net.URISyntaxException: Illegal character in hostname at index 13: //5-12-145-35_s-81:443

Where does this error come from, considering all the hostname characters seem legit, according to Types of URI characters?

If I use these URLs: //5-12-145-35_s-81:443 or /5-12-145-35_s-81:443 the error is gone.

From the comments, I understand that, according to RFC-2396, the hostname cannot contain any underscore characters.

The question that still holds is why a hostname starting with slash or double slash is allowed to contain underscores?

Body:
Host name must match the following syntax:

hostname      = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
toplabel      = alpha | alpha *( alphanum | "-" ) alphanum

As you can see, only . and - are allowed, _ is not.

You then say that //5-12-145-35_s-81:443 is allowed, and it is, but not for host name.

To see how that pans out:

URI uriBadHost = URI.create("//5-12-145-35_s-81:443");
System.out.println("uri = " + uriBadHost);
System.out.println("  authority = " + uriBadHost.getAuthority());
System.out.println("  host = " + uriBadHost.getHost());
System.out.println("  port = " + uriBadHost.getPort());

URI uriGoodHost = URI.create("//example.com:443");
System.out.println("uri = " + uriGoodHost);
System.out.println("  authority = " + uriGoodHost.getAuthority());
System.out.println("  host = " + uriGoodHost.getHost());
System.out.println("  port = " + uriGoodHost.getPort());

Output

uri = //5-12-145-35_s-81:443
  authority = 5-12-145-35_s-81:443
  host = null
  port = -1

uri = //example.com:443
  authority = example.com:443
  host = example.com
  port = 443

As you can see, when the authority has a valid host name, the host and port are parsed, but when not valid, the authority is treated as freeform text, and not parsed any further.

UPDATE

From comment:

System.out.println( new URI(null, null, "/5-12-145-35_s-81", 443, null, null, null)) outputs: ///5-12-145-35_s-81:443. I'm giving it as hostname

The URI constructor you're calling is a convenience method, and it simple builds a full URI string and then parses that.

Passing "5-12-145-35_s-81", 443 becomes //5-12-145-35_s-81:443.

Passing "/5-12-145-35_s-81", 443 becomes ///5-12-145-35_s-81:443.

In the first, it's a host and port, and fails to parse.

In the second the authority part is empty, and /5-12-145-35_s-81:443 is a path.

URI uri1 = new URI(null, null, "/5-12-145-35_s-81", 443, null, null, null);
System.out.println("uri = " + uri1);
System.out.println("  authority = " + uri1.getAuthority());
System.out.println("  host = " + uri1.getHost());
System.out.println("  port = " + uri1.getPort());
System.out.println("  path = " + uri1.getPath());

Output

uri = ///5-12-145-35_s-81:443
  authority = null
  host = null
  port = -1
  path = /5-12-145-35_s-81:443


问:
only show first item in if-statment loop
This code:

```<code>require_once 'feed.php';

$title = 'Ev 134';

ob_start();
foreach(Feed('example.url') as $f ) {
    if (strpos($f->title, $title) !== false) {

        $green_color    = 'green';
        $orange_color   = 'orange';
        $red_color      = 'red';
        $closed_text    = 'closed';
        $maintenance_text   = 'maintenance';
        $exception_text = 'could be';

        if (strpos($f->title, $title) !== false){

            if(strpos($f->description, $closed_text) !== false){
                echo (strpos($f->description, $exception_text) === false) ?
                     '<span style="color:'.$red_color.';text-shadow: 2px 2px #a50000;">closed</span>' :
                    '<span style="color:'.$green_color.'">Open</span>' ;

            } else if(strpos($f->description, $maintenance_text) !== false){
                echo (strpos($f->description, $exception_text) === false) ?
                     '<span style="color:'.$orange_color.'">maintenance</span>' :
                     '<span style="color:'.$green_color.'">Open</span>' ;

            } else {
                echo '<span>Open</span>';
            }
        }
    }
}
$status = ob_get_contents();
ob_end_clean();

echo $status;
</code>```

Outputs the current weather report from a road. Eather open/closed or maintenance.

My problem:

There could potentially be to outputs which would result in openopen or maintenanceopen which I don`t want.

I have tried:

```<code>if ($status = 'OpenOpen'){
  $status = 'Open';
}
</code>```

but it's complicated and messy to this with all possible scenarios + it doesn't work that well.

What I want: if there are multiple reports only show the first and put * behind the text.

Any help is greatly appreciated!

答:
This code make a couple of changes.

Rather than using output buffering, this just sets values into $status all through.  This allows you to check if a previous value has been set and add * to the end, or if it gets to the end of the loop and $status is still empty, it can set the open text.

I've also moved the static text assignments outside of the loop as you don't need to set them each time.

Lastly you had if (strpos($f->title, $title) !== false) in twice, so this removes that...

```<code>$green_color    = 'green';
$orange_color   = 'orange';
$red_color      = 'red';
$closed_text    = 'closed';
$maintenance_text   = 'maintenance';
$exception_text = 'could be';

$status = "";
$records = 0;
foreach(Feed('https://www.vegvesen.no/trafikk/xml/savedsearch.rss?id=604') as $f ) {
    $records++;
    if (strpos($f->title, $title) !== false) {
        if(strpos($f->description, $closed_text) !== false){
            // If no previous value, set main text,otherwise add *
            if ( empty($status) )   {
                $status = (strpos($f->description, $exception_text) === false) ?
                    '<span style="color:'.$red_color.';text-shadow: 2px 2px #a50000;">closed</span>'
                    : '<span style="color:'.$green_color.'">Open</span>' ;
            }
            else    {
                $status .= "*";
            }

        }
        else if(strpos($f->description, $maintenance_text) !== false){
            if ( empty($status) )   {
                $status = (strpos($f->description, $exception_text) === false) ?
                    '<span style="color:'.$orange_color.'">maintenance</span>' :
                    '<span style="color:'.$green_color.'">Open</span>' ;

            }
            else    {
                $status .= "*";
            }
        }
    }
}

// If still empty, say open
if ( empty ( $status ) ){
    $status = '<span>Open</span>';
    if ( $records > 0 ) {
        $status.="*";
    }
}
echo $status;
</code>```

You may be able to remove the tests for (strpos($f->description, $exception_text) === false) when setting the orange and red parts and just ignore that item if the $exception_text is in the text.

Body:
This code:

require_once 'feed.php';

$title = 'Ev 134';

ob_start();
foreach(Feed('example.url') as $f ) {
    if (strpos($f->title, $title) !== false) {

        $green_color    = 'green';
        $orange_color   = 'orange';
        $red_color      = 'red';
        $closed_text    = 'closed';
        $maintenance_text   = 'maintenance';
        $exception_text = 'could be';

        if (strpos($f->title, $title) !== false){

            if(strpos($f->description, $closed_text) !== false){
                echo (strpos($f->description, $exception_text) === false) ?
                     'closed' :
                    'Open' ;

            } else if(strpos($f->description, $maintenance_text) !== false){
                echo (strpos($f->description, $exception_text) === false) ?
                     'maintenance' :
                     'Open' ;

            } else {
                echo 'Open';
            }
        }
    }
}
$status = ob_get_contents();
ob_end_clean();

echo $status;

Outputs the current weather report from a road. Eather open/closed or maintenance.

My problem:

There could potentially be to outputs which would result in openopen or maintenanceopen which I don`t want.

I have tried:

if ($status = 'OpenOpen'){
  $status = 'Open';
}

but it's complicated and messy to this with all possible scenarios + it doesn't work that well.

What I want: if there are multiple reports only show the first and put * behind the text.

Any help is greatly appreciated!

Body:
This code make a couple of changes.

Rather than using output buffering, this just sets values into $status all through.  This allows you to check if a previous value has been set and add * to the end, or if it gets to the end of the loop and $status is still empty, it can set the open text.

I've also moved the static text assignments outside of the loop as you don't need to set them each time.

Lastly you had if (strpos($f->title, $title) !== false) in twice, so this removes that...

$green_color    = 'green';
$orange_color   = 'orange';
$red_color      = 'red';
$closed_text    = 'closed';
$maintenance_text   = 'maintenance';
$exception_text = 'could be';

$status = "";
$records = 0;
foreach(Feed('https://www.vegvesen.no/trafikk/xml/savedsearch.rss?id=604') as $f ) {
    $records++;
    if (strpos($f->title, $title) !== false) {
        if(strpos($f->description, $closed_text) !== false){
            // If no previous value, set main text,otherwise add *
            if ( empty($status) )   {
                $status = (strpos($f->description, $exception_text) === false) ?
                    '<span style="color:'.$red_color.';text-shadow: 2px 2px #a50000;">closed</span>'
                    : '<span style="color:'.$green_color.'">Open</span>' ;
            }
            else    {
                $status .= "*";
            }

        }
        else if(strpos($f->description, $maintenance_text) !== false){
            if ( empty($status) )   {
                $status = (strpos($f->description, $exception_text) === false) ?
                    '<span style="color:'.$orange_color.'">maintenance</span>' :
                    '<span style="color:'.$green_color.'">Open</span>' ;

            }
            else    {
                $status .= "*";
            }
        }
    }
}

// If still empty, say open
if ( empty ( $status ) ){
    $status = '<span>Open</span>';
    if ( $records > 0 ) {
        $status.="*";
    }
}
echo $status;

You may be able to remove the tests for (strpos($f->description, $exception_text) === false) when setting the orange and red parts and just ignore that item if the $exception_text is in the text.


问:
Using SQL to get the previous rows data
I have a requirement where I need to get data from the previous row to use in a calculation to give a status to the current row. It's a history table. The previous row will let me know if a data has changed in a date field.

I've looked up using cursors and it seems a little complicated. Is this the best way to go?

I've also tried to assgin a value to a new field...

newField =(Select field1 from Table1 where "previous row") previous row is where I seem to get stuck. I can't figure out how to select the row beneath the current row.

I'm using SQL Server 2005

Thanks in advance.

答:
```<code>-- Test data
declare @T table (ProjectNumber int, DateChanged datetime, Value int)
insert into @T
  select 1, '2001-01-01', 1 union all
  select 1, '2001-01-02', 1 union all
  select 1, '2001-01-03', 3 union all
  select 1, '2001-01-04', 3 union all
  select 1, '2001-01-05', 4 union all
  select 2, '2001-01-01', 1 union all
  select 2, '2001-01-02', 2

-- Get CurrentValue and PreviousValue with a Changed column
;with cte as
(
  select *,
    row_number() over(partition by ProjectNumber order by DateChanged) as rn
  from @T
)
select
  C.ProjectNumber,
  C.Value as CurrentValue,
  P.Value as PreviousValue,
  case C.Value when P.Value then 0 else 1 end as Changed
from cte as C
  inner join cte as P
    on C.ProjectNumber = P.ProjectNumber and
       C.rn = P.rn + 1

-- Count the number of changes per project
;with cte as
(
  select *,
    row_number() over(partition by ProjectNumber order by DateChanged) as rn
  from @T
)
select
  C.ProjectNumber,
  sum(case C.Value when P.Value then 0 else 1 end) as ChangeCount
from cte as C
  inner join cte as P
    on C.ProjectNumber = P.ProjectNumber and
       C.rn = P.rn + 1
group by C.ProjectNumber
</code>```

Title: Using SQL to get the previous rows data