I would like to add additional fees to Woocommerce. If in the cart we have few products with attribute "consigne", fees of only one product_ID are returning. How to correct the problem ? (Sorry for my imperfect English :-D)
function woo_add_cart_fee(){
global $woocommerce;
if(is_admin() && !defined('DOING_AJAX'))
return;
//Initialisation of costs
$consigne = 0.5;
//cart
$cart = $woocommerce->cart->get_cart();
foreach($cart as $product)
{
$the_product = get_product($product['product_id']);
//fee - products
$nb_products = $product['quantity'];
$activation_cost += ((float) $the_product->get_attribute('Consigne')) * $nb_products;
}
//intergration fees
if( $activation_cost >= 0 )
{
$woocommerce->cart->add_fee("Consigne", $consigne*$nb_products, true, '');
}
}
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
I found the solution :
' function woo_add_cart_fee(){
global $woocommerce;
if(is_admin() && !defined('DOING_AJAX'))
return;
//Initialisation des coûts
$consigne = 0.5;
//Parcours du panier
$cart = $woocommerce->cart->get_cart();
foreach($cart as $product)
{
$the_product = get_product($product['product_id']);
//Frais d'activation, un coût par produit
$nb_products1 = $product['quantity'];
$activation_cost += ((float) $the_product->get_attribute('Consigne')) * $nb_products1;
if( $activation_cost >= 0 )
{
$nb_products = $nb_products + $nb_products1 ;
}
}
//Application des coûts calculés
if( $nb_products >= 0 )
{
$woocommerce->cart->add_fee("Consigne", $consigne*$nb_products, true, '');
}
}
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee'); '
Related
Struggling with some Revit code to copy the profile of a floor and use it as the sketch profile for a void extrusion in a family.
Here is the Full Sharp Development Code. It half works in my custom project template, when I try to use it in an out of the box project generated from revit default template it gives the error "a managed exception was thrown by revit or by one of its external applications"
In my template it cannot properly split the curves into a secondary array. It says the array elements are being changed but when the loop runs again the element i is back to it's original content??? The TaskDialog clearly says the elements have changed, until the loop iterates again.
Full code: To work it requires a generic family with the name "Void - Custom" to be in the project. The "If found" near the bottom last page and a half of code, is where the for loop is not behaving as expected.
/*
* Created by SharpDevelop.
* User: arautio
* Date: 4/30/2019
* Time: 11:10 AM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace ARC
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.DB.Macros.AddInId("3411F411-6FC1-4A4D-9CFD-37ABB2028A15")]
public partial class ThisApplication
{
private void Module_Startup(object sender, EventArgs e)
{
}
private void Module_Shutdown(object sender, EventArgs e)
{
}
#region Revit Macros generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(Module_Startup);
this.Shutdown += new System.EventHandler(Module_Shutdown);
}
#endregion
public void FloorGrating()
{
StringBuilder sb = new StringBuilder();
Dictionary<Floor, List<ModelCurve>> dict_SketchLines = new Dictionary<Floor, List<ModelCurve>>();
UIDocument uidoc = this.ActiveUIDocument;
Document document = uidoc.Document;
View activev = document.ActiveView;
ElementId levelId = null;
levelId = activev.LevelId;
Element levelem = document.GetElement( levelId );
Level lev = document.ActiveView.GenLevel;
Reference refsel = uidoc.Selection.PickObject(ObjectType.Element, "Select Floor to Add Grating To");
Element elem = document.GetElement(refsel.ElementId);
Floor f = elem as Floor;
List<ElementId> _deleted = null;
using (Transaction t = new Transaction(document, "temp"))
{
t.Start();
document.Regenerate();
_deleted = document.Delete(elem.Id).ToList();
t.RollBack();
}
bool SketchLinesFound = false;
List<ModelCurve> _sketchCurves = new List<ModelCurve>();
foreach (var id in _deleted)
{
ModelCurve mc = document.GetElement(id) as ModelCurve;
if (mc != null)
{
_sketchCurves.Add(mc);
SketchLinesFound = true;
}
else
{
if (SketchLinesFound) break;
}
}
dict_SketchLines.Add(f, _sketchCurves);
foreach (Floor key in dict_SketchLines.Keys)
{
List<ModelCurve> _curves = dict_SketchLines[key];
sb.AppendLine(string.Format("floor {0} has sketchlines:", key.Id));
foreach (ModelCurve mc in _curves)
{
sb.AppendLine(string.Format("{0} <{1}>", mc.GetType(), mc.Id));
sb.AppendLine(string.Format("<{0}>", mc.GeometryCurve.IsBound.ToString()));
if (mc.GetType().ToString() == "Autodesk.Revit.DB.ModelArc" && mc.GeometryCurve.IsBound == false)
{
TaskDialog.Show("Revit", "Circle Found");
}
try
{
sb.AppendLine(string.Format("<{0} -- {1}>", mc.GeometryCurve.GetEndPoint(0), mc.GeometryCurve.GetEndPoint(1)));
}
catch
{
}
}
sb.AppendLine();
}
//TaskDialog.Show("debug", sb.ToString());
Document docfamily;
Family fam;
string ftitle = document.Title;
string fpath = document.PathName;
int ftitlelen = ftitle.Length + 4;
int fpathlen = fpath.Length;
int finpathlen = fpathlen - ftitlelen;
string sfinpath = fpath.Substring(0,finpathlen);
string famname = "GratingVoid";
string fext = ".rfa";
int counter = 1;
while (counter < 100)
{
famname = ("GratingVoid" + counter as String);
Family family = FindElementByName(document,typeof(Family),famname)as Family;
if( null == family )
{
sfinpath = (sfinpath + famname + fext);
counter = 1000;
}
counter += 1;
}
FilteredElementCollector collector0 = new FilteredElementCollector(document);
ICollection<Element> collection0 = collector0.WhereElementIsNotElementType().ToElements();
List<FamilySymbol> fsym0 = new FilteredElementCollector(document).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().ToList();
FamilySymbol famsymb0 = null;
foreach (FamilySymbol symb in fsym0)
{
if (symb.Name == "Void - Custom")
{
famsymb0 = symb as FamilySymbol;
}
}
fam = famsymb0.Family;
docfamily = document.EditFamily(fam);
try
{
docfamily.SaveAs(#sfinpath);
}
catch
{
TaskDialog.Show("Revit", "Could Not Save Void Family");
}
using (Transaction trans = new Transaction(docfamily))
{
trans.Start("family");
bool circleflag = false;
ElementId delid = null;
FilteredElementCollector collector = new FilteredElementCollector( docfamily );
foreach(Element element in collector.OfClass(typeof(GenericForm)))
{
delid = element.Id;
}
docfamily.Delete(delid);
CurveArray loccurva = new CurveArray();
foreach (Floor key in dict_SketchLines.Keys)
{
List<ModelCurve> _curves = dict_SketchLines[key];
foreach (ModelCurve mc in _curves)
{
if (mc.GetType().ToString() == "Autodesk.Revit.DB.ModelArc" && mc.GeometryCurve.IsBound == false)
{
circleflag = true;
}
LocationCurve lcurve = mc.Location as LocationCurve;
Curve c = lcurve.Curve as Curve;
loccurva.Append(c);
}
}
try
{
if (circleflag == true && loccurva.Size == 2)
{
Curve tempc;
if (loccurva.get_Item(0).GetType().ToString() == "Autodesk.Revit.DB.Arc")
{
tempc = loccurva.get_Item(0);
}
else
{
tempc = loccurva.get_Item(1);
}
loccurva.Clear();
loccurva.Append(tempc);
}
CurveArrArray newcurarr = new CurveArrArray();
newcurarr.Append(loccurva);
SortCurvesContiguousArray(newcurarr);
TaskDialog.Show("Revit CurveArray Array Size" , newcurarr.Size.ToString());
foreach (CurveArray ca in newcurarr)
{
TaskDialog.Show("Revit CurveArray within Array Size" , ca.Size.ToString());
}
// Below is edited for error control - leaving out the secondary loops for now
CurveArrArray switcharr = new CurveArrArray();
//switcharr.Append(newcurarr.get_Item(1));
switcharr.Append(newcurarr.get_Item(0));
//SortCurvesContiguousArray(loccurva);
//CurveArrArray newcurarr = new CurveArrArray();
//newcurarr.Append(loccurva);
double end = 1;
SketchPlane sketch = FindElementByName( docfamily,typeof( SketchPlane ), "Ref. Level" ) as SketchPlane;
docfamily.FamilyCreate.NewExtrusion(false, switcharr, sketch, end);
}
catch
{
TaskDialog.Show("Revit", "Could Not Write to Curve Array or Create Extrusion");
}
trans.Commit();
}
docfamily.Save();
docfamily.LoadFamily(document, new CustomFamilyLoadOption());
docfamily.Close();
File.Delete(sfinpath);
Family familynew = FindElementByName(document,typeof(Family),famname)as Family;
if( null == familynew )
{
TaskDialog.Show("Revit", "Family Does Not Exist");
}
FilteredElementCollector collector1 = new FilteredElementCollector(document);
ICollection<Element> collection = collector1.WhereElementIsNotElementType().ToElements();
List<FamilySymbol> fsym = new FilteredElementCollector(document).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().ToList();
FamilySymbol famsymb = null;
foreach (FamilySymbol symb in fsym)
{
if (symb.Name == famname)
{
famsymb = symb as FamilySymbol;
}
}
using (Transaction trans = new Transaction(document))
{
trans.Start("PlaceVoid");
if( ! famsymb.IsActive )
{
famsymb.Activate();
}
XYZ p = new XYZ(0,0,0);
FamilyInstance gratingvoid = document.Create.NewFamilyInstance( p, famsymb, lev, lev, StructuralType.NonStructural );
document.Regenerate();
trans.Commit();
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
static public Element FindElementByName(Document doc,Type targetType,string targetName)
{
return new FilteredElementCollector( doc ).OfClass( targetType ).FirstOrDefault<Element>(e => e.Name.Equals( targetName ) );
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
public class CustomFamilyLoadOption : IFamilyLoadOptions
{
public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
return true;
}
public bool OnSharedFamilyFound(Family sharedFamily,bool familyInUse,out FamilySource source, out bool overwriteParameterValues)
{
source = FamilySource.Family;
overwriteParameterValues = true;
return true;
}
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
const double _inch = 1.0 / 12.0;
const double _sixteenth = _inch / 16.0;
static Curve CreateReversedCurve(Curve orig )
{
//if( !IsSupported( orig ) )
//{
// throw new NotImplementedException("CreateReversedCurve for type " + orig.GetType().Name );
//}
if( orig is Line )
{
//return creapp.NewLineBound(orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ) );
return Line.CreateBound(orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ) );
}
else if( orig is Arc )
{
// return creapp.NewArc( orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ), orig.Evaluate( 0.5, true ) );
return Arc.Create( orig.GetEndPoint( 1 ), orig.GetEndPoint( 0 ), orig.Evaluate( 0.5, true ) );
}
else
{
throw new Exception(
"CreateReversedCurve - Unreachable" );
}
}
public static void SortCurvesContiguousArray(CurveArrArray curvesarr)
{
double _precision1 = 1.0 / 12.0 / 16.0; // around 0.00520833
double _precision2 = 0.001; // limit for CurveLoop.Create(...)
int cn = curvesarr.Size;
int ci = 0;
while (ci < cn)
{
CurveArray curves = curvesarr.get_Item(ci);
ci +=1;
// account for multiple curve loops with secondary array
CurveArray loop1 = new CurveArray();
CurveArray loop2 = new CurveArray();
int n = curves.Size;
int split = 1;
// Walk through each curve (after the first)
// to match up the curves in order
for (int i = 0; i < n; ++i)
{
TaskDialog.Show("Revit I Loop Run", i.ToString());
Curve curve = curves.get_Item(i);
if (curve.GetType().ToString() == "Autodesk.Revit.DB.Arc" && curve.IsBound == false)
{
break;
}
XYZ beginPoint = curve.GetEndPoint(0);
XYZ endPoint = curve.GetEndPoint(1);
XYZ p,q;
// Find curve with start point = end point
bool found = (i + 1 >= n);
for (int j = i + 1; j < n; ++j)
{
p = curves.get_Item(j).GetEndPoint(0);
q = curves.get_Item(j).GetEndPoint(1);
// If there is a match end->start,
// this is the next curve
if (p.DistanceTo(endPoint) < _precision1)
{
if (p.DistanceTo(endPoint) > _precision2)
{
XYZ intermediate = new XYZ((endPoint.X + p.X) / 2.0, (endPoint.Y + p.Y) / 2.0, (endPoint.Z + p.Z) / 2.0);
curves.set_Item(i, Line.CreateBound(beginPoint, intermediate));
curves.set_Item(j, Line.CreateBound(intermediate, q));
}
if (i + 1 != j)
{
Curve tmp = curves.get_Item(i + 1);
curves.set_Item(i + 1, curves.get_Item(j));
curves.set_Item(j, tmp);
}
found = true;
break;
}
// If there is a match end->end,
// reverse the next curve
if (q.DistanceTo(endPoint) < _precision1)
{
if (q.DistanceTo(endPoint) > _precision2)
{
XYZ intermediate = new XYZ((endPoint.X + q.X) / 2.0, (endPoint.Y + q.Y) / 2.0, (endPoint.Z + q.Z) / 2.0);
curves.set_Item(i, Line.CreateBound(beginPoint, intermediate));
curves.set_Item(j, Line.CreateBound(p, intermediate));
}
if (i + 1 == j)
{
curves.set_Item(i + 1, CreateReversedCurve(curves.get_Item(j)));
}
else
{
Curve tmp = curves.get_Item(i + 1);
curves.set_Item(i + 1, CreateReversedCurve(curves.get_Item(j)));
curves.set_Item(j, tmp);
}
found = true;
break;
}
}
if (!found)
{
// if not found, must be part of a new loop - move it to the back and keep going and add to second array
TaskDialog.Show("Revit No Match Found for item", i.ToString());
TaskDialog.Show("Revit", "Moveing it to back of list");
Curve tmp1 = curves.get_Item(i);
TaskDialog.Show("Revit tmp1 Current i item endpt", tmp1.GetEndPoint(0).ToString());
loop2.Append(tmp1);
Curve tmp2 = curves.get_Item(n - split);
TaskDialog.Show("Revit tmp2 Back of list item endpt", tmp2.GetEndPoint(0).ToString());
// set current item to rear
curves.set_Item(i, tmp2);
// set rear item to current
curves.set_Item(n - split, tmp1);
TaskDialog.Show("Revit new item i endpt", curves.get_Item(i).GetEndPoint(0).ToString());
TaskDialog.Show("Revit moved item endpt", curves.get_Item(n - split).GetEndPoint(0).ToString());
// error testing - try to append in a different manner and check values
//curves.set_Item(i, Line.CreateBound(curves.get_Item(i).GetEndPoint(0), curves.get_Item(i).GetEndPoint(1)));
//curves.set_Item(n - split, Line.CreateBound(curves.get_Item(n - split).GetEndPoint(0), curves.get_Item(n - split).GetEndPoint(1)));
//Curve ncurve = Line.CreateBound(curves.get_Item(n - split).GetEndPoint(0), curves.get_Item(n - split).GetEndPoint(1));
//TaskDialog.Show("Revit Appended to Loop2 Endpoint", ncurve.GetEndPoint(0).ToString());
//loop2.Append(ncurve);
//set the split off counter so items not fitting in first loop can be split to new array.
split += 1;
//reset the counter back so item moved from rear can be checked in next run of for loop
i -= 2;
}
//set counter to end for loop when all items that do not fit in first loop are processed
if (i >= n - (split + 1))
{
TaskDialog.Show("Revit", "End Of Looping");
TaskDialog.Show("Revit - The Split Number", split.ToString());
i = n;
}
}
int counter = 0;
// recreate array with only items from first loop found
while (counter <= (n - split))
{
loop1.Append(curves.get_Item(counter));
counter += 1;
}
TaskDialog.Show("Revit loop1 Size", loop1.Size.ToString());
curvesarr.Clear();
curvesarr.Append(loop1);
if (loop2.Size > 0)
{
string stringinfo = "";
// run the loop detection on a second array that was split from the first
TaskDialog.Show("Revit loop2 Size", loop2.Size.ToString());
CurveArrArray tmpcurvesarr = new CurveArrArray();
tmpcurvesarr.Append(loop2);
SortCurvesContiguousArray(tmpcurvesarr);
loop2.Clear();
loop2 = tmpcurvesarr.get_Item(0);
curvesarr.Append(loop2);
foreach (Curve ccc in loop2)
{
stringinfo = (stringinfo + " " + ccc.GetEndPoint(0).ToString() + " - " + ccc.GetEndPoint(1).ToString());
}
TaskDialog.Show("Revit", stringinfo);
}
}
}
}
}
Thanks for any and all help.
Shane
I have a support ticket system but I would like my channel to be named as: USERNAME-001.
Even if the old one is deleted, it's still USERNAME-002.
And at 300 it's 001.
I don't know if I was understood.
I would like to be a bit like the public discord bot: Tickety: http://prntscr.com/mwiqp5
Because right now it's like: USERNAME-USERNAMEDISCRIMINATOR : http://prntscr.com/mwit8q
Ask me if you want more details on a part of the code or the request...
My code that creates the current channel:
message.guild.createChannel(message.author.username + " - " + message.author.discriminator, "text").then((channel) => {
Sincerely.
const counter = 0; // This has to defined in previous code. If I were you, I would use a database for this.
As I wrote in the comment, I would use a database for this where you countup with every ticket which is created on a Discord server.
Then you can use the following code:
var reached300 = false;
if (reached300 === true && counter !== 0) {
counter -= 1;
} else {
counter += 1;
}
if (counter === 300) {
reached300 = true;
} else if (counter === 0) {
reached300 = false;
}
var counterName;
if (counter <= 10) {
counterName = `#000${counter}`
} else if (counter <= 100) {
counterName = `#00${counter}`
} else if (counter <= 1000) {
counterName = `#0${counter}`
} else {
counterName = `#${counter}`
}
message.guild.createChannel(`ticket-${counterName}`, "text").then((channel) => {
// CODE HERE
});
I need to convert this JavaScript function to jQuery and also to optimize it.
const sprHundredMan = 9.58,
sprHundredWoman = 10.49,
sprTwoHundredMan = 19.19,
sprTwoHundredWoman = 21.34,
sprFourHundredMan = 43.03,
sprFourHundredWoman = 47.60,
longJpMan = 8.95,
longJpWoman = 7.52,
highJpMan = 2.45,
highJpWoman = 2.09;
document.getElementById('button-calc').addEventListener('click', function (e) {
let myResult = document.getElementById('result').value;
e.preventDefault();
if (document.getElementById('male').checked && document.getElementById('sprint').value == '100') {
let score = sprHundredMan / myResult * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('male').checked && document.getElementById('sprint').value == '200') {
let score = sprTwoHundredMan / myResult * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('male').checked && document.getElementById('sprint').value == '400') {
let score = sprFourHundredMan / myResult * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('female').checked && document.getElementById('sprint').value == '100') {
let score = sprHundredWoman / myResult * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('female').checked && document.getElementById('sprint').value == '200') {
let score = sprTwoHundredWoman / myResult * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('female').checked && document.getElementById('sprint').value == '400') {
let score = sprFourHundredWoman / myResult * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('male').checked && document.getElementById('jump').value == 'Long Jump') {
let score = myResult / longJpMan * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('female').checked && document.getElementById('jump').value == 'Long Jump') {
let score = myResult / longJpWoman * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('male').checked && document.getElementById('jump').value == 'High Jump') {
let score = myResult / highJpMan * 100
document.getElementById('perf').value = score.toFixed(2);
} else if (document.getElementById('female').checked && document.getElementById('jump').value == 'High Jump') {
let score = myResult / highJpWoman * 100
document.getElementById('perf').value = score.toFixed(2);
}
});
I tried to change getElementById with $ and addEventListener with .on but it doesn't work and i do not know how to optimize it. I am beginner level and will be happy if someone help me. Thnak you.
First, no matter which language, if you find yourself using >2 if-else chain, go for switch statements (As I have done below). Such long chain just irritates reader :)
Also, learn some JQuery basics and syntax, changing just "getElementById with $ and addEventListener with .on" won't work. I have changed your code with JQuery selectors in place. See and run the snippet below.
const sprHundredMan = 9.58,
sprHundredWoman = 10.49,
sprTwoHundredMan = 19.19,
sprTwoHundredWoman = 21.34,
sprFourHundredMan = 43.03,
sprFourHundredWoman = 47.60,
longJpMan = 8.95,
longJpWoman = 7.52,
highJpMan = 2.45,
highJpWoman = 2.09;
$("#button-calc").click(function() {
let isMale = $('#male').is(':checked');
let isFemale = $('#female').is(':checked');
let score = 0;
let sprint = $("#sprint").val();
let jump = $("#jump").val();
if (isMale) {
score = (sprint) ? getSprintScore(sprint, sprHundredMan, sprTwoHundredMan, sprFourHundredMan) :
getJumpScore(jump, longJpMan, highJpMan);
} else if (isFemale) {
score = (sprint) ? getSprintScore(sprint, sprHundredWoman, sprTwoHundredWoman, sprFourHundredWoman) :
getJumpScore(jump, longJpWoman, highJpWomann);
} else
score = 0;
$("#perf").val(score.toFixed(2));
});
var getSprintScore = function(sprint, sprHundred, sprTwoHundred, sprFourHundred) {
let myResult = $("#result").val();
let scoreSprint = 0;
switch (sprint) {
case '100':
scoreSprint = sprHundred / myResult * 100;
break;
case '200':
scoreSprint = sprTwoHundred / myResult * 100;
break;
case '400':
scoreSprint = sprFourHundred / myResult * 100;
break;
default:
scoreSprint = 0;
}
return scoreSprint;
};
var getJumpScore = function(sprint, longJp, highJp) {
let myResult = $("#result").val();
return (jump === 'Long Jump') ? myResult / longJpMan * 100 : score = myResult / highJpMan * 100;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="male" type="radio" name="gender" value="male" checked="checked">
<label for="radio1">Male</label>
<input id="female" type="radio" name="gender" value="female">
<label for="radio2">Female</label>
<br/> Sprint: <input type="number" id="sprint">
<br/> Jump: <input type="number" id="jump">
<br/> Result: <input type="number" id="result">
<hr/>
<button id="button-calc">Compute score</button>
<input type="number" id="perf">
I'm facing a problem with my code... I make a query to my DB to check if a mac address of a array of macs is on the DB. If I have any result I return the count of macs in my DB and if is > 0 then I don't add nothing cause the mac already is listed, but if my result.count = 0 then I will add a new record.
My new record just have the mac address. For this I'm trying:
var countRepetidos = 0
var countPromises = []
if (obj.data.list != {} && obj.data.list.length > 0) {
var aux = obj.data["list"]
countRepetidos = 0
for (var i = 0; i < aux.length; i++) {
countPromises.push(Database.Probing.getMacAdress(aux[i]).then(function(data) {
console.log("probing countPromises aux[i] ", aux[i])
if (data.count > 0) {
countRepetidos += 1
} else {
Database.Probing.addMac(aux[i])
}
return Promise.resolve()
}))
}
Promise.all(countPromises).then(() => {
dataRepeated = [obj.data.stats.since, countRepetidos]
listaRepeated.push(dataRepeated)
console.log("probing listaRepeated --> ", listaRepeated)
if (listaRepeated != [] && (listaRepeated[0][0] != undefined && listaRepeated[0][1] != undefined)) {
Database.Probing.getLastTimestamp("probing_repeated", device.id).then(function(data) {
var lastTimestamp = data.date_part
console.log('probing lastTimestamp ', lastTimestamp * 1000)
if (lastTimestamp != listaRepeated[0][0] / 1000) {
Controllers.Agregate.agregateData("probing_repeated", 5 * 60, listaRepeated, dbHistConnectionString, device.id, device.network_id, device.organization_id, ["time", "clients"])
}
})
}
})
}
The problem is after the then of Database.Probing.getMacAddress my aux[i] gets undefined and I need this value to insert into my DB.
Anyone can help?
You need to preserve the value of i. You can do this way:
for (var i = 0; i < aux.length; i++) {
(function(i) {
countPromises.push(
Database.Probing.getMacAdress(aux[i]).then(function(data) {
console.log("probing countPromises aux[i] ", aux[i])
if (data.count > 0) {
countRepetidos += 1
} else {
Database.Probing.addMac(aux[i])
}
return Promise.resolve()
}))
})(i)
}
Edit 1: As suggested by #lain, use let over var
for (let i = 0; i < aux.length; i++) {}
I am using SPD 2010 and SharePoint Sever 2010.
Using conditional formatting I'm trying to format a list so that if today's date is greater than 30 days before the start date column a cell will turn red.
I've tried several XPath expressions from other Stackoverflow entries but nothing has worked. I'm wondering if I am even adding the XPath expression in the right place: In SPD I am selecting a date from the desired column, choosing "Conditional Formatting", selecting "Format Column", selecting "Advanced" and putting my expressions in the XPath expression textbox.
Appreciate your help!
I'm going to suggest a non-Xpath approach, but if you're looking to stick with Xpath you should take a look at the answers on this similar question.
After struggling with this problem myself, I've taken to using JavaScript for conditional formatting, since it can work with dates (including the current date), numbers, and strings, and it can manipulate HTML pretty easily.
A bit of client side code can automatically:
Detect whether a list of conditional formatting rules exists
Create the list if necessary
Provide an interface for creating new rules (which are stored as list items) that should apply to the current page
Loop through all the current page's rules and apply them to any list view web parts detected on the same page
The nicest part of this approach is that I can add the web part to a page and just let the business users configure the formatting to their liking; no need for me to be further involved whenever they want to change something.
I put the combined HTML/CSS/JavaScript in a text file that can be saved to a document library somewhere in my site collection. To then add the conditional formatting to page, I just add a content editor web part to the page and set its "content link" property to be the path to the text file.
The content editor web part then displays a gray "Conditional Formatting" button that the user can click to view and modify the formatting rules, as seen in the screen shot below.
Here's the conditional formatting code for SharePoint 2010 that I use in my text file:
<div id="_conditional_formatting_link" style="display:none; ">
<div unselectable="on" style="display:inline-block; user-select:none; cursor:pointer; padding: 3px; background-color:#9b9b9b; color:white; border:1px solid #888;" onclick="javascript:var rules = document.getElementById('_conditional_formatting'); if(rules.style.display == 'none'){rules.style.display = 'inline-block'}else{rules.style.display = 'none'}">
Conditional Formatting
</div>
</div>
<div id="_conditional_formatting" style="display:none;background-color:#dfdfdf; border: 1px solid black; width:95%; max-width:1100px;">
<a style="border:0px;padding:5px;float:right;" title="Reapply Formatting" href="javascript:getConditions(false);">
<img style="border:0px;" src="/_layouts/images/staticrefresh.gif"/>
</a>
<ol id="_conditional_formatting_rules"></ol>
<div style="text-align:right; ">
<div id="_add_conditional_formatting_rule" unselectable="on" onclick="javascript: Add_Conditional_Formatting();" style="user-select:none; cursor:pointer; padding: 3px; margin: 3px; display:inline-block; background-color:#9b9b9b; border:1px solid #888; color:white;">Add Rule</div>
</div>
</div>
<script>
this.cfl = this.cfl ? this.cfl : new Object(null);
var conditionalFormattingList = "Conditional Formatting";
function getConditions(reloadRules) {
/* if reloadRules, query the conditions list and get all the rules. Otherwise just reapply the ones in memory to the current document. */
if (typeof reloadRules == "undefined") { reloadRules = true; }
if (reloadRules) {
var conditionalFormattingRules = document.getElementById("_conditional_formatting_rules");
while (conditionalFormattingRules.children.length > 0) { /* Clear out the currently displayed list of rules. */
conditionalFormattingRules.removeChild(conditionalFormattingRules.children[0]);
}
this.cfl.clientContext = new SP.ClientContext();
this.cfl.user = cfl.clientContext.get_web().get_currentUser();
var list = cfl.clientContext.get_web().get_lists().getByTitle(conditionalFormattingList);
var camlQuery = new SP.CamlQuery();
var folder = list.get_rootFolder();
camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'URL\' /><Value Type=\'Text\'>' + document.location.pathname + '</Value></Eq></Where><OrderBy><FieldRef Name=\'Priority\' /><FieldRef Name=\'Name\' /></OrderBy></Query></View>');
this.cfl.items = list.getItems(camlQuery);
cfl.clientContext.load(cfl.user);
cfl.clientContext.load(list, 'EffectiveBasePermissions');
cfl.clientContext.load(cfl.items);
cfl.clientContext.load(folder);
}
this.cfl.clientContext.executeQueryAsync(
Function.createDelegate(this,
function () {
var Me = this.cfl.user.get_title();
if (reloadRules) {
var baseFormUrl = folder.get_serverRelativeUrl() + "/EditForm.aspx?ID=";
/* Figure out if the current user has access to create or edit items on the Conditional Formatting list */
var perms = list.get_effectiveBasePermissions();
this.cfl.hasEdit = perms.has(SP.PermissionKind.editListItems);
this.cfl.hasCreate = perms.has(SP.PermissionKind.addListItems);
/* Fill an array with our formatting rules */
this.cfl.targets = [];
var itemEnumerator = this.cfl.items.getEnumerator();
while (itemEnumerator.moveNext()) {
var item = itemEnumerator.get_current();
var targ = new Object(null);
targ.column = item.get_item("Column");
targ.comparison = item.get_item("Comparison");
targ.style = item.get_item("Style");
targ.scope = item.get_item("Scope");
targ.type = item.get_item("Type");
targ.value = item.get_item("Value"); if (targ.value == null) { targ.value = ""; }
targ.id = item.get_item("ID");
targ.offset = item.get_item("Offset");
cfl.targets.push(targ);
}
}
if (!this.cfl.hasCreate) { document.getElementById("_add_conditional_formatting_rule").style.display = "none"; }
for (var targetIterator = 0, len = cfl.targets.length; targetIterator < len; targetIterator++) {
var currentTarget = cfl.targets[targetIterator];
if (reloadRules) {
var rulelist = document.getElementById("_conditional_formatting_rules");
var ruletoadd = document.createElement("li");
var comparisondisplay = currentTarget.type.indexOf("Field") != -1 ? "value of the <b>" + currentTarget.value + "</b> column" : "<b>'" + currentTarget.value + "'</b>";
if (currentTarget.type == "Special" || currentTarget.type == "Number") {
if (currentTarget.value.toString().toLowerCase() == "[me]") { comparisondisplay = "<b>[Me](" + Me + ")</b>"; }
else { comparisondisplay = "<b>" + currentTarget.value + "</b>"; }
}
if (currentTarget.value == "") { comparisondisplay = "<b>(blank)</b>"; }
if (currentTarget.offset != null) {
comparisondisplay += "<b>" + (currentTarget.offset < 0 ? " " : " +") + currentTarget.offset + "</b>"
}
var editLink = this.cfl.hasEdit ? "<div style='display:inline-block;cursor:pointer;' onclick='SP.UI.ModalDialog.commonModalDialogOpen(" + '"' + baseFormUrl + currentTarget.id + '&Source=' + document.location.pathname + '"' + ",{},refreshPageConditions); '>" + "<img src='/_layouts/images/EDITITEM.GIF' style='vertical-align:middle;' title='Customize' alt='Customize'/>" + " </div>" : "";
ruletoadd.innerHTML = editLink + "When <b>" + currentTarget.column + "</b> "
+ currentTarget.comparison + " " + comparisondisplay
+ ", apply {" + (currentTarget.style == null ? "remove all formatting" : "<span style='" + currentTarget.style + "'>" + currentTarget.style + "</span>") + "} to the <b>" + currentTarget.scope + "</b>" + ((currentTarget.scope != "Cell" && currentTarget.scope != "Row") ? " column" : "");
rulelist.appendChild(ruletoadd);
}
var tables = document.querySelectorAll("table.ms-listviewtable"); /* Should get all the list view web parts on the page. */
var t_i = 0;
while (t_i < tables.length) {
var columnIndex = null; /* Index of the column to compare against */
var valueIndex = null; /* Index of a second column from which to pull the value to compare */
var styleTargetIndex = null; /* Index of a column to apply formatting to */
var thisTable = tables[t_i];
var headings = thisTable.rows[0].cells;
var h_i = 0;
while (h_i < headings.length) { /* Check all the column headings... */
var thisHeading = headings[h_i].querySelector("div:first-child");
if (thisHeading != null) {
/* In Internet Explorer, the headings have a DisplayName attribute you can grab. If that's not there, just grab the innerText or textContent */
var dispname = thisHeading.DisplayName ? thisHeading.DisplayName : (thisHeading.innerText ? thisHeading.innerText : thisHeading.textContent);
dispname = dispname.replace(/^\s+|\s+$/g, '');/* removes leading and trailing whitespace */
if (currentTarget.scope != "Cell" && currentTarget.scope != "Row") {
/*If the scope isn't Cell or Row, see if this is the cell to which the formatting should applied */
if (dispname == currentTarget.scope) { styleTargetIndex = h_i; }
}
if (currentTarget.type.indexOf("Field") != -1) {
/*If the value type is a Field, check to see if this is the field whose value we care about */
if (dispname == currentTarget.value.toString()) { valueIndex = h_i; }
}
if (dispname == currentTarget.column) { columnIndex = h_i; }
}
h_i += 1;
}
if (columnIndex != null) { /* If we found a matching heading, let's try to apply the rules... */
var rows = thisTable.rows;
for (var i = (rows.length > 0 ? 1 : 0) ; i < rows.length; i++) {
var cells = rows[i].children;
if (cells.length <= columnIndex) { continue }
var innerLink = cells[columnIndex].querySelector("a"); /* I want to specifically target links so that we can change their text color if necessary */
/* Populate valueToEval with the text value of the current cell, or its inner link if it has one */
var valueToEval = cells[columnIndex].innerText ? (innerLink != null ? innerLink.innerText : cells[columnIndex].innerText) : (innerLink != null ? innerLink.textContent : cells[columnIndex].textContent);
if (typeof (valueToEval) == "undefined") { valueToEval = "" } /* Treat empties as blanks */
var listValueToCompareAgainst = null;
if (valueIndex != null) { /* valueIndex only has a value if we need to grab the comparison value from another column on the list */
valueLink = cells[valueIndex].querySelector("a");
listValueToCompareAgainst = cells[valueIndex].innerText ? (valueLink != null ? valueLink.innerText : cells[valueIndex].innerText) : (valueLink != null ? valueLink.textContent : cells[valueIndex].textContent);
}
var needsStyling = false;
switch (currentTarget.type) {
case "Number":
if (!isNaN(Number(valueToEval))) {
valueToEval = +(valueToEval);
}
if (!isNaN(Number(currentTarget.value))) {
currentTarget.value = +(currentTarget.value);
}
break;
case "Date":
valueToEval = new Date(valueToEval);
currentTarget.value = new Date(currentTarget.value);
if (currentTarget.offset != null) {
currentTarget.value.setDate(currentTarget.value.getDate() + +(currentTarget.offset));
}
break;
case "Text": /* Already covered, bro */ break;
case "Date Field":
valueToEval = new Date(valueToEval);
currentTarget.value = new Date(listValueToCompareAgainst);
if (currentTarget.offset != null) {
currentTarget.value.setDate(currentTarget.value.getDate() + +(currentTarget.offset));
}
break;
case "Text Field": currentTarget.value = listValueToCompareAgainst; break;
case "Number Field":
if (!isNaN(Number(listValueToCompareAgainst))) {
currentTarget.value = listValueToCompareAgainst;
if (currentTarget.offset != null) {
currentTarget.value += Number(currentTarget.offset);
}
}
if (!isNaN(Number(valueToEval))) {
valueToEval = Number(valueToEval);
}
break;
case "Special":
if (currentTarget.value.toLowerCase) {
if (currentTarget.value.toLowerCase() == "[me]") { currentTarget.value = Me }
else if (currentTarget.value.toLowerCase().indexOf("[today]") != -1) {
var dateDifference = Number(currentTarget.value.toLowerCase().replace("[today]", "").replace(" ", "").replace("+", ""));
currentTarget.value = new Date();
if (!isNaN(dateDifference)) { currentTarget.value.setDate(currentTarget.value.getDate() + dateDifference); }
if (currentTarget.offset != null) {
currentTarget.value.setDate(currentTarget.value.getDate() + Number(currentTarget.offset));
}
valueToEval = new Date(valueToEval);
}
} else { valueToEval = new Date(valueToEval); }
break;
}
switch (currentTarget.comparison) {
case "Greater Than or Equal To": needsStyling = (valueToEval >= currentTarget.value); break;
case "Greater Than": needsStyling = (valueToEval > currentTarget.value); break;
case "Less Than or Equal To": needsStyling = (valueToEval <= currentTarget.value); break;
case "Less Than": needsStyling = (valueToEval < currentTarget.value); break;
case "Equal To": needsStyling = (valueToEval == currentTarget.value); break;
case "Not Equal To": needsStyling = (valueToEval != currentTarget.value); break;
case "Contains": needsStyling = (valueToEval.indexOf(currentTarget.value) != -1); break;
case "Does Not Contain": needsStyling = (valueToEval.indexOf(currentTarget.value) == -1); break;
}
if (needsStyling) {
var links;
if (currentTarget.scope != "Row") {
var targetIndex = (styleTargetIndex != null) ? styleTargetIndex : columnIndex;
cells[targetIndex].setAttribute("style", currentTarget.style);
links = cells[targetIndex].querySelectorAll("a");
} else {
rows[i].setAttribute("style", currentTarget.style);
for (var j = 0; j < cells.length; j++) {
cells[j].setAttribute("style", currentTarget.style);
}
links = rows[i].querySelectorAll("a");
}
for (var j = 0; j < links.length; j++) {
if (links[j].title != "Open Menu") {
links[j].setAttribute("style", currentTarget.style);
links[j].style.backgroundColor = "";
}
links[j].style.border = "0px";
}
}
}
}
t_i += 1;
}
}
document.getElementById("_conditional_formatting_link").style.display = "inline-block";
}
),
Function.createDelegate(this,
function (sender, args) { /* There was an error accessing the list. Time to create it! */
var lci = new SP.ListCreationInformation();
lci.set_title(conditionalFormattingList);
lci.set_templateType(SP.ListTemplateType.genericList);
var condition_list = clientContext.get_web().get_lists().add(lci);
clientContext.load(condition_list);
var colTitle = condition_list.get_fields().getByTitle("Title");
colTitle.set_required(false); colTitle.set_hidden(true); colTitle.update();
condition_list.update();
var colColumn = condition_list.get_fields().addFieldAsXml('<Field Description=\'The column to compare (must be visible on the page)\' DisplayName=\'Column\' Type=\'Text\'/>', true, SP.AddFieldOptions.defaultValue);
var colComparison = condition_list.get_fields().addFieldAsXml('<Field Description=\'\' Type=\'Choice\' DisplayName=\'Comparison\' Format=\'Dropdown\' FillInChoice=\'FALSE\'><Default>Equal To</Default><CHOICES><CHOICE>Greater Than</CHOICE><CHOICE>Greater Than or Equal To</CHOICE><CHOICE>Equal To</CHOICE><CHOICE>Less Than or Equal To</CHOICE><CHOICE>Less Than</CHOICE><CHOICE>Not Equal To</CHOICE><CHOICE>Contains</CHOICE><CHOICE>Does Not Contain</CHOICE></CHOICES></Field>', true, SP.AddFieldOptions.defaultValue);
var colValue = condition_list.get_fields().addFieldAsXml('<Field Description=\'The value or the name of a column to compare against\' DisplayName=\'Value\' Type=\'Text\'/>', true, SP.AddFieldOptions.defaultValue);
var colType = condition_list.get_fields().addFieldAsXml('<Field Description=\'Indicate the type of value you are comparing against. Choose Special if using the [Me] or [Today] placeholders.\' Type=\'Choice\' DisplayName=\'Type\' Format=\'Dropdown\' FillInChoice=\'FALSE\'><Default>Text</Default><CHOICES><CHOICE>Date</CHOICE><CHOICE>Number</CHOICE><CHOICE>Text</CHOICE><CHOICE>Date Field</CHOICE><CHOICE>Number Field</CHOICE><CHOICE>Text Field</CHOICE><CHOICE>Special</CHOICE></CHOICES></Field>');
var colOffset = condition_list.get_fields().addFieldAsXml('<Field Description=\'Optionally specify a number to offset the value by when comparing against a number or date.\' DisplayName=\'Offset\' Type=\'Number\' />', true, SP.AddFieldOptions.defaultValue);
var colStyle = condition_list.get_fields().addFieldAsXml('<Field NumLines=\'4\' Description=\'The CSS to apply to when the condition is met. Leave blank to remove formatting. Example syntax: background-color:darkred; color:white; font-weight:bold;\' DisplayName=\'Style\' Type=\'Note\' />', true, SP.AddFieldOptions.defaultValue);
var colScope = condition_list.get_fields().addFieldAsXml('<Field Description=\'The scope to which the style should be applied. Choose Row, Cell, or specify a column name.\' Type=\'Choice\' DisplayName=\'Scope\' Format=\'Dropdown\' FillInChoice=\'TRUE\'><Default>Cell</Default><CHOICES><CHOICE>Cell</CHOICE><CHOICE>Row</CHOICE></CHOICES></Field>', true, SP.AddFieldOptions.defaultValue);
var colPriority = condition_list.get_fields().addFieldAsXml('<Field Description=\'Priority determines which styles are applied in case of overlapping conditions. Higher numbers are applied later.\' DisplayName=\'Priority\' Type=\'Number\' />', true, SP.AddFieldOptions.defaultValue);
var colUrl = condition_list.get_fields().addFieldAsXml('<Field Description=\'Page where this rule should be applied\' DisplayName=\'URL\' Type=\'Text\'/>', true, SP.AddFieldOptions.defaultValue);
clientContext.executeQueryAsync(
Function.createDelegate(this, function () { getConditions(); }),
Function.createDelegate(this, function (sender, args) { document.getElementById("_conditional_formatting").innerHTML = ("An error occcurred while trying to apply conditional formatting to the list for you. Error details: " + args.get_message() + " " + args.get_stackTrace()); document.getElementById("_conditional_formatting_link").style.display = "inline-block"; }));
}
));
}
/* This method is called when the Add Rule button is clicked. */
function Add_Conditional_Formatting() {
/* Create a new item with only the URL and Priority fields filled out */
var currUrl = document.location.pathname;
var clientContext = new SP.ClientContext();
var itemCreateInfo = new SP.ListItemCreationInformation();
var newItem = clientContext.get_web().get_lists().getByTitle(conditionalFormattingList).addItem(itemCreateInfo);
newItem.set_item('URL', currUrl);
/* Give the new item a priority that will put it at the end of the list. This is kind of a hack since the highest priority is not necessarily the rulecount. */
newItem.set_item('Priority', document.getElementById("_conditional_formatting_rules").children.length + 1);
newItem.update();
clientContext.load(newItem);
clientContext.executeQueryAsync(Function.createDelegate(this, function () {
getConditions(); /* Reload to refresh the rules list after adding the item */
}), Function.createDelegate(this, function (sender, args) { alert(args.get_message()); }));
}
/* This method is called when the Edit Item dialog box is closed. It refreshes the page it the item was saved. */
function refreshPageConditions(result) { if (result != SP.UI.DialogResult.cancel) { window.location.replace(document.location.href) } }
ExecuteOrDelayUntilScriptLoaded(function () {
getConditions();
/* If there are any collapsible sections on the page, keep checking to see whether formatting needs to be reapplied */
this.cfl.TableRowCount = 0;
if (document.querySelector("img[alt='expand']") != null) {
setInterval(function () {
var tempTableRowCount = document.querySelectorAll("tr").length;
if (tempTableRowCount != this.cfl.TableRowCount) {
/* Only reapply formatting if the count of table rows is different than it was previously */
this.cfl.TableRowCount = tempTableRowCount;
getConditions(false) /* Passing false reapplies loaded rules without re-querying the SharePoint list */
}
}, 1000)
}
}, "SP.JS");
</script>