Creating custom mashup types

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Hi,

I am currently playing about with implementing a custom mashup type and have been reviewing the samples, begining with the "Helloworld" sample and have viewed the documentation relating to this and accessed this type but in trying to use a variation of this given by taking in an input in the form of a text box and button to invoke the service (code used and given in documentation below) i have come unstuck.

p = new Ext.FormPanel({
    id: this.inputScreen,
    labelWidth: 110,
    frame:false,
    bodyStyle:'padding:5px 5px 0',
    items: [{
        xtype:'fieldset',
        title: 'Select Weather Location',
        autoHeight:true,
        defaults: {width: 210},
        defaultType: 'textfield',
        items: fields
    }],
    buttons: [{
        text: 'Apply',
        scope: this,
        handler: function(e) {
            var values = p.form.getValues();
            this.executeWeatherService(values);
            }.createDelegate(this)
        },
        {
        text: 'Return',
        scope: this,
        handler: function(e) {
            this.onRefresh();
            }
        }]
});

When previewing the mashup type in mashup maker there is no text box or button being displayed and an error saying "fields" is not defined. The code i used is attached. Would this problem be occuring because i have not declared something in the properties of the mashup type contained in the mashlet.json file

Thanks

Jack

Normal
0

false
false
false

MicrosoftInternetExplorer4

Variation

/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}

Normal
0

false
false
false

MicrosoftInternetExplorer4

5
Your rating: None Average: 5 (1 vote)
jeremy.pitten
jeremy.pitten's picture
User offline. Last seen 2 weeks 6 days ago. Offline
Joined: 09/22/2008
Points: 275

The reason you get the fields is not defined error is because the fields property is not defined in your render method.
You do not need to defein a property in your mashlet.json file unless you want the property persisted,
say you wanted to set up a default text string to be used as a location.

So in the following example, I create a new mashlet type called Sample.Weather,  adding the following entry to mashlet.json:

    "Sample.Weather": {
        "type": "Sample.Weather",
        "title":"Weather!",
        "description": "Weather Service Mashlet",
        "properties": {
            "defaultLocation": "Fremont"
        },
        "properties-meta":{
            "defaultLocation": {
                "type": "string",
                "description": "Default Location"
            }
        },
        "resources": {
            "js": [{"script":"main.js", "property":"Sample.Weather"}]
         }
      },

Which defines a preference property called defaultLocation. When you create a mashlet instance in MashletMaker you can set up an alternative default value, the defaultLocation preference will be listed in the Mashlet Additional Preferences section. In the mashlets directory I create a new folder called Sample.Weather and add the following javascript file, main.js:


Ema.namespace('Sample');

Sample.Weather = Class.create(Ema.BoxMashlet, {

    render: function(){
       
        // initialise the location value by reading the defaultLocation preference..
        var location = this.getPreference('defaultLocation') || '';

        var fields = [{
            hideLabel: true,
            name:'location',
            value: location
        }];

        var p = new Ext.FormPanel({
            renderTo: this.bodyEl,
            labelWidth: 110,
            frame:false,
            bodyStyle:'padding:5px 5px 0',
            items: [{
                xtype:'fieldset',
                title: 'Select Weather Location',
                autoHeight:true,
                defaults: {
                    width: 210
                },
                defaultType: 'textfield',
                items: fields
            }],
            buttons: [{
                text: 'Apply',
                scope: this,
                handler: function(e) {
                    var values = p.form.getValues();
                    this.executeWeatherService(values);
                }.createDelegate(this)
            },
            {
                text: 'Return',
                scope: this,
                handler: function(e) {
                    this.onRefresh();
                }
            }]
        });

    },

    executeWeatherService: function(config){
        console.log('execute weather service with location '+config.location);
    },

    onRefresh: function() {
        this.render();
    }
});

Notice the location variable is read from the mashlet preferences using getPreference and the fields variable is initialised as an array with a single entry.

Sample.GoogleMap has similar code to the above which may help you.

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Much appreciated, the googleMap sample also provided additional ideas.

On a related note, i know that input from a custom mashlet can be passed to a different service and displayed within that mashlet but is it possible on passing these inputs to a custom mashlet this new mashlet is opened and displayed separately?

jeremy.pitten
jeremy.pitten's picture
User offline. Last seen 2 weeks 6 days ago. Offline
Joined: 09/22/2008
Points: 275

Yes, from within your first mashlet you could use the Ema.load function to load a second mashlet and pass in any inputs via the args property which will cause any named mashlet preference properties to be overridden for that rendering of the mashlet. So in the above example you could pass in an alternative value for the defaultLocation preference property like this:

      
       Ema.load({
            name: <your second mashlet name>,
            el: <another element id in which to render the mashlet>,
            args: {
                defaultLocation: 'Washington DC'
            },
            callback: {
                onSuccess: function(mashlet){
                    console.log('mashlet loaded', mashlet);                  
                },
                onFailure: function(err){
                    console.log('Error loading mashlet', err);
                },
                scope: this
            }
        });      

 

If one mashlet launches another mashlet using Ema.load they can also interact directly with that mashlet using the reference to the mashlet object returned by the callback onSuccess function.

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

I've tried to just create a new button using the sample.weather example and on its click open the HelloWorld mashlet, so without passing any parameters to start with. But when previewing the mashlet in the mashlet explorer  the button is not being showed and cannot check if this works. Would it be possible to look at the short script attached to see where i am going wrong? is there a debugger as such to use to find errors in the code written

 

Jack

 

 

jeremy.pitten
jeremy.pitten's picture
User offline. Last seen 2 weeks 6 days ago. Offline
Joined: 09/22/2008
Points: 275

The code looks fine to me and there is no problem with the new button, maybe you need to clear your browser cache.

