web_widget_markdown
Tabulator
web_widget_markdown | Tabulator | |
---|---|---|
2 | 24 | |
21 | 6,249 | |
- | - | |
0.0 | 9.6 | |
over 1 year ago | 16 days ago | |
JavaScript | JavaScript | |
GNU General Public License v3.0 only | MIT License |
Stars - the number of stars that a project has on GitHub. Growth - month over month growth in stars.
Activity is a relative number indicating how actively a project is being developed. Recent commits have higher weight than older ones.
For example, an activity of 9.0 indicates that a project is amongst the top 10% of the most actively developed projects that we are tracking.
web_widget_markdown
-
Create an Odoo 14 Markdown Widget Field with TDD - Part 2
In the last part (code available here) we ended up with a functional widget transforming pure text markdown content into HTML in render mode and behaving like a standard FieldText when in edit mode.
-
Create an Odoo 14 Markdown Widget Field with TDD - Part 1
The Odoo FieldText transforms the Dom node of your widget into a in edit mode. We can see it in
odoo/addons/web/static/src/js/fields/basic_fields.js
init: function () { this._super.apply(this, arguments); if (this.mode === 'edit') { this.tagName = 'textarea'; } this.autoResizeOptions = {parent: this}; },
Enter fullscreen mode Exit fullscreen modeThis behavior is the closest to our expected result so we are inheriting that widget to gain time.
In our widget, we defined the
className
property to add our class.o_field_markdown
to identify our widget in the DOM. Also, it is used in our tests to check widget behavior.The $el property of a widget
$el property accessible inside the Widget holds the JQuery object of the root DOM element of the widget. So in this case we use the JQuery HTML function to inject the content
inside the $el to pass this test. In TDD the workflow is to make the tests pass with minimum effort, then write new tests, refactor to make it pass again, etc...Hello World
After updating the module and going to http://localhost:8069/web/tests/ we can see that our tests pass!
Improving our tests and refactoring the widget
Adding more tests
We will add another test to make our test suite slightly more robust and see if our current implementation of the widget still holds up (Spoiler alert: it won't).
QUnit.test('web_widget_markdown readonly test 2', async function(assert) { assert.expect(2); var form = await testUtils.createView({ View: FormView, model: 'blog', data: this.data, arch: '' + '' + '' + '' + '' + '', res_id: 2, }); assert.strictEqual( form.$('.o_field_markdown').find("h2").length, 1, "h2 should be present" ) assert.strictEqual( form.$('.o_field_markdown h2').text(), "Second title", "
should contain 'Second title'" ) form.destroy(); });
Enter fullscreen mode Exit fullscreen modeWe changed "QUnit.only" to "QUnit.test" to run multiple tests and then in the test interface we searched for the "Markdown Widget" module to run only them:
Now the tests are failing because we are always injecting
Hello world as the value!
Refactoring the widget
The value property
Every widget inheriting
InputField
,DebouncedField
or evenAbstractField
hold their value inside avalue
property. So inside the _renderReadonly method, we use the same logic as before, injecting directly the HTML content inside the $el. But this time we will use the underlying markdown function of the SimpleMDE library to parsethis.value
and return the HTML transformed version.This is the new
field_widget.js
odoo.define('my_field_widget', function (require) { "use strict"; var fieldRegistry = require('web.field_registry'); var basicFields = require('web.basic_fields'); var markdownField = basicFields.FieldText.extend({ supportedFieldTypes: ['text'], className: 'o_field_markdown', jsLibs: [ '/web_widget_markdown/static/lib/simplemde.min.js', ], _renderReadonly: function () { this.$el.html(SimpleMDE.prototype.markdown(this.value)); }, }); fieldRegistry.add('markdown', markdownField); return { markdownField: markdownField, }; });
Enter fullscreen mode Exit fullscreen modeWe added the external JavaScript library SimpleMDE in the
jsLibs
definition of our widget.Running the tests again now gives us :
Victory! 😊
Simulating Edit mode in our test suite
The current use case of our widget will be, going into Edit mode, writing markdown, Saving, and then seeing it rendered as HTML.
This what we will simulate in this new test function by using some of the most useful functions in the
testUtils
module.
QUnit.test('web_widget_markdown edit form', async function(assert) { assert.expect(2); var form = await testUtils.createView({ View: FormView, model: 'blog', data: this.data, arch: '' + '' + '' + '' + '' + '', res_id: 1, }); await testUtils.form.clickEdit(form); await testUtils.fields.editInput(form.$('.o_field_markdown'), ' **bold content**'); await testUtils.form.clickSave(form); assert.strictEqual( form.$('.o_field_markdown').find("strong").length, 1, "b should be present" ) assert.strictEqual( form.$('.o_field_markdown strong').text(), "bold content", " should contain 'bold content'" ) form.destroy(); });
Enter fullscreen mode Exit fullscreen modeWhat is happening inside the test?
We create the mock form similar to the other 2 tests. Then we simulate the click on Edit button with
clickEdit
. After that, we edit the input witheditInput
and write some markdown that we will test after. Finally, we simulate the user hitting the Save button viaclickSave
.Odoo versions compatibility
clickEdit
andclickSave
are new functions in the file odoo/addons/web/static/tests/helpers/test_utils_form.js present from Odoo 12 and onwards.If you use Odoo 11, replace these calls with that
// instead of await testUtils.form.clickEdit(form); form.$buttons.find(".o_form_button_edit").click(); // intead of await testUtils.form.clickSave(form); form.$buttons.find(".o_form_button_save").click();
Enter fullscreen mode Exit fullscreen modeRun the tests again on your browser and you will see that it passes! 🥳
Conclusion
This is already running quite long and for now, our widget is functional in render and edit mode. In the next part, we will add the Markdown Editor itself instead of the
</code> tag to make it easier for the user to write.</p> <p>We will view more types of Fields, create a template and change our tests to take into consideration the change of input type.</p> <p>The code for this Part 1 of the tutorial is <a href="https://github.com/Coding-Dodo/web_widget_markdown/tree/web-widget-markdown-tutorial-part-one">available here on Github</a>.</p> <p><a href="https://codingdodo.com/create-odoo-markdown-widget-field-with-tdd-part-2/">Part 2 of this tutorial is already available at Coding Dodo.</a></p> <p>Thanks for reading, if you liked this article please consider:</p> <ul> <li>☕️ <a href="https://www.buymeacoffee.com/CodingDodo">Buying me a Coffee</a> </li> <li>🥳 Register on <a href="https://codingdodo.com">Codingdodo.com</a> </li> </ul>
Tabulator
- Tabulator – JavaScript Tables and Data Grids
- Tabulator: Tables, datagrids and tree grids for Vanilla JavaScript
- Tabulator: Interactive Data Grid for JavaScript (No React, No Vue)
-
Personal Sträva Activity Statistics
Coded mainly in Perl and Gnuplot, recently extended by Python Pandas and JavaScript Tabulator and ECharts
-
Can you recommend a React table components with virtualization and array indices (instead of key-value pairs)?
We use Tabulator for a similar use case at my job, it has a virtual DOM to support thousands of rows pretty well. It's not React based, it's a vanilla JS library. There is a React wrapper here but I don't have experience with that.
-
Simple Inventory App
If you familiar with programming, then defiantly it way to go, tabulator as a CRUD for frontend and simplest sqlite backend. The reason such type of apps not broadly exists is that because any business has it's own workflow, so all-in-one common apps became overloaded with useless features but doesn't have feature a client needs
-
I made a program that hosts a directory through a web interface. I have very little web-dev experience and it isn't quite finished, but I'm very happy with it!
as well to have a choice for theme with detailed info page (size/modefied-time) with sorting capability (by utilizing something like tabulator)
-
How to trigger a post request when a delete function is called on a Tabulator row?
I am a mostly backend dev using python and only know enough JS to be dangerous. I am doing some simple front-end work for my job, and I am using tabulator.js which creates a column with an x in it. When that x is clicked, this function runs.
-
Tables Componente Library
Yeah. NaiveUI is good. Also check tabulator. http://tabulator.info/
- [AskJS] Non-jQueryDatatables alternative?
What are some alternatives?
SimpleMDE - A simple, beautiful, and embeddable JavaScript Markdown editor. Delightful editing for beginners and experts alike. Features built-in autosaving and spell checking.
DataTables - Tables plug-in for jQuery
CodeMirror - In-browser code editor (version 5, legacy)
gridjs - Advanced table plugin
underscore - JavaScript's utility _ belt
Masonry - :love_hotel: Cascading grid layout plugin
Isotope - :revolving_hearts: Filter & sort magical layouts
HANDSONTABLE - JavaScript data grid with a spreadsheet look & feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡
Vanilla-DataTables - A lightweight, dependency-free javascript HTML table plugin
floatThead - Fixed <thead>. Doesn't need any custom css/html. Does what position:sticky can't
flexboxgrid - Grid based on CSS3 flexbox
Griddle - Simple Grid Component written in React