Select field populated with multiple entries after one checkbox change - javascript

I have something in my mind, but I have no idea how to get it done, so I hope I can get some advise here.
I'm working on an activity registration app (using Laravel), where every activity will be registered. Very important is that we need to record who was invited and who actually attended. I already have this part running. My issue is more on the practical side.
I use jQuery Select2 for the multiple select fields for invitees and attendees. Imagine now that there's a group of users that need to be invited or attend virtually all activities, while the invitation or attendance of others depends on the type of activity. Using Select2, I can only select users one at a time and that sucks if you need to do that for, say, 50 users for virtually every activity.
What is the best way to have a "group" that can be selected, which selection fills in all the names of those in the group in the select field? Or is there a better way to get this done?
I'm seeing something in my head, where there are checkboxes next to the select field, representing the groups. When you tick a checkbox of a group, the select field is populated with all users who are part of that group.
I have no idea ow this can be done. I looked around and every search brings up select boxes populating select boxes. None handle checkboxes.
Any advise on how to get this done?
My PHP/MySql is intermediate, Javascript/Ajax is very basic.

One strategy would be to build a control (checkbox element) that will set or toggle the selection of your group of users whenever it's clicked. Say we have the following markup:
<select class="my-big-group-select" multiple="multiple">
<!-- assorted options here -->
</select>
<label>
<input type="checkbox" class="toggle-default-group" />
Use my default big group of users
</label>
The Select2 API allows you programmatic control over the component it generates.
You can read more about it here: https://select2.github.io/examples.html#programmatic
Here's one way to leverage this knowledge using jQuery with Select2:
<script>
var groupSelect = $('.my-big-group-select').select2();
var groupToggle = $('.toggle-default-group');
var myBigGroup = ["Aaron", "Beth", "Cindy"]; // assorted option values
groupToggle.on("click", function() {
if ($(this).is(':checked')) {
groupSelect.val(myBigGroup).trigger('change');
} else {
var currentlySelected = groupSelect.val();
if (currentlySelected) {
var filteredSelections = currentlySelected.filter(function(key) {
return myBigGroup.indexOf(key) < 0;
});
groupSelect.val(filteredSelections).trigger('change');
}
}
});
</script>
Here's a CodePen that shows it all in action: http://codepen.io/anon/pen/qNQKOd
Of course you can build on this to make additional enhancements (the ability to select multiple groups, for example).
As an alternative, you may consider other code libraries like Bootstrap Multiselect: https://davidstutz.github.io/bootstrap-multiselect/
Hope this points you in the right direction!

Related

Django Modelmultiplechoicefield Checkboxselectmultiple Problem Getting Selected Checkbox

I have been working all day to try and get the selected values on one set of checkboxes on my Django form and copy the selected ones only to an identical checkbox on my form. If a user clicks on a checkbox in form.author defined below, I want the same identical checkbox to automatically be checked on form.favorite_author defined below.
I've tried a JQuery approach as documented here...Copy Selected Checkbox Value From One Checkbox To Another Immediately Using JQUERY but no luck so far. I've recently begun exploring an avenue with the Modelmultiplechoicefield and the checkboxselectmultiple parameters within the form itself. From what I can tell, when I am using JQuery and trying to check a box on the form, the value is coming back as undefined which is most likely why it is not propagating the checkbox selection to the other checkbox.
Here is my form....
class ManagerUpdateNewAssociateForm(forms.ModelForm):
class Meta:
model = Library
self.fields['author'] = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple(),
queryset=Books.objects.all()
self.fields['favorite_author'] = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple(),
queryset=Books.objects.all()
My HTML...
<div class="spacer83">
{{ form.author }}
</div>
<div class="spacer83">
{{ form.favorite_author }}
</div>
When I tried to trace JQuery, it told me the checkbox selections are undefined. I did read a bit about how Modelmultiplechoicefield, since it uses a queryset it doesn't show the selections, but I can't figure out how to get it to.
Thanks in advance for any thoughts.
In combination with the other issue included in this one, I went back to the JQuery route and explored further. From what I can tell, I was not able to use the class for the input because of the way the HTML for Django forms is generated in this use case. I ultimately was able to leverage the input name and then used the code below to interrogate the checkboxes accordingly:
$(document).ready(function() {
$("[name=author]").change(function() {
let selectedValA = $(this).val();
let isAChecked = $(this).prop("checked");
$(`[name=favorite_author][value="${selectedValA}"]`).prop("checked", isAChecked);
});
});
});

How to do delayed select option generation

