load an html file into a panel - sencha-touch-2

I am new to sencha touch 2.0. I have an html file. I am trying to load this html file(or content) into a panel. I am simply using an ajax call but its not working. Following is the code.
This is the html file i am running in the browser.
index.html:
<script type="text/javascript" src="touch/sencha-touch-debug.js"></script>
<script type="text/javascript" src="HTMLPanel.js"></script>
<script type="text/javascript" src="app.js"></script>
this is app.js:
Ext.setup({
name : 'SampleLoad',
requires : ['HTMLPanel'],
launch : function () {
var HTMLPanel = new HTMLPanel({
scroll : 'vertical',
title : 'My HTML Panel',
url : 'sample.html'
});
}
});
and this is HTMLPanel.js:
//HTMLPanel = Ext.extend(Ext.Panel, { //gives error
var HTMLPanel = Ext.define('HTMLPanel',{
extend : 'Ext.Panel',
constructor : function( config ) {
HTMLPanel.superclass.constructor.apply(this, arguments);
// load the html file with ajax when the item is
// added to the parent container
this.on(
"activate",
function( panel, container, index ) {
if( this.url && (this.url.length > 0) )
{
Ext.Ajax.request({
url : this.url,
method : "GET",
success : function( response, request ) {
//console.log("success -- response: "+response.responseText);
panel.update(response.responseText);
},
failure : function( response, request ) {
//console.log("failed -- response: "+response.responseText);
}
});
}
},
this
)
},
url : null
});
I just want the html content to be displayed within the panel. Can someone help?

The class system has changed quite a lot in Sencha Touch 2 compared to 1.x. It is now very similar to how ExtJS 4 is. The idea behind the changes is to make it easier to understand, quicker to develop and more dynamic.
Some changes:
you should no longer use new HTMLPanel({}). Instead, use Ext.create, i.e. Ext.create('HTMLPanel', {}).
you should no longer use Ext.extend to define your custom classes. Instead, use Ext.define with an extend property.
you do not need to use HTMLPanel.superclass.constrctor.apply(this, arguments) anymore to call the parent. Instead, you can use this.callParent(arguments)
you should very rarely override constructor. This is bad practise. Instead, you should use the config block:
Ext.define('HTMLPanel', {
extend: 'Ext.Panel',
config: {
html: 'This is the html of this panel.'
}
});
Please note that configurations only go within the config block when you define a new class using Ext.define. If you are creating a new instance of a class using Ext.create, new ClassName or using an object with an xtype, configurations do not need to be within the config object.
You can find out more information about the new class system by reading this guide. There is also a great guide on how to migrate from 1.x to 2.x here.
So, lets make your code work.
index.html (nothing needs to change):
<script type="text/javascript" src="touch/sencha-touch-debug.js"></script>
<script type="text/javascript" src="HTMLPanel.js"></script>
<script type="text/javascript" src="app.js"></script>
app.js:
// You should use Ext.application, not Ext.setup
Ext.application({
name: 'SampleLoad',
requires: ['HTMLPanel'],
launch: function () {
var HTMLPanel = Ext.create('HTMLPanel', {
// this is now `scrollable`, not `scroll`
//scroll: 'vertical',
scrollable: 'vertical',
url: 'sample.html'
});
// Add the new HTMLPanel into the viewport so it is visible
Ext.Viewport.add(HTMLPanel);
}
});
HTMLPanel.js:
// You do not need to save a reference to HTMLPanel when you define your class
//var HTMLPanel = Ext.define('HTMLPanel', {
Ext.define('HTMLPanel', {
extend: 'Ext.Panel',
// We are using Ext.Ajax, so we should require it
requires: ['Ext.Ajax'],
config: {
listeners: {
activate: 'onActivate'
},
// Create a new configuration called `url` so we can specify the URL
url: null
},
onActivate: function(me, container) {
Ext.Ajax.request({
// we should use the getter for our new `url` config
url: this.getUrl(),
method: "GET",
success: function(response, request) {
// We should use the setter for the HTML config for this
me.setHtml(response.responseText);
},
failure: function(response, request) {
me.setHtml("failed -- response: " + response.responseText);
}
});
}
});
Hopefully this helps.

