xjshiya
xjshiya

Reputation: 925

Send PHP data to Modal using Javascript loop

I am sending values on modal using data-*. The data are populated by a MySQL query.

Here's the button for edit code which is under the while loop:

<div class="btn-group">
   <a class="btn btn-primary" href="#">Action</a>
   <a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
   <span class="fa fa-caret-down"></span></a>
   <ul class="dropdown-menu">
   <?php
   $li = "<li><a class=\"open-EditRow\" data-invno=\"".$invno."\" data-date=\"".$date."\" data-shipment=\"".$shipment."\" data-bcrp=\"".$bcrp."\" data-adjbcrp=\"".$adjbcrp."\" data-begbal=\"".$begbal."\" data-adjrpbc=\"".$adjrpbc."\" data-transrpbc=\"".$transrpbc."\" data-promo=\"".$promo."\" data-damages=\"".$damages."\""; 
   foreach($i as $k)
   {
        $li.=" data-".strtolower($k)."=\"".$b[$k]."\"";
   }
   $li.=" title=\"Edit this row\"><i class=\"fa fa-pencil\"></i> Edit</a></li>";
   echo $li;
   ?>
   </ul>
</div>

echo htmlentities($li) returns:

<li><a class="open-EditRow" data-invno="2" data-date="2015-04-02" data-shipment="23" data-bcrp="41" data-adjbcrp="0" data-begbal="1500" data-adjrpbc="3" data-transrpbc="46" data-promo="3" data-damages="6" data-cebu="100" data-danao="200" data-talisay="0" title="Edit this row"><i class="fa fa-pencil"></i> Edit</a></li>

which is correct.

The data inside the array $i are from a MySQL query, and these are its data:

Here are the edit modal code:

<?php
    foreach($i as $j)
    {
        ?>
        <div class="form-group">
        <label class="col-sm-3 control-label"><?php echo $j; ?></label>
        <div class="col-sm-5">
        <input type="text" class="form-control" name="<?php echo $j; ?>" id="<?php echo $j;?>"/>
        </div>
        </div>
        <?php
    }
?> 

And here's its jquery code:

$('.open-EditRow').click(function(){
   var invno = $(this).attr('data-invno');
   var date = $(this).attr('data-date');
   var shipment = $(this).attr('data-shipment');
   var bcrp = $(this).attr('data-bcrp');
   var adjbcrp = $(this).attr('data-adjbcrp');
   var begbal = $(this).attr('data-begbal');
   var adjrpbc = $(this).attr('data-adjrpbc');
   var transrpbc = $(this).attr('data-transrpbc');
   var promo = $(this).attr('data-promo');
   var damages = $(this).attr('data-damages');
   var centers = <?php echo json_encode($i); ?>;

   $('#myModal #invno').val(invno);
   $('#myModal #date').val(date);
   $('#myModal #shipment').val(shipment);
   $('#myModal #bcrp').val(bcrp);
   $('#myModal #adjbcrp').val(adjbcrp);
   $('#myModal #begbal').val(begbal);
   $('#myModal #adjrpbc').val(adjrpbc);
   $('#myModal #transrpbc').val(transrpbc);
   $('#myModal #promo').val(promo);
   $('#myModal #damages').val(damages);

   centers.forEach(function(entry) {
       var center1 = entry.toLowerCase();
       var center2 = 'data-' + center1;
       var center = $(this).attr('data-' + center1);
       $('#myModal #' + center1).val(center);
       alert(center);
    });

   $('#myModal').modal('show');
});

I am looping everything since its a dynamic value, but alerting var center returns undefined, var center1 and var center2 returns the correct data. I think something's wrong with my jquery code since it doesn't return the correct data on the edit modal.

Upvotes: 0

Views: 103

Answers (1)

Blindman67
Blindman67

Reputation: 54069

When calling a function that is not part of the prototype of the object you are in the this keyword no longer references the object you are in. Every function uses the this keyword to set its scope. When you call a function with the new keyword the function should return the object to be bound to this for that function.

function AObject(){  // if you use the new keyword convention is to Capitalist
    .. do stuff ...
    this.aValue = 1;

    // if called with the new keyword this function will return this
}
var aObj = new AObject(); // Creates an object and binds this to that new object
aObj.aValue === 1; //  is true

Can also be done as

function bObject(){
    var obj = {}; // create an object
    obj.bValue = 1;
    return obj;  // return object referance
}
var bObj = bObject();
bObj.bValue === 1;  // is true

Its takes a little experience to know when and how to use the this keyword but I have found that when in doubt using the Function object's method bind() to set the 'this' keyword to the desired object is very useful.

The wrong way.

function MyObj(){
    this.anArray = [0,1,2,3,4,5];
    this.mag = 2;
    var sumMag = 0;
    this.anArray.forEach(function(item){
        sumMag += item * this.mag; // the code will create an error as 
                                   // this points to the global this
    });
    console.log(sumMag); // the code never get here
}

To do this correctly (and using best practice)

function MyObj(){  // Always capabilities a class type object
    // always loft functions to the top of the function block
    // Some environments will insist you do this if you use "strict mode"
    // 
    var myItteratorFunc = ( function(item){  // note the bracket
        sumMag += item * this.mag;  
    } ).bind(this); // binds the current this to the function

    // or you can
    /*
    var myItteratorFunc = function(item){  
        sumMag += item * this.mag;  
    };
    var boundItterator = myItterator.bind(this);
    */

    this.anArray = [0,1,2,3,4,5];
    this.mag = 2;
    var sumMag = 0;
    this.anArray.forEach(myItteratorFunc);  // best practice and looks better
    console.log(sumMag); // logs -> 30
}

Bind is very handy for setIntervale and setTimeout also for many DOM events such as onload

SetInterval The wrong way

function MyClass(){
    this.tick = 0;
    setInterval(function(){
            this.tick += 1;  // fails
        },
        1000
    );
}

Onload The wrong way

function MyClass(){
    this.imageLoaded = false;
    var img = new Image();
    img.src = "URL";
    img.onload = function(){
         this.imageLoaded = true; // wrong "this" is pointing to the img object
                                  // and now img.imageLoaded === true
    };
}

setInterval The correct way

function MyClass(){
    var tickFunction = (function(){  // loft function to top
        this.tick += 1;
    }).bind(this);  // bind it to this object
    this.tick = 0;
    setInterval(tickFunction,1000); 
}

Onload The correct way if you need to reference the current this otherwise this will reference the image loaded.

function MyClass(){
    var imgLoadFunc = (function(){ // loft function
         this.imageLoaded = true;
    }).bind(this);  // bind it to this

    this.imageLoaded = false;

    var img = new Image();
    img.src = "URL";
    img.onload = imgLoadFunc;
}

Bind can also be used on static objects

var aThing = {
    numberLegs:2,
    canWalk:true,
    talk:(function(){   // create a method for aThing
        var str = "I have "+this.numberLegs;  // get the number of legs
        if(this.canWalk){  // can it this walk
            str += " and can walk.";
        }else{
            str += " but can't walk.";
        }
        console.log(str);
    }).bind(aThing)    // bind it to the static reference of aThing
};

aThing.talk(); // logs -> I have 2 legs and can walk.

See MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind for more info on bind.

Upvotes: 1

Related Questions