Jump to content

Load a 2nd page into a div from within Plugin


mickle026

Recommended Posts

mickle026

I have a problem that is probably a simple answer, I have added a second page to my plugin as an embeded resource. (my page is embeded I can load it seperately by adding EnableInMainMenu = true then clicking it, so thats not the problem.)

 

What I have done so far:
 

I have given my content-primary  a div id called PageHolder

<div class="content-primary" id="PageHolder">

I have added an event listener to my plugin config page.

page.querySelector('#settingsButton').addEventListener('click', () => {  ShowBackupPage();  })

and a function to my javascript

    
        function ShowBackupPage()
        {
            console.log("ShowBackup function triggered")
            //Get the Url of the current page from the server
            var newpage = document.createElement('a');
            newpage = window.location.href;
            console.log("Old Page: "+ window.location.href)
            //Build New Url - Replace the page page
            newpage = newpage.replace("MyPosterServer", "MyPosterServerBackup");
            console.log("New Page: "+newpage)
            var logfunc = $("settingsButton").click(function () { $('PageHolder').load(newpage) });
            console.log(logfunc)
        };

The web console F12 shows my debug.log text so I can tell the event listener has triggered and the ShowBackupPage function is entered, but the div is not loaded or replaced by the load event.

 

I am left wondering if the url needs to be different as the function logs this, as I am still learning javascript its a total guess, but I think there is nothing to load as the length is 0. Im understanding the 0 as a false.

Object { length: 0, prevObject: {…} }

and it shows the previous document as 1.

prevObject: {…}
​​
0: HTMLDocument http://localhost:8096/web/index.html#!/configurationpage?name=MyPosterServer
​​
length: 1

My Console log from my function

pageshow triggered index.html:7:21
ShowBackup function triggered index.html:73:21
Old Page: http://localhost:8096/web/index.html#!/configurationpage?name=MyPosterServer index.html:77:21
New Page: http://localhost:8096/web/index.html#!/configurationpage?name=MyPosterServerBackup index.html:80:21
{…}
​
length: 0
​
prevObject: {…}

I have tried

web/index.html#!/configurationpage?name=MyPosterServerBackup

because that works from an ordinary button  like this, but it reloads the emby and the plugin and contents dont behave like they are from it.

 <button is="emby-button" style="width: 30%; height: 10%;" onclick="window.location.href = '/web/index.html#!/configurationpage?name=MyPosterServerBackup';" class="raised button-submit block"><span>Backup Page</span></button>

So i am thinking maybe the load event needs the url to be different somehow, and if it does how would what would it need to be?

 

Can anyone advise ??

 

Many thanks

 

 

Link to comment
Share on other sites

mickle026

I would take a look at AutoOrganize:

https://github.com/MediaBrowser/Emby.AutoOrganize

 

It has multiple pages so it can give you examples of how to link between the two.

I have been looking at this for ages but its as confusing as f*.... LOL

 

I tried to build tabs, I cannot get that to work just yet.

I tried adding the data controller to seperate the javascript but get pages that load on top of other pages like transparent film.

 

Im just not there yet in my understanding ... :(

Edited by mickle026
Link to comment
Share on other sites

chef

Hi again @@mickle026 :)

 

One of the best plugins to see how tabs work in a configuration webpage definitely has to be the playback_reporting plugin here: https://github.com/faush01/playback_reporting/blob/develop/playback_reporting/Pages/activity_report.html

 

here are a couple things that might help

<div data-role="page" class="page type-interior pluginConfigurationPage withTabs"
	 data-require="emby-button,emby-select,emby-checkbox,emby-linkbutton"
	 data-controller="__plugin/YOUR_PLUGIN_EMBEEDED_JAVASCRIPTFILE_NAME.js">

</div>

most importantly 'withTabs' being part of the classList. this will help emby know that you intend on having tabs and it will style the header appropriately.

 

 

Next inside the javascript we'll want to make sure we define the 'mainTabsManager' javascript file to use:

define(['mainTabsManager'], function (mainTabsManager) { 
//
});

