I am using this library: mobiscroll.custom-2.5.0.min.js. How do I set limits to deny users' selecting past dates?
My code:
xtype:'panel',
layout:'hbox',
width: (screenWidth-(84+24+55))/2,
cls: 'paymentsSectionDetailsDate',
items:[{
xtype:'panel',
html:'<div class="paymentsSectionDetailsDateLabel" >'+txt_PayOn+'</div>',
width: 80
},{
xtype: 'button',
text:txt_select_date,
name: 'BillPayDetailsForm_date',
id:'BillPayDetailsForm_date',
cls: 'paymentsSectionDetailsDateTextButt',
listeners:{
tap : function()
{
inputNumber=4;
$('#dateIos').fadeIn("slow");
}
}
}]
I am not familiar with mobiscroll, could you use a datepicker? It has 'yearFrom' and 'yearTo' configuration options. You might be able to use a listener to get the data into mobiscroll.
Related
Currently using the infinite search method that Algolia supplies through their instantSearch.js.
The following scenario is happening:
Search for an item
Refine the list
Load more pages up to page 5
Scroll back to the top and change refinement
Nothing happens
By the looks of it - it's appending the results of the new refinement to the results that are already there. I'm looking to make it resent the results, not sure if this is a bug with instant search itself?
search.addWidget(
instantsearch.widgets.numericRefinementList({
container: '#price',
attributeName: 'salePrice',
options: [
{name: 'All'},
{end: 20, name: 'less than 20'},
{end: 50, name: 'less than 50'},
{start: 50, end: 100, name: 'between 50 and 100'},
{start: 100, end: 300, name: 'Expensive'},
{start: 300, name: 'Very Expensive'}
],
templates: {
header: 'Price'
}
})
);
And the infinite search code:
search.addWidget(
instantsearch.widgets.infiniteHits({
container: '#infinite-hits-container',
templates: {
empty: 'No results',
item: hitTemplate
},
hitsPerPage: 3
})
);
This issues is fixed in 1.11.15 (instructions for getting the new version is here)
I am very confused by the Sencha documentation for ExtJS. The documentation begins with a Getting Started guide which highlights and illustrates the importance on a suitable structure for the classes and source code of your application. But the provided examples then break all the conventions laid down by the Getting Started guide. Instead of code being broken down into appropriate Model, Store, View, etc. class files the examples are provided as a single file with example source code which is not easily re-usable in separate source files.
I started by following the Portal example (http://docs.sencha.com/ext-js/4-1/#!/example/portal/portal.html) as this is the sort of application I want to create. I wanted to enhance the Portal example and add in a screen which would display a grid and use a RESTful web service as the data backend. I have created the backend I just want to create the front-end. So I looked at the RESTful example (http://docs.sencha.com/ext-js/4-1/#!/example/restful/restful.html)
I have tried to copy the RESTful example into the recommended pattern of seperate classes e.g. Model, Store, View:
Model:
Ext.define('MyLodge.model.Member', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'email', type: 'string'},
{name: 'href', type: 'string'}
]
});
Store:
Ext.require('MyLodge.model.Member');
Ext.define('MyLodge.store.Members', {
autoLoad: true,
autoSync: true,
model: 'MyLodge.model.Member',
proxy: {
type: 'rest',
url: 'http://localhost:8888/rest/memberapi/members' ,
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json'
}
},
listeners: {
write: function(store, operation){
var record = operation.getRecords()[0],
name = Ext.String.capitalize(operation.action),
verb;
if (name == 'Destroy' ) {
record = operation.records[0];
verb = 'Destroyed';
} else {
verb = name + 'd';
}
Ext.example.msg(name, Ext.String.format( "{0} member: {1}", verb, record.getId()));
}
}
});
View:
Ext.define('MyLodge.view.content.MemberGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.membergrid',
initComponent: function(){
var store = Ext.create('MyLodge.store.Members' );
Ext.apply( this, {
height: this.height,
store: store,
stripeRows: true,
columnLines: true,
columns: [{
id : 'name',
text : 'Name',
flex: 1,
sortable : true,
dataIndex: 'name'
},{
text : 'E-Mail',
width : 150,
sortable : true,
dataIndex: 'email'
},{
text : 'Href',
width : 200,
sortable : true,
dataIndex: 'href'
}],
dockedItems: [{
xtype: 'toolbar',
items: [{
text: 'Add',
iconCls: 'icon-add',
handler: function(){
// empty record
store.insert(0, new MyLodge.model.Member());
rowEditing.startEdit(0, 0);
}
}, '-', {
itemId: 'delete',
text: 'Delete',
iconCls: 'icon-delete',
disabled: true,
handler: function(){
var selection = grid.getView().getSelectionModel().getSelection()[0];
if (selection) {
store.remove(selection);
}
}
}]
}]
});
this.callParent(arguments);
}
});
But I am not sure where to put the code to control the grid row selection and enable the Delete button:
grid.getSelectionModel().on('selectionchange', function(selModel, selections){
grid.down('#delete').setDisabled(selections.length === 0);
});
Also when I press the Add button I get the following error:
Uncaught TypeError: Object [object Object] has no method 'insert'.
Any help would be appreciated.
You are having scoping issues. Basically the variable store is defined only in the initComponent function and therefore of local function scope.
Your handler function has it's own scope. It is firing in the scope of the toolbar button. So if you say this in the handler it would refer to the button. Hence you can say this.up('panel').store - and that gives you the correct reference to the store backing your grid panel.
Another advice is not to implement everything at once. Write a little bit to see if it works and then add to it little by little.
RE: the docs examples, I agree that it's frustrating, but there's not many options. Having a fully-MVC-style implementation of each example would not only be onerous to produce, but would also probably make point of the example get lost in the structure.
RE: your question about the where to "put" the code to control the grid, I would recommend setting up a controller with listeners for the events on the grid in the control() section. This will let you decouple the handling of the events that are fired by your grid from the view itself.
I'm using ExtJS3 and i want to put this chart into a panel with a dynamic store
http://dev.sencha.com/deploy/ext-3.4.0/examples/chart/pie-chart.html
I tried to include this chart into my panel code but it didn't work.
Does anybody has a solution or an example for a chart included into a panel in ExtJS3
Thank you
I used your example to generate the chart using a dynamic store:
Ext.chart.Chart.CHART_URL = 'http://dev.sencha.com/deploy/ext-3.4.0/resources/charts.swf';
Ext.onReady(function(){
var store = new Ext.data.JsonStore({
url: "sample_data.php",
root: 'results',
fields: [
{name: 'season'},
{name: 'total'}
]
});
new Ext.Panel({
width: 400,
height: 400,
title: 'Pie Chart with Legend - Favorite Season',
renderTo: 'container',
items: {
store: store,
xtype: 'piechart',
dataField: 'total',
categoryField: 'season',
//extra styles get applied to the chart defaults
extraStyle:
{
legend:
{
display: 'bottom',
padding: 5,
font:
{
family: 'Tahoma',
size: 13
}
}
}
}
});
});
where http://dev.sencha.com/deploy/ext-3.4.0/resources/charts.swf is the target where you can find the chart and sample_data.php returns the following json:
{"results":[
{"total":"150","season":"Summer"},
{"total":"245","season":"Fall"},
{"total":"117","season":"Winter"},
{"total":"184","season":"spring"}
]}
Note: This should normally be set to a local resource.
Hope this helps.
An earlier question mentioned a method using the el config in order to make the browser remember passwords. Howewer, the el config no longer exists in ExtJS 4.1.
Now, what should I do?
I believe it should be contentEl instead of el but I do this another way. You can build the entire thing with ExtJS directly. The only twist is that Ext fields will be created with the autocomplete=off attribute by default, so I use a derived class to override that.
Ext.define('ACField', {
extend: 'Ext.form.field.Text',
initComponent: function() {
Ext.each(this.fieldSubTpl, function(oneTpl, idx, allItems) {
if (Ext.isString(oneTpl)) {
allItems[idx] = oneTpl.replace('autocomplete="off"', 'autocomplete="on"');
}
});
this.callParent(arguments);
}
});
Ext.onReady(function() {
new Ext.panel.Panel({
renderTo: Ext.getBody(),
width: 300,
height: 100,
autoEl: {
tag: 'form',
action: 'login.php',
method: 'post'
},
items: [
new ACField({
xtype: 'textfield',
name: 'username',
fieldLabel: 'Username'
}),
new ACField({
xtype: 'textfield',
name: 'password',
fieldLabel: 'Password',
inputType: 'password'
}),
],
buttons: [{
xtype: 'button',
text: 'Log in',
type: 'submit',
preventDefault: false
}]
});
});
The answer from lagnat was mostly correct, to get this also working on Chrome and Firefox the following is required:
1) Override default ExtJS Textfield behavior for autocomplete (copied from lagnat):
Ext.define('ACField', {
extend: 'Ext.form.field.Text',
initComponent: function() {
Ext.each(this.fieldSubTpl, function(oneTpl, idx, allItems) {
if (Ext.isString(oneTpl)) {
allItems[idx] = oneTpl.replace('autocomplete="off"', 'autocomplete="on"');
}
});
this.callParent(arguments);
}
});
2) Make sure the textfields are within a <form> tag: (see answer from lagnat), since ExtJS 4 the <form> tag is no longer present in a FormPanel.
autoEl: {
tag: 'form',
action: '/j_spring_security_check',
method: 'post'
},
3) Make sure there is a <form> present in the HTML, with the same <input> names:
items:[
Ext.create('ACField',{
fieldLabel: 'Username',
name:'j_username',
inputId: 'username',
allowBlank:false,
selectOnFocus:true
}),
Ext.create('ACField',{
fieldLabel:'Password',
name:'j_password',
inputId: 'password',
xtype:'textfield',
allowBlank:false,
inputType:'password'
})
],
and within the HTML the regular form with same input names:
<body>
<div id="login-panel">
<form id="loginForm" action="<c:url value="/j_spring_security_check"/>" method="post">
<input class="x-hidden" type="text" id="username" name="j_username"/>
<input class="x-hidden" type="password" id="password" name="j_password"/>
</form>
</div>
<noscript>Please enable JavaScript</noscript>
</body>
With all these changes in place, saving username/password works in IE, Chrome and Firefox.
There is the autoRender property which will allow you to apply the Extjs field to an already existing element on the page. So if you set up your basic form in html, the browser should recognize the fields for the form as login info, and then Extjs will overlay itself onto that form if you use the autoRender with a reference to the correct fields (and also the button on the form to a submit type button in your basic html form) it should work correctly.
Also, keep in mind that the browser probably will not recognize an ajax call for logging in and you may need to use the basic form submission. I have a working example in my application, but I would have a hard time trying to pull out application specific code so have an example for here. Please comment if you need the example and I may be able to get back to you by monday.
Answer by #Lagnat does not work for ExtJS 4.2.1 and 4.2.2. It might be due to removal of type config from button. What we need is standard submit button <input type="submit"> for the button. So I added it on the button with opacity: 0. Below is my working code (Tested working on Firefox 27, Chrome 33, Safari 5.1.7, IE 11. Autofill/Autosave password should be enabled for browser):
Ext.create('Ext.FormPanel', {
width: 400,
height: 500,
padding: '45 0 0 25',
autoEl: {
tag: 'form',
action: 'login.php',
method: 'post'
},
renderTo: Ext.getBody(),
items: [{
xtype: 'textfield',
fieldLabel: 'Username',
name: 'username',
listeners: {
afterrender: function() {
this.inputEl.set({
'autocomplete': 'on'
});
}
}
}, {
xtype: 'textfield',
fieldLabel: 'Password',
inputType: 'password',
name: 'username',
listeners: {
afterrender: function() {
this.inputEl.set({
'autocomplete': 'on'
});
}
}
}, {
xtype: 'button',
text: 'LOG IN',
width: 100,
height: 35,
preventDefault: false,
clickEvent: 'click',
listeners: {
afterrender: function() {
this.el.createChild({
tag: 'input',
type: 'submit',
value: 'LOG IN',
style: 'width: 100px; height: 35px; position: relative; top: -31px; left: -4px; opacity: 0;'
});
}
}
}]
});
I recommend using the built in Cookie functionality of ExtJS.
You can read a cookie using: readCookie('password);
You can create a cookie using: createCookie('password', "pass123", 30); // save for 30 days
Then you can use basic business logic to auto-populate your formField with the stored password.
Does that make sense?
Just diving into SenchaTouch which seems very promising.
I'm building my first application, a simple login form check source http://pastebin.com/8Zddr9cj
I'm looking for a way to do the following things :
Display 'nice' error message when the login/password is wrong. Can be in red to replace the 'Please enter your credentials); i don't know how to access this property.
If login success, close the form and load the application (probably another js file).
Quite simple, but i'm a newbie to this,
1) Fieldset has a method called setInstructions which you can call to update the instructions. So, you could specify an id configuration in your field set, then use that later on when you want to update the instructions.
...
items: [
{
xtype: 'fieldset',
id: 'fieldset',
title: 'Login',
instructions: 'Please enter your credentials',
defaults: {
required: true,
labelAlign: 'left',
labelWidth: '40%'
},
items: [
{
xtype: 'emailfield',
name : 'email',
label: 'Email',
placeHolder: 'your#email.com',
useClearIcon: true
}, {
xtype: 'passwordfield',
name : 'password',
label: 'Password',
useClearIcon: false
}]
}
],
...
//wherever you want to update the instructions
var fieldset = Ext.getCmp('fieldset');
fieldset.setInstructions('My new instructions!');
2) Here is a simple demo of this:
//create a panel, which is full screen, and will contain your form, and another item
//which you want to show at some point
var wrapper = new Ext.Panel({
fullscreen: true,
layout: 'card',
//my two items
items: [
form,
{
xtype: 'panel',
html: 'my second panel, which is not visible on render.'
}
]
});
//change the active card/item, when you need to
wrapper.setActiveItem(1); //starts at 0
Make sure you remove fullscreen from your form, as it is no longer fullscreen (this wrapper panel is).