rdougan's answer worked for me. If it still doesn't work for you, check out this example from the Sencha Docs where they're loading .js files using AJAX a slightly different way (it would be exactly the same for .html files). To get the source, download the Sencha Touch 2 SDK and it will be under examples/nestedlist.

Related

When using the Custom HTML app, is it possible to display custom portfolio fields in a rally grid?

My goal is to display some custom porfolio fields (the field is called executive champion) in a custon HTML app using a rally grid on the dashboard. I have reviewed the docs and some examples and it does not look like this is possible. Has anyone accomplished this and how? My code is as follows. I used the following to get started https://github.com/davidpthomas/BasicRallyGrid.
<!DOCTYPE html>
<html>
<head>
<title>BasicRallyGrid</title>
<script type="text/javascript" src="/apps/2.0rc2/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function () {
// Custom Rally App that displays Stories in a grid.
//
// Note: various console debugging messages intentionally kept in the code for learning purposes
Ext.define('CustomApp', {
extend: 'Rally.app.App', // The parent class manages the app 'lifecycle' and calls launch() when ready
componentCls: 'app', // CSS styles found in app.css
// Entry Point to App
launch: function() {
console.log('our first app'); // see console api: https://developers.google.com/chrome-developer-tools/docs/console-api
this._loadData(); // we need to prefix with 'this.' so we call a method found at the app level.
},
// Get data from Rally
_loadData: function() {
var myStore = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem',
autoLoad: true, // <----- Don't forget to set this to true! heh
listeners: {
load: function(myStore, myData, success) {
console.log('got data!', myStore, myData);
this._loadGrid(myStore); // if we did NOT pass scope:this below, this line would be incorrectly trying to call _createGrid() on the store which does not exist.
},
scope: this // This tells the wsapi data store to forward pass along the app-level context into ALL listener functions
},
fetch: ['Executive Champion', 'Name', 'ScheduleState'] // Look in the WSAPI docs online to see all fields available!
});
},
// Create and Show a Grid of given stories
_loadGrid: function(myStoryStore) {
var myGrid = Ext.create('Rally.ui.grid.Grid', {
store: myStoryStore,
columnCfgs: [
'Executive Champion', 'Name', 'ScheduleState'
]
});
this.add(myGrid);
console.log('what is this?', this);
}
});
Rally.launchApp('CustomApp', {
name:"BasicRallyGrid",
parentRepos:""
});
});
</script>
<style type="text/css">
.app {
/* Add app styles here */
}
</style>
</head>
<body></body>
</html>
It is certainly possible to display PI custom field values in a grid.
Even if your custom field has a space in the DisplayName, remove the space from 'Executive Champion' in your code.
Here is an example. I have a custom field on portfolio item object that is shown in the Setup>Workspaces & Projects as follows:
Name: PiCustom
DisplayName: PiCustom
Workspace admin rights are required to see that page.
WS API references this field as c_PiCustom (with c_ prepended automatically to indicate a custom field)
In my code either one works fine:
PiCustom, c_PiCustom
If a workspace admin changes this custom field's DisplayName to include a space as follows:
Name: PiCustom
DisplayName: Pi Custom
It will still be displayed as c_PiCustom in WS API
and either one of those two ways to reference this field in my code will still work:
PiCustom,c_PiCustom
but Pi Custom will not work.
Remove the space in your code. Or check exact spelling of that field in the WS API and follow that convention.
Here is a full example using 2.0rc3:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
this.add({
xtype: 'rallygrid',
model: 'PortfolioItem/Feature',
enableRanking: true,
storeConfig: {
context: {
context: this.getContext().getDataContext()
}
},
{
dataIndex: 'FormattedID'
},{
dataIndex: 'Name',
},
{
dataIndex: 'PiCustom'
}
]
});
}
});

How to use one drive file picker in browser?

