By removing a field in a fieldset, it's label is not removed. How can I remove it? I'm using ExtJS 2.0.2. Code follows:
var predicateArguments= new Ext.form.FieldSet({
id:'predicate_arguments',
layout:'form',
title:'Predicate Arguments',
defaultType:'textfield',
autoHeight:true,
autoWidth:true,
autoScroll:true,
items:[
{
xtype:'textarea',
id:'description',
fieldLabel:'Description',
name:'description',
readOnly:true
}
],
buttons: [
{text: 'Add',
handler:function(){
//this will submit the form's fields
predicatesForm.getForm().submit();
}},
{text: 'Reset Fields',
handler:function(){
//this will reset the form's fields
predicatesForm.getForm().reset();
}}
]
})
var predicatesForm = new Ext.FormPanel({
id:'predicates-form',
region:'center',
split:true,
labelAlign:'right',
layout:'column',
items:[availablePredicatesGrid, predicateArguments]
})
var dateField = {xtype:'datefield',
fieldLabel:'Date',
name:'date',
id:'date_field'
}
var numberField = {xtype:'numberfield',
fieldLabel:'Number',
name:'number',
id:'number_field'
}
//when a rule is clicked do the following...
availablePredicatesGrid.getSelectionModel().on('rowselect', function(sm,_rowIndex,_rule){
predicatesForm.getForm().loadRecord(_rule);
var _ruleType= _rule.store.getAt(_rowIndex).get('type');
//removes previous existing fields (but not labels!)
predicateArguments.remove('date_field');
predicateArguments.remove('number_field');
//creates new fields according to the selected rule types
for(i=0; i<_ruleType.length; i++){
if(_ruleType[i]=='date'){
predicateArguments.add(dateField);
predicateArguments.doLayout();
}
else if(_ruleType[i]=='number'){
predicateArguments.add(numberField);
predicateArguments.doLayout();
}
}
});
Instead of calling remove on your Ext.Element reference, do this instead:
Ext.getCmp('id_of_your_form_field').getEl().parent().parent().remove();
EDIT: this is intended for use on form field components, as it removes the wrapper div containing the label and the component
I don't know extjs, but, normally, how would you do this (and how you should do this) is by simply adding the input and its label in a or and then, when you want to remove the input (and its label in the same time), just do:
obj = document.getElementById( ID-OF-ELEMENT )
obj.parentNode.html = '';
or just delete its parent in any other way you might find to not have empty spans lying around:
obj.parentNode.parentNode.removeChild( obj.parentNode );
or, if you know that the label is just before the input, you can just do:
obj.parentNode.removeChild( obj.previousSibling );
or just combine them to suit your purpose
Related
I'm facing a problem in using UI-GRId with row selection and custom cell elements:
The sample plunker is here : http://plnkr.co/edit/Ed6s6CGFGXyUzj2cyx2g?p=preview
$scope.gridOptions = { showGridFooter:true,enableRowSelection: true, enableRowHeaderSelection: false };
$scope.gridOptions.columnDefs = [
{ name: 'id' },
{ name: 'name'},
{ name: 'age', displayName: 'Age (not focusable)', allowCellFocus : false },
{ name: 'address.city' },
{ name:'address.pin',cellTemplate:'<select><option value="122002">122002</option><option value="122001">122001</option></select>'}];
You can see that on row click, the respective row gets selected, while if you tend to select the dropdown options implicitly the row selection event also gets fired, I want that on elements click like dropdown here the row selection event should not be triggered.
Pls guide.
Interesting question, haven't run into it yet, but I am sure it's only time before I do. I've created a plunk to demonstrate my solution.
Basically, what I have do is registered a watcher, as mentioned by AranS. From there, we have two objects to work with: the row, and the event that occured. Since the event object discloses which element was selected (clicked), we can identify if it was a DIV, or something else. In the event of the change in the select list, the value of evt.srcElement.tagName is 'SELECT'.
http://plnkr.co/edit/k2XhHr2QaD1sA5y2hcFd?p=preview
$scope.gridOptions.onRegisterApi = function( gridApi ) {
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope,function(row,evt){
if (evt)
row.isSelected = (evt.srcElement.tagName === 'DIV');
});
};
ui-grid's API allows controlling row selection. Look at this answer from another thread: https://stackoverflow.com/a/33788459/5954939. Basically you can use the event rowSelectionChanged or the isRowSelectable. Let me know if you need an example.
I have a checkbox that controls 4 dateFields in ExtJs. I want to be able to give them a common property to be able to disable all fields with one command.
I assume there is a simpler way to do that. It works, but its a big block of code.
This is the checkBox's change event implementation so far:
change: function (cmp, newValue, oldValue, eOpts) {
var dt1 = cmp.up().down('#Dtf1');
dt1.setDisabled(newValue);
var dt2 = cmp.up().down('#Dtf2');
dt2.setDisabled(newValue);
var dt3 = cmp.up().down('#Dtf3');
dt3.setDisabled(newValue);
var dt4 = cmp.up().down('#Dtf4');
dt4.setDisabled(newValue); }
You can add an attribute for example:
{
xtype: 'textfieid',
itemId: 'Dtf1',
dtf: true
}
Then you'll be able to query like:
cmp.up().query('[dtf=true]').forEach(function(item){
item.setDisabled(newValue);
});
Or can also use a query, like:
cmp.up().query('#Dtf1, #Dtf2, #Dtf3, #Dtf4').forEach(function(item){
item.setDisabled(newValue);
});
I am using Liferay 6.2 and want to retrieve the value of removed element from a Textboxlist component. I have stored a list of values in a hiddenInput element, and I display the list in a Textboxlist. As I remove the element, I want to update the values stores in the hidden input element. But I do not know how to retrieve the removed element.
AUI().ready('aui-textboxlist-deprecated', function (A) {
var source = A.one('#hiddenInput').val().split(',');
var tagslist = new A.TextboxList({
contentBox: '#demo',
dataSource: source,
matchKey: 'name',
schema: {
resultFields: ['key', 'name']
},
schemaType: 'json',
typeAhead: true,
width: 500
}).render();
var values = A.one('#hiddenInput').val().split(',');
A.each(values, tagslist.add, tagslist);
var updateHiddenInput = function (event) {
//how to get the removed element?
}
tagslist.entries.after('remove', updateHiddenInput);
});
How to achieve this?
As #jbalsas said in the comments:
If you just need the label, then you can get it using event.attrName. If you need to work with the element, it is passed in event.item.entry.
So you should be able to do it like this:
var updateHiddenInput = function (event) {
var hiddenInput = A.one('#hiddenInput');
hiddenInput.val(hiddenInput.val() + ',' + event.item.entry); // or event.attrName
}
How do I add a label to a text box (programmatically) :
el = new dijit.form.TextBox({label: '...' });
form.containerNode.appendChild(el.domNode);
this does not seem to work (dojo 1.6)
Dojo provides dojox.layout.TableContainer for automatically pairing labels with controls:
var layout = new dojox.layout.TableContainer({
showLabels: true,
orientation: "horiz"
});
var textBox = new dijit.form.TextBox({
name: 'text',
title: 'My Label'
});
layout.addChild(textBox);
layout.placeAt(form.containerNode);
layout.startup();
jsfiddle (thanks for the template, #jumpnett)
I've never seen any example where the dijit.form.TextBox uses the lable property to actually display a label next to the TextBox. The label is always a seperate label element or textnode.
I believe the TextBox only has this property because it inherits it from dijit._Widget (according to the API docs).
To add a label programmaticaly, just append a seperate textnode or label element to the form's domNode:
dojo.require("dijit.form.Form");
dojo.require("dijit.form.TextBox");
function buildForm() {
var form = new dijit.form.Form({
}, dojo.doc.createElement('div'));
var textBox = new dijit.form.TextBox({
name: 'text'
}, dojo.doc.createElement('input'));
document.body.appendChild(form.domNode);
form.domNode.appendChild(dojo.doc.createTextNode("My Label "));
form.domNode.appendChild(textBox.domNode);
}
dojo.addOnLoad(buildForm);
Here is a full example on jsfiddle.
yourPlaceholder.domNode.appendChild(dojo.doc.createTextNode("Label Text"));
yourPlaceholder.addChild(yourTextBox);
I got it using following snippet :
dojo.place('<label for="field" > Label Name </label>',dojo.byId('TextField_Id'),'before');
I was asked to post this as a question on StackOverflow by http://twitter.com/jonathanjulian which was then retweeted by several other people. I already have an ugly solution, but am posting the original problem as requested.
So here's the back story. We have a massive database application that uses ExtJS exclusively for the client side view. We are using a GridPanel (Ext.grid.GridPanel) for the row view loaded from a remote store.
In each of our interfaces, we also have a FormPanel (Ext.form.FormPanel) displaying a form that allows a user to create or edit records from the GridPanel. The GridPanel columns are bound to the FormPanel form elements so that when a record is selected in the GridPanel, all of the values are populated in the form.
On each form, we have an input field for the table row ID (Primary Key) that is defined as such:
var editFormFields = [
{
fieldLabel: 'ID',
id: 'id_field',
name: 'id',
width: 100,
readOnly: true, // the user cannot change the ID, ever.
monitorValid: true
} /* other fields removed */
];
So, that is all fine and good. This works on all of our applications. When building a new interface, a requirement was made that we needed to use a third-party file storage API that provides an interface in the form of a small webpage that is loaded in an IFrame.
I placed the IFrame code inside of the html parameter of the FormPanel:
var editForm = new Ext.form.FormPanel({
html: '<div style="width:400px;"><iframe id="upload_iframe" src="no_upload.html" width="98%" height="300"></iframe></div>',
/* bunch of other parameters stripped for brevity */
});
So, whenever a user selects a record, I need to change the src attribute of the IFrame to the API URL of the service we are using. Something along the lines of http://uploadsite.com/upload?appname=whatever&id={$id_of_record_selected}
I initially went in to the id field (pasted above) and added a change listener.
var editFormFields = [
{
fieldLabel: 'ID',
id: 'id_field',
name: 'id',
width: 100,
readOnly: true, // the user cannot change the ID, ever.
monitorValid: true,
listeners: {
change: function(f,new_val) {
alert(new_val);
}
}
} /* other fields removed */
];
Nice and simple, except that it only worked when the user was focused on that form element. The rest of the time it failed to fire at all.
Frustrated that I was past a deadline and just needed it to work, I quickly implemented a decaying poller that checks the value. It's a horrible, ugly hack. But it works as expected.
I will paste my ugly dirty hack in an answer to this question.
"The GridPanel columns are bound to
the FormPanel form elements so that
when a record is selected in the
GridPanel, all of the values are
populated in the form."
As I understand it from the quote above, the rowclick event is what actually triggers the change to your form in the first place. To avoid polling, this could be the place to listen, and eventually raise to your custom change event.
Here is the ugly hack that I did to accomplish this problem:
var current_id_value = '';
var check_changes = function(offset) {
offset = offset || 100;
var id_value = document.getElementById('id_field').value || '';
if ( id_value && ( id_value != current_id_value ) ) {
current_id_value = id_value;
change_iframe(id_value);
} else {
offset = offset + 50;
if ( offset > 2500 ) {
offset = 2500;
}
setTimeout(function() { check_changes(offset); }, offset);
}
};
var change_iframe = function(id_value) {
if ( id_value ) {
document.getElementById('upload_iframe').src = 'http://api/upload.php?id=' + id_value;
} else {
document.getElementById('upload_iframe').src = 'no_upload.html';
}
setTimeout(function() { check_changes(100); }, 1500);
};
It's not pretty, but it works. All of the bosses are happy.
If you took a moment to read the source, you would see that the Ext.form.Field class only fires that change event in the onBlur function