AJAX request parameters for JSON store. ExtJS - ajax

I want to string together some parameters into an address where I can view an AJAX request in browser... I think this is what I mean, though I am not comfortable talking about AJAX. I am only a novice front-end web application programmer.
So to start, I have an ExtJS application with a combobox. It is populated by items in a JSON file, from what I can tell. Here is the application code snippet:
items: [{
xtype : 'combobox',
queryMode : 'remote',
fieldLabel: 'twittersearch',
typeAhead : true,
allowBlank : applicationtype === 'relatedanalysis' ? true : false,
hideTrigger : false,
editable : false,
multiSelect : true,
minChars : 1,
store : 'smcc.TwitterSearch',
displayField : 'id',
name : 'twittersearch',
listConfig: {
getInnerTpl: function() {
return '<div><img src="../media/com_concilium/images/twitter/{sn}-logo-med.png" />{id}</div>';
}
}
}
So I understand how store's work in the extJS MVC setup. Documentation here: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.field.ComboBox-cfg-store
So I searched 'twittersearch' at the root of my all component files with windows explorer to find the proper twittersearch.js store file. Here it is:
Ext.define('Container.store.smcc.TwitterSearch', {
extend : 'Ext.data.Store',
model : 'Container.model.smcc.TwitterSearch',
autoLoad : false,
proxy : {
type : 'ajax',
url : './',
extraParams : {
option : 'com_concilium',
view : 'smcc',
format : 'raw',
controller : 'smcc',
task : 'getSocalMediaStream'
},
reader : {
type : 'json',
root : 'rows',
totalProperty: 'row_count'
}
},
});
So is this enough information to create an address and perhaps look at the data? I assume it is something like urlbase/index.php?option=com_concilium&view=smcc&format=raw&controller=smcc&task=getSocialMediaStream

You should be able to create the store
var store = Ext.create('Container.store.smcc.TwitterSearch');
and then call
store.load();
If you use Chrome browser, you should see the network request in the Chrome Developer Tools network panel.
https://developers.google.com/chrome-developer-tools/docs/network
I would recommend trying to replicate the sencha examples, using jsfiddle.net, which lets you "fiddle" with the code easily.

Related

Filter param value(name value) is not sending in Ajax call

Filter parameter value i.e name value is not included when i was performing filter operation in my API call as written below
_dc:1427270031651
counrtyId:2
custId:1
id:
name:
page:1
start:0
limit:10
sort:[{"property" : "id", "direction" : "desc"}]
This is my store
Ext.define('MyDesktop.store.DirectoriesStore', {
extend: 'Ext.data.Store',
requires:'MyDesktop.model.DirectoriesNumberModel',
model: 'MyDesktop.model.DirectoriesModel',
storeId:'DirectoriesStore',
autoLoad : {
params : {
start : 0,
limit : '10'
}
},
pageSize : 10,
remoteSort : true,
sorters : [{
property : 'id',
direction : 'desc'
}],
remoteFilter : true,
proxy:{
type:'ajax',
url:'./configuration/directory/get',
reader:{
type: 'json',
root: 'data',
totalProperty: 'total'
},
extraParams: {
'countryId': '',
'custId': ''
}
},
autoLoad:false
});
and this is my view
Ext.require([
'Ext.ux.grid.FiltersFeature'
]);
var filters = {
ftype: 'filters',
local: true,
features: [{type: 'integer',dataIndex: 'name'},
{type: 'string',dataIndex: 'description'},
{type: 'string',dataIndex: 'fileName'}]
};
and I added it grid as follows:
features: [filters],
Filters are working but In API call filters are not calling
Please anyone help me.
You have remote filtering disabled in your store.
Change remoteFilter: false to remoteFilter: true and try again.
From the docs:
remoteFilter : Boolean
true to defer any filtering operation to the server. If false,
filtering is done locally on the client.
It also appears that your specifically telling your application to apply the filters locally with the local:true config.
The problem is, the params are not being sent to the ajax call. But hey, try changing the page after you loaded your store. Then try sorting again. You will see that the params are now being sent along in the Ajax request.
My current workaround is to imitate a changepage via gridStore.loadPage(page, [options]). You should also change it back to first page again after that.
After you change the page, sort will be working for all following requests.
This of course is just a workaround and we may have different requirements. My grid is calling store.load() after render so I attached the change page there.
Hope you have some hints.
NOTE: THIS IS ONLY A WORKAROUND!

ajax Preloader is not working in chrome,safari while working in firefox

I have a problem in "Ajax Loader image". On Firefox it is working fine but on chrome that ajax loader image does not seems.
I have a some attributes on sidebar when I check any attribute Products changes according with it and a Preloader image generated before ajax completed.What I am doing is when I check on any attribute first I insert a gif image in div html and show it using .show() method and after success of ajax I set div html null and hide it.
You can see that div in firebug (<div id="ajax_loader_div" style="display:none;"></div>)
Code is really complicated that's why I am not posting code here.Really very Sorry for that.You can see it on http://vcompare4u.com/wpcompare/products/laptops/
I need help.Please
Thanks!!!
I've seen your code
It is well known a synchronous requests will lock the UI. So not surprisingly on chrome and safari, (it does in Firefox interestingly)
can you try something like this
jQuery('#customtag_widget-2 .compare_attribute').bind('change',
jQuery.filterProductsCompare2 = function () {
$.ajaxSetup({async:false});
jQuery('#ajax_loader_div').css('display', 'block');
jQuery('#ajax_loader_div').html('<img src="http://vcompare4u.com/wpcompare/wp-content/themes/compare/_assets/img/ajax-loader.gif" / >');
jQuery('#customtag_widget-2 .compare_attribute_group').each(function () {
jQuery(this).children().each(function () {
if (jQuery(this).children('.compare_attribute').attr('checked')) {
if (jQuery(this).children('.compare_attribute').attr('name').indexOf('b[') != -1) {
brands.push(jQuery(this).children('.compare_attribute').attr('value'));
}
if (jQuery(this).children('.compare_attribute').attr('name').indexOf('c[') != -1) {
categories.push(jQuery(this).children('.compare_attribute').attr('value'));
}
}
})
} else {
minmaxarr = jQuery(this).attr('value').split(';');
minPrice = minmaxarr[0];
maxPrice = minmaxarr[1];
}
if (!jQuery.support.placeholder) {
if (isEmptyPlaceholder == 1) {
jQuery(this).val('Search...');
}
}
})
if (jQuery('#dont_change_price').is(':checked')) {
minPrice = jQuery('#overall_min').val();
maxPrice = jQuery('#overall_max').val();
} else {}
jQuery.ajax({
url : file_url,
data : {
ajaxsearch : '1',
s : 'compare',
ki : keywords_comparei,
product : '',
c : categories,
b : brands,
checked_id : checked_string,
dont_change_price : dont_change_price,
min : minPrice,
max : maxPrice,
product_category : product_category
},
success : function (data) {
// Do stuff here
}
});
jQuery.ajax({
url : bracket_file_url,
data : {
ajaxsearch : '1',
s : 'compare',
ki : keywords_comparei,
product : '',
c : categories,
b : brands,
checked_id : checked_string,
min : minPrice,
max : maxPrice,
product_category : product_category
},
success : function (bracket_data) {
// DO stuff here
}
});
if (!jQuery('#dont_change_price').is(':checked')) {
jQuery.ajax({
url : price_file_url,
data : {
ajaxsearch : '1',
s : 'compare',
ki : keywords_comparei,
product : '',
c : categories,
b : brands,
checked_id : checked_string,
min : minPrice,
max : maxPrice,
product_category : product_category
},
success : function (price_data) {
// DO stuff here
}
});
}
jQuery('#ajax_loader_div').hide();
jQuery('#ajax_loader_div').html('');
$.ajaxSetup({async:true});
});
What I am trying to do is to do synchronous request for each ajax request and instead of using success functions I am using ajax request separately. Due to synchronous nature each request will be processed one after another.
Inspecting your code in chrome console I've seen ajax loader for very little moment get hided immediately.
here is reference problem same like yours
Force UI repaint in Webkit (Safari & Chrome) right before Synchronous "Ajax" request
<div id="#ajax_loader_css" style="display:none;"></div>
should be
<div id="ajax_loader_css" style="display:none;"></div>
Based on the accepted answer here valid values for an id element are
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
Firefox is obviously trying to fix it by removing the invalid character making the #ajax_loader_css css selector match something where as chrome is ignoring it so your selector matches nothing.

