I have two button inside a form that I don't want to submit the form but add and remove table rows. One button is dynamically added.
I have tried many ways to prevent the submission but none seem to work. When I was getting the button by id and using an event listener it was ok but that did not work with button that get added after age load. I am trying to find a solution that will work with buttons. The one that loaded on page load and the ones that get added dynamically with JavaScript.
<table id="conditions-table">
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th></th>
</tr>
<tr>
<td>
<input id="condtitions-input"></input>
<select id="condtitions-level">
<option value="Mandatory">Mandatory</option>
<option value="Important">Important</option>
<option value="Support">Support</option>
</select>
</td>
<td>
<button id="add-condtition" onclick="addCondition(e); return false;">Add Conditions</button></td>
</td>
</tr>
</thead>
</table>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>
<script>
var counter = 0;
function addCondition(e){
e.preventDefault()
var table = document.getElementById("conditions-table");
var row = table.insertRow(2);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var condtionsInput = document.getElementById("condtitions-input");
var condtionsInputValue = condtionsInput.value;
condtionsInput.value = "";
var selectedLevel = document.getElementById("condtitions-level");
var selectedLevelValue = selectedLevel.value;
cell1.innerHTML = `<input type="text" name="strategies_conditions[${counter}][name]" value=" ${condtionsInputValue}"></input>
<select>
<option ${(selectedLevelValue == "Mandatory") ? 'selected="selected"' : ""} value="Mandatory">Mandatory</option>
<option ${(selectedLevelValue == "Important") ? 'selected="selected"' : ""} value="Important">Important</option>
<option ${(selectedLevelValue == "Support") ? 'selected="selected"' : ""} value="Support">Support</option>
</select>`;
cell2.innerHTML = "<button class='remove-condition' onclick="removeCondition()">X</button></td>";
counter++;
return false;
};
function removeCondition() {
// event.target will be the input element.
var td = event.target.parentNode;
var tr = td.parentNode; // the row to be removed
tr.parentNode.removeChild(tr);
};
The default type of a button is "submit"; just override that behavior by setting it to "button".
cell2.innerHTML = "<button type='button' class='remove-condition' onclick='removeCondition()'>X</button></td>";
You also need to define event as a parameter of the event handler function.
function removeCondition(event) {
// event.target will be the input element.
var td = event.target.parentNode;
var tr = td.parentNode; // the row to be removed
tr.parentNode.removeChild(tr);
};
Just don't insert the argument e inside the onclick event in the markup you can apply an event using JavaScript like the following
btn.onclick = e => {
e.preventDefault();
}
<form>
<input type="text" name="" placeholder="Name">
<input type="submit" name="" id="btn">
</form>
or you can simply make a onclick event return false like the following
<form>
<input type="text" name="" placeholder="Name">
<input type="submit" name="" id="btn" onclick="return false">
</form>
to add an event to an element that doesn't exist yet on the DOM you need to know about event.target
here is a sample that might help you
document.addEventListener( "click", listenerFunction );
function listenerFunction(event){
var element = event.target;
// here you check for that auto generated element
if(element.tagName == 'A' && element.classList.contains("someBtn")){
console.log("hi");
}
}
All you really need to do is add:
<input type="submit" onclick="event.preventDefault();">
You probably want to handle it though so in total you'd probably do something more like this:
<script>
function myFunction(){
if (confirm("Are you sure you want to ...? This action cannot be undone.")) {
document.getElementById("myForm").submit();
}
}
</script>
<form method="post" action="/test" id="myForm">
<input type="submit" onclick="event.preventDefault();myFunction();">
</form>
This allows the user to click ok to proceed or cancel to not have it submit the form.
Related
I'm looking for using Javascript in order to enable/disable submit button.
This button should respect both following conditions :
Enable : if checkbox is checked AND dropdown list value set
Disable : if both or one of previous conditions are not good (checkbox unchecked or date value not set)
This is my code :
function checkValid() {
var cbChecked = $(".fake-radio").is(":checked"); // check if checked
var selectelem = document.getElementById('year');
var btnelem = document.getElementById('document-button');
btnelem.disabled = !selectelem.value;
}
And this is my html part :
<table id="document-table">
<thead>
<tr>
<th>{% trans 'Choice' %}</th>
<th>{% trans 'Document title' %}</th>
</tr>
</thead>
<tbody>
{% for document in query_document %}
<tr>
<td><input type="checkbox" class="fake-radio" id="document-checkbox" name="DocumentChoice"
value="{{ document.id }}"></td>
</tr>
{% endfor %}
</tbody>
</table>
<select id="year" name="q1year" value="{{ request.get.q1year }}" required>
<option selected="selected">
<option value="" selected disabled hidden></option>
</option>
</select>
<button class="btn btn-default" id="document-button" type="submit"
name="UpdateDocument">{% trans "Submit" %}</button>
I'm pretty new with Javascript
EDIT :
I made this, is it true ?
function checkValid() {
var cbChecked = $(".fake-radio").is(":checked"); // check if checked
var selectelem = document.getElementById('year');
var btnelem = document.getElementById('document-button');
btnelem.disabled = !selectelem.value;
var dropdown_value = btnelem.disabled
$("#document-button").prop("disabled", !cbChecked || dropdown_value);
}
If I understand your situation correctly, then it looks like you have a minor logic error in your latest update. Consider revising your checkValid function like so:
function checkValid() {
var selectelem = $('#year');
var isChecked = $(".fake-radio").is(":checked"); // radio is checked
var selectHasValue = !!selectelem.val(); // select has value
// use de morgans law to compute disabled property
$("#document-button").prop("disabled", !(isChecked || selectHasValue));
}
You need to ensure that checkValid() is called when ever relevant form inputs are changed. You can do this by adding the following script:
$(function() {
// Apply validation logic when relevant fields change
$('#year, .fake-radio').change(checkValid);
checkValid(); // Apply validation logic on page load automatically
});
Also, for more on de morgans law, see this wiki article. Hope this helps!
you have to add on change event for your checkbox and select. and you don't need jquery for doing this, use pure js whenever you can.
this is what you need, take this as a reference and edit your code :
function checkValid(){
var check = document.getElementById("document-checkbox").checked;
var e = document.getElementById("year");
var select = e.options[e.selectedIndex].value;
if (select && check) document.getElementById("document-button").disabled = false
else document.getElementById("document-button").disabled = true
}
<body>
<input onchange="checkValid()" type="checkbox" class="fake-radio" id="document-checkbox" name="DocumentChoice" value="{{ document.id }}">
<select onchange="checkValid()" id="year" name="q1year" value="{{ request.get.q1year }}" required>
<option selected="selected">
<option value="x">x</option>
</option>
</select>
<button disabled class="btn btn-default" id="document-button" type="submit" name="UpdateDocument">submit</button>
</body>
Thanks in advance.I have a popup window which has a dynamic text box fields.These textboxes will multiple according to the selected combo box values from the first form.The dynamic textboxes are displayed from jquery. Please anyone help me how to validate a dynamic text boxes on clicking the submit button. Actually I have to validate the textboxes before sending the mail. I have written a code which will validate only static textboxes. My code as below
<head>
<script>
$(document).ready(function () {
$(".myformid").click(function(){
var nameVal = $('.names').val();
var emailVal = $('.emails').val();
var phoneVal = $('.phones').val();
if(nameVal == "")
{
$('#errmsg').html("<p style='color:red;font-weight:bold'>Please enter the Name</p>");
}
else if(emailVal == ""){
//alert("A textbox is required");
$('#errmsg').html("<p style='color:red;font-weight:bold'>Please enter the email Id</p>");
}
else if(!ValidateEmail(emailVal))
{
$('#errmsg').html("<p style='color:red;font-weight:bold'>Invalid Email Id</p>");
}
else if(phoneVal == "")
{
$('#errmsg').html("<p style='color:red;font-weight:bold'>Please enter the Phone Number</p>");
}
else if(isNaN(phoneVal))
{
$('#errmsg').html("<p style='color:red;font-weight:bold'>Please enter the Valid Phone Number</p>");
}
else if(emailVal !="" && phoneVal != "")
{
$('#errmsg').text(" ");
var username = $('#usernameId').val();
var length = $('#lengthId').val();
var nameArray = [];
var emailArray = [];
var phoneArray = [];
$('.names').each(function(){
nameArray.push(this.value);
});
var nameboxVal = nameArray.join(",");
//alert(nameboxVal);
$('.emails').each(function(){
emailArray.push(this.value);
});
var emailboxVal = emailArray.join(",");
//alert(emailboxVal);
$('.phones').each(function(){
phoneArray.push(this.value);
});
var phoneboxVal = phoneArray.join(",");
//alert(phoneboxVal);
$.ajax({
type: "POST",
url: "/invl_exams/popSubmit",
data: {user:username,name:nameboxVal,email:emailboxVal,phone:phoneboxVal,lengths:length},
success: function(result){
console.log(result);
$('#mailSuccess').text('Mail Send Successfully');
$('#mailSuccess').fadeOut(5000);
}
});
}
});
});
// Passing dynamic textboxes inside the dialog box
$(".create-user").change(function(){
var selVal = $(this).val();
$('#lengthId').val(selVal);
$("#textboxDiv").html('');
if(selVal > 0) {
for(var i = 1; i<= selVal; i++) {
var sno = i;
$("#textboxDiv").append('<tr><td>'+sno+'. </td><td>Name:<input type="text" name="names" class="names" value="" required="required" /></td><td> </td><td>Email:<input type="email" name="emails" class="emails" value="" required="required" /></td><td> </td><td>Phone:<input type="text" name="phones" class="phones" value="" required="required" minlength="10" maxlength="16"/><br/></td></tr>');
}
}
});
});
</script>
</head>
<body>
<div id="dialog" title="Enter details to send Mail">
<!--<form id="myformid" method="post" action="<?php //echo $this->webroot?>users/sendmail">-->
<div id="mailSuccess" style="color:#019002;font-weight:bold"></div>
<form id="myformid" method="post">
<table id="examtable">
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<div id="textboxDiv"></div>
<input type="hidden" name="username" id="usernameId" value="<?php echo $this->Session->read('Auth.User.username'); ?>">
<input type="hidden" name="length" id="lengthId" value="">
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td>
<!--<input type="submit" name="btnSubmit" value="Submit">-->
<input type="button" name="btnSubmit" value="Send Mail" id="popSubmit">
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
I don't think any validation is happening at all, whether the elements are static or dynamic.
$(".myformid").click(function(){
will not bind to anything because there are no elements with the class "myformid". The "." at the start of a selector indicates a class.
However you do have an element with an id "myformid". If you change your selector from . to # to indicate an id, then it will bind the event to the form. However, "click" is not the correct event to bind to a <form> element. You want to handle the form's "submit" event:
$("#myformid").submit(function(event){
Lastly, as it stands, your form will do a regular (non-ajax) postback as well as running your function, because the default behaviour of the submit event is not suppressed. Add this line as the first line of the above function:
event.preventDefault();
This will stop a regular postback from happening and allow your validation function to execute. At that point you should have a working solution, assuming the logic in your validation code is what you want.
If your validations are right you just need to attach event in way that dinamicly created elements will be supported too (jQuery on)
$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+
for example
from
$(".myformid").click(function(){/*Some action*/});
to
$("body").on('click', ".myformid", function(){/*Some action*/});
from
$(".create-user").change(function(){/*Some action*/});
to
$("body").on('change', ".create-user", function(){/*Some action*/});
Small advice: Try to avoid using $("body") selector you can see what is your good dom element witch is parent to your dynamically generated contend/elements.
I have HTML snippet which looks like this. I generate this snippet multiple times form the backend. When I click the Save button, I catch which Save button was clicked using $(this) selector. Now I want to grab the attribute item-id of the corresponding Save button. I have the following jquery code snippet. But it does not work. I have tried to look but I don't know where the error is.
<td><input type="text" size="10" value="val1" item-id="id1"></td>
<td><input type="text" value="val2" size="4"></td>
<td>
<button class="btn btn-primary save-btn">Save</i></button>
</td>
Here is the jquery snippet
$(".save-btn").click(function(){
var ems = $(this).parent().siblings();
var item_id = ems[0].child().attr("item-id");
}
click doesn't work on dynamically added elements.You need to use on('click'). Also there is no method .child() so you need to use .children().first().
This is the corrected code:
$(document).on('click', '.save-btn', function(){
var ems = $(this).parent().siblings();
var item_id = ems.children().first().attr("item-id");
});
// The text
var text="";
text += "<td><input type=\"text\" size=\"10\" value=\"val1\" item-id=\"id1\"><\/td>";
text += "<td><input type=\"text\" value=\"val2\" size=\"4\"><\/td> ";
text += "<td>";
text += " <button class=\"btn btn-primary save-btn\">Save<\/i><\/button>";
text += "<\/td>";
// Adding the text to html
$('body').html(text);
$(document).on('click', '.save-btn', function(){
var ems = $(this).parent().siblings();
console.log(ems);
var item_id = ems.children().first().attr("item-id");
alert(item_id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
better replace item-id="id1" to data attribute html5 data-id="id1" then replace code attr('item-id') to data('id')...
$(document).on('click','.save-btn', function(){
var ems = $(this).parent().siblings(),
item_id = ems.eq(0).children('input').attr("item-id");
alert(item_id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text" size="10" value="val1" item-id="id1"></td>
<td><input type="text" value="val2" size="4"></td>
<td>
<button class="btn btn-primary save-btn"><i>Save</i></button>
</td>
</tr>
</table>
I have a simple form users can fill out and also add a new form to add multiple entries.
Everything works fine except when I enter data in the first set of inputs and click create new memberships it will take the data from the form and put it in the text boxes.
How can I stop that?
http://jsfiddle.net/811yohpn/2/
I have tried a couple different ways.
$('#education').find('input:text').val('');
$('#education: input').val('');
However that will clear all entries.
Call find on the newDiv, instead of all inputs within #education.
Updated fiddle
newDiv.find('input:text').val('');
var ed = 1;
function new_education() {
ed++;
var newDiv = $('#education div:first').clone();
newDiv.attr('id', ed);
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled(' + ed + ')" > Delete Education ' + ed + ' </a>';
newDiv.find('tr:first th').text('Education ' + ed);
newDiv.append(delLink);
newDiv.find('input:text').val(''); // <----------- added this
$('#education').append(newDiv);
}
function deled(eleId) {
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('education');
parentEle.removeChild(ele);
//ed--;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<legend>Education</legend>
<div id="education">
<div id="1">
<table border=3>
<tr>
<th colspan="4" style="background-color:#b0c4de;">Education 1</th>
</tr>
<tr>
<td>
<label>School Name</label>
<input type="text" name="schoolname[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Type</label>
<input type="text" name="degreetye[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Field</label>
<input type="text" name="degreefield[]" maxlength="30" size="30"/>
</td>
</tr>
</table>
</div>
</div>
<br/><a class="js-addNew btn btn-info" href="javascript:new_education()"> Add New Education </a>
You need to clear the inputs under the cloned element
newDiv.find('input').val('')
Demo: Fiddle
Your selectors are selecting all input elements within the #education container, that is not what you want. The newDiv variable refers to the newly created element so you can use that to find the input elements within in and then clear it
I am trying to make an editable check list, using check boxes. One feature I would like is for users to be able to add their own items to this list.
With the help of another user, I have got this far:
HTML:
<table id="myTable">
<tr>
<td>
<label for="checkbox65">
<input name="checkbox65" class="checkbox65" type="checkbox" />
Get directions for where you are going
</label>
</td>
</tr>
<tr>
<td>
<fieldset data-role="controlgroup">
<label for="textinput4">
Add new item
<input name="new_item" id="textinput4" placeholder="" value="" type="text" />
</label>
</fieldset>
<button id="add">Add</button>
</td>
</tr>
</table>
Javascript:
$('#add').on('click', function (e) {
var $this = $(this);
var $firstRow=$this.closest('table').find('tr:first');
var $newRow = $firstRow.clone();
$newRow.find(':input').prop('checked', false);
$newRow.insertAfter($firstRow);
});
What I'm trying to get is something that looks a bit like this:
What I want
But at the moment it just repeats the original check box with label.
Assuming you need to set the text next to the checkbox to what you enter in the input box, you can do:
$('#add').on('click', function (e) {
var $this = $(this);
var $firstRow=$this.closest('table').find('tr:first');
var $newRow = $firstRow.clone();
var input = $newRow.find(':input').remove();
input.prop('checked', false);
$newRow.empty().append(input).append(' '+$('#textinput4').val());
$newRow.insertAfter($firstRow);
});
Demo: http://jsfiddle.net/VHe6C/
You can add the text box value for the check box
$(document).ready(function(){
$("#addbutton").on("click",function(){
if ($("#goingtoadd").val()!="")
document.getElementById('adding').innerHTML+='<br/><input name="checkbox65" class="checkbox65" type="checkbox" />'+$("#goingtoadd").val();
$("#goingtoadd").val("");
})
});
See this Fiddle for Demo
If anyone is interested in a pure javascript based solution here is it:
document.querySelector('#add').addEventListener('click', function(e){
var table = this.parentNode.parentNode.parentNode,
rowsLen = table.rows.length,
beforeLastRow = table.rows[rowsLen - 2],
inputToAdd = document.querySelector('#textinput4');
var newRow = beforeLastRow.cloneNode(true),
input = newRow.querySelector('input');
input.checked = false;
var label = newRow.querySelector('label');
label.innerHTML = "";
label.appendChild(input);
label.appendChild(document.createTextNode(inputToAdd.value));
inputToAdd.value = "";
table.insertBefore(newRow, table.rows[rowsLen - 1]);
}, false);
Here is a jsFiddle to test it out:
http://jsfiddle.net/subhamsaha1004/2G9Qv/