# Content Query web part (SharePoint Online-Compatible) ## Summary > **NOTE:** This web part was built with SPFx 1.11.0, making it only compatible with SharePoint Online. If you wish, you can use [an earlier version of this web part](../react-content-query-onprem/README.md) which is compatible on-premises versions of SharePoint. The **Content Query web part** is a modern version of the good old **Content by Query web part** that was introduced in SharePoint 2007. Built for Office 365, this modern version is built using the **SharePoint Framework (SPFx)** and uses the latest *Web Stack* practices. While the original web part was based on an **XSLT** templating engine, this *React* web part is based on the well known [Handlebars templating engine](http://handlebarsjs.com), which empowers users to create simple, yet powerful **HTML** templates for rendering the queried content. This new version also lets the user query *any site collections* which resides on the same domain URL, add *unlimited filters*, query `DateTime` fields to the *nearest minute* rather than being limited to a day, and much more. ![Web Part Preview](assets/toolpart.gif) ## Compatibility ![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg) ![Node.js v10](https://img.shields.io/badge/Node.js-v10-green.svg) ![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg) ![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower") ![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1") ![Local Workbench Incompatible](https://img.shields.io/badge/Local%20Workbench-Incompatible-red.svg "The solution requires access to content") ![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg) ![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-green.svg) ## Applies to * [SharePoint Framework Developer](https://learn.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview) * [Office 365 developer tenant](https://learn.microsoft.com/sharepoint/dev/spfx/set-up-your-developer-tenant) ## Solution Solution|Authors --------|----------- react-content-query-web part (Online)|David Warner II ([Warner Digital](http://warner.digital), [@DavidWarnerII](https://twitter.com/davidwarnerii)) react-content-query-web part (Online)|Hugo Bernier ([Tahoe Ninjas](http://tahoeninjas.blog), [@bernierh](https://twitter.com/bernierh)) react-content-query-web part (Online)|Paolo Pialorsi ([PiaSys.com](https://piasys.com/), [@PaoloPia](https://twitter.com/PaoloPia?s=20)) react-content-query-web part |Simon-Pierre Plante react-content-query-web part (Online)|Abderahman Moujahid ## Version history Version|Date|Comments -------|----|-------- 1.0.0|May 04, 2017|Initial release 1.0.1|July 23rd 15, 2017|Updated to GA Version 1.0.3|August 12, 2017|Added external scripts functionality 1.0.4|August 31, 2017|Fixed a bug where tenant sites/sub-sites were missing from the **Web Url** dropdown 1.0.5|September 1st, 2017|Added a **Site Url** parameter next to the **Web Url** parameter in order to narrow down the results 1.0.6|September 19, 2017|Upgraded to SharePoint drop 1.2.0 and added the site URL and web URL preselection when adding the web part for the first time on a page. Also fixed a bug with fields that had spaces in their internal names (automatically replaced with `_x0020_` by SharePoint). 1.0.7|November 17, 2017|Reverted to drop 1.1.0 in order to keep compatibility for SP2016 on-premise 1.0.8|March 17, 2018|Updated to store the selected list using its ID instead of its title, so the web part keeps working if the list title gets updated. 1.0.9|March 28, 2018|Added a switch to enable the web part to apply it's query recursively within folders, and fixed a bug where webs could sometimes not appear under the web URL dropdown 1.0.10|April 5, 2018|Fixed a bug where the webs of the selected site collection were not being loaded correctly for particular tenants 1.0.11|May 22, 2018|Fixed a bug causing filters to loose their sort order in IE 1.0.12|April 19, 2020|Upgraded to SPFx 1.10 1.0.13|April 28, 2020|Added support for Dynamic Data 1.0.14|October 30, 2020|Fixed (lookup-)fields with special characters 1.0.15|November 2, 2020|Upgraded to SPFx 1.11; Added support for jsonValue 1.0.16|November 14, 2020|Fixed a bug where the fieldname starts with a special character; Added more special characters 1.1.0|January 5, 2021|Updated dependencies and added MGT support ## Minimal Path to Awesome ### Global dependencies > This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit https://aka.ms/spfx-devcontainer for further instructions. Requires Gulp globally installed: ```shell npm install --global gulp ``` ### Building the code Download & install all dependencies, build, bundle & package the project ```shell # download & install dependencies npm install # transpile all TypeScript & SCSS => JavaScript & CSS gulp build # create component bundle & manifest gulp bundle # create SharePoint package gulp package-solution ``` These commands produce the following: - `./lib`: intermediate-stage commonjs build artifacts - `./dist`: bundled script, along with other resources - `./temp/deploy`: all resources required by component(s) to deploy to a CDN (when `--ship` argument present) ## Build options - `gulp clean`: Deletes all build output (`/dist`, `/lib`, `/temp`, etc.). - `gulp build`: Transpiles all TypeScript & SCSS to JavaScript & CSS, generates source map files & TypeScript type declaration files - `gulp bundle [--ship|-p|--production]`: Runs gulp task **build**, then uses webpack to create the JavaScript bundle(s) and component manifest(s) as defined in `./config/config.json`. The `--ship`, `-p` or `--production` argument specifies a production build that will generate minified bundles. - `gulp serve [--ship|-p|--production]`: Runs gulp tasks `build`, `bundle` & starts the local webserver. Depending on the project type, it opens the browser and navigates to the local workbench or specified URL (in the case of extension components). The `--ship`, `-p` or `--production` argument specifies a production build that modifies the resulting package for production hosting rather than local hosting of assets. - `gulp package-solution`: Creates the SharePoint Package (`.sppkg`) file. - `gulp dist`: Creates a production-ready SharePoint Package (`.sppkg`) file. The following gulp task gets executed in this specific order `gulp clean`, `gulp bundle`, `gulp package-solution.` - `gulp dev`: Creates a development-ready SharePoint Package (`.sppkg`) file. The following gulp task will be executed in this specific order `gulp clean`, `gulp bundle`, `gulp package-solution.` > View all available gulp tasks by running `gulp --tasks` ## Features ### Cross site collection The web part uses the search in order to get all sites under the current domain, which makes it possible to query not only sub-sites but other site collections and their sub-sites as well. By default, the current site collection and the current web on which the user is adding the web part will be pre-selected automatically. ![Cross-Site Collection](assets/allsites_v2.gif) ### Unlimited filters The user isn't limited to 3 filters anymore, an unlimited amount of filters can be added to narrow down your query ![Filters](assets/filters.gif) ### Improved date/time filters It is now possible to include time validation when querying date fields, giving the ability to be more precise when it comes to querying items against date values. ![Date/time](assets/datetime.gif) ### Handlebars templating engine Enjoy a simple, yet powerful, HTML-based templating engine for rendering your results. The web part even generates a default Handlebars template for you based on the view fields you have selected during the configuration! For advanced users, more than 150 Handlebars block helpers are available by default within the user-defined template. For a list of all block helpers, see [handlebars-helpers](https://github.com/helpers/handlebars-helpers#helpers) ### Built-in template editor Edit your Handlebars template directly within the tool pane using a built-in [code editor](https://ace.c9.io/) which provides code folding, syntax highlighting, line wrapping, indentation and many more features to the tip of your fingers. ### Include your own external scripts and/or block helpers! You can now specify your own external scripts that needs to be loaded either **before** or **after** rendering the Handlebars template. ![External scripts](assets/externalScripts.png) External scripts can be used to include either libraries such as *jQuery*, or even *custom logic scripts* that can leverage the exposed `onPrerender` and `onPostRender` methods for advanced functionality. ### Dynamic Data support You can configure the web part to be a provider of [Dynamic Data](https://learn.microsoft.com/sharepoint/dev/spfx/dynamic-data) for other web parts. You simply need to select the `ID` field in the list of **View Fields** and to include in the Handlebars template an HTML element with CSS class name `selectItem` and a custom `data-\*` attribute with name `data-itemId` providing the value of the `ID` field for every item. Here you can see a sample code excerpt of a selection button: ```html ``` If you like, in the property pane panel where you configure the View Fields and the Handlebar template, there is a button called **Configure item selector** that you can press to automatically select the `ID` field and to enrich the auto-generated Handlebars template with the above HTML code. ![Configure item selector](assets/configureItemSelector.png) The output in the Handlebars template will be like the following one. ![Item selector template](assets/itemSelectorTemplate.png) Once you configured the item selector, you can update its HTML code, if you like. The default template will output UI like in the following image. ![Item selector template output](assets/itemSelectorTemplateOutput.png) If you did not customize the auto-generated Handlebars template, you can even remove the item selector by pressing **Clear item selector**, which will become available when the item selector is configured. ![Clear item selector](assets/clearItemSelector.png) In order to consume the Dynamic Data provided by the web part, you will have to add to the current modern page another web part -- created as a Dynamic Data consumer -- and choose **Connect to source**. ![Connect to source](assets/connectToSource.png) Once connected to a source, you will able to connect any of the following properties: * `webUrl`: the absolute URL of the web containing the currently selected item. * `listId`: the ID (GUID) of the list containing the currently selected item. * `itemId`: the ID (number) of the currently selected item. ![Dynamic Data connection](assets/dynamicDataConnection.png) ## Getting Started ### Adding the web part to your page To add the **Content Query web part** to your site page you have two options: * Either clone this repository, build the project yourself and connect it to SharePoint (see [Connect your client-side web part to SharePoint](https://docs.microsoft.com/sharepoint/dev/spfx/web-parts/get-started/connect-to-sharepoint)) * Or download the `react-content-query-web part.sppkg` file available in the `sharepoint/solution` folder of the repository and add it directly in your app catalog in order to be able to use it in your site. > Note: The second method will only work for Office 365 sites, since the `.sppkg` file points to an Office 365 public CDN URL which expects the referrer to come from a valid `https://**\*.sharepoint.com\***` URL. ### Configuring the web part As seen in the [User friendly configuration](#user-friendly-configuration) section, configuring the web part is quite straight forward. However, here's a list of *gotchas* that could save you some time : * The **Web Url** property uses the search to find all sites that are under the current domain. That being said, newly created sites can take a while to appear within the dropdown options, based on the search crawl schedule. * The **Filters** property still supports query string expressions like `[PageQueryString:ParamName]` for text fields, and date expressions such as `[Today]` or `[Today] + 4` for date fields. * The **Template** property stops getting automatically generated while selecting view fields as soon as the template is manually updated, in order to prevent unwanted loss of templating efforts. * The **Template Url** property has priority over the **Template** property, which means if a valid handlebars template URL is provided, the inline template will be kept, but ignored at runtime. ### Designing your Handlebars template #### Basics Before anything, make sure you understand the basics of Handlebars and its associated syntax by reading their [documentation](http://handlebarsjs.com) #### Available tokens To make it simple, a **template context** is automatically exposed within the handlebars template, giving the user the ability to work with the following exposed tokens : Property | Description -----------------|------------------ `{{items}}` | The array of objects that represents the items returned from the CAML query `{{pageContext}}` | The SPFx [PageContext](https://github.com/SharePoint/sp-dev-docs/blob/master/reference/spfx/sp-page-context/pagecontext.md) object which contains useful information about the current web, list, user, language etc... `{{accessDenied}}` | A boolean value indicating if the current user has a denied access to the configured site that gets queried. This gives the designer the power to decide what to render in a case where the current user doesn't have access to the queried site. `{{webNotFound}}` | A boolean value indicating if the configured site that gets queried doesn't exist anymore. This also gives the designer the power to decide what to render in a case where the queried site doesn't exist anymore. #### Available block helpers Besides the available tokens above, nearly 150 [block helpers](http://handlebarsjs.com/block_helpers.html) are also available for use in the Handlebars template, see [handlebars-helpers](https://github.com/helpers/handlebars-helpers#helpers) for a list of all possible block helpers. *Example using the "compare" block helper for conditional rendering based on current language :* ```handlebars {{#compare pageContext.web.language '==' 1033}}
MyField value : {{MyField}}
MyField text value : {{MyField.textValue}}
MyField html value : {{MyField.htmlValue}}
MyField raw value : {{MyField.rawValue}}
MyImageField JSON value : {{MyImageField.jsonValue}}
MyPersonField person value : {{MyPersonField.personValue}}
MyField text value : Simon-Pierre Plante
MyField html value : Simon-Pierre Plante
MyField raw value : 26
MyImageField JSON value: [Object]
MyPersonField person value: [Object]