web-dev-qa-db-fra.com

Obtenir des informations par javascript dans laravel

J'essaie d'obtenir une colonne spécifique de la deuxième table à l'aide de javascript et de me renvoyer des données à ce sujet, mais je ne sais pas comment cela peut être fait.

Logique

  1. La table des produits a une colonne price
  2. Le tableau de remise comporte des colonnes product_id, min, max et amount
  3. Je saisis le nombre en tant que quantité, si l'identifiant du produit figure dans mon tableau de remise Base sur min et max renvoie la amount en tant que nouveau prix

Code

jusqu'à présent, ce sont mes codes (je suis conscient que ma méthode de contrôleur a un problème d'identification pour trouver les bonnes données)

JavaScript

<script>
  $(document).ready(function() {
    // if quantity is not selected (default 1)
    $('#newprice').empty();
    var quantity =  parseInt(document.getElementById("quantity").value);
    var shipingcost = parseFloat(quantity);
    var shipingcostnumber = shipingcost;
    var nf = new Intl.NumberFormat('en-US', {
        maximumFractionDigits:0, 
        minimumFractionDigits:0
    });
    $('#newprice').append('Rp '+nf.format(shipingcostnumber)+'');

    // if quantity is changed
    $('#quantity').on('change', function() {
      var quantity = parseInt(document.getElementById("quantity").value);
      var qtyminmax = $(this).val();
      if(qtyminmax) {
        $.ajax({
          url: '{{ url('admin/qtydisc') }}/'+encodeURI(qtyminmax),
          type: "GET",
          dataType: "json",
          success:function(data) {
            $('#totalPriceInTotal').empty();
            var shipingcost = parseFloat(data)+parseFloat(quantity);
            var shipingcostnumber = shipingcost;
            var nf = new Intl.NumberFormat('en-US', {
                maximumFractionDigits:0, 
                minimumFractionDigits:0
            });
            $('#totalPriceInTotal').append('Rp '+nf.format(shipingcostnumber)+'');
          }
        });
      }else{
        //when quantity backs to default (1)
        $('#newprice').empty();
        var quantity = parseInt(document.getElementById("quantity").value);
        var shipingcost = parseFloat(quantity);
        var shipingcostnumber = shipingcost;
        var nf = new Intl.NumberFormat('en-US', {
            maximumFractionDigits:0, 
            minimumFractionDigits:0
        });
        $('#newprice').append('Rp '+nf.format(shipingcostnumber)+'');
      }
    });
  });
</script>

Route

Route::get('qtydisc/{id}', 'ProductController@qtydisc');

Controller

public function qtydisc($id){
      return response()->json(QtyDiscount::where('min', '>=', $id)->orWhere('max', '<=', $id)->pluck('min'));
    }

Question

  1. Que dois-je changer dans ma méthode de contrôleur pour obtenir les bonnes données?
  2. Que dois-je changer dans mon code JavaScript? dois-je également ajouter product ID à mon itinéraire ou ...?

METTRE À JOUR

J'essaie d'apporter quelques modifications à mon code, mais je ne parviens pas à corriger amount

controller

public function qtydisc($id, $qty){
      $price = DB::table('qty_discounts')
              ->where('product_id', $id)
              ->where([
                  ['min', '>=', $qty],
                  ['max', '<=', $qty],
              ])
              // ->where('min', '>=', $qty)
              // ->where('max', '<=', $qty)
              ->select('amount')
              ->first();
      return response()->json($price);
    }

route

Route::get('qtydisc/{id}/{qty}', 'ProductController@qtydisc');

javascript

//as before...

