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'
});
}
Related
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.
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've been coding for years, but only in recent months I started looking into JavaScript/jQuery/Ajax. I have searched for days, but none of the answers I see match what I'm trying to do (as far as I can see).
I have a select that gets a list of agendas from the controller. After an agenda is selected, an Ajax call is triggered to get related subjects from the database, and add it as radio inputs to a predefined div. There is already a radio button group for "time assignment per group", where, depending on your selected option, the right set of input fields is displayed.
This works fine for adding the info, but now I want to edit existing records on this same page. So now I want to select an agenda, get the subjects, have the system check if there are already time assignments for the subject I select. If there are, display the correct fields with the data preloaded. If not, treat it like an Add form.
My select works as expected, the Ajax call also creates the needed radio buttons, but how do I access those newly created radio buttons, to start a new Ajax call on that element, to check if there are already assignments?
SELECT
<form accept-charset="UTF-8" class="form-horizontal">
{{ csrf_field() }}
<div class="form-group">
<label for="agenda" class="col-sm-3 control-label">Agenda</label>
<div class="col-sm-6">
<select class="form-control" id="agenda" name="agenda">
<option value="">Selecteer een agenda</option>
#foreach($agendas as $key => $value)
<option value="{{ $key }}">{{ $value }}</option>
#endforeach
</select>
</div>
</div>
</form>
<form method="POST" action="{{ action('TimeController#store') }}" accept-charset="UTF-8" class="form-horizontal">
{{ csrf_field() }}
<div class="form-group"><div id="insertSubjects"></div></div>
<div class="form-group">
<label for="all_type" class="col-sm-3 control-label">Allocatie type</label>
<div class="col-sm-6">
<input type="radio" name="type" id="user" value="1"> User<br>
<input type="radio" name="type" id="fraction" value="2"> Fractie<br>
<input type="radio" name="type" id="oppcoa" value="3"> Oppositie/Coalitie
</div>
</div>
<div id="insertFields"></div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<input class="btn btn-default" type="submit" value="Voeg toe">
</div>
</div>
</form>
JAVASCRIPT
<script type="text/javascript">
$(document).ready(function() {
$('#agenda').on('change', function() {
var agenda = $('#agenda option:selected').attr('value');
var my_url = window.location.pathname + '/agenda/' + agenda;
$.ajax({
type: "post",
url: my_url,
headers: {'X-CSRF-TOKEN': $('input[name=_token]').val()},
dataType: 'json',
context: this,
success: function (data) {
var fields = '<label for="subject" class="col-sm-3 control-label">Selecteer onderwerp</label>' +
'<div class="col-sm-6">';
jQuery.each(data, function (k, v) {
fields += '<input type="radio" name="subject" value="' + v.id + '" class="subject_radio"> ' + v.subject + '<br>';
});
fields += '</div>';
$('#insertSubjects').html(fields);
$('input:radio[name=subject]:first').attr('checked', true);
}
})
});
$('input[type=radio][name=type]').change(function() {
var fields;
if (this.id == 'user') {
fields = '<div class="form-group"><label for="per_user" class="col-sm-3 control-label">Per lid</label><div class="col-sm-6"><input type="text" name="per_user" id="per_user" /></div></div>';
}
else if (this.id == 'fraction') {
fields = '<div class="form-group"><label for="NDP" class="col-sm-3 control-label">NDP</label><div class="col-sm-6"><input type="text" name="NDP" id="NDP" /></div></div>' +
'<div class="form-group"><label for="VHP" class="col-sm-3 control-label">VHP</label><div class="col-sm-6"><input type="text" name="VHP" id="VHP" /></div></div>' +
'<div class="form-group"><label for="ABOP" class="col-sm-3 control-label">ABOP</label><div class="col-sm-6"><input type="text" name="ABOP" id="ABOP" /></div></div>' +
'<div class="form-group"><label for="PL" class="col-sm-3 control-label">PL</label><div class="col-sm-6"><input type="text" name="PL" id="PL" /></div></div>' +
'<div class="form-group"><label for="BEP" class="col-sm-3 control-label">BEP</label><div class="col-sm-6"><input type="text" name="BEP" id="BEP" /></div></div>' +
'<div class="form-group"><label for="NPS" class="col-sm-3 control-label">NPS</label><div class="col-sm-6"><input type="text" name="NPS" id="NPS" /></div></div>' +
'<div class="form-group"><label for="PALU" class="col-sm-3 control-label">PALU</label><div class="col-sm-6"><input type="text" name="PALU" id="PALU" /></div></div>' +
'<div class="form-group"><label for="DOE" class="col-sm-3 control-label">DOE</label><div class="col-sm-6"><input type="text" name="DOE" id="DOE" /></div></div>' +
'<div class="form-group"><label for="Onbekend" class="col-sm-3 control-label">Onbekend</label><div class="col-sm-6"><input type="text" name="Onbekend" id="Onbekend" /></div></div>';
}
else if (this.id == 'oppcoa') {
fields = '<div class="form-group"><label for="Coalitie" class="col-sm-3 control-label">Coalitie</label><div class="col-sm-6"><input type="text" name="Coalitie" id="Coalitie" /></div></div>' +
'<div class="form-group"><label for="Oppositie" class="col-sm-3 control-label">Oppositie</label><div class="col-sm-6"><input type="text" name="Oppositie" id="Oppositie" /></div></div>' +
'<div class="form-group"><label for="Neutraal" class="col-sm-3 control-label">Neutraal</label><div class="col-sm-6"><input type="text" name="Neutraal" id="Neutraal" /></div></div>';
}
$('#insertFields').html(fields);
});
});
</script>
All the Ajax requests just return JSON encoded data from the database, but if you guys need to see those calls too, let me know. Please guide me in the right direction...
You can create array which will hold the newly created radios buttons.
var newRdoBtnsArr = []; // Array to hold the newly created new radio buttons
$.ajax({
.
.
.
.
success: function (data) {
var newRdoBtn = '<input type="radio" name="subject" value="' + v.id + '" class="subject_radio"> ';
newRdoBtnsArr.push( $( newRdoBtn ) ); // Push the radio button as jQuery object
fields += newRdoBtn + v.subject + '<br>';
.
.
.
.
});
Update after the comment:
I guess you need to execute a AJAX call when there is a change in newly created radio buttons. In that case you can add below lines and try. Like you did for $('input[type=radio][name=type]').change(function() {
$( 'body' ).on( 'change', 'input:radio[name=subject]', function() {
console.log("It works");
} );
I have managed to dynamically/programically create a modal form using bootstrap classes etc. But when I try to access the data from the input boxes I get no console.log(). Its asif the form is not present on the dom and none of the input can be gathered.
I tried this previously with same 'getFormData' function on a hardcoded modal form. The console.log() are called and the inspector shows a 'element highlight option' on the console output of the dom object, unlike the new dynamic form.
How can I get this data with the dynamically created form modals?
JQUERY
//create form modal
function getMessageTemplate(message, instance)
{
var styles =
{
success:{alert: 'alert-success', icon: 'glyphicon glyphicon-ok-sign'},
error:{alert: 'alert-danger', icon: 'glyphicon glyphicon-remove-sign'},
warning:{alert: 'alert-warning', icon: 'glyphicon glyphicon-question-sign'},
default:{alert: 'bg-primary', icon: 'glyphicon glyphicon-cog'}
};
var header =
'<div class="modal-header no-scroll '+ styles[message.style]['alert'] +'">'+
'<i class="'+ styles[message.style]['icon'] +'"></i>'+
'<h4 class="message"><strong>'+ message.title +'</strong></h4>'+
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'+
'</div>';
var body = '';
var footer = '';
if(message.form !== undefined)
{
body = $('<div class="modal-body"></div>');
form = body.append('<form id="form-' +message.form.name+ '" class="form"></form>');
$(message.form.input).each(function(index,value)
{
input = form.append(
'<div class="row">'+
'<div class="col-xs-2">'+
'<label>' +value.label+ ':</label>'+
'</div>'+
'<div class="col-xs-9">'+
'<div class="input-group add-on col-xs-2">'+
'<div class="input-group-btn">'+
'<a class="btn btn-default" data-toggle="popover-input" data-html="true" title="Item Name" data-content=" Name of the item, multiple names allowed for different container sizes. <br/>Only: characters (A-Z)."><span class="glyphicon glyphicon-question-sign"></span></a>'+
'</div>'+
'<input name="' +value.name+ '" class="form-control red-tooltip" placeholder="...." title="" type="text" >'+
'</div>'+
'</div>'+
'<div class="col-xs-1">'+
'<a class="valid-icon small fail glyphicon glyphicon-remove"></a>'+
'</div>'+
'</div>');
});
}
if(message.submit !== undefined)
{
footer =
'<div class="modal-footer msg-footer">'+
'<input class="form-input" type="hidden">'+
'<div class="row text-center">'+
'<button id= "close" class="btn btn-default btn-msg" type="button" data-dismiss="modal"> Back</button>'+
'<button id= "'+ message.submit.id +'" name= "'+ message.submit.name +'" class="btn btn-default btn-msg '+ message.submit.class +'" type="button" data-dismiss="modal"> Submit</button>'+
'</div>'+
'</div>';
}
var container = $('<div id="alert'+ instance +'" class="msg modal fade" tabindex="-1" data-focus-on="input:first" style="display: none;"></div>')
.append(header)
.append(body)
.append(footer);
return container[0].outerHTML;
}
//gather form infomation
function getFormData(form)
{
console.log(form); //dom object
var formName = form.attr('id');
$('body #'+formName+' input').each(function(inputKey, inputObj)
{
var inputName = $(inputObj).attr('name');
var inputValue = $(inputObj).val();
//none of this is displayed
console.log('------[input-start]-----');
console.log(inputName);
console.log(inputValue);
});
}
//submit button event for modal form
$('body').on('click', '.btn-form', function(e)
{
var sourceForm = $(this).closest('.modal').find('form');
var formData = getFormData(sourceForm);
//do stuff with formData etc
}
There's more these functions do, so I edited to show the core form features.
Fiddle Me
As given in Fiddle form.append is appending to $('<div class="modal-body"></div>') set as body variable and not to form element. Basically
<form id="form-..."> ..</form>
needs to contain <input> element and hence there is nothing in console.
Change form.append to form.find('form').append
Updated Fiddle
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;
}
}