I am using ExtJS 3.4 .
I have a structure with data for combobox like this:
var a = [[1,"text1"],[2,"text2"]]
I load it like this:
ComboBox.store.loadData(a);
But when I have only 1 item in the array
var a = [[1,"text1"]]
then it doesn't load at all. I've read that:
an Array : Arrays will be converted to a Ext.data.ArrayStore
internally, automatically generating field names to work with all data
components. 1-dimensional array : (e.g., ['Foo','Bar']) A
1-dimensional array will automatically be expanded (each array item
will be used for both the combo valueField and displayField)
2-dimensional array : (e.g., [['f','Foo'],['b','Bar']]) For a
multi-dimensional array, the value in index 0 of each item will be
assumed to be the combo valueField, while the value at index 1 is
assumed to be the combo displayField.
But that doesn't explain how do I load an array with one element. Or whatever, it shouldn't be necessary an array, the point is to load only one item. I've tried loading this:
Code:
[{id:1,text:"text1"}]
[[{id:1,text:"text1"}]]
{id:1,text:"text1"}
Even creating a custom ArrayStore:
Code:
var store = new Ext.data.ArrayStore({
autoDestroy: true,
storeId: 'Store1',
idProperty:"id",
fields: ["id","text"]);
ComboBox.store = store;
ComobBox.store.loadData([{id:1,text:"text1"}]);
But everything loads incorrectly . Either the combobox is empty, or it displays id instead of text.
I can see that if I lazily init the combo:
Code:
{"xtype":"combo","width":250,"fieldLabel":"my combo","value":31029,"forceSelection":true,"hiddenName":"ComboHiddenName","minChars":1,"triggerAction":"all","store":[[31029,"gdfs"]]}
then the array with one item will load successfully. At which properties of ComboBox.store should I look to configure them properly for a single-item array to be loaded correctly using loadData method?
ComboBox.store.loadData(var a); would not work for any data. It would raise exception Unexpected token var. Instead one should use ComboBox.store.loadData(a); without var
ComboBox.valueField = "id";
ComboBox.displayField = "text";
ComboBox.store = new Ext.data.ArrayStore({autoDestroy: true, fields: ["id", "text"]});
Related
Struggling with some javascript array manipulation/updating. Hope someone could help.
I have an array:
array('saved_designs'=array());
Javascript JSON version:
{"saved_design":{}}
I will be adding a label, and associated array data:
array("saved_designs"=array('label'=array('class'='somecssclass',styles=array(ill add more assoc elements here),'hover'=array(ill add more assoc elements here))))
Javascript version:
{"saved_designs":{"label":{"class":"someclass","style":[],"hover":[]}}}
I want to be able to append/modify this array. If 'label' already defined...then cycle through the sub data for that element...and update. If 'label' doesnt exist..then append a new data set to the 'saved_designs' array element.
So, if label is not defined, add the following to the 'saved_designs' element:
array('label2' = array('class'=>'someclass2',styles=array(),'hover=>array()')
Things arent quite working out as i expect. Im unsure of the javascript notation of [], and {} and the differences.
Probably going to need to discuss this as answers are provided....but heres some code i have at the moment to achive this:
//saveLabel = label the user chose for this "design"
if(isUnique == 0){//update
//ask user if want to overwrite design styles for the specified html element
if (confirm("Their is already a design with that label ("+saveLabel+"). Overwrite this designs data for the given element/styles?")) {
currentDesigns["saved_designs"][saveLabel]["class"] = saveClass;
//edit other subdata here...
}
}else{//create new
var newDesign = [];
newDesign[saveLabel] = [];
newDesign[saveLabel]["class"] = saveClass;
newDesign[saveLabel]["style"] = [];
newDesign[saveLabel]["hover"] = [];
currentDesigns["saved_designs"].push(newDesign);//gives error..push is not defined
}
jQuery("#'.$elementId.'").val(JSON.stringify(currentDesigns));
thanks in advance. Hope this is clear. Ill update accordingly based on questions and comments.
Shaun
It can be a bit confusing. JavaScript objects look a lot like a map or a dictionary from other languages. You can iterate over them and access their properties with object['property_name'].
Thus the difference between a property and a string index doesn't really exist. That looks like php you are creating. It's called an array there, but the fact that you are identifying values by a string means it is going to be serialized into an object in javascript.
var thing = {"saved_designs":{"label":{"class":"someclass","style":[],"hover":[]}}}
thing.saved_designs.label is the same thing as thing["saved_designs"]["label"].
In javascript an array is a list that can only be accessed by integer indices. Arrays don't have explicit keys and can be defined:
var stuff = ['label', 24, anObject]
So you see the error you are getting about 'push not defined' is because you aren't working on an array as far as javascript is concerned.
currentDesigns["saved_designs"] == currentDesigns.saved_designs
When you have an object, and you want a new key/value pair (i.e. property) you don't need a special function to add. Just define the key and the value:
**currentDesigns.saved_designs['key'] = newDesign;**
If you have a different label for every design (which is what it looks like) key is that label (a string).
Also when you were defining the new design this is what javascript interprets:
var newDesign = [];
newDesign is an array. It has n number of elements accessed by integers indices.
newDesign[saveLabel] = [];
Since newDesign is a an array saveLabel should be an numerical index. The value for that index is another array.
newDesign[saveLabel]["class"] = saveClass;
newDesign[saveLabel]["style"] = [];
newDesign[saveLabel]["hover"] = [];
Here explicitly you show that you are trying to use an array as objects. Arrays do not support ['string_key']
This might very well 'work' but only because in javascript arrays are objects and there is no rule that says you can't add properties to objects at will. However all these [] are not helping you at all.
var newDesign = {label: "the label", class: saveClass};
is probably what you are looking for.
I have an Ext.form.Panel which contains a mixture of "typical" fields: textfield, combobox, checkboxfield, and the like. Each combobox has forceselection : true and - therefore - an associated store. My goal is to loop over each of the fields in the Panel, determine whether it is a combobox, then do "some stuff" - i.e. load the associated store.
Two questions (each holding the hand of the over):
Is it possible to Ext.each over a particular "type" of component on a panel? Or, to approach the problem slightly differently: is it possible to select a group of components matching a particular type?
If not, how do I determine the type of the component at run-time?
Currently, I am using a list of identifiers, iterating over each identifier, and running a query against the panel, e.g.
var comboBoxIds : [
'dogs',
'cats',
'fish'
];
Ext.each(comboBoxIds, function(comboId) {
var comboBox = panel.queryById(comboId);
//....
});
The above being a very simplistic reduction.
Use query method to get what you need, and then iterate over the array:
var combos = panel.query('combobox[forceSelection=true]');
for (var i = 0; i < combos.length; i++) {
var combo = combos[i];
...
}
More on the ComponentQuery syntax: http://docs-origin.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/Ext.ComponentQuery
I need to store table cell content into array using tr and td indexes like this:
myArray[tr_idx][td_idx]='value';
It is not required to store data of all of cells in array but only several with a special content, but if i use indexes as a keys of the array i'll have many empty array elements.
e.g.
myArray[2][3]='data1';
myArray[4][3]='data2';
alert (myArray.toSource()) -> [, , [, , , "data1"], , [, , , "data2"]]
maybe there is another suitable way of storing such type of data?
Why not just store them as individual 2-item arrays [row,col]? Since the table cells are already accessible via tableElement.rows[].cells[], you can use the 2 indices to access them from the table.
var storedCells = [];
// Store row 2, column 3
storedCells.push([2,3]);
Access with:
// Table row:
storedCells[0][0]
// Table column
storedCells[0][1]
//As in :
tableElement.rows[storedCells[0][0]].cells[storedCells[0][1]].innerHTML = "New cell value!"
Or even cleaner, if you prefer to use objects rather than arrays:
storedCells.push({row: 2, column: 3});
storedCells.push({row: 4, column: 6});
Accessed with:
tableElement.rows[storedCells[0].row].cells[storedCells[0].column].innerHTML = "New cell value!";
Finally, if you don't actually need the row/column indexes, but rather the DOM nodes themselves, just push those onto your array.
var storedCells = [];
// Save references to some individual <td> nodes
storedCells.push(tableElement.rows[1].cells[2]);
storedCells.push(tableElement.rows[4].cells[6]);
They are then trivially modified:
// Set the value of the second element:
storedCells[1].innerHTML = "New content!";
Update after comment:
If you need to be able to attach the cell coordinates to a new value from the backend, a good solution would be to expand the object {} example above to include a value attribute. The server can pass back the new value in JSON.
storedCells.push({row: 2, column: 3, value: ""});
storedCells.push({row: 4, column: 6, value: ""});
Your backend should send a JSON response back to the script containing the same type of array of objects, where value: has been populated with the new cell value. You can then pass it back into the table with:
// Pass the value attribute received from JSON into the cell's contents
tableElement.rows[storedCells[0].row].cells[storedCells[0].column].innerHTML = storedCells[0].value;
Not sure if this is the right answer but you could try to check if cells are empty before pushing them into the array. In the loop place a an if statement that will check the value of the cell and compare it to the value you require. This way you should end up with just an array of value and no empties. But you may need to record the index as well then.
I have a grid using jqgrid. I need to store the some data returned by the url:, in a local variable so that I can display it in the subgrid. For this I add that column as a hidden column in the main grid, which is of the format in json:
"Details":[{"Name":"ttt", "Quantity":"12"}] .
Then in the loadcomplete: function I save the value to a variable using
var griddata = $("#grid').getCol('Details', false);
Now when I access griddata[0], I get a object Object. I tried to parse it to get the values correctly, but to no avail. I tried:
griddata[0].Details.Name
or
griddata[0].Details.0.Name
or
griddata[0].Name,
but all failed. I guess I am missing the format if the data returned by the getcol() function.I looked up the documentation on the method and it says that it returns just the values when we specify false, but could not get any examples.
If there are any examples or if there are any pointer to the solution, it will be greatly appreciated.
If you check the type of griddata[0] (for example with typeof operator) you will see that it has type of string - this is because the value you are getting is the result of toString() on the object you have passed. The reason for that is the way in which jqGrid is treating values.
If you want to store JSON as the value, you need to stringify it entirely:
"Details": "[{\"Name\":\"ttt\", \"Quantity\":\"12\"}]"
Now you can deserialize those string values into objects like this:
var griddata = $.map($("#grid").jqGrid('getCol', 'Details', false), function(value) {
return JSON.parse(value);
});
After that you can access the objects in the way you want:
var name = griddata[0].Name;
var quantity = griddata[0].Quantity;
As an alternative you can split your object into two columns, so the values can be accessed directly with getCol.
I have an object which looks like
options = {
offers : $$("div.sonan"),
prev : offers[0],
next : offers[1]
}
where the property prev represent the first element of offers array and next represent
the second element of offers array.
How may I use offers property within the options object
I see that you are defining the array inside the object definition and using that array to fetch elements to define other properties of the options object.
this approach won't work because while parsing the options object first, javascript doesn't know what is offers that is offfers is undefined unless the options object gets parsed.
you can see the below written code for more help.
// define the object
var offs = [1,2,3];
var options = {
offers : offs,
prev : offs[0],
next : offs[1]
};
//fetch values from object
options.offers; // should give u [1,2,3]
Try this.
document.write(option[1])
Change the number at the end to change objects.
option : array name.
offers : object 0.
prev : object 1.
next : object 2.