I use the Firebug plugin for Firefox more than any other debugger, I would strongly recommend this plugin.

I would also recommend the Microsoft Visual Web Developer 2008 Express Edition, which is free and can be used to debug javascript.

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Cheers the button is now appearing but when clicked is giving the following error

Error processing your request - Error: this.el is null

I am guessing this is because the mashlet is not embeded in a html page and therfore there is no "el" name referenced in the <div> to be rendered on the page, once the open button has been clicked.

I have been trying to test this to check if this is the problem but when publishing the mashlet from mashlet maker there is no textbox or buttons shown but when previewing the mashlet before publishing it these are all there. Would you have any ideas y this would be the case?

jeremy.pitten
jeremy.pitten's picture
User offline. Last seen 2 weeks 6 days ago. Offline
Joined: 09/22/2008
Points: 275

Yes, if the web page does not contain a div element with the necessary id then you will get this error. You have a choice, either you define that div statically in the web page, or you could add it dynamically, by updating the DOM, before calling the Ema.load function.

I think you will find that the reason the form isnt displayed when you view the mashlet standalone is because the Ext JS library hasnt been loaded. When you view the mashlet in mashletMaker, Ext is already present so it appears to work.

You need to update the mashlet type definition in mashlet.json to indicate that the ext library is required, for example:

"Sample.Weather": {
        "type": "Sample.Weather",
        "title":"Weather!",
        "description": "Weather Service Mashlet",

        "properties": {
            "defaultLocation": "Fremont"
        },
        "properties-meta":{
            "defaultLocation": {
                "type": "string",
                "description": "Default Location"
            }
        },
        "resources": {
            "libs": {
                "presto_ext": true
            },
            "js": [{
                "script":"main.js",
                "property":"Sample.Weather"
            }]
        }
    },

In the above I've just added "libs":{ "presto_ext":true }, to the resources object.

 

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Hi

Thanks for all the help you have been giving, yes adding the resource solved the problem exactly. Sorry for the questions but i am trying to complete this part before i move onto other areas in the mashup i am creating.

Now i have got the Sample.Weather mashlet loaded onto the web page using the embedded html, the open button is not adding the HelloWorld mashlet to the page. Below is the code i am using which specifies the div<> with the same id that is used in the ema.load function of the mashlet.

I have checked that the HelloWorld mashlet can be embedded on its own in a page to make sure it is correct and this is loading on its own fine. You have also said that the code on the open button in the Sample.Weather mashlet for the ema.load is fine.

<html>
  <head>
    <script src="http://localhost:8080/mashlets/js/mashlet-loader.js"></script>
  </head>
  <body>
  <div id="mtarget"></div>
  <script src="http://localhost:8080/mashlets?mashlet=Sample.Weather.Mashlet"></script>
  </body>
</html>

Am i going about this completly wrong. Will a ema.load from a button on a mashlet not render to a div<> in the same web page that has the same id?

jeremy.pitten
jeremy.pitten's picture
User offline. Last seen 2 weeks 6 days ago. Offline
Joined: 09/22/2008
Points: 275

The html page is fine and works for me, the HelloWorld mashlet is rendered above the other mashlet when you click the open button. If the page has more than one element with that id assigned to it then the mashlet will just be inserted as a child of the first occurance.

Are you sure you have a mashlet named HelloWorld? Assuming you do then try viewing the page using Firefox with Firebug installed and see what the firebug console tells you.

 

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Yea, i went to mashlet maker-->create from type--> HelloWorld --> publish mashlet, and then checked in explore mashlets and it is there. Copied "HTML embed" code and it loads fine from the web page. The only error i can see from firebug is the one below. This error is also present in the Sample.Weather mashlets when looked at with firebug. Could this be the problem?

<body>
<div id="c1"/>
<script src="http://localhost:8080/mashlets?mashlet=HelloWorld.Mashlet">
    1 Failed to load source for: http://localhost:8080/mashlets?mashlet=HelloWorld.Mashlet
</script>
<div>

</body>

<body>

<div id="mtarget"/>

<script src="http://localhost:8080/mashlets?mashlet=Sample.Weather.Mashlet">

1Failed to load source for: http://localhost:8080/mashlets?mashlet=Sample.Weather.Mashlet

</script>

<div>
</div>

</body>
 
Incase it is something i am doing wrong,  i publish the Sample.Weather the same as outlined for the HelloWorld mashlet. When previewing i get the error as mentioned in the previous post (but this is to do with it needing to be rendered to the id on the web page) and this mashlet too load fine to the web page with the "HTML embed" code

jeremy.pitten
jeremy.pitten's picture
User offline. Last seen 2 weeks 6 days ago. Offline
Joined: 09/22/2008
Points: 275

The only thing I can see wrong is that Sample.Weather mashlet tries to load a mashlet named "HelloWorld" instead of "HelloWorld.Mashlet".

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Tried renaming it to "HelloWorld.Mashlet" but still no joy. I've attached the two scripts im using to see if there are any differences to the ones you are using to get it to work correctly, MainPage (loading the Sample.Weather mashlet) and Sample.Weather.

Just noticed using firebug that when the open button is pressed on the Sample.Weather mashlet the row below is highlighted within the <head> but cannot be expanded. Not sure if that gives any clues to the problem

<script type="text/javascript" src="/mashlets/loadconfig.jsp?server=local">

If there are no differences i will just have to try to go another way about it, thanks for all your help

jacktyrrell
jacktyrrell's picture
User offline. Last seen 1 year 49 weeks ago. Offline
Joined: 05/27/2009
Points: 130

Sorry please ignore the post above, Got it working correctly it was the (serverUrl: "http://localhost:8080") missing from the ema.load that was causing the problem.

Your help has been very much appreciated, i have learnt alot, thanks