I'm creating a plugin for Input Files, I created everything but without having in mind the possibility of having multiple inputs on screen, then it was necessary instead to manipulate the element from the element ID. This is so that actions in one input do not affect all other inputs on the screen.
Below is the code so far, I could not make it work when informed by the element ID.
function bs_input_file() {
// TODO: add function to hide remove button when file not informed
const inputElement = $(".input-file").find('input');
const inputId = inputElement.map(function (index, dom) {
return dom.id
});
buttonInspec(inputId);
function buttonInspec(id) {
$("#" + id).find("button.btn-reset").addClass("hidden");
var element = $("#" + id).find('input');
element.on("change input propertychange", function() {
console.log("changed!")
if (element.val() != "") {
$("#" + id).find("button.btn-reset").removeClass("hidden");
}
});
}
// Necessary to put ID below also
$(".input-file").before(
function() {
if (!$(this).prev().hasClass('input-ghost')) {
var element = $("<input type='file' class='input-ghost' style='visibility:hidden; height:0'>");
element.attr("name", $(this).attr("name"));
element.change(function() {
element.next(element).find('input').val((element.val()).split('\\').pop());
});
$(this).find("button.btn-choose").click(function() {
element.click();
});
$(this).find("button.btn-reset").click(function() {
element.val(null);
$(this).parents(".input-file").find('input').val('');
});
$(this).find('input').css("cursor", "pointer");
$(this).find('input').mousedown(function() {
$(this).parents('.input-file').prev().click();
return false;
});
return element;
}
}
);
}
bs_input_file();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="col-md-8 col-md-offset-2">
<h3>Example</h3>
<form method="POST" action="#" enctype="multipart/form-data">
<!-- COMPONENT START -->
<div class="form-group">
<div class="input-group input-file" name="Fichier1">
<input id="fileInput0" type="text" class="form-control" placeholder='Select file...' />
<span class="input-group-btn">
<button class="btn btn-secondary btn-reset" type="button"><em class="glyphicon glyphicon-trash"></em></button>
<button class="btn btn-default btn-choose " type="button"><em class="glyphicon glyphicon-folder-open"></em> Search...</button>
</span>
</div>
</div>
<div class="form-group">
<div class="input-group input-file" name="Fichier2">
<input id="fileInput1" type="text" class="form-control" placeholder='Select file...' />
<span class="input-group-btn">
<button class="btn btn-secondary btn-reset" type="button"><em class="glyphicon glyphicon-trash"></em></button>
<button class="btn btn-default btn-choose " type="button"><em class="glyphicon glyphicon-folder-open"></em> Search...</button>
</span>
</div>
</div>
<!-- COMPONENT END -->
</form>
</div>
</div>
Related
Heading
I'm trying to build a submit form for my login, but I don't know why this action is not working. Any ideas ?
List item jquery
$(function() {
var $formLogin = $('#login-form');
var $formLost = $('#lost-form');
var $formRegister = $('#register-form');
var $divForms = $('#div-forms');
var $modalAnimateTime = 300;
var $msgAnimateTime = 150;
var $msgShowTime = 2000;
$("form").submit(function (e) {
e.preventDefault();
switch(this.id) {
case "login-form":
var $lg_username=$('#login_username').val();
var $lg_password=$('#login_password').val();
if ($lg_username == "ERROR") {
msgChange($('#div-login-msg'), $('#icon-login-msg'), $('#text-login-msg'), "error", "glyphicon-remove", "Login error");
} else {
msgChange($('#div-login-msg'), $('#icon-login-msg'), $('#text-login-msg'), "success", "glyphicon-ok", "Login OK");
}
return false;
break;
case "lost-form":
var $ls_email=$('#lost_email').val();
if ($ls_email == "ERROR") {
msgChange($('#div-lost-msg'), $('#icon-lost-msg'), $('#text-lost-msg'), "error", "glyphicon-remove", "Send error");
} else {
msgChange($('#div-lost-msg'), $('#icon-lost-msg'), $('#text-lost-msg'), "success", "glyphicon-ok", "Send OK");
}
return false;
break;
case "register-form":
var $rg_username=$('#register_username').val();
var $rg_email=$('#register_email').val();
var $rg_password=$('#register_password').val();
if ($rg_username == "ERROR") {
msgChange($('#div-register-msg'), $('#icon-register-msg'), $('#text-register-msg'), "error", "glyphicon-remove", "Register error");
} else {
msgChange($('#div-register-msg'), $('#icon-register-msg'), $('#text-register-msg'), "success", "glyphicon-ok", "Register OK");
}
return false;
break;
default:
return false;
}
return false;
});
$('#login_register_btn').click( function () { modalAnimate($formLogin, $formRegister) });
$('#register_login_btn').click( function () { modalAnimate($formRegister, $formLogin); });
$('#login_lost_btn').click( function () { modalAnimate($formLogin, $formLost); });
$('#lost_login_btn').click( function () { modalAnimate($formLost, $formLogin); });
$('#lost_register_btn').click( function () { modalAnimate($formLost, $formRegister); });
$('#register_lost_btn').click( function () { modalAnimate($formRegister, $formLost); });
function modalAnimate ($oldForm, $newForm) {
var $oldH = $oldForm.height();
var $newH = $newForm.height();
$divForms.css("height",$oldH);
$oldForm.fadeToggle($modalAnimateTime, function(){
$divForms.animate({height: $newH}, $modalAnimateTime, function(){
$newForm.fadeToggle($modalAnimateTime);
});
});
}
function msgFade ($msgId, $msgText) {
$msgId.fadeOut($msgAnimateTime, function() {
$(this).text($msgText).fadeIn($msgAnimateTime);
});
}
function msgChange($divTag, $iconTag, $textTag, $divClass, $iconClass, $msgText) {
var $msgOld = $divTag.text();
msgFade($textTag, $msgText);
$divTag.addClass($divClass);
$iconTag.removeClass("glyphicon-chevron-right");
$iconTag.addClass($iconClass + " " + $divClass);
setTimeout(function() {
msgFade($textTag, $msgOld);
$divTag.removeClass($divClass);
$iconTag.addClass("glyphicon-chevron-right");
$iconTag.removeClass($iconClass + " " + $divClass);
}, $msgShowTime);
}
});
List item html
<!-- Begin # DIV Form -->
<div id="div-forms">
<!-- Begin # Login Form -->
<form id="login-form" method="post" action="login.php">
<div class="modal-body">
<div id="div-login-msg">
<div id="icon-login-msg" class="glyphicon glyphicon-chevron-right"></div>
<span id="text-login-msg">Type your username and password.</span>
</div>
<input id="login_username" class="form-control" type="text" placeholder="Username (type ERROR for error effect)" required>
<input id="login_password" class="form-control" type="password" placeholder="Password" required>
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
<div class="modal-footer">
<div>
<button type="submit" name="login" class="btn btn-primary btn-lg btn-block">Login</button>
</div>
<div>
<button id="login_lost_btn" type="button" class="btn btn-link">Lost Password?</button>
<button id="login_register_btn" type="button" class="btn btn-link">Register</button>
</div>
</div>
</form>
<!-- End # Login Form -->
<!-- Begin | Lost Password Form -->
<form id="lost-form" style="display:none;" method="post" action="submit.php">
<div class="modal-body">
<div id="div-lost-msg">
<div id="icon-lost-msg" class="glyphicon glyphicon-chevron-right"></div>
<span id="text-lost-msg">Type your e-mail.</span>
</div>
<input id="lost_email" class="form-control" type="text" placeholder="E-Mail (type ERROR for error effect)" required>
</div>
<div class="modal-footer">
<div>
<button type="submit" name="submit" class="btn btn-primary btn-lg btn-block">Send</button>
</div>
<div>
<button id="lost_login_btn" type="button" class="btn btn-link">Log In</button>
<button id="lost_register_btn" type="button" class="btn btn-link">Register</button>
</div>
</div>
</form>
<!-- End | Lost Password Form -->
<!-- Begin | Register Form -->
<form id="register-form" style="display:none;" method="post" action="submit.php">
<div class="modal-body">
<div id="div-register-msg">
<div id="icon-register-msg" class="glyphicon glyphicon-chevron-right"></div>
<span id="text-register-msg">Register an account.</span>
</div>
<input id="register_username" class="form-control" type="text" placeholder="Username (type ERROR for error effect)" required>
<input id="register_email" class="form-control" type="text" placeholder="E-Mail" required>
<input id="register_password" class="form-control" type="password" placeholder="Password" required>
</div>
<div class="modal-footer">
<div>
<button type="submit" name="submit" class="btn btn-primary btn-lg btn-block">Register</button>
</div>
<div>
<button id="register_login_btn" type="button" class="btn btn-link">Log In</button>
<button id="register_lost_btn" type="button" class="btn btn-link">Lost Password?</button>
</div>
</div>
</form>
<!-- End | Register Form -->
</div>
<!-- End # DIV Form -->
</div>
</div>
</div>
You have to prevent your form from submitting first before you can run custom code, or else your form will submit before your code runs. This can be done by using e.preventDefault(). For example:
$("form").submit(function (e) {
e.preventDefault();
...
}
We are working on a dApp that is giving us problems. The site loads OK and the button to open the subform ("Post My Rental") works. When I fill out the subform and click the 'submit' button, nothing happens. I have confirmed that I am connected to Metamask and Ganache, but no transaction goes through. Checking inspect in Chrome, no errors there. I suspect there is something missing in this code, but I can't find it. If you could help out, we would really appreciate it. Here is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Rent My Place</title>
<!-- Title will appear as a tab in browser on webpage -->
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Application -->
<link href="css/app.css" rel="stylesheet">
<!-- stylesheet refers to the look of the page, Font, color-->
</head>
<body>
<div class="container">
<!-- container that contains title panel-->
<div class="jumbotron text-center">
<p style="font-size:80px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:10px;border-style:solid;border-color:#c3c3c3;">
<font color = "#880015" >Rent My Place</font></p>
</div>
<div class="col-md-12" id="article-list">
<div class="row">
<div class="col-lg-12">
<!--<p id="account" class="welcome pull-right"></p>
<p id="accountBalance" class="welcome pull-left"></p>-->
</div>
</div>
<div class="row panel panel-default">
<div class="panel-heading clearfix">
<div class="panel-title">
<p style="font-size:24px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:5px;border-style:solid;border-color:#c3c3c3;">
<font color = "#880015">Renter's Tip: </font><font color = "#000000">Inspect the property before you send money.</font><br><font color = "#880015">Landlord's Tip: </font><font color = "#000000">Meet prospective tenants in person.</font></p>
<!-- Button that opens second window to a form to fill out-->
<button class="btn btn-info btn-lg pull-right" data-toggle="modal" data-target="#sellArticle">Post a Rental</button>
</div>
</div>
<!-- when the event button gets click, it will show the list-->
<ul id="events" class="collapse list-group"></ul>
</div>
<div id="articlesRow" class="row">
<!-- ARTICLES with pertinent item information LOAD HERE -->
</div>
</div>
</div>
<!--Result that is displayed after input-->
<div id="articleTemplate" style="display: none;">
<div class="row-lg-12">
<div class="panel panel-default panel-article">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div class="panel-body">
<strong>Beds</strong>: <span class="beds"></span><br/>
<strong>Baths</strong>: <span class="baths"></span><br/>
<strong>Address</strong>: <span class="propaddress"></span><br/>
<strong>Rental Price</strong>: <span class="rental_price"></span><br/>
<strong>Description</strong>: <span class="article_description"></span><br/>
<strong>Property is available for showing</strong>: <span class="available"></span><br/>
<strong>Contact Email</strong>: <span class="contact_email"></span><br/>
<!--<strong>Sold by</strong>: <span class="article-seller"></span><br/>-->
</div>
<div class="panel-footer">
<button type="button" class= "btn btn-primary btn-success btn-buy" onclick="App.buyArticle(); return false;">Buy</button>
</div>
</div>
</div>
</div>
<!-- Modal form to sell an article -->
<div class="modal fade" id="sellArticle" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Rent Your Place</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-12">
<form>
<div class="form-group">
<!--NOTE: For radio buttons to work, 'name' field must match-->
<label for="property_type">Property Type</label>
<input type="radio" name="property" id="property_type" value="house" > House
<input type="radio" name="property" id="property_type" value="apartment" > Apartment
<input type="radio" name="property" id="property_type" value="duplex" > Duplex
</div>
<div class="form-group">
<label for="propaddress">Address</label>
<input type="text" class="form-control" id="propaddress" placeholder="Enter the address">
</div>
<div class="form-group">
<label for="beds">Beds</label>
<input type="radio" name="beds" id="beds" value="0"> Studio
<input type="radio" name="beds" id="beds" value="1"> One
<input type="radio" name="beds" id="beds" value="2"> Two
<input type="radio" name="beds" id="beds" value="3"> Three +
</div>
<div class="form-group">
<label for="baths">Baths</label>
<input type="radio" name="baths" id="baths" value="1"> One
<input type="radio" name="baths" id="baths" value="2"> Two
<input type="radio" name="baths" id="baths" value="3"> Three +
</div>
<div class="form-group">
<label for="rental_price">Rent (in USD)</label>
<input type="text" class="form-control" id="rental_price" placeholder="$" pattern="[0-9]+([\.,][0-9]+)?">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea type="text" class="form-control vresize" id="article_description" placeholder="Describe your property" maxlength="255"></textarea>
</div>
<div class="form-group">
<label for="available"></label>
<input type="checkbox" name="available" value="available" id="available"> Property is available for showing
</div>
<div class="form-group">
<label for="contact_email">Contact Email</label>
<input type="text" class="form-control" id="contact_email" placeholder="Enter your contact email">
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-success" data-dismiss="modal" onclick="App.sellArticle(); return false;">Submit</button>
<button type="button" class="btn" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="footer" class="container">
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="navbar-inner navbar-content-center text-center">
<p class="text-muted" credit>AXbean - © 2018</a></p>
</div>
</nav>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/OurRentalManualInputDataInitWeb3appMay22.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/web3.min.js"></script>
<script src="js/truffle-contract.js"></script>
</body>
</html>
Here is the app.js that is called:
App = {
web3Provider: null,
contracts: {},
account: 0x0,
loading: false,
init: function() {
return App.initWeb3();
},
initWeb3: function() {
// initialize web3
if(typeof web3 !== 'undefined') {
//reuse the provider of the Web3 object injected by Metamask
App.web3Provider = web3.currentProvider;
} else {
//create a new provider and plug it directly into our local node
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
App.displayAccountInfo();
return App.initContract();
},
displayAccountInfo: function() {
web3.eth.getCoinbase(function(err, account) {
if(err === null) {
App.account = account;
$('#account').text(account);
web3.eth.getBalance(account, function(err, balance) {
if(err === null) {
$('#accountBalance').text(web3.fromWei(balance, "ether") + " ETH");
}
})
}
});
},
initContract: function() {
$.getJSON('OurRentalTestFromClassMay24.json', function(chainListArtifact) {
//added May24 to json file name
// get the contract artifact file and use it to instantiate a truffle contract abstraction
App.contracts.OurRentalTestFromClassMay24 = TruffleContract(chainListArtifact);
// set the provider for our contracts
App.contracts.OurRentalTestFromClassMay24.setProvider(App.web3Provider);
// listen to events
App.listenToEvents();
// retrieve the article from the contract
return App.reloadArticles();
});
},
reloadArticles: function() {
//avoid reentry bugs
if(App.loading){
return;
}
App.loading = true;
// refresh account information because the balance might have changed
App.displayAccountInfo();
var chainListInstance;
App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance) {
chainListInstance = instance;
return chainListInstance.getArticlesForSale();
}).then(function(articlesIds) {
// retrieve the article placeholder and clear it
$('#articlesRow').empty();
for(var i = 0; i < articlesIds.length; i++){
var articleId = articlesIds[i];
chainListInstance.articles(articleId.toNumber()).then(function(article){
App.displayArticle(article[0], article[1], article[3], article[4], article[5]);
});
}
App.loading = false;
}).catch(function(err) {
console.error(err.message);
App.loading = false;
});
},
displayArticle: function(id, seller, beds, baths, propaddress, rental_price, description, available, contact_email){
var articlesRow = $('#articlesRow');
var etherPrice = web3.fromWei(price, "ether");
var articleTemplate = $("#articleTemplate");
//articleTemplate.find('.panel-title').text(name);
articleTemplate.find('.beds').text(beds);
articleTemplate.find('.baths').text(baths);
articleTemplate.find('.propaddress').text(propaddress);
articleTemplate.find('.rental_price').text(rental_price);
articleTemplate.find('.description').text(description);
articleTemplate.find('.available').text(available);
articleTemplate.find('.contact_email').text(contact_email);
// articleTemplate.find('.article_price').text(etherPrice + " ETH");
articleTemplate.find('.btn-buy').attr('data-id', id);
articleTemplate.find('.btn-buy').attr('data-value', etherPrice);
//seller
if(seller == App.account){
articleTemplate.find('.article-seller').text("You");
articleTemplate.find('.btn-buy').hide();
}else{
articleTemplate.find('.article-seller').text(seller);
articleTemplate.find('.btn-buy').show();
}
//add this new article
articlesRow.append(articleTemplate.html());
},
sellArticle: function() {
// retrieve the detail of the article
// var _article_name = $('#article_name').val();
var _description = $('#description').val();
var _beds = $('#beds').val();
var _baths = $('#baths').val();
var _propaddress = $('#propaddress').val();
var _rental_price = $('#rental_price').val();
var _property_type = $('#property_type').val();
var _available = $('#available').val();
var _contact_email = $('#contact_email').val();
// var _article_price = $('#article_price').val();
// var _price = web3.toWei(parseFloat($('#article_price').val() || 0), "ether");
//if((_article_name.trim() == '') || (_price == 0)) {
// nothing to sell
// return false;
// }
App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance) {
return instance.sellArticle(_description, _beds, _baths, _propaddress, _rental_price, _property_type, _available, _contact_email, {
from: App.account,
gas: 500000
});
}).then(function(result) {
}).catch(function(err) {
console.error(err);
});
},
// listen to events triggered by the contract
listenToEvents: function() {
App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance) {
instance.LogSellArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._name + ' is now for sale</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
instance.LogBuyArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._buyer + ' bought ' + event.args._name + '</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
});
},
buyArticle: function() {
event.preventDefault();
// retrieve the article price and data
var _articleId = $(event.target).data('id');
var _price = parseFloat($(event.target).data('value'));
App.contracts.OurRentalTestFromClassMay24.deployed().then(function(instance){
return instance.buyArticle(_articleId, {
from: App.account,
value: web3.toWei(_price, "ether"),
gas: 500000
});
}).catch(function(error) {
console.error(error);
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
I had this HTML script which contains a drop list and a text box, and I just need to clone those two instead of the whole div, and then send the data to AJAX, and each drop list with text box will form an array that should be add as a single row in a table, that's what I have now:
<div class="col-sm-4 rounded" style="background-color: #D3D3D3">
<div class="row clonedInput" id="clonedInput1">
<div class="col-sm-6 ">
<label for="diagnosis_data">Medication</label>
<fieldset class="form-group">
<select class="form-control select" name="diagnosis_data" id="diagnosis_data">
<option value="choose">Select</option>
</select>
</fieldset>
<!-- End class="col-sm-6" -->
</div>
<div class="col-sm-6">
<label for="medication_quantity">Quantity</label>
<fieldset class="form-group">
<input type="number" class="form-control" name="medication_quantity" id="medication_quantity">
</fieldset>
<!-- End class="col-sm-6" -->
</div>
<!-- End class="col-sm-6" -->
</div>
<div class="actions pull-right">
<button class="btn btn-danger clone">Add More</button>
<button class="btn btn-danger remove">Remove</button>
</div>
<!-- End class="col-sm-4" -->
</div>
And here is the jQuery Script:
$(document).ready(function()
{
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
})
var regex = /^(.+?)(\d+)$/i;
var cloneIndex = $(".clonedInput").length;
function clone(){
$(this).closest(".rounded").clone()
.insertAfter(".rounded:last")
.attr("id", "rounded" + (cloneIndex+1))
.find("*")
.each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = id.split('-')[0] +'-'+(cloneIndex);
}
})
.on('click', 'button.clone', clone)
.on('click', 'button.remove', remove);
cloneIndex++;
}
function remove(){
$(this).parent().parent(".rounded").remove();
}
The problem is that the whole div is being cloned and just the div id is being changed:
Here is the id of each div is being incremented:
I need to clone the 2 elements only not the whole div and buttons
At the end I need t add them to database using Ajax and PHP
Here you can go with the code.
In this code i made changes in clone()
Here the changes
You first find existing child element.
Than clone that element and append it after last element
var cloneIndex = $(".clonedInput").length; this should be in clone() So it will pass proper incremented value of child element as id in your cloned html
the below code just only make clone of clonedInput not a whole div
Edit
I also edit remove function also.
It will only removes last element which was cloned.
Hope this will helps you. :)
$(document).ready(function()
{
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
});
var regex = /^(.+?)(\d+)$/i;
function clone() {
var cloneIndex = $(".clonedInput").length;
$(".rounded").find("#clonedInput1").clone().insertAfter(".clonedInput:last").attr("id", "clonedInput" + (cloneIndex+1));
}
function remove() {
$(".rounded").find(".clonedInput:last").remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-4 rounded" style="background-color: #D3D3D3">
<div class="row clonedInput" id="clonedInput1">
<div class="col-sm-6 ">
<label for="diagnosis_data">Medication</label>
<fieldset class="form-group">
<select class="form-control select" name="diagnosis_data" id="diagnosis_data">
<option value="choose">Select</option>
</select>
</fieldset>
<!-- End class="col-sm-6" -->
</div>
<div class="col-sm-6">
<label for="medication_quantity">Quantity</label>
<fieldset class="form-group">
<input type="number" class="form-control" name="medication_quantity" id="medication_quantity">
</fieldset>
<!-- End class="col-sm-6" -->
</div>
<!-- End class="col-sm-6" -->
</div>
<div class="actions pull-right">
<button class="btn btn-danger clone">Add More</button>
<button class="btn btn-danger remove">Remove</button>
</div>
<!-- End class="col-sm-4" -->
</div>
You can add style to your actions class to prevent it from showing on all cloned elements
css
.actions {
display: none;
}
.clonedInput:first-child .actions {
display: block;
}
Also for the removing function you could use .closest() instead of .parent().parent()
$(this).closest(".rounded").remove();
There are a lot of things that could be optimized and replaced but I've edited your code. I believe that this is the easiest way to learn.
The edits are marked as "STACKOVERFLOW EDIT" in the comments.
$(document).ready(function() {
$("button.clone").on("click", clone);
$("button.remove").on("click", remove);
$("button.submit").on("click", submit_form); // STACKOVERFLOW EDIT: execute the submit function
});
var regex = /^(.+?)(\d+)$/i;
function clone() {
var cloneIndex = $(".clonedInput").length;
$(".rounded").find("#clonedInput1").clone().insertAfter(".clonedInput:last").attr("id", "clonedInput" + (cloneIndex + 1));
}
function remove() {
if($(".clonedInput").length > 1) { // STACKOVERFLOW EDIT: Make sure that you will not remove the first div (the one thet you clone)
$(".rounded").find(".clonedInput:last").remove();
} // STACKOVERFLOW EDIT
}
// STACKOVERFLOW EDIT: define the submit function to be able to sent the data
function submit_form() {
var ajax_data = $('#submit_form').serialize(); // The data of your form
$.ajax({
type: "POST",
url: 'path_to_your_script.php', // This URL should be accessable by web browser. It will proccess the form data and save it to the database.
data: ajax_data,
success: function(ajax_result){ // The result of your ajax request
alert(ajax_result); // Process the result the way you whant to
},
});
}
The HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-4 rounded" style="background-color: #D3D3D3">
<form action="" method="post" id="submit_form"> <!-- STACKOVERFLOW EDIT: generate a form to allow you to get the data in easy way -->
<div class="row clonedInput" id="clonedInput1">
<div class="col-sm-6 ">
<label for="diagnosis_data">Medication</label>
<fieldset class="form-group">
<select class="form-control select" name="diagnosis_data[]" id="diagnosis_data"> <!-- STACKOVERFLOW EDIT: Add [] so that you may receive the values as arrays -->
<option value="choose">Select</option>
</select>
</fieldset>
<!-- End class="col-sm-6" -->
</div>
<div class="col-sm-6">
<label for="medication_quantity">Quantity</label>
<fieldset class="form-group">
<input type="number" class="form-control" name="medication_quantity[]" id="medication_quantity"> <!-- STACKOVERFLOW EDIT: Add [] so that you may receive the values as arrays -->
</fieldset>
<!-- End class="col-sm-6" -->
</div>
<!-- End class="col-sm-6" -->
</div>
</form> <!-- STACKOVERFLOW EDIT -->
<div class="actions pull-right">
<button class="btn btn-danger clone">Add More</button>
<button class="btn btn-danger remove">Remove</button>
<button class="btn btn-danger submit">Submit</button>
</div>
<!-- End class="col-sm-4" -->
</div>
I want to build a small application (for learning Angular JS) that can define a list of locations and a list of events. The application was developed based on the tutorial found here: http://g00glen00b.be/prototyping-spring-boot-angularjs/.
When defining a new event I would like to associate a location for the new event. The location should be selected using a combobox.
So first I define 2 locations, let's say Location 1 and Location 2. I want to bind somehow the list of available locations (1 and 2) to the combobox labeled "Location select" see this image
So far I was able to bind the location list to the combobox, but the items of the combobox are updated only when I refresh the browser. I would like to be able to automatically refresh the content of the combobox whenever the list of available locations is changed (a new location is added or a location is removed).
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet"
href="./bower_components/bootstrap-css-only/css/bootstrap.min.css" />
</head>
<body ng-app="myEventApp">
<div class="container" ng-controller="EventAppController" >
<div class="page-header">
<h1>Edit Events</h1>
</div>
<div class="alert alert-info" role="alert"
ng-hide="events && events.length > 0">There are no events yet.
</div>
<form class="form-horizontal" role="form"
ng-submit="addEvent(newEventName,newEventDescription)" ng-controller="LocationAppController">
<div >Locations: {{locations}}</div>
<div class="form-group" ng-repeat="event in events">
<div class="checkbox col-xs-9">
<label> <strong>{{event.name}}</strong> /
{{event.description}}
</label>
</div>
<div class="col-xs-3">
<button class="pull-right btn btn-danger" type="button"
title="Delete" ng-click="deleteEvent(event)">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</div>
<hr />
<div class="input-group">
<input type="text" class="form-control" ng-model="newEventName"
placeholder="Enter the name..." /> <input type="text"
class="form-control" ng-model="newEventDescription"
placeholder="Enter the description..." />
<label for="locationSelect">Location select: </label>
<select
name="locationSelect" id="locationSelect" ng-model="data.repeatSelect">
<option value="">---Please select---</option>
<option ng-repeat="location in locations"
value="{{location.id}}">{{location.name}}</option>
</select>
<div class="col-md-6"></div>
<span class="input-group-btn">
<button class="btn btn-default" type="submit"
ng-disabled="!newEventName||!newEventDescription" title="Add">
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
</form>
</div>
<!-- Location -->
<div class="container" ng-controller="LocationAppController">
<div class="page-header">
<h1>Edit Locations</h1>
</div>
<div class="alert alert-info" role="alert"
ng-hide="locations && locations.length > 0">There are no
locations defined yet.</div>
<form class="form-horizontal" role="form"
ng-submit="addLocation(newLocationName,newLocationAddress)">
<div class="form-group" ng-repeat="location in locations">
<div class="checkbox col-xs-9">
<label> <strong>{{location.name}}</strong> /
{{location.address}}
</label>
</div>
<div class="col-xs-3">
<button class="pull-right btn btn-danger" type="button"
title="Delete" ng-click="deleteLocation(location)">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</div>
<hr />
<div class="input-group">
<input type="text" class="form-control" ng-model="newLocationName"
placeholder="Enter the name..." /> <input type="text"
class="form-control" ng-model="newLocationAddress"
placeholder="Enter the address..." />
<!-- <label>Location: </label> -->
<!-- <select -->
<!-- name="repeatSelect" id="repeatSelect" ng-model="data.repeatSelect"> -->
<!-- <option ng-repeat="option in data.availableOptions" -->
<!-- value="{{option.id}}">{{option.name}}</option> -->
<!-- </select> -->
<div class="col-md-6"></div>
<span class="input-group-btn">
<button class="btn btn-default" type="submit"
ng-disabled="!newLocationName||!newLocationAddress" title="Add">
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
</form>
</div>
<script type="text/javascript"
src="./bower_components/angular/angular.min.js"></script>
<script type="text/javascript"
src="./bower_components/angular-resource/angular-resource.min.js"></script>
<script type="text/javascript"
src="./bower_components/lodash/dist/lodash.min.js"></script>
<script type="text/javascript" src="./app/eventApp.js"></script>
<script type="text/javascript" src="./app/eventControllers.js"></script>
<script type="text/javascript" src="./app/eventServices.js"></script>
<script type="text/javascript" src="./app/locationControllers.js"></script>
<script type="text/javascript" src="./app/locationServices.js"></script>
<script type="text/css" src="./app/custom.css"></script>
</body>
</html>
And these are the controllers used:
eventControllers.js
(function(angular) {
var EventAppController = function($scope, Event) {
Event.query(function(response) {
$scope.events = response ? response : [];
});
$scope.addEvent = function(name, description) {
new Event({
locations:[],
name : name,
description : description,
}).$save(function(event) {
$scope.events.push(event);
});
$scope.newEventName = "";
$scope.newEventDescription = "";
};
$scope.updateEvent = function(event) {
event.$update();
};
$scope.deleteEvent = function(event) {
event.$remove(function() {
$scope.events.splice($scope.events.indexOf(event), 1);
});
};
};
EventAppController.$inject = [ '$scope', 'Event' ];
angular.module("myEventApp.controllers").controller("EventAppController",
EventAppController);
}(angular));
locationControllers.js
(function(angular) {
var LocationAppController = function($scope, Location) {
Location.query(function(response) {
$scope.locations = response ? response : [];
});
$scope.addLocation = function(name, address) {
new Location({
name: name,
address: address,
}).$save(function(location) {
$scope.locations.push(location);
});
$scope.newLocationName = "";
$scope.newLocationAddress = "";
};
$scope.updateLocation = function(location) {
location.$update();
};
$scope.deleteLocation = function(location) {
location.$remove(function() {
$scope.locations.splice($scope.locations.indexOf(location), 1);
});
};
return {
getLocations: function() {
return $scope.locations;
}
}
};
LocationAppController.$inject = ['$scope', 'Location'];
angular.module("myEventApp.controllers").controller("LocationAppController", LocationAppController);
}(angular));
eventServices.js
(function(angular) {
var EventFactory = function($resource) {
return $resource('/event/:id', {
id : '#id'
}, {
update : {
method : "PUT"
},
remove : {
method : "DELETE"
}
});
};
EventFactory.$inject = [ '$resource' ];
angular.module("myEventApp.services").factory("Event", EventFactory);
}(angular));
locationServices.js
(function(angular) {
var LocationFactory = function($resource) {
return $resource('/location/:id', {
id : '#id'
}, {
update : {
method : "PUT"
},
remove : {
method : "DELETE"
}
});
};
LocationFactory.$inject = [ '$resource' ];
angular.module("myEventApp.services").factory("Location", LocationFactory);
}(angular));
So, the question is: how to automatically update the content of the combobox when a new location is added / a location is deleted? Thank you.
I cannot remove input field dynamically, I can add field but my remove option is not working.
I am using jquery for dynamically add/remove field and bootstrap 3 for my layout.
Here is my markup:
<div class="row margin-bottom">
<div class="col-md-12 col-sm-12">
<button type="submit" class="add-box btn btn-info"><span class="glyphicon glyphicon-plus"></span> Add More Fields</button>
</div>
</div>
<?php $attributes = array('class' => 'form-horizontal', 'role' => 'form'); echo form_open_multipart('config/upload_image', $attributes);?>
<div class="text-box form-group">
<div class="col-sm-4"><input type="file" class="" name="txtImage[]" id="imageinput"/></div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-upload"></span> Upload</button>
</div>
</div>
<?php echo form_close();?>
Here is my jquery code:
$(document).ready(function(){
$('.add-box').click(function(){
var n = $('.text-box').length + 1;
if(n > 5)
{
alert('Only 5 Savy :D');
return false;
}
var box_html = $('<div class="text-box form-group"><div class="col-sm-4"><input type="file" class="" name="txtImage[]" id="imageinput'+ n +'"/></div><div class="col-sm-2"><button type="submit" class="remove-box btn btn-danger btn-sm"><i class="fa fa-minus-circle fa-lg"></i></button></div></div>');
$('.text-box:last').after(box_html);
box_html.slidedown('slow');
});
$('.form-horizontal').on('click', '.remove-box', function(){
$(this).parent().remove();
return false;
});
});
The error is in the remove button click event handler. You need to remove the closest form group rather than the immediate parent:
$('.form-horizontal').on('click', '.remove-box', function(){
$(this).closest(".form-group").remove();
return false;
});
check this bootply for a working example: http://www.bootply.com/x8n3dQ6wDf
EDIT
for animation on remove you can use jQuery slideUp like this:
$('.form-horizontal').on('click', '.remove-box', function(){
var formGroup = $(this).closest(".form-group");
formGroup.slideUp(200, function() {
formGroup.remove();
});
return false;
});