I am still new to AJAX and struggling a bit with form validation before uploading files to the server side using cgi-bin and IFrame.
So, my code is as below:
HTML:
<body>
<h1 align="center">Network Failure Detection</h1>
<form id="input" action= "../cgi-bin/test.py" method="post">
<div id = "table">
<table class = "center" border="1" cellpadding="10">
<tr><td style="height: 131px">Product Details</td>
<td style="height: 131px">Product Name*: <input type="text" name="product" id="product" size="35" ><br /><br />
Platform*: <input type="text" name="platform" id="platform" size="35" >
</td></tr>
<tr><td style="height: 131px">File Upload</td>
<td style="height: 131px"><p>Upload Host File: <input type="file" name="hostupload" id = "hostupload"/></p><br/>
Upload Test File: <input type="file" name="testupload" id = "testupload"/></p>
</td></tr>
<tr align="center"><td></td><td><input type = "submit" id="submit" value = "UPLOAD"/>
</td></tr>
</table>
</div>
</form>
<div id="output"></div>
JS:
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script>
$.fn.ajaxForm = function(options) {
options = $.extend({}, {
onSubmit:function() {},
onResponse:function(data) {}
}, options);
var iframeName = 'ajaxForm', $iframe = $('[name=' + iframeName + ']');
if (!$iframe.length) {
$iframe = $('<iframe name=' + iframeName + ' style="display:none">').appendTo('body');
}
return $(this).each(function() {
var $form = $(this);
$form
.prop('target', iframeName)
.prop('enctype', 'multipart/form-data')
.prop('encoding', 'multipart/form-data')
.submit(function(e) {
options.onSubmit.apply($form[0]);
$iframe.one('load', function() {
var iframeText = $iframe.contents().find('body').text();
options.onResponse.apply($form[0], [iframeText]);
});
});
});
};
$('#input').ajaxForm({
onResponse:function(data) {
alert(data);
//console.log("the data is"+data);
//$('#output').html(data);
}
});
This code works fine, and I can upload files and my text box fields. But I want to perform validation on the form for empty fields before submitting, so I tried to use the JQuery validate plugin, but my form does not submit through AJAX if I do so. Can anybody please tell me how I can perform form validation here?
The below javascript code does not submit form through AJAX:
<script>
$.fn.ajaxForm = function(options) {
$('#upload').validate({
rules: {
product: {
required: true,
},
platform: {
required: true,
},
hostupload:{
required: true,
},
testupload:{
required: true,
},
},
messages: {
product: {
required: '***Product Name Required***'
},
platform: {
required: '***Platform Required***'
},
hostupload:{
required: '***Hostfile Required***'
},
testupload:{
required: '***Testfile Required***'
},
},
options = $.extend({}, {
onSubmit:function() {},
onResponse:function(data) {}
}, options);
var iframeName = 'ajaxForm', $iframe = $('[name=' + iframeName + ']');
if (!$iframe.length) {
$iframe = $('<iframe name=' + iframeName + ' style="display:none">').appendTo('body');
}
return $(this).each(function() {
var $form = $(this);
$form
.prop('target', iframeName)
.prop('enctype', 'multipart/form-data')
.prop('encoding', 'multipart/form-data')
.submit(function(e) {
options.onSubmit.apply($form[0]);
$iframe.one('load', function() {
var iframeText = $iframe.contents().find('body').text();
options.onResponse.apply($form[0], [iframeText]);
});
});
});
});
};
$('#input').ajaxForm({
onResponse:function(data) {
alert(data);
//console.log("the data is"+data);
//$('#output').html(data);
}
});
Related
If I upload a PDF or a picture to the form, I get the following error message when changing to another form field:
The upload function is done using the following JavaScript:
;(function($,window) {
$.plugin('OnacyUpload', {
defaults: {
fileUpload: '#register_license_upload',
fileText: '.register-upload-file-text',
registerContent: '.register--content.registration-upload-finished',
registerLogin: '.register--login',
sidebar: 'aside.sidebar-main',
breadcrumb: 'nav.content--breadcrumb'
},
init: function() {
var me = this;
me._on(me.opts.fileUpload, 'change', $.proxy(me.onUploadChange, me));
me._on(me.opts.fileText, 'click', $.proxy(me.fileTextClicked, me));
if ( $(me.opts.registerContent).length ) {
$(me.opts.registerLogin).remove();
$(me.opts.sidebar).remove();
$(me.opts.breadcrumb).remove();
}
},
fileTextClicked: function() {
$(me.opts.fileUpload).trigger('click');
},
onUploadChange: function(event) {
var me = this,
$target = $(event.target),
$fileText = $(me.opts.fileText),
value = $target.val();
if ( typeof value !== 'string' || value === '' ) {
$fileText.html($fileText.attr('data-no-file-text'));
}
else {
var list = value.replace(/\\/g, '/').split('/');
$fileText.html(list[list.length-1]);
}
}
});
window.StateManager.addPlugin('body', 'OnacyUpload');
Here is the HTML Part:
<div class="panel--body is--wide"> <input type="file" id="register_license_upload" name="register_license_upload" accept="image/png, image/jpeg, application/pdf"> <label for="register_license_upload" class="btn is--secondary"> Datei aussuchen </label> <span class="register-upload-file-text" data-no-file-text="Datei wählen"> Datei wählen </span> </div>
I am attempting to add validation for a non-input, custom selection. I have a series of images that the user clicks, which act as a checkbox, but do not actually have an input. I am using jQuery validate for the rest of my form and wanted to see if there was anyway that I can add validation, whether it is adding a method (I read jQuery validate only works on inputs) or something else that will work with one click of submit.
I am wanting something similar to this, but to work like jQuery validate.
if(checkValue.length < 1) {
alert("You need at least one interested selected.");
}
I tried putting the above if-statement above the rules section in the validation code, but it throws an error.
Does anyone have any alternative ideas that I could try?
//Getting Value of the interest boxes
var interest = $('.interest');
var checkVal = '';
var checkValue = '';
interest.click(function() {
checkVal = [];
$(this).toggleClass('active');
$('.interestBox', this).toggleClass('active');
interest.each(function() {
if($(this).is('.active')) {
checkVal.push($(this).data('title'));
}
});
checkValue = checkVal.join(', ');
console.log(checkValue);
});
//Jquery Validate
$('#salesforce_submit').validate({
rules: {
first_name: {
required: true,
minlength: 2
}
},
messages: {
first_name: {
required: "Please enter your first name",
minlength: "Your first name seems a bit short, doesn't it?"
}
},
submitHandler: function(form) {
event.preventDefault();
var datastring = $('#salesforce_submit').serialize();
$.ajax({
url: '/php/quoteSend.php',
type: 'POST',
data: datastring
,
success: function(data) {
if (data == 'Error!') {
alert(data);
} else {
}
},
error: function(xhr, textStatus, errorThrown) {
alert(textStatus + '|' + errorThrown);
console.log('error');
}
});
}
});
.interest img {
height: 50px;
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<form id="salesforce_submit" type="Post">
<div><input id="first_name" placeholder="First Name*" class="input block" maxlength="40" name="first_name" type="text"></div>
<h3 class="interestTitle">A</h3>
<div class="interest" data-title="A">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="A">
</div>
<h3 class="interestTitle">B</h3>
<div class="interest" data-title="B">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="B">
</div>
<h3 class="interestTitle">C</h3>
<div class="interest" data-title="C">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="C">
</div>
<input type="Submit" value="Submit">
Full code:
<section class="sec90">
<h3 class="subTC">Enter your information below.</h3>
<form action="" id="salesforce_submit" method="POST" enctype="multipart/form-data">
<input name="oid" type="hidden" value=""><input type="hidden" id="" id="interestValue" multiple="multiple" name="" value=""><input name="retURL" type="hidden"> <input name="lead_source" required="" type="hidden" value="Quote Form"> <input id="txt_medium" name="txt_medium" type="hidden" value=""> <input id="txt_source" name="txt_source" type="hidden" value=""> <input id="txt_campaign_name" name="txt_campaign_name" type="hidden" value=""> <input id="txt_term" name="txt_term" type="hidden" value=""> <input id="txt_content" name="txt_content" type="hidden" value="">
<div><input id="first_name" placeholder="First Name*" class="input block" maxlength="40" name="first_name" type="text"></div>
<div><input id="last_name" placeholder="Last Name*" class="input block" maxlength="80" name="last_name" type="text"></div>
<div><input id="email" placeholder="Email*" class="input block" maxlength="80" name="email" type="email"></div>
<div><input id="phone" placeholder="Phone* no dashes" class="input block" maxlength="12" name="phone" type="tel"></div>
<div><input id="zip" placeholder="Zip/Postal Code*" class="input block" maxlength="5" name="zip" type="text" pattern= "[0-9]{5}"></div>
<div><input id="company" placeholder="Company*" class="input block" maxlength="40" name="company" type="text"></div>
</section>
<section class="sec90">
<h3 class="subTC">What are you interested in?*</h3>
<div><input type="hidden" name="interestHidden" value=""></div>
<section class="sec90" id="up">
<h3 class="subTC">Describe your project*</h3>
<div><textarea id="description" name="description" placeholder="Provide as much detail as possible"></textarea></div>
<h3 class="subTC block">Have a .stp file or drawing example? Send it for quicker quote times.</h3>
<input type="file" name="uploadedFile" class="inputfile" id="uploadedFile" data-multiple-caption="{count} files selected" multiple>
<label for="uploadedFile" class="button"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"/></svg><span class="marL5">Upload file</span></label>
<input type="hidden" name="MAX_FILE_SIZE" value="10000000">
<div class="margBot40"></div>
</section>
<input name="submit" class="block testB" type="submit" value="SUBMIT QUOTE">
</form>
JS:
var interest = $('.interest');
var checkVal = '';
var checkValue = '';
var showMe = '';
interest.click(function() {
checkVal = [];
$(this).toggleClass('active');
$('.interestBox', this).toggleClass('active');
interest.each(function() {
if($(this).is('.active')) {
checkVal.push($(this).data('title'));
}
});
checkValue = checkVal.join(', ');
console.log(checkValue);
//Hidden interest input value
var checkLength = checkVal.length;
console.log(checkLength);
$('[name="interestHidden"]').val(checkLength);
var interestVal = $('interestValue').val()
interestVal = checkValue;
showMe = interestVal;
console.log('Hidden val is ' + showMe);
});
/*$('#phone').keyup(function() {
$(this).val($(this).val().replace(/(\d{3})\-?(\d{3})\-?(\d{4})/,'$1-$2-$3'));
});*/
$('#phone').keydown(function (e) {
var key = e.charCode || e.keyCode || 0;
$text = $(this);
if (key !== 8 && key !== 9) {
if ($text.val().length === 3) {
$text.val($text.val() + '-');
}
if ($text.val().length === 7) {
$text.val($text.val() + '-');
}
}
return (key == 8 || key == 9 || key == 46 || (key >= 48 && key <= 57) || (key >= 96 && key <= 105));
});
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label = input.nextElementSibling,
labelVal = label.innerHTML;
input.addEventListener( 'change', function( e )
{
var fileName = '';
if( this.files && this.files.length > 1 )
fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
else
fileName = e.target.value.split( '\\' ).pop();
if( fileName )
label.querySelector( 'span' ).innerHTML = fileName;
else
label.innerHTML = labelVal;
});
});
$('#phone').keyup(function() {
jQuery.validator.addMethod("alphanumeric", function(value, element) {
//return this.optional(element) || /^[a-z0-9\-]+$/i.test(value);
return this.optional(element) || /^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*$/i.test(value);
}, "Numbers and dashes only");
});
$('#salesforce_submit').validate({
ignore: [],
rules: {
first_name: {
required: true,
minlength: 2
},
last_name: {
required: true,
minlength: 2
},
email: {
required: true,
email: true
},
phone: {
required: true,
//digits: true,
minlength: 10,
alphanumeric: true
},
zip: {
required: true,
digits: true,
minlength: 5
},
company: {
required: true,
minlength: 2
},
interestHidden: {
required: true,
min: 1
}/*,
description: {
required: true,
minlength: 5
}*/
},
messages: {
first_name: {
required: "Please enter your first name",
minlength: "Your first name seems a bit short, doesn't it?"
},
last_name: {
required: "Please enter your last name",
minlength: "Your last name seems a bit short, doesn't it?"
},
email: {
required: "Please enter your email address",
email: "Please enter a valid email address"
},
phone: {
required: "Please enter your phone number",
digits: "Please enter a valid phone number with only numbers",
minlength: "Your number seems a bit short, doesn't it?"
},
zip: {
required: "Please enter your zip code",
digits: "Please enter a valid zip code with only numbers",
minlength: "Your zip code seems a bit short, doesn't it?"
},
company: {
required: "Please enter your company name",
minlength: "Your company name seems a bit short. Please enter at least 2 characters"
},
interestHidden: {
required: "Please choose at least one interest",
min: "At least one interest needs chosen"
}/*,
description: {
required: "Please enter your project description",
minlength: "Your description seems a bit short, doesn't it?"
}*/
},
submitHandler: function(form) {
event.preventDefault();
var datastring = $('#salesforce_submit').serialize();
$.ajax({
url: '/php/quoteSend.php',
type: 'POST',
data: datastring
,
success: function(data) {
console.log(data);
if (data == 'Error!') {
alert('Unable to submit form!');
alert(data);
} else {
$('#salesforce_submit')[0].reset();
$('#consult-success').show();
$('#salesforce_submit').hide();
}
},
complete: function() {
//$("#salesforce_submit").submit();
location.href = "";
},
error: function(xhr, textStatus, errorThrown) {
alert(textStatus + '|' + errorThrown);
console.log('error');
}
});
}
});
Since jQuery Validate only validates select, textarea, and various types of input elements1, your only option is to give it what it wants.
Create a hidden element...
<input type="hidden" name="myImage" value="0" />
When the user clicks your image, use jQuery to manipulate the value of a type="hidden" input element...
$('#photo').on('click', function() {
$('[name="myImage"]').val('1');
});
And then programmatically validate its value instead. Since clicking on the image will not cause any validation, you can use the .valid() method to trigger validation on these hidden elements...
$('[name="myImage"]').valid();
You will need to leverage the ignore option since the plugin will not validate hidden elements by default. ignore: [] will effectively disable this and force the plugin to validate all hidden elements...
$('#salesforce_submit').validate({
ignore: [],
rules: { ....
Of course, you'll also need to have rules in place that properly validate the value of your hidden element.
Since the message will be placed near the hidden element, you'll have to leverage the errorPlacement function to place this message conditionally.
$('#salesforce_submit').validate({
ignore: [],
errorPlacement: function(error, element) {
if (element.attr('name') == 'myImage') {
// placement for hidden element
} else {
// default
error.insertAfter(element);
}
}
rules: { ....
1 newer versions of the plugin also support elements with the contenteditable attribute.
What about this, give all the checkboxes you trigger the same name e.g. "box". Add this custom rule "img_check":
jQuery.validator.addMethod("img_check", function() {
$(input[name='box']).each( function(){
if $(this).is(':checked') {
return true
}
})
// No box was checked
return false
}, "Please check at least one box");
Then add this rule:
rules: {
first_name: {
required: true,
minlength: 2
},
box[]: {
img_check: true
}
},
Why don't you check checkValue before going ahead with the submission process?
//Getting Value of the interest boxes
var interest = $('.interest');
var checkVal = '';
var checkValue = '';
interest.click(function() {
checkVal = [];
$(this).toggleClass('active');
$('.interestBox', this).toggleClass('active');
interest.each(function() {
if($(this).is('.active')) {
checkVal.push($(this).data('title'));
}
});
checkValue = checkVal.join(', ');
console.log(checkValue);
});
//Jquery Validate
$('#salesforce_submit').validate({
rules: {
first_name: {
required: true,
minlength: 2
}
},
messages: {
first_name: {
required: "Please enter your first name",
minlength: "Your first name seems a bit short, doesn't it?"
}
},
submitHandler: function(form) {
if(checkValue.length>0){
event.preventDefault();
var datastring = $('#salesforce_submit').serialize();
$.ajax({
url: '/php/quoteSend.php',
type: 'POST',
data: datastring
,
success: function(data) {
if (data == 'Error!') {
alert(data);
} else {
}
},
error: function(xhr, textStatus, errorThrown) {
alert(textStatus + '|' + errorThrown);
console.log('error');
}
});
}else console.log('Please select at least one interest');
}
});
.interest img {
height: 50px;
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<form id="salesforce_submit" type="Post">
<div><input id="first_name" placeholder="First Name*" class="input block" maxlength="40" name="first_name" type="text"></div>
<h3 class="interestTitle">A</h3>
<div class="interest" data-title="A">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="A">
</div>
<h3 class="interestTitle">B</h3>
<div class="interest" data-title="B">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="B">
</div>
<h3 class="interestTitle">C</h3>
<div class="interest" data-title="C">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="C">
</div>
<input type="Submit" value="Submit">
Template.body.events({
'submit .new-resolution': function(event) {
var title = event.target.title.value;
var ts = Date.now() / 1000;
Resolutions.insert({
title: title
});
event.target.title.value = "";
return false;
}
});
<body>
<div class="container">
<header>
<h1>Comment Box</h1>
<form class="new-resolution">
<input type="text" name="title" placeholder="Enter comment...">
<input type="submit" value="Submit" id="submit">
</form>
</header>
</div>
</body>
I'm trying to get values on screen but whenever I click on submit the values are not getting displayed on screen.
I tried using return event.preventDefault(); as well but this is not working. This is a small piece of code of my project.
So can anyone tell what's wrong with code or is there any meteor version issue?
Resolutions = new Mongo.Collection('resolutions');
if (Meteor.isClient) {
Template.register.events({
'submit form': function(event) {
event.preventDefault();
var registerData = {
email: event.target.registerEmail.value,
password: event.target.registerPassword.value
}
Accounts.createUser(registerData, function(error) {
if (Meteor.user()) {
console.log(Meteor.userId());
} else {
console.log("ERROR: " + error.reason);
}
});
}
});
Template.login.events({
'submit form': function(event) {
event.preventDefault();
var myEmail = event.target.loginEmail.value;
var myPassword = event.target.loginPassword.value;
Meteor.loginWithPassword(myEmail, myPassword, function(error) {
if (Meteor.user()) {
console.log(Meteor.userId());
} else {
console.log("ERROR: " + error.reason);
}
});
}
});
Template.home.events({
'click .logout': function(event) {
event.preventDefault();
Meteor.logout(function(error) {
if (error) {
console.log("ERROR: " + error.reason);
}
});
}
});
Template.body.helpers({
resolutions: function() {
return Resolutions.find();
}
});
Template.body.events({
'submit new-resolution': function(event) {
var title = event.target.title.value;
var ts = Date.now() / 1000;
Resolutions.insert({
title: title,
user: myEmail
});
event.target.title.value = "";
return false;
}
});
}
<body>
{{#if currentUser}} {{> home}}
<div class="container">
<header>
<h1>Comment Box</h1>
<form class="new-resolution">
<input type="text" name="title" placeholder="Enter comment...">
<input type="submit" value="Submit" id="submit">
</form>
</header>
{{#each resolutions}} {{> resolution}} {{/each}}
</div>
{{else}} {{> register}} {{> login}} {{/if}}
</body>
<template name="register">
<h2>REGISTER:</h2>
<form>
<input type = "email" name = "registerEmail"><br>
<input type = "password" name = "registerPassword"><br>
<input type = "submit" value = "Register"><br>
</form>
</template>
<template name="login">
<h2>LOGIN:</h2>
<form>
<input type = "email" name = "loginEmail"><br>
<input type = "password" name="loginPassword"><br>
<input type = "submit" value = "Login"><br>
</form>
</template>
<template name="resolution">
<h5> {{title}} </h5>
</template>
<template name="home">
<button class = "logout">Logout</button>
</template>
Try changing your code to this:
Template.body.events({
'submit new-resolution': function(event) {
event.preventDefault(); //this stops the page from reloading
var title = event.target.title.value;
var ts = Date.now() / 1000;
Resolutions.insert({
title: title,
user: myEmail
});
event.target.title.value = "";
}
});
I have some code that opens a modal that contains a form when a marker is placed on a layer in leaflet. It all worked well with out any issues. I copied this code so I could make a second button to control the opening of another modal containing a different form. I changed the link information but when the button is clicked the
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', L.bind(this.startCreating, this));
Opens up both forms at the same time or opens one then when closed and clicked againit will open both. Im not sure whats going on because each modal has a different ID.
Here is a live example of the map with the modals. Click the small elements/buttons on the left under the zoom control and drag the new market and click again to set its place on the map.
Leaflet Map with modals
Here is the JS code that should call the first modal called eventDataModal. The main link in the code is near the top:
L.MarkerControl = L.Control.extend({
options: {
position: 'topleft',
url: 'http://echostorm.mynetgear.com:8080/geoserver/usa/ows',
userName: 'wfspost',
password: 'createfeature'
},
map: null,
marker: null,
binded: false,
onAdd: function (map) {
this.map = map;
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
// link = L.DomUtil.create('a', 'glyphicon glyphicon-map-marker', container);
link = L.DomUtil.create('a', 'glyphicon glyphicon-eye-open', container);
link.href = '#';
link.title = 'Create a new visual report';
link.innerHTML = '';
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', L.bind(this.startCreating, this));
map.on("editable:drawing:commit", L.bind(this.onMarkerAdd, this));
return container;
},
startCreating: function() {
this.marker = this.map.editTools.startMarker();
},
onMarkerAdd: function(e) {
this.nearestFeature = null;
this.findNearestPoints(e.layer.getLatLng());
},
onFormClosed: function() {
if (this.marker!=null) {
this.map.editTools.featuresLayer.removeLayer(this.marker);
this.marker = null;
}
},
findNearestPoints: function(latlng) {
var defaultParameters = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: 'usa:within5mi',
maxFeatures: 5,
outputFormat: 'text/javascript',
format_options: 'callback: nearestPoints',
srsName: 'EPSG:4326',
viewparams: 'radius:802;lon:'+latlng.lng+';lat:'+latlng.lat,
};
var parameters = L.Util.extend(defaultParameters);
$.ajax({
jsonp: false,
url: this.options.url + L.Util.getParamString(parameters),
dataType: 'jsonp',
jsonpCallback: 'nearestPoints',
success: L.bind(this.handleNearestPoints, this)
});
},
handleNearestPoints: function(data) {
this.clearModal();
this.setModalDate();
if (data && data.type=="FeatureCollection"
&& data.features && data.features.length
&& data.features.length > 0) {
this.fillModal(data.features[0]);
}
this.openPopup();
},
formatDate: function(date) {
var day = date.getDate();
return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+(day < 10 ? "0"+day : day);
},
clearModal: function() {
$('#eventDataModal').find('input').each(
function() {
$(this).val("");
}
);
$('#eventDataModal').find('textarea').each(
function() {
$(this).val("");
}
);
},
setModalDate: function() {
$("#form-patrolDate").val(this.formatDate(new Date()));
},
fillModal: function(feature) {
var props = feature.properties;
$("#form-region").val(props["Region"]);
$("#form-circuitID").val(props["Circuit_ID"]);
$("#form-circuitName").val(props["Circuit_Name"]);
$("#form-vendor").val(props["Vendor"]);
$("#form-quad").val(props["Quad"]);
},
openPopup: function() {
this.bindEvents();
$('#eventDataModal').modal('show');
},
bindEvents: function() {
if (!this.binded) {
$('#eventDataModal').on('hidden.bs.modal', L.bind(this.onFormClosed, this));
$("#saveEventDataModal").on('click', L.bind(this.onSave, this))
this.binded = true;
}
},
onSave: function() {
var properties = this.getFormData(),
request = this.wfsBody("usa", "usa:pecotest", "geom", properties);
console.log(request);
this.makeRequest(request);
},
makeRequest: function(body) {
$.ajax({
method: "POST",
crossDomain: true,
url: this.options.url,
contentType: "text/xml",
dataType: "text",
data: body,
headers: {
"Authorization": "Basic " + btoa(this.options.userName + ":" + this.options.password)
},
jsonpCallback: 'datasave',
success: L.bind(this.onDataSave, this),
failure: function(r){console.log("AJAX Failure!");console.log(r);}
});
},
onDataSave: function(data) {
console.log(data);
},
getFormData: function() {
var result = {};
$('#eventDataModal').find('input').each(
function() {
if (this.type=="checkbox") {
result[this.name] = this.checked ? "Yes" : "No";
} else {
result[this.name]=$(this).val();
}
}
);
$('#eventDataModal').find('textarea').each(
function() {
result[this.name]=$(this).val();
}
);
return result;
},
wfsBody: function(namesapce, typeName, geometryField, properties) {
var xml;
xml ='<wfs:Transaction service="WFS" version="1.0.0"';
xml += ' xmlns:wfs="http://www.opengis.net/wfs"';
xml += ' xmlns:usa="http://census.gov"';
xml += ' xmlns:gml="http://www.opengis.net/gml">\n';
xml += ' <wfs:Insert>\n';
xml += ' <'+typeName+'>\n';
xml += ' <usa:'+geometryField+'>\n';
xml += this.marker.toGML()+"\n";
xml += ' </usa:'+geometryField+'>\n';
for (var k in properties) {
if (properties.hasOwnProperty(k)) {
xml += "<"+namesapce+":"+k+">";
xml += properties[k];
xml += "</"+namesapce+":"+k+">\n";
}
}
xml += ' </'+typeName+'>\n';
xml += ' </wfs:Insert>\n';
xml += '</wfs:Transaction>\n';
return xml;
}
});
L.Marker.include({
toGML: function(){
var latlng = this.getLatLng(),
xml;
xml = '<gml:Point srsName="EPSG:4326"><gml:coordinates cs=","
decimal="." ts=" ">';
xml += latlng.lng + ',' + latlng.lat;
xml += '</gml:coordinates></gml:Point>';
return xml;
}
});
Here is the corresponding HTML for the modal evenDataModal
<div class="modal fade" id="eventDataModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-
label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Create New Visual Report</h4>
</div>
<div class="modal-body">
<form action="php\new_peco_visual_report_db_insert.php
method="POST"><div class="form-group">
<label for="form-priority">ID Code</label>
<input type="number" class="form-control" id="form-priority"
name="ID_Code" placeholder="ID_Code">
</div>
<div class="form-group">
<label for="form-region">Region</label>
<input type="text" class="form-control" id="form-region"
name="Region" placeholder="region">
</div>
<div class="form-group">
<label for="form-circuitID">Circuit ID</label>
<input type="number" class="form-control" id="form-circuitID"
name="Circuit_ID" placeholder="Circuit ID">
</div>
<div class="form-group">
<label for="form-circuitName">Circuit Name</label>
<input type="text" class="form-control" id="form-circuitName"
name="Circuit_Name" placeholder="Circuit Name">
</div>
<div class="form-group">
<label for="form-patrolDate">Patrol Date</label>
<input type="date" class="form-control" id="form-patrolDate"
name="Patrol_Date" placeholder="Patrol Date">
</div>
<div class="form-group">
<label for="form-vendor">Vendor</label>
<input type="text" class="form-control" id="form-vendor"
name="Vendor" placeholder="Vendor">
</div>
<div class="form-group">
<label for="form-repairNumber">Repair Number</label>
<input type="text" class="form-control" id="form-repairNumber"
name="Repair_Number" placeholder="Repair Number">
</div>
<div class="form-group">
<label for="form-problemDescription"> Problem
Description</label>
<input type="text" class="form-control" id="form-
problemDescription" name="Problem_Description"
placeholder="Problem
Description">
</div>
<div class="form-group">
<label for="form-urgency">Priority</label>
<input type="number" class="form-control" id="form-urgency"
name="Urgency" placeholder="Urgency">
</div>
<div class="form-group">
<label for="form-circuitPortion">Circuit Portion</label>
<input type="text" class="form-control" id="form-circuitPortion"
name="Circuit_Portion" placeholder="Circuit Portion">
</div>
<div class="form-group">
<label for="form-quad">Quad</label>
<input type="text" class="form-control" id="form-quad"
name="Quad" placeholder="Quad">
</div>
<div class="form-group">
<label for="form-location">Location</label>
<input type="text" class="form-control" id="form-location"
name="Location" placeholder="location">
</div>
<div class="form-group">
<label for="form-poleSub">PolSub</label>
<input type="number" class="form-control" id="form-polSub"
name="PolSub" placeholder="PolSub">
</div>
<div class="form-group">
<label for="form-poleNumber">Pole Number</label>
<input type="number" class="form-control" id="form-poleNumber"
name="Pole_Number" placeholder="Pole Number">
</div>
<div class="form-group">
<label for="form-aerialName">Aerial Name</label>
<input type="text" class="form-control" id="form-aerialName"
name="Aerial_Name" placeholder="Aerial Name">
</div>
<div class="form-group">
<label for="form-workRequired">Work Required?</label>
<input type="text" class="form-control" id="form-workRequired"
name="Work_Required" placeholder="Work Required">
</div>
<div class="form-group">
<label for="form-long">GPS Longitude</label>
<input type="text" class="form-control" id="form-long"
name="long" placeholder="long">
</div>
<div class="form-group">
<label for="form-lat">GPS Latitude</label>
<input type="text" class="form-control" id="form-lat" name="lat"
placeholder="lat">
</div>
<div class="form-group">
<label for="form-notes">Comments</label>
<textarea class="form-control" id="form-comments"
name="Comments" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-
dismiss="modal">Close</button>
<button type="sumbit" class="btn btn-primary"
id="saveEventDataModal">Save</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
Here is the code for that should call the second modal called evenDataModal2
L.MarkerControl2 = L.Control.extend({
options: {
position: 'topleft',
url: 'http://echostorm.mynetgear.com:8080/geoserver/usa/ows',
userName: 'wfspost',
password: 'createfeature'
},
map: null,
marker: null,
binded: false,
onAdd: function (map) {
this.map = map;
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
// link = L.DomUtil.create('a', 'glyphicon glyphicon-map-marker', container);
link = L.DomUtil.create('a', 'glyphicon glyphicon-fire', container);
link.href = '#';
link.title = 'Create a new thermal report';
link.innerHTML = '';
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', L.bind(this.startCreating, this));
map.on("editable:drawing:commit", L.bind(this.onMarkerAdd, this));
return container;
},
startCreating: function() {
this.marker = this.map.editTools.startMarker();
},
onMarkerAdd: function(e) {
this.nearestFeature = null;
this.findNearestPoints(e.layer.getLatLng());
},
onFormClosed: function() {
if (this.marker!=null) {
this.map.editTools.featuresLayer.removeLayer(this.marker);
this.marker = null;
}
},
findNearestPoints: function(latlng) {
var defaultParameters = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: 'usa:within5mi',
maxFeatures: 5,
outputFormat: 'text/javascript',
format_options: 'callback: nearestPoints',
srsName: 'EPSG:4326',
viewparams: 'radius:802;lon:'+latlng.lng+';lat:'+latlng.lat,
};
var parameters = L.Util.extend(defaultParameters);
$.ajax({
jsonp: false,
url: this.options.url + L.Util.getParamString(parameters),
dataType: 'jsonp',
jsonpCallback: 'nearestPoints',
success: L.bind(this.handleNearestPoints, this)
});
},
handleNearestPoints: function(data) {
this.clearModal();
this.setModalDate();
if (data && data.type=="FeatureCollection"
&& data.features && data.features.length
&& data.features.length > 0) {
this.fillModal(data.features[0]);
}
this.openPopup();
},
formatDate: function(date) {
var day = date.getDate();
return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+(day < 10 ? "0"+day : day);
},
clearModal: function() {
$('#eventDataModal2').find('input').each(
function() {
$(this).val("");
}
);
$('#eventDataModal2').find('textarea').each(
function() {
$(this).val("");
}
);
},
setModalDate: function() {
$("#form-patrolDate").val(this.formatDate(new Date()));
},
fillModal: function(feature) {
var props = feature.properties;
$("#form-region").val(props["Region"]);
$("#form-circuitID").val(props["Circuit_ID"]);
$("#form-circuitName").val(props["Circuit_Name"]);
$("#form-vendor").val(props["Vendor"]);
$("#form-quad").val(props["Quad"]);
},
openPopup: function() {
this.bindEvents();
$('#eventDataModal2').modal('show');
},
bindEvents: function() {
if (!this.binded) {
$('#eventDataModal2').on('hidden.bs.modal', L.bind(this.onFormClosed, this));
$("#saveEventDataModal2").on('click', L.bind(this.onSave, this))
this.binded = true;
}
},
onSave: function() {
var properties = this.getFormData(),
request = this.wfsBody("usa", "usa:pecotest", "geom", properties);
console.log(request);
this.makeRequest(request);
},
makeRequest: function(body) {
$.ajax({
method: "POST",
crossDomain: true,
url: this.options.url,
contentType: "text/xml",
dataType: "text",
data: body,
headers: {
"Authorization": "Basic " + btoa(this.options.userName + ":" + this.options.password)
},
jsonpCallback: 'datasave',
success: L.bind(this.onDataSave, this),
failure: function(r){console.log("AJAX Failure!");console.log(r);}
});
},
onDataSave: function(data) {
console.log(data);
},
getFormData: function() {
var result = {};
$('#eventDataModal2').find('input').each(
function() {
if (this.type=="checkbox") {
result[this.name] = this.checked ? "Yes" : "No";
} else {
result[this.name]=$(this).val();
}
}
);
$('#eventDataModal2').find('textarea').each(
function() {
result[this.name]=$(this).val();
}
);
return result;
},
wfsBody: function(namesapce, typeName, geometryField, properties) {
var xml;
xml ='<wfs:Transaction service="WFS" version="1.0.0"';
xml += ' xmlns:wfs="http://www.opengis.net/wfs"';
xml += ' xmlns:usa="http://census.gov"';
xml += ' xmlns:gml="http://www.opengis.net/gml">\n';
xml += ' <wfs:Insert>\n';
xml += ' <'+typeName+'>\n';
xml += ' <usa:'+geometryField+'>\n';
xml += this.marker.toGML()+"\n";
xml += ' </usa:'+geometryField+'>\n';
for (var k in properties) {
if (properties.hasOwnProperty(k)) {
xml += "<"+namesapce+":"+k+">";
xml += properties[k];
xml += "</"+namesapce+":"+k+">\n";
}
}
xml += ' </'+typeName+'>\n';
xml += ' </wfs:Insert>\n';
xml += '</wfs:Transaction>\n';
return xml;
}
});
The corresponding HTML for eventDataModal is exactly the same as the above html code except the id has been changed to eventDataModal2
I have a Model as
var Info = Backbone.Model.extend({
defaults: {
name: '',
email :''
},
initialize: function(){
console.log('Object created');
},
validate: function(attr){
if(!attr.name){
return 'Name cannot be empty';
},
if(!attr.email){
return 'Email cannot be empty';
}
}
});
var model = new Info();
model.set({
name: '',
email: ''
});
var viewClass = Backbone.View.extend({
_modelBind: undefined,
initialize: function(){
this._modelBind = new Backbone.ModelBinder();
this.render();
},
render: function(){
var template = _.template($('#App1').html());
this.$el.html(template);
var bindings = {
name: '[name=name]',
email: '[name=email]'
};
this._modelBind.bind(model, this.el, bindings);
},
'events': {
'click #btnSubmit': 'Submit'
},
Submit: function(){
var response = {
name: model.get('name'),
email: model.get('email')
};
this.model.save(response);
}
});
html is
<script type="text/template" id="App1">
Name: <input type="text" id="name" name="name"/><br />
Email: <input type="text" id="email" name="email" /><br />
<input type="button" id="btnSubmit" value="Submit" />
</script>
On save event, it goes to validate method and after that it goes to the value specified in the url attribute of the model.
I don't want to specify a url parameter. Can i still use validate method without url ?
Call validate directly:
var error = this.model.validate(this.model.attributes);
If you don't specify url parameter, you will get an error on this.model.save():
Uncaught Error: A "url" property or function must be specified