Question

Iam using ember js with bootstrap i have a table using bootstrap

 <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th>Request Id</th>
        <th>Applied By</th>
        <th>Leave Type</th>
        <th>Leave From</th>
        <th>Leave To</th>
        <th>Days</th>
        <th>Status</th>
        <th>Applied date</th>
        <th>Applied/Declined date</th>
      </tr>
    </thead>
    <tbody data-link="row" class="rowlink">
      {{#each model.pending}}
      <tr id="ptable" data-toggle="modal" data-target="#pendingrequestsmodal" style="cursor: pointer">
        <td id="eid">{{id}}</td>
        <td>{{employee_id}}</td>
        <td>{{type_id}}</td>
        <td>{{from_date}}</td>
        <td>{{to_date}}</td>
        <td>{{days}}</td>
        <td>{{status}}</td>
        <td>{{to_date}}</td>
        <td>{{to_date}}</td>
      </tr>
      {{/each}}
    </tbody>
      </table>

now when someone clicks on the table row i am showing bootstrap modal for confirmation

  <div id="pendingrequestsmodal" class="modal fade">
<div class="modal-dialog">
  <div class="modal-content">
    <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
      <h4 class="modal-title">Confirmation</h4>
    </div>
    <div class="modal-body">
      <button type="button" class="btn btn-default" data-dismiss="modal">Decline</button>
      <button type="button" class="btn btn-primary" {{action "pendingAction" target="controller" }}>Approve</button>
    </div>
  </div>
</div>

and i want these clicked row details in the ember so that i can process it on the server

App.ApprovalrequestsController = Ember.ObjectController.extend({
actions: {
pendingAction: function () {
 //here i want to get the details of clicked row 
    //this.transitionToRoute("approvalrequests", rdata);
}
}
});

can anyone tell me how to get the clicked row details in ember

Was it helpful?

Solution

There are two issues that need to be solved, passing the selected object/model on an event (eg when clicking the approve button) being able to use a complicated template as content of the modal (eg when clicking on a row the modal could contain a form or data from a master-detail(s) relationship).

One approach would be to refresh the content of the modal every time a selection on a row happens. The selection can be handled when clicking the row and the refresh of the (possibly rich/complicated) content of the modal could be achieved by assigning a template to it and binding its rendering to a property.

The following example for simplicity has used a partial template to hold the modal's content and simple objects with one property (name) as model.

http://emberjs.jsbin.com/gecehotu/1/edit

hbs

<script type="text/x-handlebars" data-template-name="index">
    <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr>
        <th>color</th>
      </tr>
    </thead>
    <tbody data-link="row" class="rowlink">
      {{#each model}}
      <tr id="ptable" data-toggle="modal" data-target="#pendingrequestsmodal" style="cursor: pointer" {{action "selectColor" this target="view"}}>

        <td>{{name}}</td>

      </tr>
      {{/each}}
    </tbody>
      </table>

      {{#if selectedColor}}

          {{partial "popup"}}

      {{/if}}
  </script>

  <script type="text/x-handlebars" data-template-name="_popup">
  <div id="pendingrequestsmodal" class="modal fade">
<div class="modal-dialog">
  <div class="modal-content">
    <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
      <h4 class="modal-title">Confirmation</h4>
      <br/>
      {{selectedColor.name}}
    </div>
    <div class="modal-body">
      <button type="button" class="btn btn-default" data-dismiss="modal">Decline</button>
      <button type="button" class="btn btn-primary" {{action "pendingAction" selectedColor target="controller" }}>Approve</button>

    </div>
  </div>
</div>
  </script>

js

App = Ember.Application.create();

App.Router.map(function() {
  // put your routes here
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return [{name:'red'}, {name:'yellow'}, {name:'blue'}];
  }
});

App.IndexController = Ember.ArrayController.extend({
  selectedColor:null,
  actions:{
    pendingAction:function(color){alert("the color is:"+color.name);}
  }
});

App.IndexView = Ember.View.extend({
  actions:{
    selectColor:function(color){
      this.controller.set("selectedColor",color);
    }
  }
});

OTHER TIPS

You could specify the action on the

tr

like this:

 <tr id="ptable" data-toggle="modal" {{action 'pendingAction' this}} //blah>

Now, when a row is clicked, the controller's method in the actions hash 'pendingAction' is triggered with a parameter which is the row that was clicked on, or more precisely, the object which has materialized into the row.

To get this to work properly, you're going to have to change how you trigger the modal. Instead of using the Bootstrap plugin, it's much better to use Ember to handle it.

In your application template, add a second named outlet for your modal:

<script type="text/x-handlebars">
     {{outlet}}
     {{outlet modal}}
</script>

Then in your template, add a new action that will trigger the opening of the modal and pass the model along with it, like this:

<script type="text/x-handlebars data-template-name="pending">
    <tbody data-link="row" class="rowlink">
        {{#each request in model.pending}}
            <tr id="ptable"  style="cursor: pointer" {{action 'openModal' request}}>
                <td id="eid">{{item.id}}</td>
                <td>{{request.employee_id}}</td>
                <td>{{request.type_id}}</td>
                <td>{{request.from_date}}</td>
                <td>{{request.to_date}}</td>
                <td>{{request.days}}</td>
                <td>{{request.status}}</td>
                <td>{{request.to_date}}</td>
                <td>{{request.to_date}}</td>
            </tr>
        {{/each}}
    </tbody>
</script>

After that, you'll need to setup a modal template like this:

<script type="text/x-handlebars" data-template-name="pendingrequestmodal">
    <div id="pendingrequestsmodal" class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" {{action 'closeModal'}} aria-hidden="true">&times;</button>
                    <h4 class="modal-title">Confirmation</h4>
                </div>
                <div class="modal-body">
                {{model.id}}
                    <button type="button" class="btn btn-default" {{action 'closeModal'}}>Decline</button>
                    <button type="button" class="btn btn-primary" {{action "pendingAction" model}}>Approve</button>
                </div>
            </div>
        </div>
    </div>
    <div class="modal-backdrop" {{action 'closeModal'}}></div>
</script>

In the openModal action, we passed in the model as well. This will make it accessible when we react the to the event. You need to listen for the event and render the modal in your route, like this:

App.ApplicationRoute = Ember.Route.extend({
  actions: {
    openModal: function(request) {
      this.controllerFor('approvalrequests').set('model',request);

      return this.render('pendindrequestmodal', {
        into: 'application',
        outlet: 'modal',
        controller:'approvalrequests'
      });
    },
    closeModal: function() {
    return this.disconnectOutlet({
      outlet: 'modal',
      parentView: 'application'
    });
  }
  }
});

In the action, we're setting the modal property for our controller to the model we passed in and we're setting that controller as the controller for the modal. This will mean we can access the model properties in the template as normal. I also added the closeModal event that works by disconnecting the outlet.

Finally, we can handle the pendingAction event in your controller. In the modal, we passed the model along with the action, so it's accessible here as well.

App.ApprovalrequestsController = Ember.ObjectController.extend({
    actions: {
        pendingAction: function (model) {
            this.transitionToRoute("approvalrequests", model);
        }
    }
});

I kinda guessed on some of your template, route and controller names so they may need to be changed to fit your situation. If something here doesn't work, let me know and I can modify the answer.

You can find instructions and a working example of how to set up a modal dialogue here in the Ember Cookbook.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top