renvrant / conditionize.js

Small jQuery plugins for handling conditional form fields via data attributes. Unmaintained.
MIT License
53 stars 30 forks source link

Support multi-value fields like `array_name[]` or many checkboxes with the same name #18

Closed IsmailM closed 5 years ago

IsmailM commented 5 years ago

Hey,

The original conditionize.js works with names with [] but it would be nice to upgrade to conditionize.flexible.js...

The original version cleaned the parameter to take this into account

https://github.com/renvrant/conditionize.js/blob/4120b6d6aa1d2303e3e30aaf62bbf6c917010475/conditionize.jquery.js#L49

The new version uses \w in a regex which doesn't match [\w+]

https://github.com/renvrant/conditionize.js/blob/4120b6d6aa1d2303e3e30aaf62bbf6c917010475/conditionize.flexible.jquery.js#L31

Perhaps changing the regex to (#?[\w\[\]]+) will fix this issue?

rguliev commented 5 years ago

Hi Ismail,

I see your point. But it's a bit tricky about names with []. It's not just about adding brackets to regex. The problem is that such inputs may have many values. So, which one to use then? Could you provide your non-working example? It would save some time for me to figure something out.

BassemN commented 5 years ago

@rguliev I have the same issue with names with []

rguliev commented 5 years ago

Hi @BassemN , Could you provide an example describing your problem with some context?

BassemN commented 5 years ago

@rguliev Please check the following example https://codepen.io/anon/pen/dwGEyW?editors=1000

landwire commented 5 years ago

Yes, I can see this being a problem too, with many CMS using weird class names with brackets etc...

rguliev commented 5 years ago

@BassemN, Thanks! Additional thanks for https://cdn.jsdelivr.net/gh/renvrant/conditionize.js@ - it will make my life easier:) Well, I must admit it, I have never used brackets in names like that. Usually, I use them for multifields like

<input type="text" name="my_favorite_books[]">
<input type="text" name="my_favorite_books[]">
<input type="text" name="my_favorite_books[]">
<button id="add_book_btn">Add a book</button>

And according to the issue title and suggested regex change, I think that the initial question is about such a case. But it is ambigous to get values and check conditions for such fields. That is why I refused to add it without any further details. I can add a support for names like my_favorite_book[0], my_favorite_book[1][name], etc. But it would not work well for names like my_favorite_book[] anyway. So they are quite different issues.

BassemN commented 5 years ago

@rguliev Welcome :) We hope to see support for [] names shortly :pray:

CodeCurosity commented 5 years ago

Is there any ETA on this as it is very critical for my project as my checkboxes & selects are using names[ ] and it is not ideal to use ID's for this project, thank you.

CodeCurosity commented 5 years ago

My situation is similar to this you mentioned above :

`

` How can i use the name selector in this situation above?

rguliev commented 5 years ago

@CodeCurosity As I said, for such cases the plugin would not work well. The problem is that it is ambiguous which value you want to check. It would help if you provide a more detailed example with the context.

CodeCurosity commented 5 years ago

Here https://codepen.io/digtalmind/pen/ZVOYYr

For checkboxes & select we have to use [ ] next to the name so it can be submitted as an array.

rguliev commented 5 years ago

What does the condition data-condition="my_favorite_books==1" mean? At least one checked?

Well, here are options you have:

1) Is possible with the current version. Just add ID's. I know it is not elegant but it works right now and acceptable. 2) ~15 Jan 2019. Wait for support of names like 'my_favorite_books[0]', 'my_favorite_books[1]' as described above and add the numbers to the names.

As for 'my_favorite_books[]' it is not considered for implementation because it is a very unclear case. I think it's easier to add some JS (as you will need it anyway if you use muti-fields) to add numbers to IDs or names.

CodeCurosity commented 5 years ago

data-condition="my_favorite_books==1" means checkbox has a value of 1 then there is another checkbox with a value of 2, as you may have not noticed checkboxes have predefined values, it won't work as on & off switch.

rguliev commented 5 years ago

Yeah, sorry did not notice values. Well, it works without brackets) But it may lead to some data loss on the backend. Anyway, options 1 and 2 described above still possible.

CodeCurosity commented 5 years ago

For it to work without brackets we also have to remove [ ] from names which we can't do, its just very odd that we have to tell client to use names for certain fields and ids for other fields.

rguliev commented 5 years ago

You can use both names and IDs; or names for all fields and add IDs only for those used in conditions. Or you can name them without brackets like my_favorite_book-1, my_favorite_book-2, etc.(which seems a bit ugly) and parse it on the backend.

CodeCurosity commented 5 years ago

Thanks to IsmailM this solution worked perfectly : https://codepen.io/ismailm___/pen/QzEbyZ?editors=1010

rguliev commented 5 years ago

