I am new to Meteor and Javascript. I have slowly figured out how to set up a modal form that will show up when I click a button, and can capture my form data and have the form close when I click submit. Where I am stuck is that whenever I click the button to add more data, the previous values are still in the modal form. I have tried most of the other answer and examples I have found, but I can't seem to figure out what I need to do to make it clear the values. Any suggestions would be appreciated. Here is what I have currently:
Modal Template
<template name="addButton">
<div class="modal fade" id="addButton">
<form>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Add Button</h4>
</div>
<div class="modal-body">
<form role="form">
<div class="form-group">
<label for="buttonOrder">Button Order</label>
<input type="text" class="form-control" name="buttonOrder">
</div>
<div class="form-group">
<label for="buttonName">Button Name</label>
<input type="text" class="form-control" name="buttonName">
</div>
<div class="form-group">
<label for="buttonDescription">Button Description</label>
<input type="text" class="form-control" name="buttonDescription">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
<input type="submit" value="Submit" class="btn btn-primary"/>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</form>
</div>
</template>
Modal JS Helper
Template.addButton.events({
'submit form': function(e) {
e.preventDefault();
var button = {
buttonOrder: $(e.target).find('[name=buttonOrder]').val(),
buttonName: $(e.target).find('[name=buttonName]').val(),
buttonDescription: $(e.target).find('[name=buttonDescription]').val()
}
button._id = Buttons.insert(button);
$('#addButton').modal('hide');
$(this).removeData('#addButton.modal');
}
})
#Jeremy-s
I couldn't get your suggestion to work, although the Session key suggestion got me a solution that did for work with Bootstrap 2 but not with Bootstrap 3. I did finally get things working with Bootstrap 3, although I doubt it is the most elegant solution. I added ids to the elements and just set the value for each element to null like so:
$('#addButton').modal('hide')
$('#buttonOrder').val(null);
$('#buttonName').val(null);
$('#buttonDescription').val(null);
Now I just need to figure out why I can't get it to work with the Session key and Bootstrap 3.
One possible way to go is to use Meteor's findAll to find the inputs in the template, then iterate through them and set the value of each input to null. The findAll is a jquery selector but is limited here to the context of the template.
Template.addButton.events({
'submit form': function(e) {
e.preventDefault();
var button = {
buttonOrder: $(e.target).find('[name=buttonOrder]').val(),
buttonName: $(e.target).find('[name=buttonName]').val(),
buttonDescription: $(e.target).find('[name=buttonDescription]').val()
}
button._id = Buttons.insert(button);
_.each(
this.findAll("input"),
function(element){element.value = null}
);
$('#addButton').modal('hide');
}
})
Note also that instead of using jquery to show and hide the modal, Meteor's preferred approach would be to add and remove it completely from the DOM based on a reactive source like a Session key. I would look at Meteor's reactivity summary for additional guidance on how to do this.
Related
I created the following HTML form inside a jqxWindow widget for a Laravel project:
<div id="provinceWindow">
<div id="provinceWindowHeader"></div>
<div id="provinceWindowContent">
<form id="provinceForm" method="POST" action="{{route('province.store')}}">
{{ csrf_field() }}
<input type="hidden" name="provinceId" id="provinceId" value=""/>
<div class="form-group row">
<div class="col-6"><label>English province name</label></div>
<div class="col-6"><input type="text" name="provinceNameEn" id="provinceNameEn" maxlength="20"/></div>
</div>
<div class="form-group row">
<div class="col-6"><label>Spanish province name</label></div>
<div class="col-6"><input type="text" name="provinceNameSp" id="provinceNameSp" maxlength="20"/></div>
</div>
<br/>
<div class="form-group row justify-content-center">
<input type="button" value="Submit" id="submitBtn" class="btn btn-sm col-3" />
<span class="spacer"></span>
<input type="button" value="Cancel" id="cancelBtn" class="btn btn-sm col-3" />
</div>
</form>
</div>
</div>
This is the javascript file:
$(document).ready(function () {
var datarow = null;
$.ajaxSetup({
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
});
//-----------------------------
// Window settings
//-----------------------------
$('#provinceWindow').jqxWindow({
autoOpen: false,
isModal: true,
width: 400,
height: 160,
resizable: false,
title: 'Province name',
cancelButton: $('#cancelBtn'),
initContent: function () {
$('#submitBtn').jqxButton();
$('#submitBtn').on('click', function () {
$('#provinceForm').submit();
});
}
}).css('top', '35%');
The file routes\web.php has only one resourse route defined for this page:
// Routes for province maintenance
Route::resource('province', 'provinceController');
Checking the available routes with php artisan route:list command, I get these:
Method URI Name Action
GET|HEAD / APP\Http\Controllers\homeController#index
GET|HEAD province province.index APP\Http\Controllers\provinceController#index
POST province province.store APP\Http\Controllers\provinceController#store
GET|HEAD province/create province.create APP\Http\Controllers\provinceController#create
GET|HEAD province/{province} province.show APP\Http\Controllers\provinceController#show
PUT|PATCH province/{province} province.update APP\Http\Controllers\provinceController#update
DELETE province/{province} province.destroy APP\Http\Controllers\provinceController#destroy
GET|HEAD province/{province}/edit province.edit APP\Http\Controllers\provinceController#edit
My controller action:
public function store(Request $request)
{
$fields = $request->all();
if ($request->provinceId == '') {
$province = new province($fields);
$validator = Validator::make($fields, $province->rules());
if ($validator->fails()) {
return redirect('')->withErrors($validator)->withInput();
}
else {
$province->save();
}
return view('province/index');
}
}
The form is shown on top of a jqxGrid widget, as a modal window, in order to capture the required information and perform the CRUD operations for the corresponding DB table.
The problem is, when I click the "Submit" button the window is closed and nothing else happens. The form is not posted to the indicated action and the data entered get lost.
It does not matter if I initialize the submitBtn inside the initContent or outside of it. The form is never posted.
I also tried the Close event of the jqxWindow to no avail.
If I take a look to the generated HTML it looks like this:
<form id="provinceForm" method="POST" action="http://mis:8080/province">
<input type="hidden" name="_token" value="Y9dF5PS7nUwFxHug8Ag6PHgcfR4xgxdC43KCGm07">
<input type="hidden" name="provinceId" id="provinceId" value="">
<div class="form-group row">
<div class="col-6">
<label>English province name</label>
</div>
<div class="col-6">
<input type="text" name="provinceNameEn" id="provinceNameEn" maxlength="20">
</div>
</div>
<div class="form-group row">
<div class="col-6">
<label>Spanish province name</label>
</div>
<div class="col-6">
<input type="text" name="provinceNameSp" id="provinceNameSp" maxlength="20">
</div>
</div>
<br>
<div class="form-group row justify-content-center">
<input type="button" value="Submit" id="submitBtn" class="btn btn-sm col-3 jqx-rc-all jqx-button jqx-widget jqx-fill-state-normal" role="button" aria-disabled="false">
<span class="spacer"></span>
<input type="button" value="Cancel" id="cancelBtn" class="btn btn-sm col-3">
</div>
</form>
Pressing the submit button takes me to the home page and nothing gets added to the DB table.
I guess the issue has something to do with Laravel routes because I get no errors.
What is missing or what is wrong with this approach?
Any light is appreciated.
Alright, because I erroneously added in my Model a validation, that was not needed, for a column (there was already a constraint defined at the DB table level), it was not possible to fulfill the validator when saving a new record. I commented that line in my Model and, that was it!
protected $rules = array(
'provinceNameEn' => 'required|alpha|max:20',
'provinceNameSp' => 'required|alpha|max:20'
//'deleted' => 'required|in:M,F' // This is already validated in a DB constraint.
);
I noticed the control was returned to my home page but without any message or error, but if you pay attention to my controller it was precisely the behavior programmed. However, there is no implementation to display the error messages, so I added dd($validator); before that return statement. There I read the message and finally found the solution.
I have a form like this:
$(document).ready(function() {
$('#create_lop_monhoc_modal').on('show.bs.modal', function(event) {
var button = $(event.relatedTarget)
var tenmh = button.data('tenmh')
var mamh = button.data('mamh')
var modal = $(this)
modal.find('#input_tenmh').val(tenmh).trigger("change")
modal.find('#tenmh').text(tenmh).trigger("change")
modal.find('#input_mamh').val(mamh).trigger("change")
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<div class="modal fade " id="create_lop_monhoc_modal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<form action="/monhoc" method="POST">
<input type="hidden" value="" id="input_mamh" name="mamh" />
<input type="hidden" value="" id="input_tenmh" name="tenmh" />
<div class="modal-body">
<h4 id="mamh"></h4>
<div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">Crate</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<button type="button" data-toggle="modal" data-target="#create_lop_monhoc_modal" data-tenmh="tenmh" data-mamh="mamh">
Open Modal
</button>
When i click 'Open Modal', the value of input hidden was put, but when i submit that form, the value of it is not submit. when i click back button of browser and submit again, this submit success!.
I dont know why, please help!!
I think my problem is caused by another javascript library, namely due to bootstrap-datepicker.js. Because when i click datepicker input, value of it is reset.
I solved this problem by remove datepicker and try submit again, and it is working.
In my question, i think I think that .trigger("change") is no longer needed:
modal.find('#input_tenmh').val('tenmh').trigger("change")
modal.find('#tenmh').text('tenmh').trigger("change")
modal.find('#input_mamh').val('mamh').trigger("change")
after that:
modal.find('#input_tenmh').val('tenmh')
modal.find('#tenmh').text('tenmh')
modal.find('#input_mamh').val('mamh')
Thank for all!
Edit: this is not a duplicate, because I am using HTML5 validating and the required attribute, and when the input is hidden with the modal, the required attribute is removed from it. I only have it as required when the fixed-term radio button is clicked and during the time the modal is open. When submitting the form, it is not required anymore (although this might not be the right way to solve this).
/*Change expiration date input to required once the fixed term choice is
taken, change back when open-ended is chosen*/
function updateRequired() {
document.getElementById('expdate').required = true;
}
function updateNonRequiredCancel() {
document.getElementById('expdate').removeAttribute('required');
radiobtn = document.getElementById("openend");
radiobtn.checked = true;
}
function updateNonRequired() {
document.getElementById('expdate').removeAttribute('required');
}
My problem:
Seen some posts on this topic, but no solutions have worked yet. I have a form with many inputs I'm trying to validate. Currently I am stuck on validating an input inside a bootstrap modal, since it keeps giving me the error: "An invalid form control with name='expdate' is not focusable." when I try to submit the form. All other inputs validate fine outside the radio buttons and modal.
The modal is toggled when the radio button "fixed-term" is chosen and contains the input to choose an expiration date. I have some onclick functions in there for:
1) when open-ended is clicked, 'expdate' is no longer required
2) when fixed-date is chosen, 'expdate' is required
3) when cancel is clicked inside the modal, 'expdate' is no longer required and the radio button selection goes to open-ended automatically
4) when save changes is clicked I validate whether the 'expdate' field is empty or not.
These onclick functions work fine, for example I can't save changes inside the modal without
entering an expiration date. Only problem arises when trying to submit the whole form.
<fieldset>
<div class="form-check form-check-inline">
<input type="radio" required class="form-check-input" id="openend"
name="term" onClick="updateNonRequired();">
<label class="form-check-label" for="openend">
Open-ended
</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input"
onclick="updateRequired();" id="fixed-term" name="term" data-toggle="modal"
data-target="#dateModal">
<label class="form-check-label" for="fixed-term">
Fixed-term
</label>
<div class="modal fade" id="dateModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="end-date" id="end-date">Pick the end-date</h4>
</div>
<div class="modal-body">
<label for="expdate">
Enter a date of expiration:
</label>
<input type="date" oninvalid="InvalidTerm(this);" oninput="InvalidTerm(this);" id="expdate" class="form-control" name="expdate" min="2000-01-02" max="2020-01-01">
<br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="updateNonRequiredCancel();">Close</button>
<button type="button" class="btn btn-primary" onclick="ValidateModal();">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</fieldset>
And some Javascript I'm using to try and validate 'expdate' while the modal is open which is not working, except for checking if the field is empty (which sets var isFine to true and let's the save button hide the modal):
var isFine = false;
function InvalidTerm(datebox) {
var date = new Date(datebox.value);
if (!isNaN(date.getTime())) {
datebox.setCustomValidity('Required field!');
}
else if (datebox.validity.rangeOverflow || datebox.validity.rangeUnderflow){
numberbox.setCustomValidity('Date must be between today and 2020-01-
01');
}
else {
datebox.setCustomValidity('');
}
isFine=true;
return true;
}
function ValidateModal(){
if (isFine === true) {
//document.getElementById('expdate').removeAttribute('required'); //questionable
$('#dateModal').modal('hide');
}
else{
alert('no no');
}
}
Any help is appreciated!
I have a modal window where I want to display an Autocomplete of Jquery UI, this object is inside a form that will then be sent with a submit button to a controller action
my modal window in my main view:
<div class="modal fade" id="agregarProducto">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Agregar Material</h5>
</div>
<form id="myForm">
<label>Producto</label>
<input type="text" class="form-control" name="nombreproducto" id="nombreproducto" autofocus="" />
<br />
<label>Precio Producto</label>
<br />
<input type="text" class="form-control" name="precio" id="idprecioproducto" />
</form>
</div>
<div class="modal-footer">
<input type="submit" value="Agregar Material" class="btn btn-primary" id="btnSubmit" />
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
my Javascript code in my main view calls a JsonResult method that looks for a product:
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script>
$(function () {
$("#nombreproducto").autocomplete({
source: "/Recepcions/BuscarProducto"
});
});
</script>
}
my controller:
public JsonResult BuscarProducto(string term)
{
using (DataContext db = new DataContext())
{
var resultado = db.Productoes.Where(x => x.v_Nombre.Contains(term)).Select(y => y.v_Nombre).Take(10).ToList();
return Json(resultado, JsonRequestBehavior.AllowGet);
}
}
How can I establish that by pressing the button that calls my modal window
Agregar Material
Can my modal window be displayed with the autocomplete my products?
I have to call the event from my button? Where do I put the Jquery code? It's the first time that I have to develop something like that ... what Jquery events do I have to handle?
PS: this implementation goes to my controller's JsonResult, but obviously it's not displaying anything, why?
any example or help for me?
What version are you using? If you are using these versions based on the documentation of JQuery UI Autocomplete, this might not work on your bootstrap modal due to conflicts.
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
Try to use these versions on your Javascript code and it works:
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script src="https://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>
Here is the screenshot based on your code:
I have a problem with my input fields in my modal view.
When I take a change in the input fields then it is updating the table list but when I leave the page and go back to this page with the table list then die changes are disappeared.
This is my modal view:
<form class="form-horizontal" name="editForm" novalidate>
<div class="modal-body">
<div class="form-group-sm has-feedback">
<label class="control-label">Firstname</label>
<input type="text"
class="form-control"
name="Fname"
ng-model="selected.fname"
ng-model-options="{updateOn: 'updateItem'}"
ng-required="true"
/>
</div>
</div>
//the same input field for lastname
...
<div class="modal-footer">
<button class="btn btn-default" ng-click="createItem(selected)" type="submit">Erstellen</button>
<button class="btn btn-default" ng-click="updateItem(selected)"> Ändern</button>
<button class="btn btn-default" ng-click="cancel()">Abbrechen</button>
</div>
</form>
Modal Ctrl:
$scope.cancel = function () {
$scope.editForm.$rollbackViewValue();
$modalInstance.dismiss('cancel');
}
$scope.updateItem = function (updateItem) {
CrudService.update(updateItem);
$scope.ok();
}
Crud Service:
...
update: function (updateItem) {
updateItem.$update();
},
...
I have only seen examples of $rollbackViewValue() with one input field and the code: $scope.myForm.inputName.$rollbackViewValue() but I have more than one input fields?
you should call $rollbackViewValue() through the form name:
editForm.$rollbackViewValue()
call it in your template:
{{editForm.$rollbackViewValue.toString()}}
and you will see how it actually works:
function () {
forEach(controls, function(control) {
control.$rollbackViewValue();
});
}
A little late but for others reference (I came across this looking for another issue with $rollbackViewValue).
Using $rollbackViewValue in controller: to use $scope to reference the form from the controller, you have to use the ng-form attribute on a child element of the form (like for instance the form-group div in your example).
That makes $scope.editForm.$rollbackViewValue() available in the controller and resets the entire form.
For cases where buttons are inside the form, using ng-submit and ng-model-options="{ updateOn: 'submit' }" on input fields, then adding 'type=button' attribute to cancel button element (so submit isn't triggered) is a quick solution.
Example:
https://embed.plnkr.co/IQ4vvutC3tcHvVBH0821/