0

I've a custom element which, among other things, has a core-input and a paper button in it. When the element is created, the input is disabled, and I want to enable it when I tap the button. I've tried several ways and can't access the input's attribute.

<paper-input-decorator label="Nombre de usuario" floatingLabel>
      <input id="usernameinput" value="{{UserName}}" is="core-input" disabled />
</paper-input-decorator>
<paper-button raised id="edprobutton" on-tap="{{edbutTapped}}">EDITAR</paper-button>

What should I write in

edbutTapped: function () {

        },

EDIT

So, I've learned that the problem was that my username input element was inside a repeat template, and that's bad for what I was trying to do. Now I'm trying to bind a single json object to my element, with no luck so far.

What I have right now:

In my Index page:

<profile-page id="profpage" isProfile="true" entity="{{profEntity}}"></profile-page>

<script>
    $(document).ready(function () {
        var maintemplate = document.querySelector('#fulltemplate');

        $.getJSON('api/userProfile.json', function (data) {
            var jsonString = JSON.stringify(data);
            alert(jsonString);
            maintemplate.profEntity = jsonString;
        });
    }
</script>

In my element's page:

<polymer-element name="profile-page" attributes="isprofile entity">
    <template>
        <style>
            [...]
        </style>
        <div flex vertical layout>
            <core-label class="namepro">{{entity.Name}}</core-label>
            <core-label class="subpro">{{entity.CompanyPosition}}</core-label>
            <core-label class="subpro">{{entity.OrgUnitName}}</core-label>
        </div>
    </template>
</polymer-element>

And my JSON looks like this:

{"Name": "Sara Alvarez","CompanyPosition": "Desarrollo","OrgUnitName": "N-Adviser"}

I'm asuming I need to "update" my element somehow after changing its entity attribute?

Iskalla
  • 381
  • 3
  • 17

3 Answers3

0

Try the following

<script>
    Polymer({
         edbutTapped: function () {
              this.$.usernameinput.disabled = false;
         }
    });
</script>

The this.$ allows you to access controls defined in an elements and the usernameinput is the id you assigned to the input.

This can go below the closing tag of the element you are defining.

Paul S Chapman
  • 832
  • 10
  • 37
  • I've already tried that, an error shows "unable to get property 'disabled' of undefined or null reference" – Iskalla Feb 23 '15 at 14:13
  • I've added some more detail to the answer - try that. Might need to see more of your code if that does not deal with it. Sounds like the usernameinput is not defined at the point the hander is called. – Paul S Chapman Feb 23 '15 at 14:31
  • Sorry, I now realize it is inside a repeat template. It shouldn't, though, since its only one object, but comes from a json file and I don't know how to bind just one object, not using repeat. – Iskalla Feb 23 '15 at 14:43
  • I could create a user object on element created, but how can I extract it from a JSON, and - more important than this - will I be able to access to userinput's attributes if the bind is not a repeated template, or for it to work needs to be outside a template? – Iskalla Feb 23 '15 at 14:45
  • Is there a reason why you have put it into the repeat template? If you only want one copy then put it outside of the repeat. Otherwise yours is the same issue I've just posted, where I am trying to create an event handler for objects within a repeat template - although in my case there are 'n' entries where n is the number of records in a database. – Paul S Chapman Feb 23 '15 at 15:05
  • The only reason it is in a repeat template is that I just don't know how to get only one object from a JSON file and pass it to my custom element. – Iskalla Feb 23 '15 at 15:27
  • Have you tried JSON.Parse(string) - this will take some JSON and convert it into an object, you can then use ordinary javascript to access the object you want. – Paul S Chapman Feb 23 '15 at 15:50
  • It seems like I can't do that inside Polymer js, or at least I'm doing something wrong about it. Right now I'm trying to pass a parsed JSON as an attribute of my element, but so far it hasn't worked either. I'm gonna update my question and code, so it's easier to see where am I right now – Iskalla Feb 23 '15 at 16:09
0

'disabled' is conditional-attribute.

So this will be the correct use of it:

<input id="usernameinput" value="{{UserName}}" is="core-input" disabled?="{{isDisabled}}" />

In the prototype:

//first disable the field, can be done in ready callback:
ready: function () {
           this.isDisabled = 'true';
 }

//set idDisabled to 'false' i.e. enable the input
edbutTapped: function () {            
           this.isDisabled = 'false';
        },
Goce Ribeski
  • 1,352
  • 13
  • 30
  • Tried that also, didn't work, but I think the problem is that it is inside a Repeat Template, as I wrote on the comments above – Iskalla Feb 23 '15 at 14:52
0

OK this is going to be a long answer (hence why I am not entering this as an edit of my original answer). I've just done something which is functionally the same.

The first thing is this code;

    $.getJSON('api/userProfile.json', function (data) {
        var jsonString = JSON.stringify(data);
        alert(jsonString);
        maintemplate.profEntity = jsonString;
    });

Polymer has a control called core-ajax - this as it's name suggests makes an ajax call. The other really nice thing is that it can be made to execute when the URL changes. This is the code from the project I've got.

    <core-ajax id="ajax"
               auto=true
               method="POST"
               url="/RoutingMapHandler.php?Command=retrieve&Id=all"
               response="{{response}}"
               handleas="json"
               on-core-error="{{handleError}}" 
               on-core-response="{{handleResponse}}">
    </core-ajax>

The auto is the bit which tells it to fire when the URL changes. The description of auto from the polymer documentation is as follows;

With auto set to true, the element performs a request whenever its url, params or body properties are changed.

you don't need the on-core-response but the on-core-error might be more useful. For my code response contains the JSON returned.

So for your code - it would be something like this

    <core-ajax id="ajax"
               auto=true
               method="POST"
               url="/api/userProfile.json"
               response="{{jsonString}}"
               handleas="json"
               on-core-error="{{handleError}}" >
    </core-ajax>

Now we have the data coming into your project we need to handle this. This is done by making use of Polymer's data-binding.

Lets detour to the element you are creating. Cannot see anything wrong with the following line.

<polymer-element name="profile-page" attributes="isprofile entity">

We have an element called 'profile-page' with two properties 'isprofile' and 'entity'.

Only because my Javascript leaves a bit to be desired I would pass each property as a seperate entity making that line

<polymer-element name="profile-page" attributes="isprofile name companyposition OrgUnitName">

Then at the bottom of your element define a script tag

<script>
    Polymer({
        name: "",
        companyposition: "",
        OrgUnitName: ""
        });
</script>

Now back to the calling (profile-page). The following code (from my project) has the following;

    <template repeat="{{m in response.data}}">
        <map-list-element mapname="{{m.mapName}}" recordid="{{m.Id}}" on-show-settings="{{showSettings}}">
        </map-list-element> 
    </template>

Here we repeat the following each element. In your case you only have one entry and it is stored in jsonString so your template is something like this

    <template repeat="{{u in jsonString}}">
         <profile-page name="{{u.name}} companyposition="{{u.companyposition}}" OrgUnitName="{{u.OrgUnitName}}">
         </profile-page>
    </template>

Now we get to the issue you have. Return to your profie-page element. Nothing wrong with the line

on-tap="{{edbutTapped}}"

This calls a function called edbutTapped. Taking the code I gave you earlier

<script>
    Polymer({
         edbutTapped: function () {
              this.$.usernameinput.disabled = false;
         }
    });
</script>

The only thing to change here is add the following code

created: function() {
     this.$.usernameinput.disabled = true;
},

This is inserted after the Polymer({ line. I cannot see in your revised code where the usernameinput is defined but I am assuming you have not posted it and it is defined in the element.

And you should be working, but remember to keep your case consistent and to be honest I've not been - certain parts of Polymer are case sensitive - that catches me out all the time :)

Paul S Chapman
  • 832
  • 10
  • 37
  • Thanks for the detailed answer, I tried just like this and core-ajax's response seems empty, no profile-page is drawn. Also, do I really need the repeated template? I mean, is not an array of objects, but one only. Even if I could make this work, my concern is that what I wrote is a small example of what I actually have, meaning that a profile has a lot more properties, not only those three, so I'd prefer if I could send the whole object and handle it inside the element. Is that not possible? – Iskalla Feb 24 '15 at 08:08
  • You could use the on-core-response attribute of the core-ajax. Add the following to the core-ajax on-core-response="{{handleResponse}}. Then the handler is defined like this the script of the custom element. handleResponse: function (event, detail, sender) { }, detail should contain the result - if you use the following alert(JSON.stringify(detail)); and that will show you detail as a JSON string - which should contain an object made up of your JSON. – Paul S Chapman Feb 24 '15 at 08:46