I have some web pages which display a number of (up to several dozen) work items.
Each work item is a form consisting of several fields, two of which are large selects (one about 350 items and the other about 650 options) which are always identical other than the initially selected item.
The page can be pretty slow to load. Some of this may be due to the 24KB + 52KB of html for each copy of those selects, and I'm betting a fair amount of it is the time for the browser to build what is essentially the same huge chunk of (mostly of no interest) DOM over and over again.
What I'm thinking might be better is to just keep a master copy of the options for each in an array and just start each select out with only a single option (the initially selected value), For example:
<form ...>
<input ...>
<select class='dept_select' id='dept' name='dept' size='1'>
<option value='12345' selected>Department of Banking and Finance
</select>
<select class='approver_select' id='approver' name='approver' size='1'>
<option value='jpflat' selected>J. Pierpont Flathead
</select>
</form>
and then when the user clicks on the one selectbox they are interested in, build the rest of it from the array. Is this at all sensible, and if it might be, is there some clever and succinct way to do this in jQuery or am I going to have to invent it from whole cloth and raw JavaScript? FWIW, there's no real correlation between the selects (e.g., like selecting a state limits the valid choices for selecting a city).
I'm not going to post code so far. I recommend to re-build your concept a bit to get to a simpler structure:
A user can only edit one item at a time. There's no need to generate "a couple of dozen forms", as long as no edit action is taken.
render the items as a simple two-dimensional array with rows and fields, preferable in a JSON
built the table of items dynamically in the client by use of jQuery
if the user wants to edit an item, open a div layer, render a form into it by the use of the above array. Of course with just one single set of these dropdowns.
consider to load these dropdowns on request by AJAX or use some "combo box" features like in jQuery ui (below).
on "save" submit the form and close the div layer
There are certain containers and dialogs ready-to-use in jQuery ui to achieve this. The result will be
more generic code
less html overhead
better usability even
Well, turns out it wasn't as hard as I was imagining it...
<form ...>
<select id="ts" name="ts" size="1" class="tsc">
<option value="12345" selected>This is the initial value</option>
</select>
</form>
and:
var arr = [
{V:'alpha',T:'One'},
{V:'bravo',T:'Two'},
{V:'charlie',T:'Three'}
];
$(function() {
$( '.tsc' ).mousedown(function() {
var sel = $(this);
sel.unbind('mousedown');
$(arr).each(function() {
sel.append($('<option>')
.attr('value', this.V)
.text(this.T));
});
});
});
jQuery rocks.

Creating a javascript that creates a dynamic total depending on radio box checked in html form