Inside our 'viewshow' event callback we want to utilize the 'mainTabsManager' object to manage our tabs when the page loads up

mainTabsManager.setTabs(this, getTabIndex("activity_report"), getTabs);

Note: The developer has uses two functions which he loads from a helper.js file which is side loaded. This can get a little confusing, so in order to keep it simple these are the two functions he has written which are important:

function getTabs() {
    var tabs = [
        {
            href: Dashboard.getConfigurationPageUrl('activity_report'),
            name: 'Active'
        },
        {
            href: Dashboard.getConfigurationPageUrl('resource_usage'),
            name: 'Resources'
        },
        {
            href: Dashboard.getConfigurationPageUrl('user_playback_report'),
            name: 'Playback'
        },
        {
            href: Dashboard.getConfigurationPageUrl('user_report'),
            name: 'Users'
        },
        {
            href: Dashboard.getConfigurationPageUrl('user_play_report'),
            name: 'Summary'
        },
        {
            href: Dashboard.getConfigurationPageUrl('breakdown_report'),
            name: 'Breakdown'
        },
        {
            href: Dashboard.getConfigurationPageUrl('hourly_usage_report'),
            name: 'Time'
        },
        {
            href: Dashboard.getConfigurationPageUrl('duration_histogram_report'),
            name: 'Duration'
        },
        {
            href: Dashboard.getConfigurationPageUrl('custom_query'),
            name: 'Query'
        },
        {
            href: Dashboard.getConfigurationPageUrl('playback_report_settings'),
            name: 'Settings'
        }];
    return tabs;
}

Which returns all the tabs that will show at the top of the screen.

 

and also:

function getTabIndex(tab_name) {
    var tabs = getTabs();
    var index = 0;
    for (index = 0; index < tabs.length; ++index) {
        var path = tabs[index].href;
        if (path.endsWith2("=" + tab_name)) {
            return index;
        }
    }
    return -1;
}

which is super confusing, but allows him to choose the tab by name... ... ... you still with me?  :huh:

getTabIndex("activity_report")

get the tab index out of the array of tabs by name.

 

 

 

You are correct Tabs can be confusing as f***, and I'm afraid I might have made things worse for you.

 

 

 

 

 

To be completely honest, I have stayed away from tabs and used dialogs (the 'dialogHelper' object)  in order to organize the UI. This way I can open a dialog with ui elements in it, save the configuration data, and close them out.

 

Here are some Github examples:

 

Phillips Hue: https://github.com/chefbennyj1/Emby.PhillipsHue

uTorrent: https://github.com/chefbennyj1/Emby.uTorrent

 

 

Please don't hesitate to ask more questions.

Edited by chef
Link to comment
Share on other sites

mickle026

@@chef thank you very much, I will definately look at that.

 

I simply wantred a button click that loaded a page, it couldn't be that easy could it - I think I could become a professional web page builder before finishing a plugin for Emby!.  I spent like a day getting nowhere already.

 

I say getting nowhere I have more understanding of javascript so its not totally wasted.

 

The bit I seem to understand is that this bit of code puts the all under the same umberella

class="page type-interior pluginConfigurationPage withTabs"

So all pages belong to the same group

pluginConfigurationPage 

and you can give them MainPage a name

class="page type-interior MainPage pluginConfigurationPage withTabs"

But I cannot get them to show, with tabs at all.

I have tried to use this many times now, but i keep getting pages overlay other pages like a transparency, so i am definately doing something wrong.

data-controller="__plugin/MyPage.js">

The pages just overwrite the page underneath, and its not just mine it causes emby menus to do it aswell.

 

Im going to go away and try and consume the linked code you just gave me.  Wish me luck.

 

Thank you :D:huh:
 

Link to comment
Share on other sites

mickle026

I was looking at the DNLA code on the older mediabrowser

 

Settings tab html

<div id="dlnaSettingsPage" data-role="page" class="page type-interior withTabs" data-require="scripts/dlnasettings,emby-select,emby-input,emby-checkbox,emby-button">

Profile Tab Html

