2

I have created this sample (jsbin) which shows a band member and an instrument he plays with.

This is how it looks :

enter image description here

At first , no one plays at anything , and so the instumentId is null :

s.users= [
        { id: 1, firstname: 'John', lastname: 'Lennon', instrumentId: null },
        { id: 2, firstname: 'Paul', lastname: 'McCartney', instrumentId: null},
        { id: 3, firstname: 'George', lastname: 'Harrison', instrumentId: null },
        { id: 4, firstname: 'Ringo', lastname: 'Star', instrumentId: null },
    ]; 

When I click "edit" - I have a template which is in :

enter image description here

And the user should choose :

enter image description here

All ok.

But I have 2 problems :

Question 1 :

Currently the template is in each row ( hidden) and I dont want that ! I want it to be temporary injected ( so user will be able to choose an instrument ) and then remove it from dom.

How can I do it ?

Question 2 :

The template is :

 <script type=text/ng-template id='instrument.html'>
    <select ng-model='instrumentDdl' >
     <option ng-repeat='ins in instruments'>{{ins.id +' - '+ins.name}}</option>
  </select>
</script>

So I bind the select to ng-model='instrumentDdl' . Also , the save function do this :

  s.save=function (user){ 
    console.log(s.instrumentDdl) //<----- undefined...why ?
    user.instrumentId=s.instrumentDdl;
   s.userUnderEdit  = null;
  };

But I get undefined at the console.log(s.instrumentDdl) ( s===$scope). why is that ?


PS , My goal : dynamic temporary injection , and when saved - to look like (john's only example):

enter image description here

2 Answers 2

2

For Question 1 use ng-if='user.isEdited'

For Question 2 try with select and ng-option

Update: My bad on the question 2. You need to provide some of your directive code and where are you calling s.save (html element) to know why is it not working.

Update 2: Looking at your jsbin, this is a scoping issue.

<li ng-repeat='user in users'> is creating a new scope for each user. instrumentDdl is getting added to the scope created for each user when you show the dropdown. It is not getting added to the parent controller scope. You can do is write

<button ng-click='save(user,instrumentDdl)'>Save</button>

and the change the save method accordingly.

Sign up to request clarification or add additional context in comments.

10 Comments

Do I deserve such a poor answer for this very detailed question ? ( Also , ng-option is not related. my sample also works. you can use also ng-repeat. Also , I dont see how ng-if related to dynamic temporary insertion. Also , a fiddle would be much appreciated.
@RoyiNamir, well i have fixed some part of the answer.
console.log(s.instrumentDdl) this smell a little I think should be instrumentDdl all in all it's the model
ng-if only injects html in DOM when the condition is true.
@Whisher no. it appended tpo the $scope object. and the $scope is s in my code.
|
1

UPDATE

I removed the ngInit as it's not what you need. Here is a working jsbin: http://jsbin.com/EPabuQAm/11/edit

Inside the template use ngOptions & ngModel:

<script type=text/ng-template id='instrument.html'>
    <select ng-model='user.instrumentSelected' 
            ng-options="(ins.id + ' - ' + ins.name) for ins in instruments">    
</script>

Users list , use ngIf:

<li ng-repeat='user in users'>
    {{user.firstname +' '+  user.lastname + ' plays at: '+ (user.instrumentDdl.name ||'?')  }}

    <button ng-click='edit(user)'>Edit</button>
    <div  ng-if='user.isEdited'> Tool : 
        <my-tool > </my-tool>
        <button ng-click='save(user)'>Save</button> 
        <button ng-click='cancel(user)'>Cancel</button>           
     </div>
 </li>

Contoller: - set the variable on save, edit & cancel events

scope.edit=function (user){ 
    user.isEdited = true;
};

scope.cancel = function (user)
{
    user.isEdited=false;
};

scope.save=function (user){ 
    user.isEdited=false;
    user.instrumentDdl= user.instrumentSelected;
};

You can also get a way without any scope functions:

 <button ng-click='user.isEdited = true'>Edit</button>
 <div  ng-if='user.isEdited'> Tool : 
    <my-tool > </my-tool>
    <button ng-click='user.isEdited = false; user.instrumentDdl = user.instrumentSelected'>Save</button> 
    <button ng-click='user.isEdited = false'>Cancel</button>           
 </div>

5 Comments

tnx. why the template is open and present at each row ?
What do you mean by why? ng-init initiates user.isEdited = true
my first question is talking about it. I dont want to duplicate this template in the dom. I want it to appear only at the edited row. (I dont want even hidden) the template should be injected only at the relevant row and disposed after save/cancel.
Also , why did you put in the template :ng-model='user.instrumentSelected' ? this will bind to $scope.user.instrumentSelected ....right ?
yes, ngRepeat creates a new child scope for each item so it's scoped to the right item

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.