I am using bootbox to make pop-up windows with forms and I have to validate them and throw error to user if something is wrong with the form fields.
But I cannot prevent bootbox window from closing after user clicks 'Send' button. I need to show error notifications to user, so errors could be corrected and the form be sent again.
return false works ok, but after it I cannot find method, to restore usual method of bootbox to close the windows.
Does somebody faced the same problem and how you get rid of this situation?
As asked, fsFiddle:
<button id="test">Bootbox</button>
Code:
$(document).ready(function() {
$("#test").on('click', function() {
bootbox.dialog({
title: "This is a form in a modal.",
message: '<div class="row"> ' +
'<div class="col-md-12"> ' +
'<form class="form-horizontal"> ' +
'<div class="form-group"> ' +
'<label class="col-md-4 control-label" for="name">Name</label> ' +
'<div class="col-md-4"> ' +
'<input id="name" name="name" type="text" placeholder="Your name" class="form-control input-md"> ' +
'<span class="help-block">Here goes your name</span> </div> ' +
'</div> ' +
'<div class="form-group"> ' +
'<label class="col-md-4 control-label" for="awesomeness">How awesome is this?</label> ' +
'<div class="col-md-4"> <div class="radio"> <label for="awesomeness-0"> ' +
'<input type="radio" name="awesomeness" id="awesomeness-0" value="Really awesome" checked="checked"> ' +
'Really awesome </label> ' +
'</div><div class="radio"> <label for="awesomeness-1"> ' +
'<input type="radio" name="awesomeness" id="awesomeness-1" value="Super awesome"> Super awesome </label> ' +
'</div> ' +
'</div> </div>' +
'</form> </div> </div>',
buttons: {
success: {
label: "Save",
className: "btn-success",
callback: function () {
var name = $('#name').val();
var answer = $("input[name='awesomeness']:checked").val()
console.log(name + " " + answer);
}
}
}
});
});
});
I am not 100% sure about what it is that you want. I understand it as: "Keep the modal open until the form is valid".
If this is what you need, you could proceed as such:
callback: function () {
var name = $('#name').val();
var answer = $("input[name='awesomeness']:checked").val()
console.log(name + " " + answer);
// proceed to your validation, if your form is not valid
// the validation should return false
var formIsValid = doFormValidation();
if(!formIsValid) {
// show error messages to the user here
showFormErrors();
// prevent the modal from closing
return false;
}
}
Related
So I'm developing a website for a medical clinic and they asked me to add a button beneath every doctor to make an appointment.
this is what i have for the doctors section
for (var i = 0; i < 3; i++) {
$('#get_medicos').append(
'<div class="col-md-3 dummy">' +
'<div class="text-box">' +
'<img src="assets/images/corpo-clinico/' + medico[i].ficheiro + '" alt="" class="img-responsive"/>' +
'<div class="clearfix"></div>' +
'<div class="text-box white padding-3">' +
'<h5 class="less-mar1 text-blue">' + medico[i].nome +'</h5>' +
'<p>' + medico[i].especialidade + '</p>' +
'<a id="marcar" type="button" class="btn btn-primary">Marcar consulta</a>' +
'</div>' +
'</div>' +
'</div>'
);
}
The then code for the click function (that doesn't work):
$('#marcar').click(function() {
var offset = $('#marcacao').offset();
$('html, body').animate({
scrollTop: offset.top-100,
scrollLeft: offset.left
}, 1000);
$('#marcacao-consulta').find('#especialidade-marcacao option[id="default"]').text(medico[i].especialidade);
$('#marcacao-consulta').find('#corpo-clinico option[id="default"]').text(medico[i].nome);
console.log('test');
});
This is all inside a $(document).ready(function() {}); and what should do is when i click that button beneath the doctor, should go up to the form and fill the doctor's name and specialty... but it seems it's not working for some reason... this is a copy of other click functions in the code, but they seem to work fine.
HTML form:
<div id="marcacao-consulta" data-target="#marcacao-consulta">
<div class="row">
<div class="col-md-6 col-lg-6 col-sm-12">
<div class="section">
<label class="field select prepend-icon">
<select id="especialidade-marcacao" class="gui-input">
<option id="especialiade-default" value="default">Escolha a especialidade</option>
<?
$query = $dbHandle->prepare("
SELECT `especialidade`
FROM `especialidade`
ORDER BY `especialidade` ASC
");
$query->execute();
if ($query->rowCount() > 0) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) { ?>
<option value="<?=$row["especialidade"]; ?>"><?=$row["especialidade"]; ?></option>
<? }
} else { ?>
<option value="">Nenhum resultado</option>
<? }
?>
</select>
<span class="field-icon"><i class="fas fa-heartbeat"></i></span>
</label>
</div>
</div>
<div class="col-md-6 col-lg-6 col-sm-12">
<div class="section">
<label class="field select prepend-icon">
<select id="corpo-clinico-marcacao" class="gui-input">
<option id="corpo-clinico-default" value="default">Escolha o médico</option>
<?
$query = $dbHandle->prepare("
SELECT `nome`
FROM `medico`
ORDER BY `nome` ASC
");
$query->execute();
if ($query->rowCount() > 0) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) { ?>
<option value="<?=$row["nome"]; ?>"><?=$row["nome"]; ?></option>
<? }
} else { ?>
<option value="">Nenhum resultado</option>
<? }
?>
</select>
<span class="field-icon"><i class="fas fa-user-md"></i></span>
</label>
</div>
</div>
<div class="col-md-12 col-lg-12 col-sm-12">
<div class="section">
<label class="field prepend-icon">
<input id="nome" class="gui-input" type="text" placeholder="Nome Completo">
<span class="field-icon"><i class="fas fa-user"></i></span>
</label>
</div>
<div class="section">
<label class="field prepend-icon">
<input id="email" class="gui-input" type="text" placeholder="Endereço de correio eletrónico">
<span class="field-icon"><i class="fas fa-envelope"></i></span>
</label>
</div>
<div class="section">
<label class="field prepend-icon">
<input id="telefone" class="gui-input" type="text" placeholder="Telefone/Télemovel">
<span class="field-icon"><i class="fas fa-phone-square"></i></span>
</label>
</div>
<div class="section">
<label class="field prepend-icon">
<input id="tipo" class="gui-input" type="text" value="consulta" disabled>
</label>
</div>
</div>
</div>
</div>
You have to add the element and register the event for the element. Here is the fiddle which works for you
https://jsfiddle.net/0q3kpyfv/
Your sample HTML
<div id="get_medicos">
</div>
Sample jquery code
Notice I have added the data-val attribute to the added anchor tag which will help you to get the information and perform the logic based on which button is clicked. you can pass dynamic data to data-val attribute and use it in click event.
$(document).ready(function() {
var sampleString = "";
var medico = [{'especialidade':'speciality 0','nome':'Doctor 0'},{'especialidade':'speciality 1','nome':'Doctor 1'},{'especialidade':'speciality 2','nome':'Doctor 2'}]
for (var i = 0; i < 3; i++) {
var doctorData = medico[i];
$('#get_medicos').append(
'<div class="col-md-3 dummy">' +
'<div class="text-box">' +
'<img src="assets/images/corpo-clinico/' + medico[i].especialidade + '" alt="" class="img-responsive"/>' +
'<div class="clearfix"></div>' +
'<div class="text-box white padding-3">' +
'<h5 class="less-mar1 text-blue">' + medico[i].nome +'</h5>' +
'<p>' + medico[i].especialidade + '</p>' +
'<a id="marcar" data-doctor-especialiadade="'+medico[i].especialidade+'" data-doctor-nome="'+medico[i].nome+'" type="button" class="btn btn-primary">Marcar consulta'+i+'</a>' +
'</div>' +
'</div>' +
'</div>'
);
};
$('#get_medicos').on('click','a',function(event){
var elementClicked = event.target;
var doctorEspecialiadade = $(elementClicked).data('doctor-especialiadade');
var doctorName = $(elementClicked).data('doctor-nome');
$('#marcacao-consulta').find('#especialidade-marcacao option[id="default"]').text(doctorEspecialiadade);
$('#marcacao-consulta').find('#corpo-clinico option[id="default"]').text(doctorName);
})
});
if you create the button after your event, you could have problem so, use the delegate version of click:
$('div').on('click', 'a', (function()....
and better put an id on the ancestor div:
'<div class="text-box white padding-3" id="mydiv"'
:
$('#mydiv').on('click', 'a', (function()....
another thing, with the loop you will have same id more time in your html??its no good.
so you'll have to rebuild your program logic...and bind the event with the right button (use a common class) it will be better than an id
If you bind the event to the parent element, and filter by the children, you can listen to any new elements that are added, doesn't matter how many.
<div class="container"></div>
<button class="js-add-new">Add new</button>
const $addNew = $('.js-add-new')
const $container = $('.container')
let count = 0
$addNew.on("click", () => {
count += 1
$container.append(`
<div>
<button>log me ${count}</button>
</div>
`)
})
$container.on("click", "button", (event) => {
console.log(event.currentTarget)
})
A working example: https://codepen.io/alexmccabe/pen/jOrXZxj?editors=1111
The button click is working. Here is a fiddle showing it does:
https://jsfiddle.net/bradberkobien/qL4m10y6/3/
There must be an issue with the code that comes before the console.log("test") line within the click. I would use the debugger to help you with that.
In order to display two input fields in a bootbox.confirm box, I've embedded an HTML form in the message field. Everything works fine, but if I enter text in the textarea, the Save button loses focus, and two clicks on the save button are required to execute save and clear the modal. The problem is exterior to the code below, though. This jsfiddle functions just fine with one click. I can't practically share the thousands of lines of codes this sits in, anyone know what might be causing this and how I can fix it?
bootbox.confirm({
title: "Save Foo",
message: '<div class="row"> ' +
'<div class="col-md-12"> ' +
'<div class="text-center">Save</div>' +
'<form class="form-horizontal"> ' +
'<div class="form-group"> ' +
'<label class="col-md-4 control-label" for="Question">Question</label> ' +
'<div class="col-md-4"> ' +
'<input id="name" name="name" type="text" value="Question" class="form-control input-md"> ' +
'<span class="help-block">You can edit your question before saving</span> </div> ' +
'</div> ' +
'<div class="form-group"> ' +
'<label class="col-md-4 control-label" for="notesbox">Notes:</label> ' +
'<div class="col-md-4"> <div class="textarea"> <label for="notesbox"> ' +
'<textarea name="notesbox" id="notesbox" rows="10" cols="30"></textarea></form></div> ' +
'</label> ' +
'</div>' +
'</div> ' +
'</div> </div>' +
'</form> </div> </div>',
buttons: {
'cancel': {
label: 'Don\'t save',
className: 'btn-danger pull-left'
},
'confirm': {
label: 'Save',
className: 'btn-success pull-right',
}
},callback: function (result) { if (result == true)
{ alert('Success')}
}
}
);
I'd start by using a script template, rather than using string concatenation to build your message - it would make it obvious that your current message has some invalid markup, which isn't doing you any favors. Here's one way of doing that:
<script type="text/template" id="form-template">
<div class="text-center">Save</div>
<form class="form-horizontal">
<div class="form-group">
<label class="col-md-4 control-label" for="Question">Question</label>
<div class="col-md-4">
<input id="name" name="name" type="text" value="Question" class="form-control input-md">
<span class="help-block">You can edit your question before saving</span>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="notesbox">Notes:</label>
<div class="col-md-4">
<div class="textarea">
<textarea class="form-control" name="notesbox" id="notesbox" rows="10" cols="30"></textarea>
</div>
</div>
</div>
</form>
</script>
The type="text/template" attribute on the script tag means that your browser won't treat the contents of the tag as JavaScript to be executed. You can pretty much use just about anything there, but text/template conveys the meaning pretty well, so I stick with that.
With that template tag, you can then get the message for your dialog by doing something like this:
let message = $('#form-template').html();
With that in place, I'd update your Bootbox usage to use the bootbox.dialog helper, rather than try to use bootbox.confirm for something it wasn't intended for. Here's your code, updated:
let message = $('#form-template').html();
let msgbox = bootbox.dialog({
title: "Save Foo",
message: message,
buttons: {
'cancel': {
label: "Don't save",
className: 'btn-danger pull-left'
},
'confirm': {
label: 'Save',
className: 'btn-success pull-right',
callback: function () {
let form = msgbox.find('form');
if(form.valid()){
alert('Valid!');
msgbox.modal('hide');
}
return false;
}
}
}
});
When using the dialog helper, the global callback is no longer executed; rather, each button would have it's own callback, as shown. In this example, I have return false; as the last line, so that the modal will not close automatically. This lets me validate the form (here, I'm assuming jQuery Validate is in use) and whatever else I wanted to do (such as submit the form via AJAX, etc.). Then, we use Bootstrap's modal() function to dismiss our dialog.
my web page shows a jquery confirm prompt view. And once the user selects the input field and the keyboard shows, the keyboard pushes the jquery confirm prompt view. The problem only happens on iOS device. Is there a work around to this?
Here is my code
$.confirm({
title: 'Add Your Name Information',
content: 'Please provide the ff<br/><br/>'+
'<div class="form-row">'+
'<div class="form-group col-md-2">'+
'<input type="number" id="age" class="form-control" max="2" required>'+
'<label class="form-control-placeholder" for="age">Age</label>'+
'</div>'+
'<div class="form-group col-md-2">'+
'<input type="number" id="contact" class="form-control"required>'+
'<label class="form-control-placeholder" for="contact">Contact No</label>'+
'</div>'+
'<div class="form-group col-md-8">'+
'<input type="text" id="bldg" class="form-control" value="' + Name+ '" readonly="true">'+
'<label class="form-control-placeholder" for="bldg">Name</label>'+
'</div>'
'</div>',
buttons: {
formSubmit: {
text: 'Confirm',
btnClass: 'btn-blue',
action: function () {
params += "&age=" + age
params += "&contact=" +contact
$.post( "/name/save", values)
.done(function( data ) {
data = JSON.parse(data);
}
});
}
},
cancel: function () {
}
},
columnClass: 'medium'
});
}
I have an function in the custom.js file as follows :
function contactTraxio(fullname, telephone, email) {
if (typeof(fullname)==='undefined') fullname = null;
if (typeof(telephone)==='undefined') telephone = null;
if (typeof(email)==='undefined') email = null;
bootbox.dialog({
title: "Limit reached",
message: '<p class="text-main text-center">You have reached the limit of your calculations.</p>' +
'<p class="pad-btm mar-btm text-center">Upgrade your account by contacting us on +32 9 111 12 12 or filling in the form below.</p>' +
'<div class="row"> ' +
'<div class="col-md-12"> ' +
'<form class="" method="POST"> ' +
'<div class="form-group"> ' +
'<div class="col-md-6" style="padding-left: 0"> ' +
'<input id="contact-fullname" name="fullname" type="text" placeholder="Your fullname" class="form-control input-md" value="' + fullname + '"> ' +
'<span class="help-block"><small></small></span> </div> ' +
'</div> ' +
'<div class="col-md-6" style="padding-right: 0"> ' +
'<input id="contact-telephone" name="telephone" type="text" placeholder="Telephone" class="form-control input-md" value="' + telephone + '"> ' +
'<span class="help-block"><small></small></span> </div> ' +
'</div> ' +
'<div class="col-md-12 pad-no-lr-md" style="margin-top: 7.5px;"> ' +
'<input id="contact-email" name="email" type="text" placeholder="Your email address" class="form-control input-md" value="' + email + '"> ' +
'<span class="help-block"><small></small></span> </div> ' +
'</div> ' +
'</div>' +
'</form> ' +
'</div>' +
'</div>',
buttons: {
success: {
label: "Send",
className: "btn-primary",
callback: function () {
$.ajax({
type: 'POST',
url: '/master/contact_traxio/',
data: {
fullname: $('#contact-fullname').val(),
telephone: $('#contact-telephone').val(),
email: $('#contact-email').val(),
csrfmiddlewaretoken: '{{ csrf_token }}'
},
success: function (data) {
debugger;
}
});
}
}
}
});
}
Thus, I have an contact form in js. And I'm trying to send the form data to the django view with ajax.
I've added csrfmiddlewaretoken: '{{ csrf_token }}' to the data, but for some reason I get an error :
Forbidden (CSRF token missing or incorrect.): /master/contact_traxio/
[03/Mar/2017 08:52:46] "POST /master/contact_traxio/ HTTP/1.1" 403 2502
The contact_traxio view is as follows :
#login_required
def contact_traxio(request):
if request.method == 'POST':
# Just test
return HttpResponse('{} / {} / {}'.format(request.POST['fullname'], request.POST['telephone'], request.POST['email']))
else:
return HttpResponseBadRequest("Sorry. Something went wrong.")
And the django template from where I call the contactTraxio function is as follows :
{% block page_content %}
<script>
$(document).ready(function () {
var fullname = '{{ user.user.first_name }} {{ user.user.last_name }}';
contactTraxio(fullname, '{{ user.telephone }}', '{{ user.user.email }}')
})
</script>
{% endblock %}
Why is the csrf token isn't sent?
Any advice?
You're using Django template syntax in an external JS file. That can't work, because Django does not parse those files.
The documentation shows exactly what you need to do to access the token from your JS; you should follow it.
I am trying to append the contents of a file selected from file input into a collapsible DIV element. For this, I need to read the contents of the selected file and append it to the DIV element. I am using Angular JS.
sweeper.html
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<form>
<div class="form-group">
<label class="control-label"> Choose a HTML File: </label> <input
id="file" type="file" file-model="sweep.file" name="file">
</div>
<div>
<button class="btn btn-primary" type="submit"
ng-click="addCollapsibleDiv();">upload</button>
</div>
<div id="fileloader">
<div class="panel-group" id="accordion" role="tablist"
aria-multiselectable="true">
</div>
</div>
</form>
</div>
controller.js
myApp
.controller(
'HTMLSweeperCtrl',
function($scope, $http, $state, DataService, $window) {
$scope.sweep = {
file : ''
};
$scope.addCollapsibleDiv = function() {
console.log("the selected file is: ");
console.log($scope.sweep.file);
if (typeof $scope.sweep.file != "undefined"
&& $scope.sweep.file != "") {
var divHtml = "<div class='panel panel-default'>"
+ "<div class='panel-heading' role='tab' id='headingOne'>"
+ "<h4 class='panel-title'>"
+ "<a role='button' data-toggle='collapse' data-parent='#accordion'"
+ "href='javascript:void(0)' aria-expanded='true' data-target='#collapseOne'"
+ "aria-controls='collapseOne'>"
+ $scope.sweep.file.name
+ "</a>"
+ "</h4>"
+ "</div>"
+ "<div id='collapseOne' class='panel-collapse collapse in'"
+ "role='tabpanel' aria-labelledby='headingOne'>"
+ "<div class='panel-body'> Collapsibel DIV added </div>"
+ "</div>" + "</div>";
var file = $('#file').files[0];
if (file) {
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(e) {
alert(e.target.result);
};
}
$('#fileloader #accordion').append(divHtml);
$scope.sweep.file = '';
}
}
});
I am getting the following error:
Cannot read property '0' of undefined
Where am I going wrong here?