1) Try data-condition="my_favorite_books[] == 2" and check first checkbox + second checkbox (order matters: firtst then second) 2) Try to replace it with text inputs

rguliev commented 5 years ago

Closed related issue #28 . Let's keep our discussions in one place. Our summary so far:

Not working cases

  1. Multi-value checkboxes

    <label><input type="checkbox" name="options" value="1">Option1</label>
    <label><input type="checkbox" name="options" value="2">Option2</label>
    <label><input type="checkbox" name="options" value="3">Option3</label>
    <button id="add_book_btn" class="conditional" data-condition="options == 2">
  2. Multi-value fields with names like input_name[]. For example,

    <label>Favorite book name</label><input type="text" name="my_favorite_books[]">
    <label>Favorite book name</label><input type="text" name="my_favorite_books[]">
    <label>Favorite book name</label><label><input type="text" name="my_favorite_books[]">
    <button id="add_book_btn" class="conditional" data-condition="my_favorite_books[] == 3">
  3. Array inputs like my_favorite_book[0][name], my_favorite_book[1][name]. i.e. the name itself is unique in DOM, but data is send to servers as an array. This is a bit different issue, but will be solved with the problem 2.

Suggested solution

  1. Square brackets added as a valid part of a name.
  2. In case when one name has multiply values (related inputs in a DOM) array will be used as a value in data-condition. I.e. in case 1: options will be interpreted as [1,2,false] if only first two are selected, in case 2 my_favorite_books[] will be resolved to ['Book1', 'Test', '']. Case 3 will be closed automatically along with 2nd.

About ETA Because of the end of the year, I have a lot of work to do at my work. I will try my best to implement it faster but I cannot estimate it earlier than the middle of Jan. If some of you do not want (or cannot) wait for it you can create a branch, let's say multivalue-fields and implement suggested solution. Adding tests is encouraged:)

CodeCurosity commented 5 years ago

So Multi Value Checkboxes don't even work with names, id's & names with [ ] , i have tried below doesn't work either, this is very critical we can wait for name [ ] but it should work with ID's, look at the example below :

<label><input id="mybox" type="checkbox" name="my_favorite_books[]" value="1">Option1</label>
<label><input id="mybox" type="checkbox" name="my_favorite_books[]" value="2">Option2</label>
  <label><input id="mybox" type="checkbox" name="my_favorite_books[]" value="3">Option3</label>

<button id="add_book_btn" class="conditional" data-condition="#mybox==1 && #mybox==2">Add a book</button>
BassemN commented 5 years ago

@CodeCurosity id should be used only once on the same HTML page https://www.w3.org/TR/WCAG20-TECHS/H93.html https://www.w3.org/TR/html401/struct/global.html#adef-id

rguliev commented 5 years ago

Thanks, @BassemN. Here another link: https://stackoverflow.com/a/37280087/5055891. So it will not be supported anyway since it is invalid usage of id.

CodeCurosity commented 5 years ago

@CodeCurosity id should be used only once on the same HTML page https://www.w3.org/TR/WCAG20-TECHS/H93.html https://www.w3.org/TR/html401/struct/global.html#adef-id

Yeah i just recalled, thanks i guess for now i will give unique id to each of my checkboxes.

CodeCurosity commented 5 years ago

Thanks, @BassemN. Here another link: https://stackoverflow.com/a/37280087/5055891. So it will not be supported anyway since it is invalid usage of id.

Yes i think giving unique id's to each of my input is the ideal way to go at the moment as my field names are coming from labels and i only wanted to make it easier for my clients to see the names while they are creating the logic, now i will just generate the unique id next to the input so they can use ID's, thanks guys :+1:

rguliev commented 5 years ago

Welcome:)

CodeCurosity commented 5 years ago

Multi Radio buttons also don't seem to work although i am using id's for condition and each radio button has different id but same name.

https://codepen.io/digtalmind/pen/ZVOYYr/

It shows the field but it doesn't hide when other radio button is clicked.

Checkboxes on the other hand with different id's work just fine even though they have same name and even have [ ] at the end.

rguliev commented 5 years ago

You are confusing things. Radio buttons are not a multi-value inputs. Multi-value means that an input has many values and when you send it to the server side it will appear something like an array. On the other hand, using the same name for many inputs in case of a radio button is an expected syntax. Why? Because radio button takes only one value even though you have many inputs with the same name. Because it is the way radio buttons are designed and work. So you can just ask for a value of a radio button. In case of your example just try data-condition="my_favorite_books == 1".

CodeCurosity commented 5 years ago

I never mentioned anywhere that radio buttons are multi value, i just mentioned i have multi radio buttons, previously we had issues with multi check boxes with same name or [ ] so i replanned everything and decided to stick to ID's now that i have given unique id to every input radio buttons doesn't seem to work with ID's? the sole purpose of using multi radio buttons is so clients can select one value from multiple options, i still can't get my head wrapped around that why it doesn't work with ID even though i gave the value?

