so I've been struggling with this issue.
I want to add a checkbox into a div dynamically by clicking a button. Let's say I already have 2 checkboxes in the div, then I uncheck those 2. When I click the button, the checkboxes become 3 (which is what I want), but all those 3 will be checked. What I want is when I add a checkbox, the other checkbox(s)' checked state remain the same as before.
Here is my code (http://jsfiddle.net/gr2o47wt/4/):
HTML:
<div id="chkbox_container">
<input type="checkbox" checked>Check<br />
</div>
<input type="button" value="Add CheckBox" onClick="addCheckBox();">
JavaScript:
function addCheckBox() {
txt = "<input type=\"checkbox\" checked>Check<br />";
document.getElementById('chkbox_container').innerHTML += txt;
}
Thanks in advance for your answers! :)
You can use insertAdjacentHTML() rather than manipulating the innerHTML:
<input type="button" value="Add CheckBox"
onClick="document.getElementById('chkbox_container').insertAdjacentHTML('beforeend','<input type=\'checkbox\' checked=\'checked\' />Check<br />');">
JS Fiddle demo.
The problem you had was that the original HTML (as returned by innerHTML) is from the source of the page, not the DOM; and therefore the checked/unchecked nature of the checkbox originally in place was restored.
insertAdjacentHTML() simply adds the HTML string in the specified place ('beforeend' in this case).
More or less as an aside, it's worth trying, where possible, to keep your event-handling outside of your HTML elements; and binding those event-handlers in the JavaScript itself. This makes for somewhat easier maintainability, and would lead to code like the following:
// note that I gave the button an 'id' for simplicity:
var button = document.getElementById('addCheckboxes');
button.addEventListener('click', function () {
document.getElementById('chkbox_container').insertAdjacentHTML('beforeend', '<input type=\'checkbox\' checked=\'checked\' />Check<br />');
});
JS Fiddle demo.
Finally, some of your HTML is invalid (or at least erroneous), an <input /> is a void element, it can have no descendants; therefore it either has no closing tag (just: <input>) or self-closes (<input />).
Further, the text beside the checkboxes is a little misleading, usually with an HTML form the text beside the <input /> will focus that input; that's achieved by using a <label> element to associate the text with the control, for example:
<label><input type="checkbox" /> click</label>
JS Fiddle demo.
Or:
<input type="checkbox" id="inputElementID" />
<label for="inputElementID">click</label>
But this latter form does require the dynamic generation of ids (which is a little beyond the scope of this question).
References:
insertAdjacentHTML().
Related
On Firefox 54, the first and the third checkbox show their inner text while the second does not but they all have the same structure, just constructed using different methods. What is the reason for this behaviour?
input2 = document.getElementById("input2");
input2.innerHTML = "Check me inner HTML";
input2.innerText = "Check me inner Text";
input3 = document.createRange().createContextualFragment("<input type='checkbox'>Check me fragment</input>");
document.body.appendChild(input3);
<input type="checkbox">Check me HTML</input>
<input type="checkbox" id="input2"></input>
<input> elements do not have an "inner HTML". The resulting HTML structure is:
<input type="checkbox">Check me HTML
<input type="checkbox" id="input2">Check me inner Text</input>
<script type="text/javascript">/* your js */</script>
<input type="checkbox">Check me fragment
The second one isn't valid HTML. The "inner" text won't be rendered.
I'm not quite sure why the 3rd one renders properly. The browser might be able to fix the fragment before it's included in the page.
(The </input> may just be getting stripped, making the HTML valid)
I understand that to bind a ractive variable to a radio-button, the easiest way is to have
<input type="radio" name="{{myVar}}" value="1" checked>
in the template, but the curly brackets on the name persist into the html. Is there a clever way to get it to output
<input type="radio" name="myVar" value="1" checked>
in the html, so I don't have to alter the form-handling? I've tried some logic along the lines of
<input type="radio" name="myVar" value="1" {{#myVar==1}}checked{{/myVar==1}}
but that doesn't bind.
Also, less importantly, is there a way to bind it as a numeric value, as if I have
data:{myVar:1}
Then the button doesn't get checked?
Ractive adds the curly braces to input names to guard against the (highly unlikely) possibility of a conflict between name='{{myVar}}' and name='myVar' - no other reason. The binding is created when the element is rendered; what the name becomes after that is irrelevant.
So although there's no way to prevent the curly braces being added in the first place, you can certainly change them afterwards:
ractive.findAll('input[type="radio"]').forEach( function(input) {
input.name = input.name.replace('{{','').replace('}}','');
});
If you were creating a component with Ractive.extend() this could be part of the init() method, for example.
It shouldn't have a problem with numeric values, at least as of the last released version (0.3.9) and current development version (0.4.0). See this fiddle for an example: http://jsfiddle.net/rich_harris/7qQZ8/
Short answer: I don't think it's possible to do what you want.
Ractive handles radio buttons differently than simple HTML markup. It assumes that you're going to want to retrieve which radio button is set using a simple variable, and it relies on the name attribute to do that. Specifically, it expects you to set the name attribute to the same specific variable (e.g. "{{myVar}}") in all radio buttons in a group. It will then automatically set that variable to the value attribute of whichever individual radio button is selected.
For example, if you have the following code:
<label><input type='radio' name='{{myVar}}' value='1' checked> 1</label>
<label><input type='radio' name='{{myVar}}' value='2' > 2</label>
<label><input type='radio' name='{{myVar}}' value='3' > 3</label>
<p>The selected value is {{myVar}}.</p>
Then Ractive will automatically update the <p> with information on whatever radio button is selected.
Short Question:
How do you link a label element to an input element without using the input element's id using jQuery and javascript?
Long Question:
I am using jQuery to clone a form with possibly more than one instance of the form being available for the user to fill in.
A label's 'for' attribute is supposed to be set to the 'id' attribute of the input element that it is for. This works when the input element has a unique id.
Because I am cloning the same input element there will be multiple input elements with the same id in the document. Therefore I'm avoiding having id attributes for input elements but I'd still like to focus on the input element when the label is clicked. I also want to avoid generating random ids for fields or setting onclick events on labels.
Edit #1
Example mark up (note no ids)
<form>
<label>First Name:</label><input type='text' name='FirstName' /><br/>
<label>Last Name:</label><input type='text' name='LastName' /><br/>
</form>
Example cloning code:
var newForm = $('form').clone();
$(newForm).find('label').each(function(){
var inputElement = $(this).next('input');
// I'd love to set the label's for attribute to an element
$(this).attr('for', inputElement);
});
$(document).append(newForm);
Edit #2
There currently are three options:
Set onclick events for labels to focus on the input field they're for. Criteria for deciding which labels are for which inputs can be the next input element or something else
Embed the input fields in the label fields (might not be possible due to designer's choices)
Generate random ids while cloning each form
Well it would be nice to see the markup, but if i can assume that the markup will look somewhat like this
<form name="f1">
<label>this is my label</label>
<input />
<label>this is my other label</label>
<input />
</form>
<form name="f2">
<label>this is my label</label>
<input />
<label>this is my other label</label>
<input />
</form>
then you could do something like this
$('form label').live('click',function(){
$(this).next('input').focus();
});
you will need to use live or delegate since you're cloning the forms on the fly i'm assuming.
The simplest solution is to move the <input> tags inside the <label> tags and forgo the for attribute altogether. Per the HTML spec, <input> tags without for attributes are implicitly associated with their contents.
Try this:
<form>
<label>First Name: <input type='text' name='FirstName' /></label><br/>
<label>Last Name: <input type='text' name='LastName' /></label><br/>
</form>
(See: http://www.w3.org/TR/html401/interact/forms.html#h-17.9.1)
You shouldn't have multiple identical ids in the page. It defeats the purpose of the id attribute and is against the W3C spec.
Regardless, jQuery's $(this) could help you in this situation. Say you gave all your the "focusable" class. Then you could do:
$('.focusable').focus( function(){
$(this).doSomething();
});
This is really an HTML question. A label can be associated wtih a form control either by its for attribute having the same value as the associated control's id attribute, or by having the control as a child of the label, e.g.
<form ...>
<label for="nameField">Name:<input id="nameField" name="nameField" ... ></label>
<label>email:<input name="emailField" ... ></label>
</form>
I suppose in jQuery you need something like:
var labelAndInput = $('<label>text<input ... ></label>');
or whatever. Note that older versions of IE (and maybe more recent ones too) the label will not be associated with the control without the for attribute (or htmlFor property), there is no other way.
I have a form that I want to be used to add entries. Once an entry is added, the original form should be reset to prepare it for the next entry, and the saved form should be duplicated prior to resetting and appended onto a div for 'storedEntries.' This much is working (for the most part), but Im having trouble accessing the newly created form... I need to change the value attribute of the submit button from 'add' to 'edit' so properly communicate what clicking that button should do. heres my form:
<div class="newTruck">
<form id="addNewTruck" class='updateschedule' action="javascript:sub(sTime.value, eTime.value, lat.value, lng.value, street.value);">
<b style="color:green;">Opening at: </b>
<input id="sTime" name="sTime" title="Opening time" value="Click to set opening time" class="datetimepicker"/>
<b style="color:red;">Closing at: </b>
<input id="eTime" name= "eTime" title="Closing time" value="Click to set closing time" class="datetimepicker"/>
<label for='street'>Address</label>
<input type='text' name='street' id='street' class='text' autocomplete='off'/>
<input id='submit' class='submit' style="cursor: pointer; cursor: hand;" type="submit" value='Add new stop'/>
<div id='suggests' class='auto_complete' style='display:none'></div>
<input type='hidden' name='lat' id='lat'/>
<input type='hidden' name='lng' id='lng'/>
</form>
</div>
ive tried using a hundred different selectors with jquery to no avail... heres my script as it stands:
function cloneAndClear(){
var id = name+now;
$j("#addNewTruck").clone(true).attr("id",id).appendTo(".scheduledTrucks");
$j('#'+id).filter('#submit').attr('value', 'Edit');
$j("#addNewTruck")[0].reset();
createPickers();
}
the element is properly cloned and inserted into the div, but i cant find a way to access this element... the third line in the script never works.
Another problem i am having is that the 'values' in the cloned form revert back to the value in the source of the html rather than what the user inputs.
advice on how to solve either of these issues is greatly appreciated!
I think you want to use find not filter
$j('#'+id).find('#submit')
That should work in practice, though you've got problems there because there are multiple elements with the same id. I'd change your HTML to use classes, or in this specific case, you don't need either:
$j('#' + id).find(":submit")
have you tried using .val()? and instead of .filter(), use .find()
$j('#'+id).find(':submit').val('Edit');
nickf solution works. (just wrote a piece of code to check that). Do check the definition of filter in jquery documentation.
Reduce the set of matched elements to those that match the selector or pass the function's test.
You have use find in this case. Also as nick mentioned having multiple elements with same id is troublesome, especially when you are doing dom manipulation. Better go with appropriate classes.
I need to write a java script. This is supposed to validate if the checkbox is selected in the page or not. The problem here is that the check box is inside a grid and is generated dynamically. The reason being the number of check box that need to be rendered is not know at design time. So the id is know only at the server side.
Here is a thought:
As indicated by Anonymous you can generate javascript, if you are in ASP.NET you have some help with the RegisterClientScriptBlock() method. MSDN on Injecting Client Side Script
Also you could write, or generate, a javascript function that takes in a checkbox as a parameter and add an onClick attribute to your checkbox definition that calls your function and passes itself as the parameter
function TrackMyCheckbox(ck)
{
//keep track of state
}
<input type="checkbox" onClick="TrackMyCheckbox(this);".... />
You have to generate your javascript too, or at least a javascript data structure (array) wich must contain the checkboxes you should control.
Alternatively you can create a containing element, and cycle with js on every child input element of type checkbox.
If it's your only checkbox you can do a getElementsByTagName() call to get all inputs and then iterate through the returned array looking for the appropriate type value (i.e. checkbox).
There is not much detail in the question. But assuming the the HTML grid is generated on the server side (not in javascript).
Then add classes to the checkboxes you want to ensure are checked. And loop through the DOM looking for all checkboxes with that class. In jQuery:
HTML:
<html>
...
<div id="grid">
<input type="checkbox" id="checkbox1" class="must-be-checked" />
<input type="checkbox" id="checkbox2" class="not-validated" />
<input type="checkbox" id="checkbox3" class="must-be-checked" />
...
<input type="checkbox" id="checkboxN" class="must-be-checked" />
</div>
...
</html>
Javascript:
<script type="text/javascript">
// This will show an alert if any checkboxes with the class 'must-be-checked'
// are not checked.
// Checkboxes with any other class (or no class) are ignored
if ($('#grid .must-be-checked:not(:checked)').length > 0) {
alert('some checkboxes not checked!');
}
</script>