Firstly please excuse my phrasing here, quite new to JS.
I have the below JS code running and it works perfectly with the parameters set to colour the 'Assigned Mins' column in my table.
What I am looking to do is add a 2nd parameter where the same colouring and parmeters but adding a column called 'Pending'
for(var i=0; i<columns.length; ++i) {
if(columns[i].text == 'Assigned Mins') {
columns[i].renderer = function (value, meta, rec) {
if(value > '0:19') {
meta.style = "background-color:red;font-weight:bold;color:white;";
}
else if(value > '0:09') {
meta.style = "background-color:orange;font-weight:bold;color:white;";
}
else {
meta.style = "background-color:green;font-weight:bold;color:white;";
}
return value;
I've tried:
if(columns[i].text == 'Assigned Mins','Pending') {
and
if(columns[i].text == 'Assigned Mins'||'Pending') {
and a few other variations using the || and && operators but either nothing happens or it colours all columns in the table.
As suggested I have also just tried the duplicate post (Check variable equality against a list of values) using:
if (['Assigned Mins','Pending'].indexOf(columns[i]) > -1)
and
if (~['Assigned Mins','Pending'].indexOf(columns[i]))
However in both cases the result is that none of the colouring works at all
Please can someone advise?
Thank you
this should work. It's the solution you provided but you just forgot the .text
if (['Assigned Mins','Pending'].indexOf(columns[i].text) > -1)
Related
I currently have a table with a function that checks certain columns that have checkboxes, whenever they are "clicked off", to see if they're all completely empty.
The function does a loop from the first of the checked columns up until the last one that has to be checked. They go from 1 to 8, and their ids go from "f01_check" up until "f08_check". If all are empty, it adds a css class to its description column that changes background color.
The function looks like this:
function unChecked(rowNumber) {
alert(rowNumber);
var i = 1;
var check = false;
// Column loop
while (i < 9 && check == false) {
if (rowNumber.getElementById("f0" + i + "_check").checked == false) {
i++;
} else {
check = true;
}
// If all checkboxes are empty, add class
if (i == 9 && check == false) {
$s(description.addClass(emptyRecords));
}
}
}
The Dynamic Action leading to this function and its parameter is this:
var row = this.triggeringElement.closest('tr');
unChecked(row);
I realize that the rowNumber.getElementById doesn't work, but I can't figure out how to link or connect them. The way I'm looping through the columns might be a rough attempt, but it works. I've tested it on a set column and it it does stop whenever the loop reaches a checked checkbox. The problem is I just can't dynamically set the row to match the one that I've clicked.
I've tried getting the property .rowIndex as well, but I can't figure out where to use it, even if I do get the correct value.
I found a different solution, that also somewhat solves a different problem in the future.
Rather than use rownum to set a dynamic id for the columns, I changed it to it's primary key:
apex_item.checkbox (1, '1_' || pk, decode(data1,null,null,'CHECKED'), null, null, 'f01_' || pk) as lpb1
This basically helped me on knowing which row was being clicked, because the id also held it's primary key. This allowed me to use it's primary key value to improve the function. The item_pkis an item that gets its value from the corresponding table column:
function unChecked(row) { // var row = this.triggeringElement.closest('tr').rowIndex;
// unChecked(row);
var i = 1;
var check = false;
while (i < 9 && check == false) {
if (document.getElementById("f0" + i + "_" + item_pk.value).checked == false) {
i++;
} else {
check = true;
}
if (i == 9 && check == false) {
//addClass Segment
}
}
}
So if the report were to be filtered, the row number wouldn't match what the filter actually showed on the report table.
The previous solution was also fixed by removing the case clause from the select, as follows:
apex_item.checkbox (1, '1_' || a.pk, case when max(decode(data1,1,1,null)) is null then '' else 'CHECKED' end, null, null, 'f01_chk') as lpb1,
But again, the first solution showed actually foresees and handles a filtered report, so I believe it's a superior and more accurate solution.
Now I just need to complete the addClass segment. For some reason Apex is setting the field "static id" as the column header, which is slightly problematic since I meant to use the document.getElementById. But at least the main problem has been fixed. Thanks for the responses.
I am looking for a way to filter out empty cell data from my grid, I have implemented sorting, I am able to get all the blank cell at one place, but it would be great if any kind of filtering is possible on blank cells.
What I was thinking (theoretical), that if we could map the empty cell with some kind of expression e.g. {blank}{`}, anything of that sort then maybe the filtration is possible. But have no idea how to implement that.
function filter(item) {
for (var columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== "") {
var c = grid.getColumns()[grid.getColumnIndex(columnId)];
if (item[c.field] !== undefined)
{
if (item[c.field].toString().toLowerCase().search(columnFilters[columnId].toLowerCase()) === -1) {
return false;
}
} else if(columnFilters[columnId] === "#blank")
{
return true;
} else
return false;
}
}
return true;
}
adding this line "else if(columnFilters[columnId] === "#"){return c;}"
got me all the blank cells (that do not have any data), cell property = "undefined". By typing '#' in the search box all the blank cells get filtered.
So I've written some code to sort all my site's select menus, and it works perfectly in every browser we support... except Firefox.
http://jsfiddle.net/vkjAC/6/
My code takes in the options for a select element, sorts them, and returns them. Somewhere in there, the selectedIndex on the select element changes to the last item.
I check what values are selected/defaultSelected:
for(k=0; k<options.length; k++)
{
if(options[k].defaultSelected == true)
{
sel = k;
break;
}
}
if(sel === null)
{
for(k=0; k<options.length; k++)
{
if(options[k].selected == true)
{
sel = k;
break;
}
}
}
if(sel === null)
{ options[0].selected = true; }
else
{ options[sel].selected = true; }
But I can't set the selectedIndex from this function because I'm not passing in the entire select object, just the option list.
I tried looking up similar problems, but every other thread I saw said it was a caching problem, or that I needed to add autocomplete="off", but those didn't work. I assume it has something to do with my code, but I haven't modified the selectedIndex property anywhere.
Any suggestions? I'm losing my mind (and running out of time!)
I've had this before. It has something to do with the fact that the options are removed then added again. You have to re-select the value after sorting. For example:
var ops = $('#mass').find('option');
$('#mass').prepend(sortDropDown(ops)).val($("#mass > option[selected]").val());
I'm wanting to set the tab order on my forms to go left to right. I've seen the following code around the web
for (var i = 0; i < crmForm.all.length; i++)
{
var element = crmForm.all[i];
if (element.tabIndex && element.tabIndex != "0") {
if (element.className == 'ms-crm-Hidden-NoBehavior')
continue;
if (element.tagName == 'A') {
if (element.className != 'ms-crm-InlineTabHeaderText')
continue;
}
element.tabIndex = 10000 + (i * 10);
}
}
which sets the tab order as i want it. However there is a problem when it comes to currency fields as when you first tab into it the currency symbol is selected, and you can't type anything, and you have to tab again to be able to type anything into the field.
Is there a way for the code to ignore these symbols and go straight into the field itself?
Thanks
Your approach constitutes an unsupported customisation, but with a little manual work you can achieve the same outcome in a fully supported way. All you need to do is add a new "Section" (without showing the header or divider) to your form, for every row of fields.
The result is no unsupported JScript and predictable behaviour that is entirely consistent with the rest of the application.
In my example below I show an example of how I must lay out my form so that native tabbing behaviour "makes sense". However if I wish to use horizontal tabbing, I can rearrange my form, introduce some new sections and then have it work as I want without code.
The beauty of this approach is that it only affects the parts of the form that you want it to.
While technically it's unsupported still, I seem to have fixed the currency problem here:
function TabOrderLefttoRight() {
for (var i = 0; i < crmForm.all.length; i++) {
var element = crmForm.all[i];
if (element.tabIndex && element.tabIndex > "0") { //less than zero instead of !=
if (element.className == 'ms-crm-Hidden-NoBehavior')
continue;
if (element.tagName == 'A') {
if (element.className != 'ms-crm-InlineTabHeaderText')
continue;
}
element.tabIndex = 10000 + (i);
}
}
}
This way it does not affect items that are below 0 in tabindex (currency fields).
I have an if statement:
if(firstString == "no" && secondString == "no" && thirdString == "no"){
// Do stuff here
}
Is there a prettier way to format this? Using false instead of "no" is not an option, since the data I'm checking is from an AJAX request and I don't control its output. Otherwise I'd write it this way:
if(!firstString && !secondString && !thirdString){
// Do stuff here
}
Thanks
UPDATE:
I know this is totally ridiculous, but it occurred to me that this might actually be the shortest way:
if(firstString + secondString + thirdString == "nonono"){
// Do stuff here
}
Given that the number of strings is known in advance, then you have 2 options as far as I can see..
Leave it as it is. The if statement isn't hard to read, and any alternate formats will either be as complicated or more complicated.
convert the strings to booleans when you retrieve the data from the AJAX request, so that you're storing TRUE or FALSE instead of "yes" and "no". That would allow you to use a your preferred if statement format, and might be more efficient than many string comparisons if you do a lot of them.
In the end, which you do is up to you, but personally I think it would be better to just stick with what you've got. Don't worry about formatting an if statement, it's pretty obvious what it does, and in my opinion doesn't need to change.
If( "no" == firstString && firstString == secondString && secondString == thirdString )
It was a little difficult to determine exactly what you are evaluating to true or false, but this can be tweaked a tad to get what you're looking for.
var checkStrings = function() {
var no = "no",
args = Array.prototype.slice.call(arguments);
for (var i = 0, len = args.length; i < len; i++) {
if (args[i] !== no) {
return false;
}
}
return true;
};
if (checkStrings(firstString, secondString, thirdString)) {
// Do stuff here
}
Sorry, wasn't thinking--this is if you were checking whether ANY were 'no'
if ($.inArray('no', [firstString, secondString, thirdString]) >= 0) {
// Do something if the value is 'no'
}
UPDATED ANSWER
Unfortunately, jQuery doesn't have the reduce() function (another Array extra introduced in JS 1.6, but not available in older browsers) which would do the trick nicely.
Here's one way to check if all are 'no':
var found = true;
$.each([firstString, secondString, thirdString], function (i, str) {
if (str !== 'no') {
found = false;
}
});
It may seem uglier, but it should be shorter if you have a lot more strings to check.
If you want it wrapped in a function you could do:
function allTrue (arr, checkStr) {
var found = true;
$.each(arr, function (i, str) {
if (str !== checkStr) {
found = false;
}
});
return found;
}
if (allTrue([firstString, secondString, thirdString], 'no')) {
// ...
}
function F(var value){
return value === "no";
}
if(F(firstString) && F(secondString) && F(thirdString)){
// Do stuff here
}
Another option, using jQuery.unique:
var uniques = $.unique([firstString, secondString, thirdString]);
if (uniques.length === 1 && uniques[0] === "no") {
// do stuff
}