I need to integrate One Driver file picker in my website. I am using this js lib to do the task.
<script type="text/javascript" src="//js.live.net/v5.0/wl.js"></script>
The code I wrote is
WL.init({ client_id: "000000004C1xxxxx", redirect_uri: 'https://xxx.net/' });
WL.login({
scope: "wl.skydrive wl.signin"
}).then(
function(response) {
WL.fileDialog({
mode: "open",
select: "multi"
}).then(
function (response) {
},
function (responseFailed) {
}
);
},
function(response) {
log("Failed to authenticate.");
}
);
It showed the popup window, and went through the authentication process. However once I've logged in within the popup window. It just redirected to the redirect URL I provided, the file picker never showed. Any ideas?
I solved this issue by including the js script in my callback page, wl sdk will automatically handle the oauth process for you.
<script type="text/javascript" src="//js.live.net/v5.0/wl.js"></script>
It's weird as I could not find any documents related to how you should do with your callback page on MS developer website.
Can you get the "Using the open from OneDrive picker" sample working on http://isdk.dev.live.com?
Use the function below in your js file and don't forget to include :
<script type="text/javascript" src="https://js.live.net/v7.0/OneDrive.js"></script>
function launchOneDrivePicker() {
var odOptions = {
clientId: "*******************************",
action: "download",
multiSelect: true,
openInNewWindow: true,
advanced: {
queryParameters: "select=id,name,size,file,folder,photo",
redirectUri: (Eneter your default url e.g :)"http://localhost:60666/WebForm1.aspx"
},
success: function (response) { /* success handler */ },
cancel: function () { /* cancel handler */ },
error: function (e) { /* error handler */ },
};
OneDrive.open(odOptions);
}
I hope it works for everyone thanks.

Tooltipster not working in a ajax content

While searching in stack overflow .I find an old issue that i am facing too.But no one answered it.
So just wants to know anyone have any idea about it
How to get jquery Tooltipster Plugin to work for newly created DOM elements?
Following is my code
$(document).ready(function() {
$('.test_link').tooltipster({
interactive:true,
content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
continueTooltip();
// next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'POST',
url: 'example.php',
success: function(data) {
// update our tooltip content with our returned data and cache it
origin.tooltipster('content', $(data)).data('ajax', 'cached');
}
});
// }
}
});
});
My problem solved.
Just add the instantiation script in the ajax content too.
also set the option multiple:true
ie
$(document).ready(function() {
$('.test_link').tooltipster({
interactive:true,
multiple:true,
content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
continueTooltip();
// next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'POST',
url: 'example.php',
success: function(data) {
// update our tooltip content with our returned data and cache it
origin.tooltipster('content', $(data)).data('ajax', 'cached');
}
});
// }
}
});
});
It worked for me in Firefox.But didn't tested in other browser
I know this is an old post, and the problem was solved, but i recently needed something similar.
Adding the initialization on every ajax function was not a solution since we had several content dynamically loaded on the page, so the simplest solution found was:
$(document).on('mouseenter', '[data-toggle="tooltip"]', function(){
if ($(this).is('.tooltipstered')) {
// Do nothing
} else {
$(this).tooltipster({
delay: 50,
// Your other Tooltipster options
});
$(this).mouseover();
}
});
$('[data-toggle="tooltip"]') being the OP's $('.test_link').
The if deter the repeated initialization of document mouseenter.

Using a json file to store configurations for a dojo application

I am writing a fontend web app using dojo that does a lot of calls to rest endpoints using xhr. I would like to have a place to store configurations for things like endpoint locations and html tag references. I thought I would use an xhr call to a json file to do this, but I am having trouble getting my functions to trigger in the right order/at all. Below is my main js file which has an init() function that I am passing as the callback to my conf initializer ("ebs/conf") module, also below. I have used the Chrome debugger to set breakpoints within my conf.get() method, and it looks as though it never gets called.
Can someone give me some advice please?
Main JS File:
// module requirements
require([ "dojo/dom", "dojo/on", "ebs/prices", "ebs/cart", "ebs/conf",
"dojo/ready" ], function(dom, on, prices, cart, conf, ready) {
ready(function() {
conf.get("/js/config.json", init());
function init(config) {
on(dom.byId("height"), "keyup", function(event) {
prices.calculate(config);
});
on(dom.byId("width"), "keyup", function(event) {
prices.calculate(config);
});
on(dom.byId("qty"), "keyup", function(event) {
prices.calculate(config);
});
on(dom.byId("grills"), "change", function(event) {
prices.calculate(config);
});
cart.putSampleCart();
cart.load(config);
}
});
});
And here is my 'conf' module ("ebs/conf"):
define(["dojo/json", "dojo/request/xhr"], function(json, xhr) {
return {
get : function(file, callback) {
// Create config object from json config file
var config = null;
xhr(file, {
handleAs : "json"
}).then(function(config) {
callback(config);
}, function(error) {
console.error(error);
return error;
});
}
}
});
Your are not passing the function as the callback. You are executing it and passing the result as the second argument.
conf.get("/js/config.json", init());
should be
conf.get("/js/config.json", init);

