ukrbublik / react-awesome-query-builder

User-friendly query builder for React
https://ukrbublik.github.io/react-awesome-query-builder
MIT License
1.91k stars 490 forks source link

More data source #788

Open bartmint opened 1 year ago

bartmint commented 1 year ago

Is your feature request related to a problem? Please describe. I need to add another data source next to value, field and func. Is it possible? How can I achieve it?

ukrbublik commented 1 year ago

What's the purpose of new data source?

bartmint commented 1 year ago

I have a form to which I can attach values ​​from another form. I want to create a query based on the value in the attached form. The data is already available from the attached form, but I need a new data source, something like "related document" or "relation". It is not a value, a field, or a function. So I need another source.

ukrbublik commented 1 year ago

It still looks like afield But you want to have field in right part (RHS) from another data source, meaning another set of fields. Correct?

bartmint commented 1 year ago

Correct. But it has to be separated from the fields in the current form. There must be two separate options in select: where in the first I can select fields from the current form and in the second I can select fields from another form. For me, these are two different things.

Lord-of-Bugs commented 1 year ago

Hi there, is any chance this issue can still be addressed? I have something of similar nature. I want to build a query as follows: [field] [a dropdown/select with 4 predetermined values] [operator] [value]. I'm wondering how can this be done?

ukrbublik commented 1 year ago

Have you tried renderAfterWidget in settings? (There's an issue #879 with types of this render function, I'll fix it soon)

How do you want to save a value from dropdown in jsonTree or jsonlogic format? What is the purpose of this dropdown value? You could use operatorOptions if it's some meta

Elaard commented 1 year ago

I solved this problem by bypassing the default options. I.e. in the config, I sent my component to the renderField function and added fields in the config, which I hid thanks to "hideForSelect". My component contains two selects, the first has regular fields and the second is what I want to select and have a value. I set the operator and all the rest after selecting the value in the second select. For example, in the first select you set "User", the second select generates options such as "name" and "email". After selecting the second select, you use the setField method on its values ​​(that's why there must be an extra field in the config) and then you catch everything together. It would be much easier if u have property like lhsValue, which u can set with setField but we dont have it for now.

ukrbublik commented 1 year ago

@Elaard What value do you pass to setField? Some object like { mainField: "User", secondaryField: "email" } ? Or just User.email?

Lord-of-Bugs commented 1 year ago

I want it to be saved as one of the properties for a rule, and I mean to use it as some sort of "flag" or "indicator" when I process which type of query the current one belongs to, or which type of data it would query upon.

Have you tried renderAfterWidget in settings? (There's an issue #879 with types of this render function, I'll fix it soon)

How do you want to save a value from dropdown in jsonTree or jsonlogic format? What is the purpose of this dropdown value? You could use operatorOptions if it's some meta

@Elaard Would you mind dropping a couple code examples? There're very few demos/examples out there about this one specifically so I'd greatly appreciate it.

Elaard commented 1 year ago

Written quickly. I don't really recommend this approach for larger configs as things can get out of control. It would help a lot if we were able to set the lhsValue assigned to the field and based on it build whatever we want after selecting the field. Still field has to be in config, because everything after field selection is based on field type.

@Lord-of-Bugs maybe u will find it helpful. https://codesandbox.io/p/sandbox/aged-water-bp7ifh?selection=%5B%7B%22endColumn%22%3A19%2C%22endLineNumber%22%3A16%2C%22startColumn%22%3A19%2C%22startLineNumber%22%3A16%7D%5D

@ukrbublik setField won't accept anything other than a string, and that's a critical point in the application that I'd rather not break :)

ukrbublik commented 1 year ago

@Elaard Does using !struct (as in examples) not satisfy your requirements?

As for lhsValue, there is a draft PR to add ability to set function in the LHS instead of field. But it's not intended to put subfields in LHS. To be clear, do you want to set field: "user", lhsValue: "email" ?

Elaard commented 1 year ago

Yeah something like that, but lhsValue in my case would be sometimes a very complex object. Even more complex than the rule. So i would like to add also translate function for lhsValue.

As for the !struct type, I had requirements where the fields had to be grouped, i.e. if the field had type "A", then another select with children for this field should be rendered. Here I presented a simple case. But in my case I came to generate even 4 selects. Widget has to change based on last selected element (but you dont have to choose last right? you can choose the second of the four). And there could be more depending on the type of document. Displaying so many fields without grouping would be problematic. And grouping here makes sense, because these fields with type "A" come from other documents.

Maybe there is a better solution to this problem, but at the time of making this functionality I didn't see anything that would suit me.

ukrbublik commented 1 year ago

Ok. Can you please describe a complex example of lhsValue you plan to use? I need to make a decision on the format of new lhsValue that will be added in new versions to be forward compatible as much as possible. Or maybe add another property named like metadata that can co-exist with lhsValue. In what format do you plan to store query values on backend? JsonTree or JsonLogic?

Elaard commented 1 year ago

Nothing interesting comes to my mind in the current configuration. In my case, I needed to create functions on the left side of the operator and therefore I needed a function that would translate what the user created. This was a few months ago and I no longer have access to the project. The solution was simple but not too clean.

How it works: You selected the field on the left, which, for example, was called "Sum" and right next to it you generated a component that allowed you to create a function. Such a function was saved as lhsValue, then translated as string and distributed to qureyString as lhsValue.

But that was the case a few months ago when there was no lhs value. So at the moment I don't think there is any need to add anything like that.