$('#quantity').on('change', function() {
      var idofproduct = ["{{$product->id}}"]; //added
      var quantity = parseInt(document.getElementById("quantity").value);
      var qtyminmax = $(this).val();
      if(qtyminmax) {
        $.ajax({
          url: '{{ url('admin/qtydisc') }}/'+idofproduct+'/'+encodeURI(qtyminmax), //changed
          type: "GET",
          dataType: "json",
          success:function(data) {
            $('#totalPriceInTotal').empty();
            var shipingcost = parseFloat(data)+parseFloat(quantity);
            var shipingcostnumber = shipingcost;
            var nf = new Intl.NumberFormat('en-US', {
                maximumFractionDigits:0, 
                minimumFractionDigits:0
            });
            $('#totalPriceInTotal').append('Rp '+nf.format(shipingcostnumber)+'');
          }
        });
      }else{
//rest of it as before

Capture d'écran

 screenshotdb

c’est à quoi ressemble ma base de données et en tant que résultat pour une quantité entre 2 et 6 j’obtiens 7000 pendant que je dois obtenir 5000 de 2 à 5.

Du numéro 7 à 9 je n'obtiens aucun résultat.

Du numéro 10 à tout ce que je reçois est 7000

Une idée?

9
mafortis

Le problème principal provient de votre déclaration éloquente. Vous devez utiliser le >= dans les deux conditions avec l'opérateur OR à l'aide de l'assistant orWhere. Il devrait donc ressembler à ceci:

$price = QtyDiscounts::where('product_id', $id)
    ->where('min', '>=', $qty)
    ->orWhere('max', '>=', $qty)
    ->pluck('amount')
    ->first();

Mais vous devez vraiment jeter un coup d'oeil à votre structure JS, je suggère de scinder votre code pour qu'il fonctionne pour le concept DRY, d'abord l'écouteur d'événement tel que:

$('body').off('input', '#quantity').on('input', '#quantity', function () {
    var qty = parseInt( $(this).val() );

    if(qty) {
        getAmount(qty);
    }else{
        getAmount(1);
    }
});

Ensuite, l’assistant s’appelle pour appeler:

function setValue(quantity, amount)
{
    var newPrice = $('#newprice');
    var totalPrice = $('#totalPriceInTotal');

    newPrice.empty();
    totalPrice.empty();

    var nf = new Intl.NumberFormat('en-US', {
        maximumFractionDigits:0,
        minimumFractionDigits:0
    });

    newPrice.val('Rp '+nf.format(amount)+'');
    totalPrice.val('Rp '+nf.format(parseFloat(amount)*parseFloat(quantity))+'');
};

function getAmount(quantity)
{
    var url = $('#qty_url').val();
    var productId = $('#product_id').val();

    $.ajax({
        url: url+'/'+productId+'/'+encodeURI(quantity),
        type: "GET",
        dataType: "json",
        success:function(amount) {
            setValue(quantity, amount);
        }
    });
};

Je suppose que vous avez une structure HTML simple, elle devrait donc fonctionner de cette façon. Pourquoi est-ce que je suggère ici de ne jamais utiliser la variable php telle que url & product_id directement dans votre code JS? ces entrées utilisent le JS:

<input type="hidden" id="qty_url" value="{{ url('admin/qtydisc') }}" />
<input type="hidden" id="product_id" value="{{ $product->id }}"/>
2
Zakaria Acharki

Vous devriez écrire votre requête comme ceci:

public function qtydisc($id, $qty){
      $price = DB::table('qty_discounts')
              ->where('product_id', $id)
              ->where($qty, '>=', 'min')
              ->where($qty, '<=', 'max')
              ->select('amount')
              ->first();
      return response()->json($price);
    }
0
Bruno Lebtag

Arrêtez de mélanger JavaScript avec jQuery, au lieu de

var quantity = parseInt(document.getElementById("quantity").value);

Tu pourrais juste faire

var quantity = +$('#quantity').val();

Et attendez-vous à ce que cela fonctionne même dans le vieil Internet Explorer

Aller plus loin

Itinéraires

Route::get('/ajax/product/{product}/distcounts', 'AjaxController@productDiscounts);

Html

<input type="number" name="quantity" data-product_id="{{ $product->getKey() }}">

PHP

public function productDiscounts(Product $product, Request $request) {
    // $product is just a product you are interested in
    // $request->quantity containts passed amount

    $discounts = DiscountModel::product(     // Scope
        $product->getKey()
    )
    ->get()
    ->filter(function($element) use($request) {
        return ($element->min <= $request->quantity && $element->max >= $request->quantity);
    })
    ->values();

    return response->json(discounts);
}

JavaScript

(function($) {
    var getDiscountAmount(e) {
        var $input      = $(e.target);
        var product_id  = $input.data('product_id');

        $.ajax({
            method: 'GET',
            url: '/ajax/product/' + product_id + '/discount',
            data: {
                quantity: $input.val()
            },
            beforeSend: function() {
                $input.prop('disabled', true);
            },
            success: function(discounts) {
                $input.prop('disabled', false);

                // Dunno what you want to do with list of discounts right there
                // It should be an array containing 1 object, but who knows
            }
        })
    }

    $(input[name="quantity"]).on('change', getDiscountAmount);
})(jQuery);

J'espère que ça aide, n'a pas testé le code, vous devrez donc peut-être ajouter quelques modifications.

0

Si vous souhaitez partager des données d'un contrôleur à JS, je vous suggère d'utiliser ce package JsTransformers . Ça te fait faire quelque chose comme ça

// in controller
public function index()
{
    JavaScript::put([
        'foo' => 'bar',
        'user' => User::first(),
        'age' => 29
    ]);

    return view('index');
}

// in view scripts
console.log(foo); // bar
console.log(user); // User Obj
console.log(age); // 29
0
Yamen Ashraf

Utilisez la condition opposée dans le contrôleur principal:

$price = DB::table('qty_discounts')
          ->where('product_id', $id)
          ->where('min', '<=', $qty)
          ->where('max', '>=', $qty)
          ->select('amount')
          ->first(); 

Donc, pour $id = 2 et $qty = 5, vous obtiendrez

product id = 2  and `min` <= 5 and `max` >= 5

sélectionner la première ligne (row_id = 1)

0
F.Igor