I have a Grid and some options outside of the grid... my proxy is a POST Request to an ASPX page.
_store = new Ext.data.JsonStore({
proxy: new Ext.data.HttpProxy({
url: 'resultpage.aspx?initalparam=1...',
method: "POST"
}),
reader: _reader,...
What I want, it's when any of my options is selected, add that option as query string parameter (or post parameter) and made the post request.
REF: http://www.objis.com/formationextjs/lib/extjs-4.0.0/docs/api/Ext.grid.Panel.html
Note: the fallowing code DOESN'T Work is just ideas.***********
I am looking for something like:
myoption=...; //with DOM get option value
myurl = panelobj.getGrid().getStore().getProxy().getUrl();
panelobj.getGrid().getStore().getProxy().setUrl(myurl+"&myoption=" + myoption);
panelobj.Update();
or something more cool like:
Ext.create('...ON OPTION CLICK...', append("&myoption=" + myoption); submit();..)
Are you looking for this? http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Ajax-cfg-extraParams
Each proxy has an extra parameters which can be added to each request.
I see this example http://www.sencha.com/forum/showthread.php?9067-Ext.data.HttpProxy-and-extraParams. Assume that ds is datastore:
ds.proxy.getConnection().request({extraParams: { testParam2: 200 }, method: 'POST',url: ds.proxy.buildUrl()});
That make the request but in the server side I can't read testParam2. Request["testParam2"] is null
That way wasn't working for me (I use version 3) so I using params instead of extraParams http://docs.sencha.com/ext-js/3-4/#!/api/Ext.data.Connection (Form Parameter: POST)
ds.proxy.getConnection().request({params: { testParam2: 200 }, method: 'POST',url: ds.proxy.buildUrl()});
other possibility is passing by url (QueryString Parameter: GET)
ds.proxy.getConnection().request(method: 'POST',url: ds.proxy.buildUrl() + '&testParam2=200'});
//***********
Other Problem:
With the code above, I can made the request... but it's totally independent from the grid... the data that is retrieve is unhandled... how make the grid do the request????? I don't know....
//**********
Solution:
Remove previous grid and add new one with new parameters! that work for me!
Related
My initial grid is build
$("#dims_list").jqGrid({
url: "ajax_get_dims_for_grid.php",
postData: {'dims_guid': $('#dims_guid').val()},
When I refresh the grid with a new parameter the original value is sent (persists)
var dims_guid = $("#dims_guid").val(); // New value for the grid
$("#dims_list").jqGrid('setGridParam',{"dims_guid":dims_guid}).trigger('reloadGrid');
I have monitored this in the Chrome developer window and can see the new value in var dims_guid but the old value is posted to the page that retrieves the data from the database.
I have just moved from freeJQgrid to Guriddo jqGrid
I actually tried the following code
var url="ajax_get_dims_for_grid.php?dims_guid="+$("#dims_guid").val();
$("#dims_list").jqGrid('setGridParam',{"url":url}).trigger('reloadGrid');
And in Chrome the query string was duplicated with the old one taking precedence
Query String Parameters
dims_guid: 100d7c6d-bcba-4b13-8832-f9de7794498c
dims_guid: dbc02dbe-e3d8-4b7d-8389-2678221ea189
_search: false
nd: 1586531572226
rows: 20
page: 1
sidx:
sord: asc
Is this a known issue?
If a postData is used to send parameters to the server this parameter (postData) extend every time the parameters that are posted to the server if a request is made. As per documentation. This array is appended directly to the url.
The problem you have is that you do not have correctly set the new parameter when you trigger the grid. What you do is:
var dims_guid = $("#dims_guid").val(); // New value for the grid
$("#dims_list").jqGrid('setGridParam' {"dims_guid":dims_guid}).trigger('reloadGrid');
This way you append new parameter th the grid and do not have change the existing one. In order to make it correct it is needed to change this in postData like this
var dims_guid = $("#dims_guid").val(); // New value for the grid
$("#dims_list").jqGrid('setGridParam',{ "postData" : { "dims_guid":dims_guid} }).trigger('reloadGrid');
I hope you understand the difference.
Another possible solution is to not use postData (remove postData from options) , but use url only to change the parameter, like you do in your second published code. Like this:
$("#dims_list").jqGrid({
url: "ajax_get_dims_for_grid.php?dims_guid="+$("#dims_guid").val(),
and then
var url="ajax_get_dims_for_grid.php?dims_guid="+$("#dims_guid").val();
$("#dims_list").jqGrid('setGridParam',{"url":url}).trigger('reloadGrid');
I need to make a POST to a server-side API. I must send an id key into the request body to the server.
I use a Backbone model. But when I do:
myModel.set("id", somevalue)
myModel.save()
The network request that is fired is : URL/someValue [PUT]
Backbones doesn't do a POST but a PUT and appends the id to the url.
So I just want to pass an id key to the server without Backbone noticing.
From Backbone's doc:
Backbone is pre-configured to sync with a RESTful API.
[...]
The default sync handler maps CRUD to REST like so:
create → POST /collection
read → GET /collection[/id]
update → PUT /collection/id
patch → PATCH /collection/id
delete → DELETE /collection/id
A new entry doesn't have an ID, so if you give an ID to the model before saving it, Backbone defaults to a PUT request because it thinks you want to save an existing entry.
How to make a POST request with an id?
Choose one of the following solutions.
Stick to a RESTful API
This one is the obvious one. If you can, stick to the standard.
Change the API to handle PUT/PATCH requests and only use POST on creation. Make the API endpoint take the ID from the URL.
RESTful API best practices
Pass the type option1
Simple and works really well for a one-off situation.
Every options passed to save (or fetch) overrides the options the sync function defines by default and passes to jQuery.ajax function.
Backbone sync source
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
var url = model.url(); // get the url before setting the `id`
model.save({
id: somevalue
}, {
url: url, // fix the url
type: 'POST' // choose the HTTP verb
});
Fixing the url that the model uses is simple, you have also some choices:
pass the url option (like above)
override the url function of the model
Overriding the url function (source) works well for situation where every call should use a specific url, without the default id appended to it.
var MyModel = Backbone.Model.extend({
url: function() {
return _.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
}
});
Set the idAttribute on the model
This depends on what the id you're trying to pass means in the data.
Backbone Model uses "id" has the default id attribute name. You can specify a different name by overriding the idAttribute property of the model. Whatever the name, it is always automatically made available through the model.id property.
Now, assuming the id attribute isn't related to this model and this model's real id attribute name is something like UID, you could change the idAttribute of the model to reflect the real name of the attribute (or it could even be a string that's never going to be an attribute).
var MyModel = Backbone.Model.extend({
idAttribute: 'UID',
});
Now, the id attribute is not considered an id for the current model, and model.isNew() will return true, sending a POST request to create it on save.
Change the sync/save function behavior
If the API you're using is not RESTful, you can adjust the behaviors by overriding the sync function. This can be done on the model or collection, or on the Backbone.sync function which is used by default by the collections and models.
For example, if you wanted to make every request use POST by default for MyModel class:
var MyModel = Backbone.Model.extend({
sync: function(method, model, options) {
return Backbone.sync.call(this, method, model,
_.extend({ type: 'POST' }, options));
}
});
You could do something similar with only the save function to let the fetch do its GET request as usual.
Use the emulateHTTP setting2
If you want to work with a legacy web server that doesn't support
Backbone's default REST/HTTP approach, you may choose to turn on
Backbone.emulateHTTP. Setting this option will fake PUT, PATCH and
DELETE requests with a HTTP POST, setting the X-HTTP-Method-Override
header with the true method.
[...]
Backbone.emulateHTTP = true;
model.save(); // POST to "/collection/id", with "_method=PUT" + header.
Do not override isNew
Has this model been saved to the server yet? If the model does not yet
have an id, it is considered to be new.
Some other answers on this site suggest overriding the isNew function. Don't. The function has its purpose and overriding it to force a POST request is a poor hack, not a solution.
isNew is used internally but can also be used by your code or other libraries and Backbone plugins.
1 While I did not take this from stack overflow, it was already an answer by Andrés Torres Marroquín on a similar question.
2 Taken from Maanas Royy's answer.
I want to pass a parameter to my Store proxy to retrieve the right data from the server. I need to pass the parameter without the name prefix and just the value.
Instead of this kind of url :
myAppUrl/collections/units?collectionId=54
which can be done like this:
myStore.getProxy().extraParams.collectionId = 54;
I want to have a call like this:
myAppUrl/collections/54/units
My web service is adapted for both calls I just need the correct client code to pass the parameter.
Please help and advise.
An old question, but I write for anyone with this problem. I implemented the idea of #Saki in this package (for ExtJS 6) because of my own needs:
https://bitbucket.org/alfonsonishikawa/extjspackages/wiki/Server%20URL%20Placeholders
The idea is being able to use an URL like:
proxy: {
type: 'rest',
url: 'myAppUrl/collections/${collectionId}/units',
appendId: false
}
With that package, you just have to configure your proxy like above and call #load() with params:
store.load({
params: {
collectionId: 54
}
});
(getProxy().extraParams can be used as default value)
This is the source code as example that you asked #Saki about.
It looks almost like REST request but not exactly as REST places indexes at the end of url. You could solve it by implementing a custom buildUrl of Ajax or Rest proxy. In any case, see how is this method implemented in Rest proxy.
you can set your url dynamically and then call load method of store using below code.
store.getProxy().setUrl('your new url');
store.load();
but if you gonna use this method then you have to set correct url every time other-vice may be you will get wrong data.
I have an asp.net mvc 3 application with some Action Method that handles GET requests and returns a page. Code looks like this:
[HttpGet]
public ActionResult Print(IEnumerable<string> arrayOfIds)
{
.......................
return View(someModel);
}
Also there is JavaScript code, that calls this action:
window.open('#Url.Action("Print","Appointments")' + urlArray, "Print", "width=620,height=410,scrollbars=yes");
Where urlArray can be really big. How can I pass this data to the Action Method without using URL string (maybe using content of HTTP Request)? I need it because URL is so big that browsers can't work with it.
UPD: May be my explanation wasn't really clear... I solved my problem. This is JavaScript code:
$.ajax({
url: '#Url.Action("Print","Appointments")',
type: "POST",
data: { listOfIds : listOfIds },
dataType: "text",
traditional: true,
success: function (data) {
printWindow = window.open('', 'Print');
printWindow.document.write(data);
}
});
Also I changed attribute of Action Method from HttpGet to HttpPost.
I don't think your question has much to do with JavaScript. The URL limitation is a feature of HTTP GET. You need to use HTTP POST, which you can't do with window.open().
However, you can do something like this...
window.open('about:blank', 'Print', 'width=620,height=410,scrollbars=yes');
document.myForm.target='Print';
document.myForm.urlArray=urlArray;
document.myForm.submit();
This opens a new window and posts an existing HTML form (method="post") to the new window. The example above assumes a hidden field with the name "urlArray", but you just need to supply whatever your Action Method expects.
You can tidy this up quite a bit if you have an existing form on the page already that you're using to capture the urlArray, you'll just need to target the form at a new window that is created by your form's onsubmit event handler.
You'll be better off posting a form to the current page (and thus transfer everything to the server side through POST) and then use RedirectToAction and pass your data at the server side.
It's a better way to do it. You can post the form using Javascript. So rather than window.open you'll be using form.submit()
EDIT:
Add target="_blank" to your form tag to open the results in a new window.
I have an ExtJS based application. When editing an object, an ExtJS window appears with a number of tabs. Three of these tabs have Ext GridPanels, each showing a different type of data. Currently each GridPanel has it's own JsonStore, meaning four total AJAX requests to the server -- one for the javascript to create the window, and one for each of the JsonStores. Is there any way all three JsonStores could read from one AJAX call? I can easily combine all the JSON data, each one currently has a different root property.
Edit: This is Ext 2.2, not Ext 3.
The javascript object created from the JSON response is available in yourStore.reader.jsonData when the store's load event is fired. For example:
yourStore.on('load', function(firstStore) {
var data = firstStore.reader.jsonData;
otherStore.loadData(data);
thirdStore.loadData(data);
}
EDIT:
To clarify, each store would need a separate root property (which you are already doing) so they'd each get the data intended.
{
"firstRoot": [...],
"secondRoot": [...],
"thirdRoot": [...]
}
You could get the JSON directly with an AjaxRequest, and then pass it to the loadData() method of each JSONStore.
You may be able to do this using Ext.Direct, where you can make multiple requests during a single connection.
Maybe HTTP caching can help you out. Combine your json data, make sure your JsonStores are using GET, and watch Firebug to be sure the 2nd and 3rd requests are not going to the server. You may need to set a far-future expires header in that json response, which may be no good if you expect that data to change often.
Another fantastic way is to use Ext.Data.Connection() as shown below :
var conn = new Ext.data.Connection();
conn.request({
url: '/myserver/allInOneAjaxCall',
method: 'POST',
params: {
// if you wish too
},
success: function(responseObj) {
var json = Ext.decode(responseObj.responseText);
yourStore1.loadData(json.dataForStore1);
yourStore2.loadData(json.dataForStore2);
},
failure: function(responseObj) {
var message = Ext.decode(responseObj.responseText).message;
alert(message);
}
});
It worked for me.