Using Ext-JS 4.1 with Spring 3.1 Controllers.
I am trying to retrieve an object from my Spring Controller using the load() method. I read a string from a text field and send that into the load method. The string field will contain a fully qualified server name such as "company.server.com". What's happening is that the value within the Spring controllers is "company.server", in other words it drops the ".com". It I put in an additional period at the end such as "company.server.com." then it comes in properly as "company.server.com". There seems to be some sort of tokenizing going on. I used commas (,) just to see what would happen. Using commas the string came in as expected. For some reason periods (.) is causing the issue.
Here is the Model:
Ext.define('AB.model.Server', {
extend: 'Ext.data.Model',
fields: [
{name:'serverName', type:'String'},
{name:'memory', type:'String'},
{name:'cpus', type:'int'}
],
proxy {
type: 'rest',
url: '/web/user/'
}
});
Here is a snippet from the form which makes the load() call:
Ext.define('AB.view.Form', {
extend: 'Ext.form.Panel',
....
,{
xtype: 'button',
text: 'Retrieve Information',
handler: function() {
Ext.ModelManager.getModel('AB.model.User').load(Ext.getCmp('serverName').getValue(), {
success: function(user) {
alert("Success");
}
....
}
Using Firebug I see this as the URL being called:
http://myServer/web/user/company.server.com?_dc=13461612333647?id=company.server.com
So the URL has the correct server name but on the Spring Controller side the value of my parameter is "company.server".
When I directly put the following URL directly in my web browser:
http://myServer/web/user/company.server.com/
it works properly with the parameter in the Spring Controller being "company.server.com".
Is this an EXT JS problem? Is a problem with EXT JS to Spring? I don't think it is a Spring issue alone since the URL directly in the browser works properly.
UPDATE:
When I put the following URL directly in my web browser:
http://myServer/web/user/company.server.com
it behaves the same as the EXT JS Rest call. Notice there is no ending slash (/). So maybe this is a Spring issue? Or maybe a web.xml issue?
Related
I am learning ExtJS framework, for experiments I use on front-end side ExtJS and on back-end side JavaEE Spring framework (it is configured like as REST service). So, I start my front-end part on localhost:1841 and back-end part on localhost:8080. Question is:
How I can say to ExtJS.Store that requests need to send to
localhost:8080/** instead of localhost:1841/**?
Sorry for my English!
In ExtJS have singleton you can use this class.
Singleton pattern is a design pattern which restricts instantiation of a class to only one object. This is useful when exactly one object is needed across the system. The Singleton pattern provides a single point of access to a particular instance. Implementation of a singleton pattern must satisfy the single instance and global access principles.
For this "How I can say to ExtJS.Store that requests need to send to localhost:8080/** instead of localhost:1841/**?"
You can use in your app like below code :
Firstly create singletone class
/*
* Create singletone class in your application
* This class you can access in your application anywhere you want within the app.
* Usage:
* commonUtility.getServerUrl();// whatever property you have defined inside of config you can access like this
*/
Ext.define('APPNAME.utils.SingleToneClassName', {
alternateClassName: 'commonUtility',
singleton: true,
config: {
/*
* you can put local or live also or whatever you want.
* for local it will be ip address like this {'http://192.168.30.83:8080/'}
* for live is will be live tomcate host url {http://example.com/}
*/
serverURL: 'http://192.168.30.83:8080/'
},
constructor: function(config) {
var me = this;
me.initConfig(config);
},
});
Create/Define your store
//Your store
Ext.define('APPNAME.store.StoreName', {
extend: 'Ext.data.Store',
fields: ['your fields here'],
storeId: 'storeIdHere',
alias: "store.storeAliasHere",
proxy: {
type: 'ajax',
url: commonUtility.getServerUrl() + 'your Server Method name here', //Based on your server URL acceptance
withCredentials: true,
reader: {
type: 'json',
rootProperty: 'data',
keepRawData: true
}
},
autoLoad: true, //If you need auto load then put true otherwise false
listeners: {
beforeload: function(store, operation, options) {
//If you have token based authenthication then you need to put like below
store.getProxy().setHeaders({
"x-auth-token": 'your token here'
});
//If you have need to pass some parameter in API method then you can pass like below
store.getProxy().extraParams.your_parameter_name = 'value';
}
},
});
//If you want to load your store on some event or any other functions
//then
Ext.getStore('your_storeId_herer').load({
url: commonUtility.getServerUrl() + 'your Server Method name here', //Based on your server URL acceptance
params: {
//If you have need to pass some params in server side then
//you put here like
name: 'value'
}
});
I hope this will help you. for more details you can refer ExtJS6.x Docs
I am new to ExtJS and I am a Flex Developer. I am trying to do a mockup of a page we have in our Flex App. I am trying to do a basic service call to hit our servers (on same domain as the ExtJS App) and add the data into Store, which will then be populated into our dataGrid.
I did the tutorial online, but now I am trying to modify it to use my services from our Flex App. I am able to make the service call, and get a success response; However, it looks like the response is what you get when you paste the URL in your browser (this is a WSDL).
It is not hitting the actual method in the service, and returning data. I did do a simple soapclient.js JS project and was able to get data using that tool, but I do not get data back using Ajax. I think I am doing something simple wrong, but cannot figure it out.
Ext.define('DG.store.PhoneCalls', {
extend: 'Ext.data.Store',
model: 'DG.model.PhoneCall',
autoLoad: true,
proxy: {
type: "ajax",
dataType: 'xml',
contentType: 'text/xml; charset=utf-8',
data: '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Header> <ns0:HeaderID xmlns:ns0="http://urlgoeshere.com/"> <ns0:string>thisisastring</ns0:string> </ns0:HeaderID> </SOAP-ENV:Header> <SOAP-ENV:Body> <tns:getRecaPayments xmlns:tns="http://urlgoeshere.com/"> <arg0>false</arg0> </tns:getRecaPayments> </SOAP-ENV:Body></SOAP-ENV:Envelope>',
url: "https://urlgoeshere.com.com/Payments_UISupport_HTTPRouter/RecaCompFacadeService/RecaCompFacadeService.wsdl",
reader: {
type: 'xml',
root: 'return',
record: 'contents'
},
afterRequest:function(req, res) {
console.log("Result: " + req.operation.response);
}
}
});
When I debug, this is not hitting the method for this service. It returns the entire WSDL response that shows all of the methods available for that service.
In Flex, I have no issue. This app is on the same domain, so that is not the issue. I tried using soap in ExtJS and it didn't work either. I am sure it is a user error here! =)
All I need to do is:
Call this service: https://urlgoeshere.com.com/Payments_UISupport_HTTPRouter/RecaCompFacadeService/RecaCompFacadeService.wsdl
Pass in a false boolean
Hit this method within that service: getRecaPayments
This service returns a bunch of data like this:
<return>
<contents>
<name>Joe</name>
<ssn>111112222</ssn>
</contents>
<contents>
<name>Bob</name>
<ssn>222342222</ssn>
</contents>
<contents>
<name>Jan</name>
<ssn>555443333</ssn>
</contents>
</return>
Here is my model PhoneCall:
Ext.define('DG.model.PhoneCall', {
extend: 'Ext.data.Model',
fields: ['name', 'ssn']
});
Just did some research - and found the two required SOAP classes within the docs.
These files are indeed not contained within the src/data/soap directory...
http://docs.sencha.com/extjs/4.2.2/source/Proxy3.html
http://docs.sencha.com/extjs/4.2.2/source/Reader3.html#Ext-data-soap-Reader
Here it's explained in detail, better than I ever could:
http://docs.sencha.com/extjs/4.2.2/#/guide/soap
I have seen questions slightly related to this, but none that answer my problem. I have set up an Ext.Ajax.request as follows:
var paramsStringVar = 'param1=1¶m2=two¶m3=something¶m4=etc';
Ext.Ajax.request({
url: '/cgi-bin/url.pl',
method:'POST',
params:paramsStringVar,
timeout:120000,
success: function(response, opts){
var objhtml = response.responseText; //content returned from server side
console.log(objhtml);
}
});
This request retrieves the appropriate content from the backend. One parameter is outputType, which can take values {html, excel, csv}. When returning html to display I am able to handle and display it correctly. Now on to the problem...
When I set the outputType parameter to csv or excel, I get back the appropriate content as csv or tsv(excel) as requested. BUT, I don't want the content, I want a prompt to download the file(csv or excel). How can I have the browser auto prompt the user to download the file instead of just retrieving the text content within extjs?
Version 4.07 so I can't use any 4.1 only features
There seems to be no bulletproof solution but there are several approaches I would try:
1) Use an iframe instead of real XHR to POST data to the server, e.g. <form action="/something" target="myiframe"> where myiframe is the name of your hidden iframe. That way your form would use the iframe (not your main window) to submit data to the configured URL. Your server should set response header as application/octet-stream (or some ither MIME type for binary data) so the browser triggers download. Otherwise (if html returned in your case) you can just retrieve iframe's body innerHTML and display it to the user in UI. While using an iframe (or a new window) instead of XHR doesn't sound like the best idea, this solution seems to be the most reliable so far (and with best browser support).
Here is a slightly modified example from Ext.form.Basic docs page:
Ext.create('Ext.form.Panel', {
title: 'Basic Form',
renderTo: Ext.getBody(),
width: 350,
// Any configuration items here will be automatically passed along to
// the Ext.form.Basic instance when it gets created.
// *THIS* makes the form use a standard submit mechanism, not XHR
/**/standardSubmit: true,
// URL to submit to
url: 'save-form.php',
items: [{
fieldLabel: 'Field',
xtype: 'textfield',
name: 'theField'
}],
buttons: [{
text: 'Submit',
handler: function() {
// The getForm() method returns the Ext.form.Basic instance:
var form = this.up('form').getForm();
if (form.isValid()) {
// Submit the Ajax request and handle the response
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
},
// You can put the name of your iframe here instead of _blank
// this parameter makes its way to Ext.form.Basic.doAction()
// and further leads to creation of StandardSubmit action instance
/**/ target: '_blank'
});
}
}
}]
});
There are two key parameters here (lines marked with /**/):
standardSubmit: true config that you pass to your form will make it do a standard submit instead of XHR.
Passing a target parameter to the form's submit action. This feature is not documented but you can see it being used in Ext.form.action.Submit source code (all options that you pass to Ext.form.Basic.submit() method end up as parameters of Ext.form.action.* instance.
In the example code I put target: '_blank' to demonstrate that it works right away (will create a new browser window). You can replace it with the name of your iframe later but I suggest that you first test how your form submits data to a regular new window and then develop logic that creates and processes an iframe. You will have to process the result inside iframe yourself, thought. It's not that difficult, see Ext.data.Connection.upload() implementation as an example of iframe processing.
ExtJS actually already uses the iframe technique for file uploads. See Ext.data.Connection and Ext.form.field.Field.isFileUpload() for an idea of how it can work.
2) Suggested here: Using HTML5/Javascript to generate and save a file.
If you don't want to go the iframe way, you can try generate data URI from response data and navigate to that URI triggering download:
content = "Hello world!";
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
window.location.href = uriContent;
Again, mimetype is essential here. This worked for me, you should note, however, that browsers impose a size limit to data URIs (256Kb is a safe bet).
3) Another answer in the mentioned thread links to FileSaver.js library the implements the (abandoned?) w3 spec. Usage and demo here. It uses [BlobBuilder] to generate a blob of binary data that is further used to initialize downloads using one of several methods. While this solution seems to work, it uses deprecated APIs and may not be future-proof.
Below is my solution. This is how I have it currently working. The response generates a download/open prompt, based on a response type of text/csv. Note that no iFrame or reference to an iframe are needed. I spent a lot of time hung up on the need for an iFrame, which actually broke my solution. An iFrame is not needed to generate a download prompt. What is needed is a request(submittal) similar to this one, along with a backend generating the appropriate csv with text/csv response header.
var hiddenForm = Ext.create('Ext.form.Panel', {
title:'hiddenForm',
standardSubmit: true,
url: /cgi-bin/url.pl
timeout: 120000,
height:0,
width: 0,
hidden:true,
items:[
{xtype:'hiddenField', name:'field1', value:'field1Value'},
// additional fields
]
})
hiddenForm.getForm().submit()
The standardSubmit line is vital
You don't need to create a form panel and make it hidden in your extjs file. We can add a html form and on click of button in extjs file we can submit the form using the url. This will work both in IE as well as chrome browsers. Below is my code i tried and its working fine,
<form action="<%=fullURL%>/DownloadServlet.do" method="get" id="downloadForm" name="downloadForm" target="_self">
</form>
click:
{
fn: function()
{
document.getElementById('downloadForm').submit();
}
}
To get it working on ExtJS 3.4:
var hiddenForm = new Ext.FormPanel({
id:'hiddenForm',
region: 'south',
method: 'POST',
url: "/cgi/test.wsgi",
height: 0,
standardSubmit: true,
hidden:true,
items:[
{xtype:'hidden', name:'p', value:p},
{xtype:'hidden', name:'g', value:g},
// ...
],
});
linkThis = new Ext.Button({
text: 'Download this CSV',
handler: function() {
hiddenForm.getForm().submit();
},
maxHeight: 30,
});
Remember that in order to make it working, you should put the hiddenForm in any container (i.e. in the same Ext.Window of the button), for example:
risultatiWindow = new Ext.Window({
title: 'CSV Export',
height: 400,
width: 500,
....
items: [...., hiddenForm]
});
I want to load the form fields using json data.
I am using extjs 4.1 for ui and asp.net webapi to fetch the data.
My objective is to load the data and bind it to the field dynamically which form.load is used for if the name of field corresponds to the data.fieldnameproperty.
i have taken the below link as reference :
Ext JS: FormPanel not populating fields with JSON data
It loads the data if the Webapi is on the same project :
i.e.
projectname:
--ui folder
-- webapi controller folder
but in my case the data is coming from different domain 2 different project for ui and webapi. My form.load code is as below
formCmp.getForm().load({
url: 'http://localhost/WebApiCore/api/Values/',
method: 'GET',
headers: {'Content-type': 'application/json'},
// params: {
// empId: '111'
// },
success: function (form, action) {
console.log(action.result);
//Ext.Msg.alert("Load success", action.result);
},
failure: function (form, action) {
//Ext.Msg.alert("Load failed", action.result.errorMessage);
}
});
I get the error as "NetworkError: 405 Method Not Allowed - "http://localhost/WebApiCore/api/Values/?_dc=1340261175475" in firebug.
my project is running on "http://localhost:54118/PreHospital.htm"
I am not sure is it the problem of extjs not sending the cross domain request using form.load or the problem with webapi doesn't allow cross domain request.
I am not sure how to set extjs to send the jsonp request using form.load.
any kind of help is appreciated.
If you just have regular form fields on your Ext Form, it will actually do an AJAX call to submit this data. I don't think there is a way to force a form.load to do a JSONP request. You will probably need to do a manual JSONP request like you would a manual AJAX request.
Ext.data.JsonP.request({
url : websiteURL,
scope : this,
params : {
empId: '111'
},
success : function(jsonData) {
},
failure : function(jsonData) {
Ext.Msg.show({
title : 'Warning',
msg : message,
buttons : Ext.Msg.OK,
icon : Ext.Msg.WARNING
});
}
});
I am using this to get the result from server
controller.allVisitStore = new Ext.data.Store({
model: 'allVisit',
autoLoad : true,
proxy: {
type: 'ajax',
id: 'allvisit_app_localstore',
url: '/RadMobApp/api',
extraParams:{
action:'query',
queryName:'GET_ALL_VISIT',
authToken: localStorage.getItem("auth_token"),
patTicketId: localStorage.getItem("patientId"),
retFormat:'XML',
keyValuePair:'yes'
},
// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "T4" tag
record: 'data'
})
}
});
but i am not getting any thing.But i formed this url in browser and checked this i got the correct result. now here i want to check is there any problem in the url formation.How to check the url formation with extra parameter which is pass through ajax. I have checked in Inspect element-> network -> api there is no any api request found there.Is anything wrong in my code. Thanks in advance...
Use Firebug for Firefox or Chrome's developer tools to see what's going on when that store attempts to load itself. My hunch is that your url is incorrect and should be url: '/api' because RadMobApp is probably your app root.