MVC 4 View Knockout Bindings not updating on ajax call

I have gone through as many questions on here as I could find and tried all the different suggestions and cannot get this to work. I have a view that is bound with Knockout using the mapping plugin and it works okay but only when I do the "wrong thing". Everything that I have read says that you should only make one call to ko.applyBindings() per view and then everything should update using ko.mapping.fromJS(). I cannot seem to get this to work, the only way I have been able to get my view to refresh is to call ko.applyBindings() again in the success call back from my .ajax() call. Here is the offending code.
<script type="text/javascript">
var viewModel;
$(document).ready(function() {
$("#panelbar").kendoPanelBar({
expandMode: "multiple"
});
$.ajax({
type: 'GET',
url: '/Home/IsUserMarketingManager',
success: function (data) {
if (data == true) {
$('#submitNewCase').hide();
$('#approveCase').show();
$('#disapproveCase').show();
}
}
});
// Generate client View Model from Server View Model
viewModel = new ViewModel();
ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)),{}, viewModel);
ko.applyBindings(viewModel);
});
function ViewModel () {
var self = this;
self.addLocation = function() {
self.AdditionalLocations.push({ GaNumber: "" });
};
}
</script>
And later this to update the form with retrieved data:
<script type="text/javascript">
$('#btnImport').click(function () {
$.blockUI({ message: '<h2>Importing Client Information...</h2> <img src="/Images/ajax-loader.gif"><br />' });
$.ajax({
type: 'post',
url: '/Home/ImportClientCrmInfoJson',
dataType: "json",
data: ko.mapping.toJS(viewModel),
success: function (data) {
$.unblockUI();
if (!data.AccountNull) {
ko.mapping.fromJS(data, {}, viewModel);
} else {
alert("Could not find account for this GA Number, please try again.");
}
}
});
});
</script>
When submitting the form to my controller, all the data is there and mapped correctly to my server side View Model, but the form in the view isn't updated with the data that comes back from the $.ajax call. I've gotten the form to update if I do the following, but I know it's not the right way and has caused me other issues as well.
<script type="text/javascript">
$('#btnImport').click(function () {
$.blockUI({ message: '<h2>Importing Client Information...</h2> <img src="/Images/ajax-loader.gif"><br />' });
$.ajax({
type: 'post',
url: '/Home/ImportClientCrmInfoJson',
dataType: "json",
data: ko.mapping.toJS(viewModel),
success: function (data) {
$.unblockUI();
if (!data.AccountNull) {
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel); // This works but isn't the right way...
} else {
alert("Could not find account for this GA Number, please try again.");
}
}
});
});
</script>
Any help would be much appreciated.
Have you examined that the following line of code appears to create a 'NEW' viewmodel?
viewModel = ko.mapping.fromJS(data);
When you do this the new viewModel the old bindings are destroyed. This is why you have to call ApplyBindings again. Anyway, I think the above line of code is the root of the problem.
Is there a way for you to create an observable property on the viewModel and allow the viewModel to reflect the data in this object? That may be a more practical approach to the update process.
In the success callback of the ajax call, use this method ko.applyBindings(viewModel) but pass as a second parameter the DOM portion you want to update as follows
ko.applyBindings(viewModel, $("#mydiv")[0])
Don't use a jquery object but a REAL DOM object.