Dojo/Dijit: Dynamically choosing input required attribute - javascript

I am attempting to put together a fairly complex form using dojo and dijit widgets. The form has multiple 'sections' which allow the user to attach an existing object (via select tag) or create an entirely new object inline in the form.
My inputs are rendered conditionally based radio buttons and manipulated via javascript. What I am having problems doing, is conditionally making dijit widgets required based on whether the inputs are rendered or not (which itself depends on which radio button is selected.
My html (actually jsp)
<div>
<input id="useExisting" type="radio" name="radio" checked value="useExisting" onclick="renderExistingInput()" /> <label for="useExisting">Use Existing</label>
<input id="new" type="radio" name="radio" value="new" onclick="renderNewInputs()"/> <label for="new">Create New</label>
</div>
<br>
<div id="newInputs">
<div class="row">
<label class="label" for="newName">Name </label>
<span class="formInput"><input type="text" id="newName" name="newName" required="true" dojoType="dijit.form.ValidationTextBox"/></span>
</div>
<!-- More inputs with required="true"-->
<br>
</div>
<div id="existingInput>
<div class="row">
<label class="label" for="existingSelect">Existing Object </label>
<span class="formInput">
<select name="existingSelect" id="existingSelect" dojoType="dijit.form.Select">
<!--JSTL tags for compiling list of options -->
</select>
</span>
</div>
</div>
Accompanying javascript functions:
function renderExistingInput() {
dojo.fx.wipeOut(getWipeArguments('newInputs')).play();
dojo.fx.wipeIn(getWipeArguments('existingInput')).play();
}
function renderNewInputs() {
dojo.fx.wipeOut(getWipeArguments('existingInput')).play();
dojo.fx.wipeIn(getWipeArguments('newInputs')).play();
}
function getWipeArguments(id) {
var wipeArgs = {
node : id
};
return wipeArgs;
}
The basic 'flow' of user interactions is User clicks a radio button, the correct div renders as a result of that. What I want then are inputs that are not rendered to not be considered required. I'm not entirely sure how to do this. Is it possible to manipulate that particular attribute directly via dojo? Or is there a better way to do this entirely?

Seem's like My answer was staring me right in the face. I simply needed to pull together the different parts I had come across. My final function for changed the 'required' attribute looks like:
function setWidgetRequiredAttributes(baseDomNodeId, requiredValue){
foundWidgets = dijit.findWidgets(dojo.byId(baseDomNodeId));
console.log(foundWidgets);
foundWidgets.forEach(function(widget){
widget.required=requiredValue;
});
}

Related

Mapping multiple form inputs of the same name into a JavaScript object

I have an HTML form similar to this.
<label for="person-firstname">First Name</label>
<input type="text" id="person-firstname" name="person-firstname"/>
<label for="person-lastname">Last Name</label>
<input type="text" id="person-lastname" name="person-lastname" />
<label for="person-phone">Phone</label>
<input type="text" id="person-phone" name="person-phone" />
<!-- Button will add the same input as above -->
<button type="button" onclick="addAnotherPersonSection()">+ Add Another Person</button>
<!-- More HTML of different section of the overall form -->
<label for="person-terms">Agree to Terms and Conditions</label>
<input type="checkbox" id="person-terms" name="person-terms" />
<label for="person-initals">Initals</label>
<input type="text" id="person-initals" name="person-initals" />
What I'm trying to do is map out the input into an object with the key name as the name of the input and value being the input text.
{
"Persons":[{
"person-firstname":input.value,
"person-lastname":input.value,
"person-phone":input.value,
"person-terms":input.value,
"person-initals":input.value
}, {
"person-firstname":input.value,
"person-lastname":input.value,
"person-phone":input.value,
"person-terms":input.value,
"person-initals":input.value
}]
}
The problem is naming the key of the object as "person-firstname" instead of when $("input[name^=business]").serializeArray(); creates it the key is named "name" and is structured wrong.
{ name: "person-firstname", value:input},
{ name: "person-lastname", value:input}
I'm just looking for a JavaScript or jQuery solution to create a dynamic object based on multiple inputs of the same name. Also, have control of the key name.
The crux of the problem is that you can't have multiple form fields with the same name. If you do, that's called a "naming collision" which will bust native functionality of an HTML form. But you can use a sort of template-like logic and generate variant names that make sense base on the number of people that are added to the HTML form. My example may not be what you're looking for exactly, but it's what I came up with:
https://codesandbox.io/s/admiring-hypatia-30lrv

Changing the value of a hidden field to the value of a checkbox on submit with javascript inside Contact Form 7 Wordpress plugin

I have been trying to get this working for more than a week now, searching endlessly for the solution and I can't figure out what I'm doing wrong. I am not a coder, just trying to duct tape some functions together to get this working... Please help!
I have the following checkbox inputs on my Contact Form 7 form inside a Wordpress page. I have Mailchimp for Wordpress updating a group which reflects the visitors interests. I'm trying to get the value of the group assigned to a hidden input field so that the built in mail feature and other Zapier integrations can use the interest values. Most of these apps seem to lack support for the groups functionality inside Mailchimp.
The form html is as follows:
<p>
<label>Which Are You Most Interested In?</label></br>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="ac2ed8233d"
required=""><span>Interest 1</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="s3g2c99k0x"
required=""> <span>Interest 2</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="k9n6xp3s26"
required=""> <span>Interest 3</span>
</label>
</p>
<input type="hidden" id="int-in" name="int-in"</input>
--
I've tried several variations of this including some inline stuff, putting the code in the top or bottom of the page, putting it into the Additional section of Contact Form 7, putting it into a scripts plugin inside wordpress, trying to see if it's an array thing and trying code for pushing from array (more over my head) and so many others. Here is what I'm basically trying to do, albeit wrongly via this code because obviously it is not working...
JS:
$('form').submit(function() {
$('input[name="#mc4wp-INTERESTS[gs8o25e9bc] .
[]"]').change(function(){
$('#int-in').val($('input[name="#mc4wp-INTERESTS[gs8o25e9bc] .
[]"]').val());
});
--
Online there is not much support for Mailchimp groups, and I suspect groups functions of most contact apps, not even with paid plugin feature. Mailchimp for Wordpress has the most support I could find and you still have to do some tinkering to get it working. I'm soooo ready to know what the heck works instead of all the stuff I've been trying! Thank you in advance. I really appreciate it!
Wordpress disables the $ shortcut, so you need to either replace $ with jQuery or wrap your code:
(function($){
// your code here
})(jQuery);
Plus, the name of those checkboxes doesn't contain a hashtag. I also have no idea what you're doing with those dots and linebreaks there.
In addition, you're assigning a onchange handler only when the form is submitted, but you'll want that to work from the start instead.
Here's a solution that sets the onchange handler to grab the value from all checked checkboxes and puts it into the hidden input.
var selector = 'form input[name="mc4wp-INTERESTS[gs8o25e9bc][]"]';
(function($) {
$(selector).change(function() {
var interests = Array.from(document.querySelectorAll(selector))
.filter(e => e.checked).map(e => e.value).join(",");
$('#int-in').val(interests);
console.log("set to", interests);
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<p>
<label>Which Are You Most Interested In?</label><br/>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="ac2ed8233d"><span>Interest 1</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="s3g2c99k0x"> <span>Interest 2</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="k9n6xp3s26"> <span>Interest 3</span>
</label>
</p>
<input type="hidden" id="int-in" name="int-in">
<input type="submit">
</form>

Angular ngRepeat - How to have multiple objects containing radio buttons

I am doing some updates to a clients Ionic app but stuck on some binding.
There is a form with some fields including a couple of radio buttons.
E.g.
<div class="fields">
<input ng-model="student.name" type="text" name="student_name" id="name" />
<input ng-model="student.has_booked" type="radio" checked="checked" name="made_booking" id="made_booking_yes" value="1" />
</div>
The request for the update is to have a button that duplicates the details in this first form and add its to an array where the details can be used for another student as they are normally similar.
To do this I have a button that calls this method:
$scope.additionalStudents = []; // <-- for context of question
$scope.duplicateStudentDetails = function() {
var firstStudent = angular.copy($scope.student);
$scope.additionalStudents.push(firstStudent);
}
Then in my view:
<div class="fields" ng-repeat="(key, student) in additionalStudents track by $index">
<input ng-model="student.name" type="text" name="student_name" id="name" />
<input ng-model="student.has_booked" type="radio" checked="checked" name="made_booking" id="made_booking_yes" value="1" />
</div>
The issue I am having is that the name came be changed independently, but the checkbox always affects the original student. Im guessing this is because of the name attribute...
How do I go around this?
There might be two solutions to your problem.
If your case is just to show the status and not to change the booking status
Then, remove name attribute
If you want change the booking status in future
Better to have input of type checkbox with different names

How can I check a radio button with no id using a single line of javascript (no jQuery)?

All right, this is a pretty specific question from a beginner, so bear with me.
I'm a newbie just learning the ropes. Here's the background (skip to next para if you don't care): I'm updating my first android app and I'm using MIT App Inventor 2 to do it. It's a free tool online that uses a WYSIWYG screen editor and Blockly to create behaviors, interactions, etc. The app I'm making loads a specific web page with a form and fills out most of the form for you (specifically, it's to help people enter the online ticket lottery for a theater show). The page is not my own so I can't edit the HTML. But I can run javascript on top of it by plugging single lines of javascript code into the Blockly side of App Inventor. Here's a relevant example of how it looks.
I've figured out how to fill in most of the form using getElementByID(). But there's a set of radio buttons that have no id. Here's a lightly modified version of the HTML (which I cannot edit):
<div id="cont_id_tickets">
<div>
<input type="radio" name="tickets" value="1" />
<span style="font-family:Times New Roman; font-size:15px;">1</span>
</div>
<div>
<input type="radio" name="tickets" value="2" />
<span style="font-family:Times New Roman; font-size:15px;">2</span>
</div>
<div id="required_info_tickets" class="requiredInfo floatLeft">
</div>
<input type="hidden" name="reqField" value="tickets" alt="Radio" req="true" errorMsg="Please enter a valid value." requredErrorMsg="This field is required. Please enter a value."
patternID="0" customRegex="" />
</div>
I've made some progress by using the following:
document.querySelector('input[name=tickets]').checked = true;
But that of course only selects the first radio button. I'd like to able to get a value (1 or 2) and have it select the right button accordingly. The Blockly backend I'm using allows me to define a variable to plug into the line of javascript, but the line of javascript itself has to be essentially a single line. I was hoping one of the following would work if I wanted the value to be 2 for example:
document.querySelector('input[name=tickets][value=2]').checked = true;
document.querySelector('input[name=tickets]').2.checked = true;
But neither does. Any ideas on the correct syntax?
Thank you!
You need to place the value that you are trying to select using in quotes:
document.querySelector('input[name=tickets][value="2"]').checked = true;
Example
document.querySelector('input[name=tickets][value="2"]').checked = true;
<div id="cont_id_tickets">
<div>
<input type="radio" name="tickets" value="1" />
<span style="font-family:Times New Roman; font-size:15px;">1</span>
</div>
<div>
<input type="radio" name="tickets" value="2" />
<span style="font-family:Times New Roman; font-size:15px;">2</span>
</div>
<div id="required_info_tickets" class="requiredInfo floatLeft">
</div>
<input type="hidden" name="reqField" value="tickets" alt="Radio" req="true" errorMsg="Please enter a valid value." requredErrorMsg="This field is required. Please enter a value." patternID="0" customRegex="" />
</div>

Grouping Radio Button Input elements in loop

I currently have this UI:
the problem is that when I click one radio button, any preselected button will become unselected. So that's telling me that there aren't different input groups - all of the <input> tags are probably in one big group.
This is probably a pretty vanilla problem, but I am simply not an HTML or Angular expert.
Here is the code for this, there is an outer loop and an inner loop using ng-repeat:
<form name="myQuestionsForm" ng-submit="submit()"> // outer form
<div class="panel panel-default" ng-repeat="q in questions | orderBy:[]">
<h1>{{q.prompt.value}}</h1>
<div class="panel-body">
<form id="aform"> // inner form
<div ng-repeat="c in q.children | orderBy:[]">
<div ng-if="c.kind == 'text'">
<label>
{{c.value}}
<textarea name="response" class="form-control" ng-value="c.value" ng-model="q.newResponse.value"></textarea>
</label>
</div>
<div ng-if="c.kind == 'checkbox'">
<label>
{{c.value}}
<input type="checkbox" name="response" class="form-control" ng-value="c.value" ng-model="q.newResponse.value">
</label>
</div>
<div ng-if="c.kind == 'radio'">
<label>
{{c.value}}
<input type="radio" name="response" class="form-control" ng-value="c.value" ng-model="q.newResponse.value">
</label>
</div>
</div>
</form>
</div>
</div>
<div style="text-align: center;">
<button type="submit" class="btn btn--success btn">
<h5>Submit</h5>
</button>
</div>
</form>
Perhaps the reason this is happening is because I have nested forms? Maybe I need to get rid of the outer form?
Group radio buttons with the name attribute.
<input> type attribute
The type of control to display. The default type is text, if this attribute is not specified. Possible values are:
radio: A radio button. You must use the value attribute to define the value submitted by this item. Use the checked attribute to indicate whether this item is selected by default. Radio buttons that have the same value for the name attribute are in the same "radio button group". Only one radio button in a group can be selected at a time.
– MDN HTML Element Reference - <input>
See also:
AngularJS input[radio] Directive API Reference
AngularJS ng-value Directive API Reference
AngularJS ng-checked Directive API Reference

Categories