{"id":26674819,"url":"https://github.com/intersel/jamrules","last_synced_at":"2025-04-12T07:23:02.939Z","repository":{"id":74553110,"uuid":"83233470","full_name":"intersel/jamrules","owner":"intersel","description":"Javascript/jQuery configurator to match rules on massive number of objects","archived":false,"fork":false,"pushed_at":"2025-03-04T20:36:22.000Z","size":1213,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T02:41:23.440Z","etag":null,"topics":["business-rules","configurator","engine","filtering","finite-state-machine","jquery","jquery-plugin","rule-engine","rules"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/intersel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-26T19:11:02.000Z","updated_at":"2025-03-04T20:36:25.000Z","dependencies_parsed_at":"2025-02-20T00:25:32.482Z","dependency_job_id":"cfd73237-cd42-4569-9da1-6d647ab0fee7","html_url":"https://github.com/intersel/jamrules","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intersel%2Fjamrules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intersel%2Fjamrules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intersel%2Fjamrules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intersel%2Fjamrules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/intersel","download_url":"https://codeload.github.com/intersel/jamrules/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248531345,"owners_count":21119747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["business-rules","configurator","engine","filtering","finite-state-machine","jquery","jquery-plugin","rule-engine","rules"],"created_at":"2025-03-26T02:39:20.945Z","updated_at":"2025-04-12T07:23:02.915Z","avatar_url":"https://github.com/intersel.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JamRules\nJavascript/jQuery filtering tool that helps to filter objects among a set of objects according to rules.\n\n# What is JamRules?\nLet's say you have a set of objects with properties and you'd like to filter them according to a user configuration of criteria and specific rules of selection... then JamRules is for you!\n\nJamRules is a Javascript/jQuery library.\n\nWith it, you configure:\n  * a set of parameters/criteria of selection (filters configurator) that can be driven by checkboxes and input\n  * a set of rules to find the objects according to the filters configuration\n  * a set of objects to play with\n\nOnce configured, you can start the filtering process so that JamRules selects the objects that match your criteria and calls a 'selected' function on each of them, and call a 'not selected' function for the others...\n\n![alt JamRules designed for the selection of objects](https://cloud.githubusercontent.com/assets/1048488/24730721/91d34c04-1a65-11e7-8fb8-9e47dec60691.jpg)\n\nFor example, connected to a dialog box of criteria managed with checkboxes, JamRules can be activated each time a criteria changes and so to alert the selected/unselected object of their new selection status, for instance to be displayed or not...\n\nAs an object filter library, Jamrules is your best friend! Ideal for product configurators, objects selection on criteria, ...\n\n[See JamRules in action](https://demo.intersel.fr/jamrules/tests/filterDocsExclusive.html) (source code in test/filterDocsExclusive.html)\n\n# How it works...\nTo run jamrules, you will have to:\n* create a jamrules object,\n* define the filter configuration\n* create rules,\n* add objects to test,\n* run the filtering process,\n\n## Create a Jamrules object\n\n```javascript\n//Create a jamrules object\nvar rulesEngine = jamrules.build();\n```\n\n## Identify the properties used to filter\n\nThe properties are data that define your object. They are used to identify the objects that answer your filtering rules.\n\nEg, if your objects to filter are animals, properties of an animal may be \"Type\" ('mammal', 'bird', 'insect', ...), \"Name\" ('cat', 'dog', ...), \"Number of limbs\" (0,2,4,8, ...), \"Color\" ('brown', 'green', ...), ...\n\nSome of the properties may be used in the filtering configuration to select the objects.\n\nYour objects needs to have a json definition, eg. :\n\n```javascript\nlet myobjects = [\n  {\n    \"type\":\"mammal\",\n    \"name\":\"cat\",\n    \"color\":\"black\"\n  },\n  {\n    \"type\":[\"mammal\",\"carnivora\"],\n    \"name\":\"dog\",\n    \"color\":\"white\"\n  },\n  //and so on\n  ]\n```\n\nA same property may have several values.\n\nEach object may have its own set of properties that may be different from the other object's sets... Up to you to define in your rules how to select or not your objects...\n\n## Add objects\n\nUse the function **addPropertyObjects** of your rules engine to add your objects and the behavior of the selected and not selected objects by jamRules:\n\n```javascript\nrulesEngine.addPropertyObjects(\n  myobjects,\n  function(){console.log('I am selected:'+this.name)},\n  function(){console.log('I am NOT selected'+this.name)}\n);\n```\n\n## Filtering configuration\n\nGenerally, the filtering configuration is driven by the status of checkboxes, radio buttons, input... that the user can click to select a configuration value. These input set the status of the value of a property as chosen or not.\n\nFor example, for the property \"color\", you could set several checkboxes, each allowing to select a color as \"red\", \"blue\", \"green\", ...\n\nTo configure the property values of the configurator, we use the function **selectConfigurationPropertyValue**.\n\n```html\n\u003clabel for=\"check_green\" onclick=\"rulesEngine.selectConfigurationPropertyValue(\"color\",\"green\",$(this).children('input').value());\"\u003e\n  \u003cinput type=\"checkbox\"\u003e\n  Green\n\u003c/label\u003e\n\u003clabel for=\"check_red\" onclick=\"rulesEngine.selectConfigurationPropertyValue(\"color\",\"red\",$(this).children('input').value());\"\u003e\n  \u003cinput type=\"checkbox\"\u003e\n  Red\n\u003c/label\u003e\n```\n\n## Define the rules to select objects\n\nA rule is a boolean test on your configuration and objects.\n\nRules are defined within a rule set. You can defined as rule sets as you need.\n\nIf all the rules in a rule set are valid ('and'), then the object is selected.\n\nHence, to be selected (\"matched\"), an object should match ONE rule set. If none of the rule sets are validated by the object, it is considered as \"not matched\"...\n\nThe rules will be based on pre-defined test functions as \"is property xxx of object equal this value?\" (ObjectPropertySet), \"is property value is selected in the filtering configuration?\" (MatchProperty), ...\n\nSo, you first define your rule set, then add rules in it, then define a second rule set, and so on...\n\n```javascript\n\n// rules setting\nrulesEngine.createRulesSet(\"HasGreenColor\");\n\trulesEngine.addRule(\"HasGreenColor\",\"lightgreen\",'ObjectPropertySet(\"color\",\"light green\")');\n\trulesEngine.addRule(\"HasGreenColor\",\"darkgreen\",'ObjectPropertySet(\"color\",\"dark green\")');\n\trulesEngine.addRule(\"HasGreenColor\",\"green\",'ObjectPropertySet(\"color\",\"green\")');\n\n```\n\n## Test your objects against the rules...\n\nOnce done, we will be able to run our jamrules engine with **runRulesEngine**:\n\n```Javascript\nrulesEngine.runRulesEngine();\n```\n\nAny object that matches the rules will have their \"Matched\" function called. Any object that is not selected with the rules will have their \"NotMatched\" function called....\n\n\n# Demos\n* [filtering of animals according to filters](https://demo.intersel.fr/jamrules/tests/exampleReadMe.html) (source code in test/exampleReadMe.html)\n* [filtering of documents according to filters that include (or not) the docs](https://demo.intersel.fr/jamrules/tests/filterDocsInclusive.html) (source code in test/filterDocsInclusive.html)\n\n# Create the JamRules object: jamrules.build(options)\n\n```Javascript\n\n//initialisation of jamrules and its configurator\nvar rulesEngine = jamrules.build({\n\t\"debug\":\t\t\"\u003cboolean\u003e\", //default: false\n\t\"matched\":\t\"\u003ca function to call when the rule find a match\u003e\", // default: null\n\t\"notmatched\":\t\"\u003ca function to call when the rule did not find a match\u003e\",// default: null\n  \"matchedFunctionName\": \"\u003cproperty name for the 'matched' function in objects\u003e\",// default: matched\n  \"notmatchedFunctionName\": \"\u003cproperty name for the 'notmatched' function in objects\u003e\"// default: notmatched\n  \"startProcessing\": \"\u003ca function to call when rule engine starts to process rules\u003e\"// default: null\n  \"stopProcessing\": \"\u003ca function to call when rule engine finished to process rules\u003e\"// default: null\n});\n```\n\n## the options parameter\n### debug\nif true, the rule engine will send debug message on the console\n\n\n### the \"Matched\" and \"NotMatched\" functions\n\nThe \"matched\" and \"notmatched\" functions are called whenever the rule engine matches an object profile.\n\nFunctions have the following parameters:\n  * aListOfMatchedObjects: the list of objects that matched the rule\n  * this refers to the rule engine object\n\n**Remarks**: These functions are not to be confused with the ones defined on the object level...\n\n### \"matchedFunctionName\" and \"notmatchedFunctionName\" options\n\nThese options allows to change the default property names of the object that define the 'matched' and 'notmatched' functions of it.\nMay be used if by any chance, these property names are used for other things...\n\n\n# The JamRules Objects\nIn order to test objects with jamrules, you have to give it objects to test against the rules defined in the rule engine.\n\nThese objects may be any with properties...\n\n```javascript\n{\n\t\"color\": \"red\",\n\t\"size\": \"xl\",\n\t...\n}\n```\n\nInternally, the objects are formatted in order to process the matching functions and rules, the internal format of your data in jamrules will be :\n\n```javascript\n{\n\tpropertiesSet:{\n\t\t\u003cpropertyName1\u003e:{\u003cpropertyValue1:\u003c0|1\u003e,\u003cpropertyValue2:\u003c0|1\u003e, ...},\n\t\t\u003cpropertyName2\u003e:{\u003cpropertyValue1:\u003c0|1\u003e,\u003cpropertyValue2:\u003c0|1\u003e, ...},\n\t\t...\n\t},\n\tmatched: \u003ca function to call when it matches\u003e,\n\tnotmatched: \u003ca function to call when it does not match\u003e,\n}\n```\n\neg:\n```javascript\n{\n\tpropertiesSet:{\n\t\tcolor: {red:1},\n\t\tsize: {xl:1}\n\t\t...\n\t},\n\tmatched: function(ruleEngine){console.log(\"object matched!\")},\n\tnotmatched: null,\n}\n```\n\n\n\n\n**Remark**: The properties of the objects should be \"static\". The use of functions to define dynamic properties within objects is not possible.\n\n# The JamRules Filtering Configurator\nThe JamRules filtering configurator is a special object that can be used in a rule to test a configuration of properties against the properties of the objects to filter.\n\nFor example, let's say we have white and black trousers.\nIf you'd like to get only the white trousers, you can set a configurator property \"color\" with a \"white\" property value set to 1.\nThen you'll be able to test this configurator property against your objects.\n\nThe **selectConfigurationPropertyValue** function allows to create and edit such entry in the configurator.\n\n\n```javascript\nrulesEngine.selectConfigurationPropertyValue(\"color\",\"white\",1);\n\n```\n\n# The JamRules rules\n\n## Rules set\n\nWhen \"run\", Jamrules tests each objects against the defined sets of rules in their order of declaration.\n\nIt declares an object as \"**matched**\" as soon as **a set of rules is compliant with the object** and its properties.\n\nRules are defined within a \"rules set\" declation. A rules set is validated **when all its rules are validated to true**.\n\nWhen a rule set is not ok, Jamrules tries the next rules set.\n\nIf **none of the rules sets** are validated, then the object is declared \"**unmatched**\".\n\nWe use the **createRulesSet** function to create a rules set, and the **addRule** function to add a rule in a rule set.\n\n## Rules\n\nA rule declares a test to try.\n\nThe test can use information on the object properties, the configurator or any other information you'd like...\n\nJamRules has several matching functions ready to use as:\n* ObjectPropertySet: tests the value of the property of the object currently tested\n* ObjectPropertiesSameValue: tests the value of one property against another property...\n* ...\n\nThere are several filtering functions that may help to test a configuration in the filtering configurator against the properties of objects:\n* MatchProperty\n* MatchPropertyValue\n* MatchProperties\n* MatchPropertiesSameValue\n* MatchPropertiesSameValues\n* MatchPropertySearch\n* ConfigurationPropertySet\n* ConfigurationPropertiesSameValue\n* ConfigurationPropertiesSameValues\n* MatchExternalRule\n\n\n\n## Example\n```javascript\nrulesEngine.createRulesSet(\"SameTrousers\");\nrulesEngine.addRule(\"SameTrousers\",\"O1Trouser\",'ObjectPropertySet(\"object1\",\"trouser\")');\nrulesEngine.addRule(\"SameTrousers\",\"O2Trouser\",'ObjectPropertiesSameValue(\"object1\",\"object2\")');\nrulesEngine.createRulesSet(\"SameShirts\",[\"object1\",\"object2\"]);\nrulesEngine.addRule(\"SameShirts\",\"O1Shirt\",'ObjectPropertySet(\"object1\",\"shirt\")');\nrulesEngine.addRule(\"SameShirts\",\"O2Shirt\",'ObjectPropertiesSameValue(\"object1\",\"object2\")');\n```\n\n# Adding Objects to test by JamRules\n\n## addPropertyObjects(Objects \u003c, aMatchingFunction, aNotMatchingFunction\u003e)\n\nAdd objects to the list of objects to test against rules.\n\n  * **Objects**: array of objects with their properties plus these optional ones:\n    * **matched** (option): function to call when a rule will match for the object\n    * **notmatched** (option): function to call when rules will be tested but no rules match for the object\n  * **aMatchingFunction** (option): a matching function, same as to define a \"matched\" property in the object\n  * **aNotMatchingFunction** (option): a 'not' matching function, same as to define a \"notmatched\" property in the object\n\n### Example\n```javascript\nruleEngine = jamrules.build();\nvar anObject = {\n\tobject1Color : \"white\"\n};\nmyMatchFunction = function(){alert(\"Hello:\"+this.object1Color)};\nrulesEngine.addPropertyObject(onObject,myMatchFunction);\n```\n\n## addPropertyObject(anObject\u003c, aMatchingFunction, aNotMatchingFunction\u003e)\n\nAdd an object to the list of objects to test against rules.\n\n  * **anObject** with its properties plus these optional ones\n    * **matched** (option): function to call when a rule will match for the object\n    * **notmatched** (option): function to call when rules will be tested but no rules match for the object\n  * **aMatchingFunction** (option): a matching function, same as to define a \"matched\" property in the object\n  * **aNotMatchingFunction** (option): a 'not' matching function, same as to define a \"notmatched\" property in the object\n\n### Example\n```javascript\nruleEngine = jamrules.build();\nvar anObject = {\n\tobject1Color : \"white\"\n};\nmyMatchFunction = function(){alert(\"Hello:\"+this.object1Color)};\nrulesEngine.addPropertyObject(onObject,myMatchFunction);\n```\n\n## addObject(anObject)\nAdd an object to the list of objects to test against rules.\n\n### parameters  \n* **anObject**: a object to test in jamrules in **jamrules format**\n\n### Example\n```javascript\nruleEngine = jamrules.build();\nvar anObject = {\n\t\tpropertiesSet : {\n\t\t\tobject1Color : {\n\t\t\t\twhite : 1\n\t\t\t},\n\t\t},\n\t\tmatched : myMatchFunction,\n\t\tnotmatched : null\n\t};\nrulesEngine.addObject(onObject);\n```\n\n## _addObject(anObject) - static function\n\nRemark: to be called with jamrules variables.\n\nAdd an object to the list of objects to test against rules.\nThis function differs from addObject in the way that all the jamrules engines will share the objects added this way.\nSo, you include once your objects in the first jamrules object and then they will be processed by all the other rules.\n\n### parameters  \n* **anObject**: a object to test in jamrules\n\n### Example\n```javascript\nvar anObject = {\n\t\tpropertiesSet : {\n\t\t\tobject1Color : {\n\t\t\t\twhite : 1\n\t\t\t},\n\t\t},\n\t\tmatched : myMatchFunction,\n\t\tnotmatched : null\n\t};\njamrules._addObject(onObject);\n```\n\n# Creating rules set and rules\n\n## createRulesSet(aRulesGroup, ruleEvents)\nCreates a rule set.\n### parameters  \n* **aRulesGroup**: name of the rules set to create\n* **ruleEvents**: [array] (option) a list of one or several property names used in the configurator. The rules set will be processed if a property of the configurator changes when using \"selectConfigurationPropertyValue\" function (see selectConfigurationPropertyValue).\n\n### Example\n```javascript\nrulesEngine.createRulesSet(\"SameTrousers\");\n...\nrulesEngine.createRulesSet(\"SameTrousers\",[\"aProperty1\",\"aProperty2\"]);\n\n```\n\n## addRule(aRulesGroup, aRuleName, aRuleTest)\nAdd a new \"and\" rule in aRulesGroup.\n\n### parameters  \n* **aRulesGroup**: a rule set name\n* **aRuleName**: a rule to define in the rules set\n* **aRuleTest**: a filtering function with its parameters to assess\n  * eg: \"[!]\u003cfilterFunction(p1[,p2,...])\"\n\n### Example\n```javascript\n// colortop should have the same color name than colorbottom but different from colormiddle\nrulesEngine.addRule(\"SameColorTrousersPack\",\"Test1\",'ObjectPropertiesSameValue(\"colortop\",\"colorbottom\")');\nrulesEngine.addRule(\"SameColorTrousersPack\",\"TestNot2\",'!ObjectPropertiesSameValue(\"colortop\",\"colormiddle\")');\n```\n\n# Run JamRules\n\n## compileRules\nInitialize the rule engine - to do before action and after adding new rules\n\n### Example\n\n```javascript\n// prepare the rule engine\nrulesEngine.compileRules();\n```\n\n## runRulesEngine\nRun the rules engine.\n\n### Example\n```javascript\nrulesEngine.runRulesEngine();\n```\n\n# Filtering configurator\n\n## selectConfigurationPropertyValue(aPropertyName, aPropertyValue, doTest)\nSelect a value in the filtering configurator as a radio would do: unselecting other values of aPropertyName.\n\n### parameters  \n* **aPropertyName**: name of the property that has changed\n* **aProperyValue**: value of the property\n* **doTest**: \u003cboolean\u003e \u003cdefault:true\u003e (option) if false, configure the configurator but does not run the rules engine test\n\n### Remarks\nIf \"doTest\" is set, the rules engine will **run** and process -only- the rules sets that have configured the \"aPropertyName\" in the \"ruleEvents\" parameter in createRulesSet function.\n\naPropertyValue may be set to \"*\" to match any value of aPropertyName.\n\n### Example\n```javascript\n\n\trulesEngine.createRulesSet(\"SameTrousers\",[\"object1\"]);\n\trulesEngine.addRule(\"SameTrousers\",\"Trouser\",'MatchProperty(\"object1\")');\n\t....\n\t//as 'object1' is defined in the \"SameTrousers\" rules set, the following line will configure the \"object1\" property and see the rule set \"SameTrousers\" processed\n\trulesEngine.selectConfigurationPropertyValue(\"object1\",\"trouser\");\n\t...\n\t//no rule set to process... just configure the property in the configurator\n\trulesEngine.selectConfigurationPropertyValue(\"object1\",\"trouser\",false);\n\t...\n\t//will process all the rules sets\n\trulesEngine.runRulesEngine();\n```\n\n## checkConfigurationPropertyValue(aPropertyName,aPropertyValue,aStatus, doTest)\nset a property/property value status in the rules configurator. It is designed for checkboxes/multiple select as it set a value as a checkbox would do.\n\n### parameters  \n* **aPropertyName**: name of the property that has changed\n* **aProperyValue**: value of the property\n* **aStatus**: \u003cboolean\u003e  \u003cdefault:false\u003e (option) status of the property for this property value set or not\n* **doTest**: \u003cboolean\u003e \u003cdefault:true\u003e (option) if false, configure the configurator but does not run the rules engine test\n\n### Remarks\nIf \"doTest\" is set, the rules engine will **run** and process -only- the rules sets that have configured the \"aPropertyName\" in the \"ruleEvents\" parameter in createRulesSet function.\n\naPropertyValue may be set to \"*\" to match any value of aPropertyName.\n\n### Example\n```javascript\n\n\trulesEngine.createRulesSet(\"SameTrousers\",[\"object1\"]);\n\trulesEngine.addRule(\"SameTrousers\",\"Trouser\",'MatchProperty(\"object1\")');\n\t....\n\t//as 'object1' is defined in the \"SameTrousers\" rules set, the following line will configure the \"object1\" property and see the rule set \"SameTrousers\" processed\n\trulesEngine.checkConfigurationPropertyValue(\"object1\",\"trouser\",1);\n\t...\n\t//no rule set to process... just configure the property in the configurator\n\trulesEngine.checkConfigurationPropertyValue(\"object1\",\"trouser\",1,false);\n\t...\n\t//will process all the rules sets\n\trulesEngine.runRulesEngine();\n```\n\n## resetConfigurationPropertyValues(aPropertyName)\nreset a property by setting all its property values to a false status in the rules configurator\n\n### parameters  \n* **aPropertyName**: name of the property that has changed\n\n### Remarks\n\n### Example\n```javascript\n```\n\n## resetConfigurationProperty(aPropertyName)\nreset a property completely\n\n### parameters  \n* **aPropertyName**: name of the property that has changed\n\n### Remarks\n\n### Example\n```javascript\n```\n\n# The Available filtering functions for \"addRule\"\n\n## MatchProperty(aPropertyName)\nTests if at least a property value of a property is shared between the configuration and the object\n\n### parameters  \n* aPropertyName: a property name\n\n### returns\nReturns true if any property value for a given aPropertyName is set in the profile object and in the configuration property set\n\n### Example\n\n* object.priority.priority1=1\n* object.technician.technician1=1\n* configuration.priority.priority1=1\n* configuration.priority.priority2=0\n* configuration.technician.technician1=0\n* configuration.technician.technician2=1\n* MatchProperty('priority') -\u003e match\n* MatchProperty('technician') -\u003e no match\n\n## MatchPropertySearch(aPropertyName)\nTest if a string aPropertyName is found as a property value of objects. Generally used for text input as search input.\n\n### parameters  \n* aPropertyName: a string to search in the property values of objects.\n  wildcards are possible: '\\*' (0 or more char), '?' (0 or 1 char)\n  eg:\n  * 'my\\*propert?' will match 'myproperty','mygivenpropert','myREDproperts'\n  * but it won't match 'property', 'myREDproperties'\n* searchMode: default:'or'\n  * or: blank are considered as 'or' operator between keywords to find\n  * and: blank are considered as 'and' operator with all keywords to be found in any property values\n   \n\n### returns\nreturns true if the pattern string(s) defined in the configurator are found in property values of object\n\n### Example\n\n*  object.priority.priority1=1\n*  object.technician.technician1=1\n*  configuration.priority['prio\\*']=1\n*  configuration.technician['technician2']=1\n*  MatchPropertySearch('priority') -\u003e match\n*  MatchPropertySearch('technician') -\u003e no match\n\n\n## MatchPropertyValue(aPropertyName,aPropertyValue)\nTests if a given property value is set for configuration and the object\n\n### parameters  \n* aPropertyName: a property name\n* aPropertyValue: a value of aPropertyName\n\n### returns\nReturns true if the configuration for the aPropertyName.aPropertyValue == the one defined for the current objectProfile being tested\n\n### Example\n* object.priority.priority1=1\n* object.technician.technician1=1\n* configuration.priority.priority1=1\n* configuration.technician.technician1=0\n* MatchPropertyValue('priority','priority1') -\u003e match\n* MatchPropertyValue('technician','technician1') -\u003e no match\n\n## MatchPropertiesSameValue(aConfigurationPropertyName,anObjectPropertyName,aPropertyValue)\nTests if a property value of a property is set for the configurator and the object\n\n### parameters  \n\n* aConfigurationPropertyName: a configuration property name\n* anObjectPropertyName: a object property Name\n* aPropertyValue: [option] a value that should match. if undefined, test if at least one of the property values of property is set in Object and in configuration\n\n### returns\n\nReturns true if aPropertyValue in aConfigurationPropertyName and in anObjectPropertyName are both set.\n\n### Example\n\n*  object.priority.priority1=1\n*  configuration.priority.priority1=0\n*  configuration.activity.priority1=1\n*  configuration.strawberry.priority2=1\n*  MatchPropertiesSameValue('activity','priority','priority1') -\u003e match\n*  MatchPropertiesSameValue('strawberry','priority','priority1') -\u003e no match\n*  MatchPropertiesSameValue('activity','priority') -\u003e match\n*  MatchPropertiesSameValue('strawberry','priority') -\u003e no match\n\n## MatchPropertiesSameValues(aConfigurationPropertyName,anObjectPropertyName)\ntests the property values set for the configurator's property and the object's property and if they are the same between the two\n\n### parameters  \n\n* aConfigurationPropertyName: a configuration property name\n* anObjectPropertyName: a object property Name\n\n### returns\n\nReturns true if all properties values of aConfigurationPropertyName and of anObjectPropertyName are both set\n\n### Example\n\n*  object.priority.priority1=1\n*  configuration.priority.priority1=0\n*  configuration.activity.priority1=1\n*  configuration.strawberry.priority2=1\n*  MatchPropertiesSameValues('activity','priority') -\u003e match\n*  MatchPropertiesSameValues('strawberry','priority') -\u003e no match\n\n## MatchProperties(aConfigurationPropertyName,anObjectPropertyName)\nTests if at least a property value exists and is set between the configurator property and the object property\n\n### parameters  \n* aConfigurationPropertyName: a configuration property name\n* anObjectPropertyName: a object property Name\n\n### returns\nreturns true if it exists a value of aConfigurationPropertyName that is the same that in anObjectPropertyName\n\n### Example\n*  object.priority.priority1=1\n*  configuration.priority.priority1=0\n*  configuration.activity.priority1=1\n*  configuration.strawberry.priority2=1\n*  MatchProperties('activity','priority') -\u003e match\n*  MatchProperties('strawberry','priority') -\u003e no match\n\n## MatchObjectSearch(aConfigurationPropertyName,anObjectPropertyName)\nTests if the value of a configuration property string is found in the values of object's properties\nGenerally used for a text input in the configuration, as search input...\n\n### parameters  \n* aPropertyValueWithWildcard: a string to search in the property values of objects.\n   wildcards are possible: '*' (0 or more char), '?' (0 or 1 char)\n   eg: 'my*propert?' will match 'myproperty','mygivenpropert','myREDproperts'\n                     won't match 'property', 'myREDproperties'\n* searchMode:\n  - or (default): blank are considered as 'or' operator between keywords to find\n  - and: blank are considered as 'and' operator with all keywords to be found in any property values\n\n\n### returns\nreturns true if the pattern string(s) defined in the configurator are found in property values of object\n\n### Example\n*  object.priority.priority1=1\n*  object.technician.technician1=1\n*  configuration.technician.technician2=1\n*  MatchObjectSearch('priority1') -\u003e match\n*  MatchObjectSearch('prior*') -\u003e match\n*  MatchObjectSearch('tec?ician') -\u003e no match\n*  MatchObjectSearch('tec*ician2') -\u003e no match\n\n\n## ObjectPropertySet(aPropertyName,aPropertyValue,valueSet)\ntests if the property in theObjectPropertySett has its value set\n\n### parameters  \n\n* aPropertyName: an element property name\n* aPropertyValue: a value of aPropertyName\n* valueSet: [0|1(default)]\n\n### returns\n\nReturns true if the configuration for the aPropertyName.aPropertyValue == valueSet\n\n### Example\n\n## ConfigurationPropertySet(aPropertyName,aPropertyValue,valueSet)\ntests if the property in the configurator has its value set\n\n### parameters  \n\n* aPropertyName: an element property name\n* aPropertyValue: a value of aPropertyName\n* valueSet: [0|1(default)]\n\n### returns\n\nReturns true if the configuration for the aPropertyName.aPropertyValue == valueSet\n\n### Example\n\n## ObjectPropertiesSameValue(aPropertyName1,aPropertyName2,aPropertyValue)\nTests if the property in the element has the same value as an other element property\n\n### parameters  \n\n* aPropertyName1: an element property name\n* aPropertyName2: an other element property name\n* aPropertyValue: a value of aPropertyName\n\n### returns\n\nReturns true if the configuration for the aPropertyName.aPropertyValue == valueSet\n\n### Example\n\n## ObjectPropertiesSameValues(aPropertyName1,aPropertyName2)\nTests if the property in the element has the same values as an other element property\n\n### parameters  \n\n* aPropertyName1: an element property name\n* aPropertyName2: an other element property name\n\n### returns\n\nReturns boolean\n\n### Example\n\n## ConfigurationPropertiesSameValue(aPropertyName1,aPropertyName2,aPropertyValue)\ntests if the property in the configuration has the same value as an other configuration property\n\n### parameters  \n\n* aPropertyName1: an element property name\n* aPropertyName2: an other element property name\n* aPropertyValue: a value of aPropertyName\n\n### returns\n\nReturns true if the configuration for the aPropertyName.aPropertyValue == valueSet\n\n### Example\n\n## ConfigurationPropertiesSameValues(aPropertyName1,aPropertyName2)\nTests if the property in the element has the same values as an other element property\n\n### parameters  \n\n* aPropertyName1: an element property name\n* aPropertyName2: an other element property name\n\n### returns\n\nReturns boolean\n\n### Example\n\n## MatchExternalRule(aRule)\nTests the given rule and return true/false according to the test.\n\n### parameters  \n\naRule: a statement to evaluate during the rule test\n\nyou can use these variables to access to the properties of the configurator or of the object\n* propertiesObjectProfile : properties of the current object being tested\n* propertiesConfiguration : properties set in the configurator\n\nyou can use the other matching functions prefixing them with \"this.\u003cmatchingFunction\u003e\"\nex: this.MatchPropertiesSameValue('strawberry','priority','priority1')\n\n### returns\n\nReturns boolean\n\n### Example\n\n* object.priority.priority1=1\n* object.technician.technician1=1\n* configuration.priority.priority1=1\n* configuration.technician.technician1=0\n* MatchExternalRule('propertiesObjectProfile\\[priority\\]==propertiesConfiguration\\[priority\\]') -\u003e match\n* MatchExternalRule('propertiesObjectProfile\\[technician\\]\\[technician1\\]==propertiesConfiguration\\[technician\\]\\[technician1\\]') -\u003e not match\n\n# Install JamRules\n\n  * download JamRules from [github](https://github.com/intersel/jamrules) where you'd like in your project\n  * include the following javascript libraries (provided in the 'extlib' directory)\n```html\n\t\t\u003cscript type=\"text/javascript\" src=\"../extlib/jQuery/jquery-2.2.4.js\"\u003e\u003c/script\u003e\n\t\t\u003cscript type=\"text/javascript\" src=\"../extlib/iFSM/extlib/jquery.dorequesttimeout.js\"\u003e\u003c/script\u003e\n\t\t\u003cscript type=\"text/javascript\" src=\"../extlib/iFSM/extlib/jquery.attrchange.js\"\u003e\u003c/script\u003e\n\t\t\u003cscript type=\"text/javascript\" src=\"../extlib/iFSM/iFSM.js\"\u003e\u003c/script\u003e\n\t\t\u003cscript type=\"text/javascript\" src=\"../extlib/jQuery-MD5/jquery.md5.js\"\u003e\u003c/script\u003e\n\t\t\u003cscript type=\"text/javascript\" src=\"../jamrules.js\"\u003e\u003c/script\u003e\n```\n  * include JamRules\n\n```html\n  \u003cscript type=\"text/javascript\" src=\"../jamrules.js\"\u003e\u003c/script\u003e\n```\n\nYou're done!\n\n# Library Dependencies\n\nJamRules needs to include the following javascript libraries and here's what they do:\n* jQuery (\u003e= 1.10) `\u003cscript type=\"text/javascript\" src=\"extlib/jQuery/jquery-3.1.1.js\"\u003e\u003c/script\u003e`\n* [iFSM by intersel](https://github.com/intersel/iFSM/).\n  * This library manages finite state machines and needs these libraries:\n    * doTimeout by [\"Cowboy\" Ben Alman](http://benalman.com/projects/jquery-dotimeout-plugin/)\n\t  * this library brings some very usefull feature on the usual javascript setTimeout function like Debouncing, Delays \u0026 Polling Loops, Hover Intent...\n\t  * `\u003cscript type=\"text/javascript\" src=\"extlib/iFSM/extlib/jquery.dorequesttimeout.js\"\u003e\u003c/script\u003e`\n    * attrchange by Selvakumar Arumugam](http://meetselva.github.io/attrchange/)\n\t  * a simple jQuery function to bind a listener function to any HTML object on attribute change\n\t  * `\u003cscript type=\"text/javascript\" src=\"../extlib/iFSM/extlib/jquery.attrchange.js\"\u003e\u003c/script\u003e`\n* [jquery.MD5](https://github.com/placemarker/jQuery-MD5)\n  * gives the MD5 function used in jamrules\n  * `\u003cscript type=\"text/javascript\" src=\"extlib/jQuery-MD5/jquery.md5.js\"\u003e\u003c/script\u003e`\n\n# Official website\n\n# FAQ\n## How to get why the rule did not match\n\nYou can get the reasons why the engine did not match by accessing to the following reason property :\n\n```javascript\n// notmatched function of an element\nvar notmatched=function(aJamRules){\n\tvar reason = aJamRules.myRulesEngine.opts.reason; //array of strings with the rules that did not match\n}\n\n// notmatched function of engine rule\nvar notmatched=function(aListOfObjects){\n\tvar reason = this.myRulesEngine.opts.reason; //array of strings with the rules that did not match\n}\n```\n\n## Can I define a match function different for each object?\n\nYes.\n\nTo do that, define a \"matched\" function like in this example:\n\n```javascript\n\nvar myObject1 ={property1:20}\nmyObject1.matched=function(){\n\talert(\"it matches this object 1\"+this.property1);\n}\nvar myObject2 ={property2:40}\nmyObject2.matched=function(){\n\talert(\"it matches this object 2:\"+this.property2);\n}\nrulesEngine.addPropertyObjects([myObject1,myObject2]);\n```\n\n\n\n# Contact\nIf you have any ideas, feedback, requests or bug reports, you can reach me at github@intersel.org,\nor via my website: http://www.intersel.fr\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintersel%2Fjamrules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fintersel%2Fjamrules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintersel%2Fjamrules/lists"}