I tried data-condition="#id" or data-condition="#id == 2" none of these options work multiple radio buttons.

I think this is very odd that it shows the field but then it doesn't hide the field when other options are selected even though you can see the selected radio button is no longer selected, it seems to me like a bug.

Please understand that we can either work with names or with ID, we need to give our clients the selector to select fields so it can either output ID or Name.

rguliev commented 5 years ago

I see your point. But getting a value of a radio button by id is odd even more. I understand that you kinda have to because you want multi-value radio buttons. But the problem is that javascript does not trigger a change event for one of radio buttons input. Get better understanding try following:

<label><input id="mybox0" type="radio" name="my_favorite_books" value="0">Option0</label>
<label><input id="mybox1" type="radio" name="my_favorite_books" value="1">Option1</label>
<label><input id="mybox2" type="radio" name="my_favorite_books" value="2">Option2</label>
<script>
$('#mybox1').change(function(){
    console.log('Change is triggered');
})
</script>

So, a workaround you can use is to trigger change events manually:

$('#mybox, #mybox2').change(function(){
  $('#mybox1').trigger("change");
});
$(document).ready(function() {
  $('.conditional').conditionize();
});

And change data-condition to just the id, i.e. data-condition="#mybox1".

CodeCurosity commented 5 years ago

I can trigger change event manually but unfortunately fields are generated on the fly and i can only get unique id of each input, i can't define other radio buttons id's in a function.

Can i manually trigger change event on each input by specifying just that input unique ID?

rguliev commented 5 years ago

I think you have to write some additional javascript handling event triggering. Or maybe it will be simpler for you to write your own conditionize.js working just for your special project. But it is out of scope here. I would recommend asking at Stack Overflow with comprehend description, so more people could help you.

renvrant commented 5 years ago

@CodeCurosity Just chiming in to say @rguliev is correct and the use case you're describing seems very specific to what you're trying to achieve. You may wish to try writing your own event handling or forking this plugin to make changes specific to your needs.

CodeCurosity commented 5 years ago

Thanks guys yes i will do that :+1:

CodeCurosity commented 5 years ago

Really looking forward to get this by the end of january πŸ‘

CodeCurosity commented 5 years ago

Hey guys, end of january, anything on this issue, its really bugging my clients to not been able to use radio button and checkboxes at all.

rguliev commented 5 years ago

Hi @CodeCurosity, Sorry, for delays. It takes more time that I estimated because I decided to reorganize and cover everithing by tests . I ended up with creating a conditionize2. I will write more about it later. For your question. For now, you can use multivalue-fileds branch from conditionize2. It works with multifieds as far as I checked. It is not documented and covered by tests yet. But the idea is quite simple: if a field has many values then its value is array with values of each input. Otherwise, it works as usually. You can see some examples in demo.html. Please, take into account that usage will be changed slightly soon. I will add some parameters to give more control. In general it will look something like this

CodeCurosity commented 5 years ago

Hi, Sounds great, although i tried with radio buttons but it doesn't seem to do anything, how do we make it work with radio button using my_favorite_book[] as name and here is the condition i tried.

            <div>
                <p>Write three books name:</p>
                <label>Favorite book name</label><input type="radio" value="1" class="w3-input" name="my_favorite_book[]">
                <label>Favorite book name</label><input type="radio" value="2" class="w3-input" name="my_favorite_book[]">
                <label>Favorite book name</label><input type="radio" value="3" class="w3-input" name="my_favorite_book[]">
                <p class="conditional msg" data-condition="my_favorite_book[] === 3">Multifield without provided keys</p>
            </div>

Thanks.

rguliev commented 5 years ago

The problem is that now my_gavorite_books[] is an array. So your condition becomes something like [false, β€œ2”, false] == 3 which is always false. Try something like my_favorite_book[].indexOf(β€˜3’) !== -1

P.S. For further discussions, please, use issues in the new repo, since it’s irrelevant here.

rguliev commented 5 years ago

Hey! I have some news. I finished conditionize2.js -- an improved version of conditionize.js. What changed:

Why I did not keep it in this repo:

The new version is a fork from this repo because I wanted to give credits to other contributed developers. First, I thought about transferring the repo but I was not able to contact the owner anyway.

So now I stop maintenance of conditionize.flexible.js and all updates/issues will be in conditionize2.js. I highly recommend migrating to it since it has better support and more features. In the README you can find instructions for migration.

renvrant commented 5 years ago

Exciting! Thank you for taking over maintenance/improving this project, @rguliev!

rguliev commented 5 years ago

Thank you for the inspiration and the opportunity to contribute!