Dearest stackoverflow friends,
I am creating an online html form and have created a javascript function to dynamically (not completely sure I'm using this word correctly) display the total due in membership fees at the bottom of the form as options are selected. The total fee depends on one's membership type, country, and method of payment. It worked perfectly when all I was calculating was the membership type and postage according to country (I used drop down forms for these two options). Now I'd like to add the third term to the equation (the method of payment - one has a choice of cheque or paypal) but I can't get it to work. I'm using radio buttons this time.
My totalling function is this (without "+ getPaypalfee()" it works just fine):
function getAmountDue()
{
var amountDue = getMembershipPrice() + getExtraPostagePrice() + getPaypalfee();
document.getElementById('amountDue').innerHTML ="Amount Due: $"+amountDue;
}
The javascript I wrote to return the paypal fee is this (it's become very convoluted and I'm not sure where I've gone wrong and how to restart!):
var paymentmethod_Fee = new Array();
paymentmethod_Fee["cheque"]=0;
paymentmethod_Fee["paypal"]=2;
function getPaypalfee()
{
var paypalFee=0;
for (var i=0; i < document.membershipform.payment_method.length; i++)
{
if (document.membershipform.payment_method[i].checked)
{
var selectedPaymentmethod = document.membershipform.payment_method[i].value;
}
}
paypalFee = paymentmethod_Fee[selectedPaymentmethod.value];
return paypalFee;
}
The html for the radio buttons looks like this:
<p>I will make payment via: <BR>
<input type="radio" id="payment_method" name="payment_method" value="cheque" checked="yes" onchange="getAmountDue()">Cheque
<input type="radio" id="payment_method" name="payment_method" value="paypal" onchange="getAmountDue()">Paypal (Add $2)
Any insights into the flaw in my logic is greatly appreciated! I'm a javascript novice and radio buttons seem to be my nemesis (I'd like to learn how to use them rather than replace them with a drop-down menu or something I know how to do already).
Thank you!
Arrays shouldn't be used to create mappings between items. What you're looking for is an object:
var fees = {
cheque: 0,
paypal: 2
};
As for your error, it's this line right here:
paypalFee = paymentmethod_Fee[selectedPaymentmethod.value];
paymentmethod_Fee is already a string. It doesn't have a value attribute.
Don't use more than one element with the same id. Doing so creates glitches. OVER 9000 glitches. So, don't use duplicate ids. Just don't. It is a maxim of web development. It will serve you well. Follow it to the letter. Or, you will have glitches. I am sure you don't want glitches. Rid yourself of glitches. Don't use duplicate ids.
(preceding paragraph tl;dr: Always have unique ids, or you get glitches.)
You should wrap your radio buttons in a div with id payment_methods. Then, use document.getElementById("payment_methods").childNodes[i] to access each successive button.
(By the way, two radio buttons with the same name are mutually exclusive, so the buttons should have identical names but different ids.)
You are using checked correctly. It's just how you're accessing elements that's causing glitches.
Hope this gets rid of your glitches.

How to create dynamic select field with blank option and unfiltered state

I need to create a dynamic select field in Rails 3.2, where the options available in the second fields (states) depends on the value of the first (country). I've referred to the revised version of this Railscast, and am using the following code:
jQuery ->
$('#person_state_id').parent().hide()
states = $('#person_state_id').html()
$('#person_country_id').change ->
country = $('#person_country_id :selected').text()
escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g, '\\$1')
options = $(states).filter("optgroup[label='#{escaped_country}']").html()
if options
$('#person_state_id').html(options)
$('#person_state_id').parent().show()
else
$('#person_state_id').empty()
$('#person_state_id').parent().hide()
I need to make two changes to this code, which I think should be pretty straightforward for someone with stronger javascript skills than I have.
In the filtered list, I need to include a blank option. Currently selecting a country results in the first state state in the filetred list being selected. I need to leave the prompt "please select". How can I do this?
EDIT
SMathew's suggestions helped here. I'm using $('#person_state_id').html(options).prepend('<option></option>') which, together with a prompt attribute on the html tag, acheives the required result.
If no country is selected (ie the else statement) person_state_id should contain a complete, unfiltered list of all states. I've tried:
else
$('#person_state_id').html(states)
But this is not behaving as expected. I'm having these issues.
If I select a country that has associated state records, #person_state_id options are correctly filtered (and with smathews suggestion, a prompt is included).
If I select a country with no associated state records, #person_state_id contains all states, a blank option in the markup, but the first state option is selected by default. (It should be empty, with a blank option selected by default and a prompt displayed).
If I clear the selection in #person_country_id, #person_state_id contains an unfiltered list of all states (correct), and an empty option in the markup (correct) but the first state record is selected by default (should be a prompt).
How can I resolve these issues?
Thanks
Try
...
if (options) {
$('#person_state_id').html(options).prepend('<option>Please select</option>').parent().show()
} else {
$('#person_state_id').html(states).prepend('<option>Please select a state</option>').parent().show()
}
To deal with my second problem, I added the following coffeescript
jQuery ->
resetCountry = ->
$('#person_state_id').select2 "val", "0"
$('#person_country_id').bind("change", resetCountry);
This, coupled with smathew's answer, seems to be working
(I'm using select2 to format my select fields. You'll need a different approach to set the value if not using select2)

cakephp - Javascript

We are working on an application using the CakePHP framework
Basically, its a questionnaire application and it has a few dependant questions, i.e. based on a response to a specific question, it needs to show or hide the next one
For e.g.
Question: Are you married? Yes/No
If the user selects Yes, then using javascript the next question gets displayed for user input
Question: Spouse's name
Saving this information is fine, but when editing, when populating the form, we would want to be able to display the fields for which user has inputted data - in this case, it needs to show the field that has the spouse's name
Since by default we are hiding the spouse name field, when editing, it doesn’t display the field, even though there is a value to it
Is there some way that CakePHP can handle this or does it require us to write some javascript to take care of this?
Thanks in advance.
CakePHP does not manage this for you. While CakePHP is very powerful and a great framework, it will not write this kind of logic for you. You must write it.
I would suggest making the EDIT screen different from the ADD screen. Build the list of values from the database and display the fields that have values (and include any empty fields that should require values).
Keep in mind reusable does not necessarily mean that all CRUD actions fit into the same view.
Like others I advise you use differents EDIT and ADD screens.
But you can try make it with Javascript like this:
<script>
function enableDisableField(targetFieldId){
var targetField = document.getElementById(targetFieldId);
var checkbox = event.target;
console.log(checkbox.checked);
if (checkbox.checked){
targetField.disabled = false;
targetField.value = "empyt";
}else{
targetField.disabled = true;
targetField.value = "empyt";
}
}
</script>
<label><input type="checkbox" onchange="enableDisableField('married')"/> Merried</label>
<?= $this->Form->input('married',['label' => false, 'disabled']); ?>
It works well for ADD, but if you and EDIT you have to change de disable value according a field value:
<label><input type="checkbox" onchange="enableDisableField('married')"/> Merried</label>
<?= $this->Form->input('married',['label' => false, !isset($user->married) ? 'disabled' : '' ]); ?>

Categories

Resources