Extjs4 RESTful CRUD grid with Spring Controllers

I am new to Extjs4 and the javascript world in general. I have looked up the documentation and samples and trying to get a basic CRUD grid up and running with my spring backend.
I have a confusion related to the proxy in extjs, are they in the store or model according to the MVC paradigm ?
I have a controller.js defined which wraps these up together.
I would have thought that the REST calls would be made accroding to the urls being specified, which it is for now , but a create call is still sending the entire list. I am using jackson at the backend for automatic conversion to java objects but somehow that is not working (for add and update only).
How do i link these all up ?
a) Add a user .. do i create a new UserModel and then invoke a rest call like so or is it automatically supported by the proxy specified in the model ?
var record = new App.model.UserModel();
store = Ext.getStore('UsersStore');
store.insert(0, record);
store.save(); // .. this invokes the /createUser method
// .. what about /update ?
b) I am using the RowEditing plugin .. how can i fetch the roweditor in my controller.js where the reference for the view is available
Thanks in advance
relevant code listings ...
//UserController.js
Ext.define('App.controller.UsersController', {
extend : 'Ext.app.Controller',
init: function() {
this.control({
'userList button[action=add]' : {
click : this.editUser
} }); },
views : ['user.List','user.Edit'],
stores : ['UsersStore'] ,
models : ['UserModel'],
editUser : function(grid,record)
{
// empty record
var record = new App.model.UserModel();
// created new record
//How to get a reference to the roweditor here and then save that to the backend ?
//store = Ext.getStore('UsersStore');
//store.insert(0, record);
//store.save();
// this.getView('user.List').getP('rowEditor').startEdit(0, 0);
}});
//List.js
var rowEditor = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2
}
Ext.define('App.view.user.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.userList',
title : 'All Users',
store : 'UsersStore',
selType: 'rowmodel',
plugins: rowEditor,
initComponent: function() {
this.columns = [
{header: 'SNo', dataIndex: 'userID', width:50},
{header: 'UID', dataIndex: 'userUID', flex: 1, editor: 'textfield', allowBlank:false},
{header: 'Name', dataIndex: 'userName', flex: 1, editor:'textfield',allowBlank:false},
{ header: 'Level', dataIndex: 'userLevel', flex: 1,
editor: {xtype: 'combobox', typeAhead: true, triggerAction: 'all', selectionOnTab:true,
store : [
['Level 1','Level 1'],
['Level 2','Level 2'],
['Level 3','Level 3']
]
}
},
{header: 'Email', dataIndex: 'emailID', flex: 1, editor: 'textfield'}
];
this.callParent(arguments);
},
dockedItems : [{
xtype : 'toolbar',
items : [{
text: 'Add',
iconCls: 'icon-add',
action: 'add'
}]
}]});
//Model.js
Ext.define('App.model.UserModel', {
extend: 'Ext.data.Model',
fields: ['userID','userUID','userName', 'userLevel' ,'emailID'],
proxy : {
type: 'ajax',
api :
{
read : 'rest/user/fetchAll',
update:'rest/user/updateUser',
create :'rest/user/createUser',
destroy : 'rest/user/deleteUser'
},
reader :
{
type : 'json',
root : 'users',
successProperty : 'success'
},
writer :
{
type : 'json',
allowSingle : 'true'
}
}});
//UserStore
Ext.define('App.store.UsersStore', {
extend: 'Ext.data.Store',
model: 'App.model.UserModel',
autoLoad : true});
//Sample Java controller
#Controller
#RequestMapping("/rest/user")
public class UserController {
#RequestMapping(value = "/fetchAll" , method= RequestMethod.GET)
public #ResponseBody Map<String,? extends Object>
fetchUsers() {
Map<String,Object> responseMap = new HashMap<String,Object>();
responseMap.put("success",true);
responseMap.put("users",userService.getUserRepository().findAll());
return responseMap; }
// was expecting a single object here ?
#RequestMapping(value = "/createUser")
public #ResponseBody Map<String,? extends Object>
createUser(#RequestBody List<User> users)
{ ... }
}
I would put Proxy's inside store objects, not models. But that just personal preference.
When you add record to the store object, if it has autoSync property set to true it would automatically generate create request. What exactly is happening with your create request? What is being sent?
After trying out Sha's comments above, i was finally able to nail the issue.
The problem is with the json reader
reader :
{
type : 'json',
root : 'users',
successProperty : 'success'
//added
idProperty : 'userID'
},
I had to add the idProperty to make Json recognize the dirty record, else it treats everything as a new record and sends back the whole list

dijit.form.ValidationTextBox calls validator function twice onBlur

I have an AJAX call to check the availability of username using Dojo and PHP. Everything is working great, but there is something huge happening behind. Every time I type a word or during onBlur event, dojo makes AJAX call twice and sometimes thrice. I read this link and they say it is fixed since v1.3, I am using v1.7. I tried putting the AJAX function inside setTimeout() and put a 3 secs delay but still the same thing happens. How can prevent that and do only one AJAX call?
var _username = new dijit.form.ValidationTextBox({
name : "{{ username.name }}",
type : "text",
required : true,
invalidMessage : message.invalid.username
}, "{{ username.id }}");
dijit.byId("{{ username.id }}").validator = fnUsernameAvailable;
function fnUsernameAvailable(a) {
if (a === "" )
return false;
dojo.xhrPost({
url : "{{ site_url() }}/ajax/check_username_availability",
handleAs: "json",
content : {
username : a,
csrf_libtracking : fnCsrf()
},
load : function(data) {
_isAvailable = data.result;
}
});
return _isAvailable;
}
You could use a little trick like :
inside you ValidationTextBox, add a property :
var _username = new dijit.form.ValidationTextBox({
_beingChecked: false,
name : "{{ username.name }}",
type : "text",
required : true,
invalidMessage : message.invalid.username
}, "{{ username.id }}");
function fnUsernameAvailable(a) {
if (a === "" || this._beingChecked)
return false;
this._beingChecked = true;
dojo.xhrPost({
url : "{{ site_url() }}/ajax/check_username_availability",
handleAs: "json",
content : {
username : a,
csrf_libtracking : fnCsrf()
},
load : dojo.hitch(this, function(data) {
// _isAvailable = data.result; <-- is this really useful ?
this._beingChecked = false;
dojo.publish("some/topic/to/tell/widgets/it/is/done", [data.result]);
})
});
}
then somewhere in your code, or in your widget you dojo.subscribe to the topic, so that when something is published, you run a function ?
Thanks for the reply. My original plan was to contact the server, check if username is available, via AJAX, and return the var _isAvailable to trigger the invalidMessage property of the ValidationTextBox if the result is false. This would also trigger the tooltip to appear beside the textbox which I wanted to happen.
Pardon for my little knowledge on dojo as this is my first time using this framework.

uploadify scriptData problem

I'm having problems with scriptData on uploadify, I'm pretty sure the config syntax is fine but whatever I do, scriptData is not passed to the upload script.
I tested in both FF and Chrome with flash v. Shockwave Flash 9.0 r31
This is the config:
$(document).ready(function() {
$('#id_file').uploadify({
'uploader' : '/media/filebrowser/uploadify/uploadify.swf',
'script' : '/admin/filebrowser/upload_file/',
'scriptData' : {'session_key': 'e1b552afde044bdd188ad51af40cfa8e'},
'checkScript' : '/admin/filebrowser/check_file/',
'cancelImg' : '/media/filebrowser/uploadify/cancel.png',
'auto' : false,
'folder' : '',
'multi' : true,
'fileDesc' : '*.html;*.py;*.js;*.css;*.jpg;*.jpeg;*.gif;*.png;*.tif;*.tiff;*.mp3;*.mp4;*.wav;*.aiff;*.midi;*.m4p;*.mov;*.wmv;*.mpeg;*.mpg;*.avi;*.rm;*.pdf;*.doc;*.rtf;*.txt;*.xls;*.csv;',
'fileExt' : '*.html;*.py;*.js;*.css;*.jpg;*.jpeg;*.gif;*.png;*.tif;*.tiff;*.mp3;*.mp4;*.wav;*.aiff;*.midi;*.m4p;*.mov;*.wmv;*.mpeg;*.mpg;*.avi;*.rm;*.pdf;*.doc;*.rtf;*.txt;*.xls;*.csv;',
'sizeLimit' : 10485760,
'scriptAccess' : 'sameDomain',
'queueSizeLimit' : 50,
'simUploadLimit' : 1,
'width' : 300,
'height' : 30,
'hideButton' : false,
'wmode' : 'transparent',
translations : {
browseButton: 'BROWSE',
error: 'An Error occured',
completed: 'Completed',
replaceFile: 'Do you want to replace the file',
unitKb: 'KB',
unitMb: 'MB'
}
});
$('input:submit').click(function(){
$('#id_file').uploadifyUpload();
return false;
});
});
I checked that other values (file name) are passed correctly but session_key is not.
This is the decorator code from django-filebrowser, you can see it checks for
request.POST.get('session_key'), the problem is that request.POST is empty.
def flash_login_required(function):
"""
Decorator to recognize a user by its session.
Used for Flash-Uploading.
"""
def decorator(request, *args, **kwargs):
try:
engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
except:
import django.contrib.sessions.backends.db
engine = django.contrib.sessions.backends.db
print request.POST
session_data = engine.SessionStore(request.POST.get('session_key'))
user_id = session_data['_auth_user_id']
# will return 404 if the session ID does not resolve to a valid user
request.user = get_object_or_404(User, pk=user_id)
return function(request, *args, **kwargs)
return decorator
I found a solution without using scriptData. You can pass your data by passing through your URL:
$("#image_upload1").uploadify({
'method':'POST',
'buttonText':'Select',
'fileTypeDesc' : 'Image Files',
'fileTypeExts' : '*.gif; *.jpg; *.png',
'swf':'<?php echo base_url()?>resources/flash/uploadify.swf',
'uploader':'<?php echo site_url('item/update_item_images/'.$picid[0]); ?>',
'width': 40,
'multi':false,
'onUploadComplete':function(file)
{
$('.original').hide();
$('#image1').attr('style','background-image:url("../resources/uploads/<?php echo $id;?>/'+file.name+'");background-size: 140px 119px;');
$('#hidden_img_value1').attr('value',file.name)
}
});
Here I pass the value $picid[0] in uploader. This data you can access in your controller.
#Jimbo after removing inverted comma (') ,then also the value is not reciving in controller.
$("#image_upload1").uploadify({
'method':'POST',
'buttonText':'Select',
'fileTypeDesc' : 'Image Files',
'fileTypeExts' : '*.gif; *.jpg; *.png',
'swf':'<?php echo base_url()?>resources/flash/uploadify.swf',
'uploader':'<?php echo site_url('item/update_item_image1')?>',
'width': 40,
'multi':false,
'scriptData':{id:'<?=$picid[0]?>'},
'onUploadComplete':function(file)
{
//alert(response);
$('.original').hide();
$('#image1').attr('style','background-image:url("../resources/uploads/18/'+file.name+'")');
$('#hidden_img_value1').attr('value',file.name)
}
});
This might sound silly, but are you sure it's a session_key problem?
I had an authentication problem with filebrowser+uploadify but the problem was not the session_key but that the site was protected by a HTTP digest authentication set in Apache and, although session_key was sent fine, uploadify does not send the HTTP authentication headers.
Is your web server requiring any form of authentication?
I had a a similar problem passing script data in the past. Removing the inverted comma (') around the key in the key/value pairs fixed my problem
Instead of:
'scriptData' : {'session_key': 'e1b552afde044bdd188ad51af40cfa8e'},
Use:
'scriptData' : {session_key: 'e1b552afde044bdd188ad51af40cfa8e'},
(useful Uploadify post here)

Resources