I have a ExtJS Panel with a number of columns some of which are hidden.
I want to be able to change the CSS of these columns depending on whether the column is set to hidden or not, is this possible?
First of all there is no such thing as column from DOM's point of view. There are bunch of cells(divs and tds actualy) that have same className:
-------------------------------------------------------------------
| div#gridcolumn-1018 | div#gridcolumn-1019 |
|-----------------------------------------------------------------|
| td.x-grid-cell-gridcolumn-1018 | td.x-grid-cell-gridcolumn-1019 |
| td.x-grid-cell-gridcolumn-1018 | td.x-grid-cell-gridcolumn-1019 |
| td.x-grid-cell-gridcolumn-1018 | td.x-grid-cell-gridcolumn-1019 |
| ... | ... |
-------------------------------------------------------------------
So when you are doing thing like:
grid.columns[1].addCls('myCls');
you are adding class to div#gridcolumn-1019 but not to all other column's cells.
So to add class to all cells of column on column hiding you have to do something like this:
grid.column[1].on('hide', function(column){
var id = column.getId(); // gridcolumn-1019
var cells = Ext.DomQuery.select('.x-grid-cell-'+id);
column.addCls('myCls');
for (var i = 0; i < cells.length; i++)
Ext.fly(cells[i]).addCls('myCls');
}
UPDATE: changed the incorrect cells[i].addCls('myCls'); to correct Ext.fly(cells[i]).addCls('myCls');
I've never done this before but try this out:
Use hiddenchange : ( ColumnModel this, Number columnIndex, Boolean hidden ) event of the columnmodel. Get the column using this.getColumnById(this.getColumnId(columnIndex)) and then access the renderer property of the column. Specifically check the css config option of the column from the docs.
Related
I'm working in a codebase using React (CRA) and TypeScript. We've got the typical settings with a few linters and our own Design System.
Recently, we updated the Design System with CSS in JS, to allow the use of props like width="125px" on any components coming from it. We also introduced a Sizing and Spacing scales, which allows to use width={8} (for example).
While we're trying our best to share the knowledge within the company, I'm seeing some code changes including changes like width="8" (it does make sense that if you're not used to it, a number as prop will usually be set as a string, and you would keep the {} only for actual variables and objects). This still works and outputs the right value in the HTML, but it takes away the validation within the editor (width={30} would be out of our scale and the dev would be notified, width="30" is just a string so we're not checking it).
So TLDR, my question is: Is it possible to type check more aggressively but also in a smart way. My goal would be to:
Allow: {10} "10px" "10rem" "10%" "inherit" etc.
Deny: "10"
Allow "10" on other props like line-height or font-weight (typed separately so I don't even think this needs to be changed)
Right now, if I take width for example, the typing is using our own scale going from {1} to {18}:
export type Width<TLength = (string & {}) | 0> =
| Globals
| TLength
| "-moz-fit-content"
| "-moz-max-content"
| "-moz-min-content"
| "-webkit-fit-content"
| "-webkit-max-content"
| "auto"
| "fit-content"
| "intrinsic"
| "max-content"
| "min-content"
| "min-intrinsic"
| (string & {});
You can use Template Literal Types (tsc >=4.1)
type Nums = 1 | 2 | 3;
type Unit = "px" | "em" | "%";
type NumWithUnit = `${number}${Unit}`
type Width = Nums | NumWithUnit | "inherit"
const passes: Width[] = [
1, 2, 3,
"10px",
"1.5em",
"50%",
"inherit"
]
const fails: Width[] = [
// #ts-expect-error
4,
// #ts-expect-error
"10",
// #ts-expect-error
"x em"
]
Playground
Is there a way to pass an array of parameters instead of passing each parameter individually?
For example I have the following scenarios:
When i login to a site
then <firstname>, <lastname>, <middleName>, <Desingation>, <Street>, <Apartmentno> are valid
The list can go on above. Instead can I pass all the above variables in an array?
You can pass a comma separated string and then transform it into a list:
When i login to a site
then 'Joe,Bloggs,Peter,Mr,Some street,15' are valid
[Then("'(.*)' are valid")]
public void ValuesAreValid(List<String> values)
{
}
[StepArgumentTransformation]
public List<String> TransformToListOfString(string commaSeparatedList)
{
return commaSeparatedList.Split(",").ToList();
}
if you want the values to come from examples then you could do this instead:
When I login to a site
then '<values>' are valid
Examples
| values |
| Joe,Bloggs,Peter,Mr,Some street,15|
| Joe,Bloggs,Peter,Mr,Some street,16,SomethingElse,Blah|
If you want to use a table then you could do this instead:
When I login to a site
then the following values are valid
| FirstName | LastName | MiddleName | Greeting| Etc | Etc |
| Joe | Bloggs | Peter | Mr | you get| The Idea|
(you could omit the headers if you want and just use the row values I think)
you can also use examples with this:
When I login to a site
then the following values are valid
| FirstName | LastName | MiddleName | Greeting | Etc | Etc |
| <name> | <lastName>| <middleName>| <greeting>| <etc> | <etc> |
This might be of help:
https://github.com/techtalk/SpecFlow/wiki/Step-Argument-Conversions
Add the following code snippet to your Common Step Definition File:
[StepArgumentTransformation]
public string[] TransformToArrayOfStrings(string commaSeparatedStepArgumentValues)
{
string sourceString = commaSeparatedStepArgumentValues;
string[] stringSeparators = new string[] { "," };
return sourceString.Split(stringSeparators, StringSplitOptions.None);
}
SpecFlow will then automatically convert all comma-separated values in the SpecFlow Steps data table into an array of strings.
Then in your individual step binding function, change the type of the input parameter as string[] as in snippet below:
[Then(#"the expected value is '(.*)'")]
public void ThenTheExpectedValueIs(string[] p0)
{
//ScenarioContext.Current.Pending();
Assert.AreEqual(25, Convert.ToInt32(p0[0]));
Assert.AreEqual(36, Convert.ToInt32(p0[1]));
Assert.AreEqual(79, Convert.ToInt32(p0[2]));
}
Then, based on your expected value for a test step, you may want to apply the appropriate type conversion.
Just transfer the data as a string Example:
Then LEDS 0, 1, 7 are on
[Then(#"LEDS (.*) are on(.*)]
public void ThenLEDAreOn(string p0)
{
int count = p0.Split(',').Length - 1;
string[] Leds_on = p0.Split(',');
foreach (string s in LEDs_on)
{
int.TryParse(s, out LEDS[index]);
index++;
}
}
Then you have your values as integers in an array
A simple select of this form:
$select = $this->select();
return $rowset = $this->fetchAll($select);
Now, There is an inherit column in the array, so the table is of the form:
id | role | inherits |
1 | admin | 2 |
2 | player | 3 |
And When displayed I would like the inherirs column to show the Role it actually inherits from instead of the id.
The array returned by Zend_Db_Table_Abstract is extremely convoluted, so I can't just say:
$array[0][inherits]
First of all $this->fetchAll will not return array it is going to return Zend_Db_Table_Rowset_Abstract object. You can learn more about it here in Zend_Db_Table_Rowset Zend Docs.
You can get data from it as an object
// use Zend_Db_Table_Row_Abstract object
$array[0]->inherits
Or if you want to get an array you can do this:
// get rowset and convert it to array
$rowset = $this->fetchAll($select);
$data = ($rowset) ? $rowset->toArray() : array();
Better solution would be to write a left join on the same table and get the role in the dataset without any PHP code.
$sql = $this->getAdapter()->select()
->from(array('r1' => 'your_roles_table'), '*')
->joinLeft(array('r2' => 'your_roles_table'), 'r2.id = r1.inherits', array(
'inherits_role' => 'r2.role',
));
$data = $this->getAdapter()->fetchAll($sql);
var_dump($data);
The AngularJS Noob Handbook has some code which reduces class manipulation to a simple expression and binding :
<a ng-click="flags.open=!flags.open">...<div ng-class="{active:flags.open}">
However, what is the expression syntax in ng-class? I understand that a vertical bar (|) would pass through a filter and that a filter can be passed parameters after a colon but the above code is doing something different. If the scope variable on the right evaluates to true then the expression on the left is included otherwise it's dropped.
Is this specific to the ng-class directive? Is there some documentation on http://docs.angularjs.org that explains this?
This is mentioned briefly (too briefly, in my opinion) in the ngClass documentation. If you pass an object to ngClass, then it will apply each key of the object as a class to the element if that key's value is true. For example:
$scope.first = true
$scope.second = false
$scope.third = true
with
<div ng-class="{a: first, b: second, c: third}"></div>
would result in
<div class="a c"></div>
you've probably also seen something like this:
<div ng-class="{true: 'complete'}[item.Id != 0]"></div>
Very rad syntax.
EDIT:
What happens here, is that the "complete" class is added to the element if(item.Id != 0). Alternatively, we could write: <div ng-class="{false: 'cookieless'}[monsterEatsCookies('Elmo')]. As its decided by the monsterEatsCookies function, Elmo does not eat cookies so since this function returns false the html element gains a class called cookieless.
A simple example: <div ng-class="{false: 'DoubleNegative'}[1 == 0]. 1 !== 0 which is "false" -- the "DoubleNegative" class is added to the element.
<div ng-class="{ true: 'complete' } [item.Id != 0]"></div>
`
| | | | | | | |
| |result| |className | | | |
| | | | |
| function | | | condition |
Addendum
Also, I just realized that you can use a variety of different keys to map to your condition. For example:
ng-class="{ true: 'highlight', undefined: 'mute' }[ item.hasValue ]"
The mute class will be applied if item has no "hasValue" property. Furthermore, you can apply a class for any given type or value:
{'Jonathan Chapman': 'embolden', '[object Object]': 'hide'}[ item.toString() ]
In the following collection, this would embolden a person's name while hiding items that are objects:
[
'Jonathan Chapman',
{ aka: 'Johnny Applyseed' },
'Brad Pitt',
{ details: 'Fights Zombies' }
]
With this, you could watch for specific values in any $scope property. I suppose this could come in very handy at times.
Cheers
ng-click="flags.open=!flags.open"
switch the value of the flags.open to true or false.
And
ng-class="{active:flags.open}"
decides whether the class active is present or not based on the value of flags.open.
Please see the Fiddle demonstrating the above example.
like this example below :
div(ng-class=" condition ? ['class_one', 'class_two'] : ['class_three', 'class_four']")
Here's how you can pass expression with filter:
<div ng-class="{ 'customer-page': ('customer' | isRoute),
'orders-page': ('orders' | isRoute) }">....</div>
Okay, I have what I think is a simple question.. or just a case of me being a C# beginner.
I have an array of custom objects (clsScriptItem) that I am populating from a database. Once the items are loaded, I want to back them up to "backup" array so I can revert the information back after changing the main array. However, when I use CopyTo to copy the array and then alter the original array, the backup array is also being altered... I thought CopyTo merely copied values + structure from one array to another.
private void backupItems()
{
//lastSavedItems and items are both of type clsScriptItem[]
//(declaration not shown)
lastSavedItems = new clsScriptItem[items.Length];
items.CopyTo(lastSavedItems, 0);
//items[0].nexts[0] is 2
//lastSavedItems[0].nexts[0] is 2
items[0].nexts[0] = "-1";
//items[0].nexts[0] is -1
//lastSavedItems[0].nexts[0] is also -1
}
How do I backup this data without having the two arrays be 'linked'??
UPDATE :
I have updated the backup function to this
private void backupItems()
{
lastSavedItems = new clsScriptItem[items.Length];
for (int i = 0; i < items.Length; i++)
lastSavedItems[i] = (clsScriptItem)items[i].Clone();
items[0].nexts[0] = "-1";
}
And I have update my class thusly....
public class clsScriptItem : ICloneable
{
//other declarations...
object ICloneable.Clone() { return Clone(); }
public clsScriptItem Clone()
{
return ((clsScriptItem)MemberwiseClone());
}
}
** - and the same thing is happening.. Any thoughts?**
they aren't linked, you are using references to objects (So the second array contains 'pointers' to elements, which are the same as 'pointers' in first array..) so declare clsScriptItem as struct, or implement ICloneable interface and use
for(int i = 0; i < items.Length; i++)
lastSavedItems[i] = (clsScriptItem)items[i].Clone();
try this:-
public static MyType[] DeepClone(MyType[] obj)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (MyType[])formatter.Deserialize(ms);
}
}
This is a classic shallow copy vs deep copy problem. When you copy an array of reference types it is merely the references that are copied, not the objects those references point to. So your end result is two arrays that contain references to the same objects.
So when you copy an array that looks like this
Original
----
| |
| 0 |---> Cls
| |
----
| |
| 1 |---> Cls
| |
----
You get this
Original Copy
---- ----
| | | |
| 0 |---> Cls <--- | 0 |
| | | |
---- ----
| | | |
| 1 |---> Cls <--- | 1 |
| | | |
---- ----
If you change the referenced object in any way and it will look like you've changed the contents of both arrays when really all you've done is change the single object pointed to by both arrays.