<div id="dlnaProfilesPage" data-role="page" class="page type-interior dlnaPage withTabs" data-require="scripts/dlnaprofiles,emby-button">

And noted that the tabs did not all follow suit.

 

the getTabs functions differ too, but they show how to load data from the drive or via the api.

    function getTabs() {
        return [{
            href: "dlnasettings.html",
            name: Globalize.translate("TabSettings")
        }, {
            href: "dlnaprofiles.html",
            name: Globalize.translate("TabProfiles")
        }]
    }
    $(document).on("pageinit", "#dlnaSettingsPage", function() {
        $(".dlnaSettingsForm").off("submit", onSubmit).on("submit", onSubmit)
    }).on("pageshow", "#dlnaSettingsPage", function() {
        libraryMenu.setTabs("dlna", 0, getTabs), loading.show();
        var page = this,
            promise1 = ApiClient.getNamedConfiguration("dlna"),
            promise2 = ApiClient.getUsers();
        Promise.all([promise1, promise2]).then(function(responses) {
            loadPage(page, responses[0], responses[1])
        })
    })
    function getTabs() {
        return [{
            href: "dlnasettings.html",
            name: globalize.translate("TabSettings")
        }, {
            href: "dlnaprofiles.html",
            name: globalize.translate("TabProfiles")
        }]
    }
    $(document).on("pageshow", "#dlnaProfilesPage", function() {
        libraryMenu.setTabs("dlna", 1, getTabs), loadProfiles(this)
    })

I am currently trying to understand the javascript define followed by a function.  It appears to be an array of includes (like php) followed by which functions will be referenced.

define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby-linkbutton"], function($, globalize, loading, libraryMenu) {
    "use strict";

My Brain Hurts !!  LOL  :(

Edited by mickle026
Link to comment
Share on other sites

chef

With regards to your understanding of the 'define' keyword. You are correct.

 

It is a library called 'require.js', and also it is fairly common in 'node.js'

 

An example:

 

(["loading"],

 

Refers to the file "loading.js" in the project. It infers the JS extension. So it loads "loading" as a module to use on that particular page of your webapp/plugin page.

 

The next part:

 

function(loading){});

 

Puts all the modules functions into an object we can utilize on the page.

 

 

For instance, the loading.js module file has a function called 'show()'.

 

Once we add loading into the define function, and give the module the name 'loading', we can now call 'loading.show()' in our plugin js.

 

 

I pretty sure that it is the 'mainTabsManager' that will handle showing and hiding tabs.

Edited by chef
Link to comment
Share on other sites

mickle026

With regards to your understanding of the 'define' keyword. You are correct.

 

It is a library called 'require.js', and also it is fairly common in 'node.js'

 

An example:

 

(["loading"],

 

Refers to the file "loading.js" in the project. It infers the JS extension. So it loads "loading" as a module to use on that particular page of your webapp/plugin page.

 

The next part:

 

function(loading){});

 

Puts all the modules functions into an object we can utilize on the page.

 

 

For instance, the loading.js module file has a function called 'show()'.

 

Once we add loading into the define function, and give the module the name 'loading', we can now call 'loading.show()' in our plugin js.

 

 

I pretty sure that it is the 'mainTabsManager' that will handle showing and hiding tabs.

Thanks again @@chef :D, in your debt again!

 

I have made an empty plugin to try to get tabs working and now I know how they work and have a template project for them with just the bare essentials :).  If you want it I'd be happy to send you it.

 

5e8a437d973dc_Untitled.png

 

One thing I will say though, is every Tab or Loaded Resource name cannot be the same as another plugin or else it plays havoc with all the server pages.  So if you use the template you have to rename the lot!

Edited by mickle026
Link to comment
Share on other sites

chef

Sure thing. Did you want to zip it up and pm me?

 

I've got an entire day of sitting in an empty restaurant tomorrow to see what I can do.

Link to comment
Share on other sites

mickle026

Sure thing. Did you want to zip it up and pm me?

 

I've got an entire day of sitting in an empty restaurant tomorrow to see what I can do.

Sent via pm.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...