jquery form plugin to edit an entire form in place - forms

I've been searching a bit for a jquery plugin that could help me to edit an entire form in place without having to write markup for both the form and displaying the data. Where you can just click "edit" and then the form fields would appear instead of the text, and then save and the form fields would turn into text again.
Does anyone know of one?

Here's the plugin in its crudest form:
(function( $ ){
var YesNo = new Array();
YesNo["true"] = "Yes";
YesNo["false"] = "No";
$.fn.inline = function() {
this.each(function(){
if ($(this).is('table')) {
$(this).find('input, select, textarea').not('[type=button],[type=submit]').each(function(){
if($(this).attr("type")=="checkbox"){
$(this).parent().append("<span class=\"editable\">"+YesNo[$(this).attr('checked')]+"</span>");
$(this).hide();
//$(this).append("<span>"+$(this).val()+"</span>");
$(this).bind('blur',function(){
var t = YesNo[$(this).attr('checked')];
$(this).hide().next().show().text(t);
});
}
else{
$(this).parent().append("<span class=\"editable\">"+$(this).val()+"</span>");
$(this).hide();
//$(this).append("<span>"+$(this).val()+"</span>");
$(this).bind('blur',function(){
var t = $(this).val();
$(this).hide().next().show().text(t);
});
}
});
$(this).find('td').live('dblclick', function(){
$(this).children('.editable').hide().prev().show().focus();
});
}
});
};
})( jQuery );
Call to plugin:
<script type="text/javascript">
$().ready(function () {
$('#dataform').inline();
});
</script>
And the supporting example markup:
<table id="dataform">
<tr>
<td class="label">First Name</td>
<td><input type="text" value="Robin" /> </td>
<td class="label">Last Name</td>
<td><input type="text" value="Maben" /> </td>
</tr>
<tr>
<td class="label">City</td>
<td><input type="text" value="Bangalore" /> </td>
<td class="label">Country</td>
<td><input type="checkbox" checked="checked" /> </td>
</tr>
<tr>
<td class="styleLabel">Status</td>
<td class="styleControl">
<select id="Select1" class="styleDrop">
<option>Active</option>
<option>Inavtive</option>
<option>Pending</option>
</select></td>
</tr>
<tr>
<td>Description</td><td><textarea>Hello World</textarea></td>
</tr>
<tr>
<td>
<input type = "button" value="Click" />
<input type = "submit" />
</td>
</tr>
</table>

Related

How to send object that is retrived in a get request to a post requet | Spring Boot Thymeleaf

Let's say I have rendered the output rom the get request on an html template, now I need to use this same data to pass to a post request via a button on a same page. How do I do that?
I'm trying to do something like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Customer Home</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div th:replace="fragments/header :: header">
</div>
<div class="container">
<p> Thanks for booking with Gamma Airlines, here are your booking summary: </p>
<table th:object="${booking} class="table table-bordered table-striped">
<tbody>
<tr>
<td>Source</td>
<td th:text="${routeStart}"></td>
</tr>
<tr>
<td>Destination</td>
<td th:text="${routeDestination}"></td>
</tr>
<tr>
<td>Booking Charges</td>
<td th:text="${bookingCharges}"></td>
</tr>
<tr>
<td>Booking Charges Currency</td>
<td th:text="${chargesCurrency}"></td>
</tr>
<tr>
<td>Booking Date</td>
<td th:text="${#calendars.format(bookingDate)}">July 11, 2012 2:17:16 PM CDT</td>
<tr>
<td>
<div class="col-sm-9">
<form action="#" th:action="#{/email}"
th:object="${booking}" method="post"
role="form">
<button type="submit" class="btn btn-primary btn-block">Email</button>
</form>
</div>
</td>
<td>
<div class="col-sm-9">
<form action="#" th:action="#{/genpdf}"
th:object="${booking}" method="post"
role="form">
<button type="submit" class="btn btn-primary btn-block">Generate PDF</button>
</form>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Edit: Somebody please help tell me a simple method to pass the object since I have to use it at many places and object contains many child object as well in some cases. eg. the following case:
<div style = "margin-top: 2cm" class="container">
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>Source</td>
<td>Destination</td>
<td>Amount</td>
<td>Currency</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr th:if="${offers.empty}">
<td colspan="5">No Offers</td>
</tr>
<tr th:each="offer : ${offers}">
<td th:text="${offer.route.from}"></td>
<td th:text="${offer.route.to}"></td>
<td th:text="${offer.price.amount}"></td>
<td th:text="${offer.price.currency}"></td>
<td>
<form action="#" th:action="#{/user/booking}"
th:object="${offer}" method="post"
role="form">
<button type="submit" class="btn btn-primary btn-block">Book</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
UPDATE 2:
I even changed the template by sending a new object in the get request and try to assign values one by one but I still get it as null in a controller.
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>Source</td>
<td>Destination</td>
<td>Amount</td>
<td>Currency</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr th:if="${offers.empty}">
<td colspan="5">No Offers</td>
</tr>
<tr th:each="offer : ${offers}">
<td th:text="${offer.route.from}"></td>
<td th:text="${offer.route.to}"></td>
<td th:text="${offer.price.amount}"></td>
<td th:text="${offer.price.currency}"></td>
<td>
<form action="#" th:action="#{/user/booking}"
th:object="${booking}" method="post"
role="form">
<input type="hidden" th:attr="value = ${offer.route.from}" th:field="*{routeStart}" />
<input type="hidden" th:attr="value = ${offer.route.to}" th:field="*{routeDestination}" />
<input type="hidden" th:attr="value = ${offer.price.amount}" th:field="*{bookingCharges}" />
<input type="hidden" th:attr="value = ${offer.price.currency}" th:field="*{chargesCurrency}" />
<button type="submit" class="btn btn-primary btn-block">Book</button>
</form>
</td>
</tr>
</tbody>
</table>
These are my get and post methods:
#RequestMapping(value="/user/booking", method = RequestMethod.GET)
public ModelAndView getOffers()
{
ModelAndView modelAndView = new ModelAndView();
AirlineOffer[] offersArray= airlineClient.getOffers();
List<AirlineOffer> offers = Arrays.asList(offersArray);
modelAndView.addObject("offers", offers);
Booking booking = new Booking();
modelAndView.addObject("booking", booking);
modelAndView.setViewName("user/booking");
return modelAndView;
}
/** POST method for submitting deposit request */
#RequestMapping(value = "/user/booking", method = RequestMethod.POST)
public ModelAndView book(#Valid Booking booking,
BindingResult bindingResult, HttpServletRequest request)
{
ModelAndView modelAndView = new ModelAndView();
......
}
Alright, I finally resolved it using the following in my form:
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>Source</td>
<td>Destination</td>
<td>Amount</td>
<td>Currency</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr th:if="${offers.empty}">
<td colspan="5">No Offers</td>
</tr>
<tr th:each="offer, stat : ${offers}">
<td th:text="${offer.route.from}"></td>
<td th:text="${offer.route.to}"></td>
<td th:text="${offer.price.amount}"></td>
<td th:text="${offer.price.currency}"></td>
<td>
<form action="#" th:action="#{/user/booking}"
th:object="${booking}" method="post"
role="form">
<input type="hidden" th:value="${offer.route.from}" name="routeStart" />
<input type="hidden" th:value = "${offer.route.to}" name="routeDestination" />
<input type="hidden" th:value = "${offer.price.amount}" name="bookingCharges" />
<input type="hidden" th:value = "${offer.price.currency}" name="chargesCurrency" />
<button type="submit" class="btn btn-primary btn-block">Book</button>
</form>
</td>
</tr>
</tbody>
All it took was to remove th:field and add the name attribute.

cloning input text in a form

I have the following form:
<form method="post">
<table>
<tr>
<td>Foo</td><td><input type="text" name="field1" /></td>
</tr>
<tr>
<td>Bar</td><td><input type="text" name="field2" /></td>
</tr>
<tr>
<td>Foo</td><td><input type="text" name="field3" /></td>
</tr>
<tr>
<td>Test</td><td><input type="text" name="field4" /></td>
</tr>
<tr>
<td>Foo</td><td><input type="text" name="field5" /></td>
</tr>
</table>
I'd like to insert text in field1 and automatically cloning it in all fields that are in foo rows. For example, if I insert "abcd" in field1, also field3 and field5 could be filled automatically with the same "abcd". Is it possible?
Using jquery it can be done this way:
$("input[name='field1']").on("input change", function() {
$("input[name='field3'],input[name='field5']").val($(this).val());
});
$("input[name='field1']").keyup(function(e){
if(e.keyCode == 13)
{
$( "input[name^='field']" ).val($(this).val());
}
});

Adding new row of fields with AngularJS ng-repeat

I am trying to add a new row of fields after the first row when you click the "Add New Participant" button. I've looked at a few sources and followed suggestions but first of all with this ng-repeat in the code, my fields do not show up. And when I click the "Add New Participant" nothing happens. Not sure what I've got wrong here.
HTML:
<table class="col-md-12" id="client-table">
<tr>
<td></td>
<td>Given Name*</td>
<td>Middle Name</td>
<td>Last Name*</td>
<td>Date of Birth*</td>
<td>Nationality</td>
<td>Gender</td>
<td>Adult or Student</td>
</tr>
<tr data-ng-repeat="travelers in traveler">
<td>1.</td>
<td>
<input type="text" placeholder="Given Name" ng-model="travelersForm.givenName"/>
</td>
<td>
<input type="text" placeholder="Middle Name" ng-model="travelersForm.middleName"/>
</td>
<td>
<input type="text" placeholder="Last Name" ng-model="travelersForm.lastName"/>
</td>
<td>
<input type="date" class="date-picker"/>
</td>
<td>
<input type="text" placeholder="Nationality" ng-model="travelersForm.nationality"/>
</td>
<td>
<select name="gender" id="gender" ng-model="travelersForm.gender">
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</td>
<td>
<select name="student" id="student" ng-model="travelersForm.types">
<option value="student">Student</option>
<option value="adult">Adult</option>
</select>
</td>
</tr>
<tr>
<td>
<button ng-show="showAddTraveler(traveler)" ng-click="addNewTraveler()">Add New Participant</button>
</td>
</tr>
</table>
ANGULARJS
angular.module("travelers", [])
.controller("travelersController", function($scope) {
$scope.travelersForm = {};
$scope.travelersForm.givenName = "Test";
$scope.travelersForm.middleName = "T";
$scope.travelersForm.lastName = "Tester";
$scope.travelersForm.nationality = "White";
$scope.travelersForm.gender = "male";
$scope.travelersForm.types = "adult";
$scope.travelers = [];
$scope.addNewTraveler = function() {
var newItemNo = $scope.travelers.length+1;
$scope.travelers.push({'id':'travelers'+newItemNo});
};
$scope.showAddTraveler = function(choice) {
return travelers.id === $scope.travelers[$scope.travelers.length-1].id;
};
} );
Because your ng-repeat syntax is flipped:
Change:
data-ng-repeat="travelers in traveler">
To:
data-ng-repeat="traveler in travelers">

post value still retains the same value after assigning it using $.post

<script type="text/javascript">
$(document).ready(function($) {
$('#searchicon').click(function(){
$('#searchicon.toappear').toggle();
$('#searchicon2.appear').toggle();
$('#extraSearch').slideToggle('fast');
});
$('#searchicon2').click(function(){
$('#searchicon.toappear').toggle();
$('#searchicon2.appear').toggle();
$('#extraSearch').slideToggle('fast');
});
$('input[name=estimate]').click(function(){
if (this.checked) {
$("input.groupestimate").removeAttr("disabled");
} else {
$("input.groupestimate").attr("checked", false);
$("input.groupestimate").attr("disabled", true);
}
});
$("input.groupgatepass").attr("disabled", true);
$('input[name=gatepass]').click(function(){
if (this.checked) {
$("input.groupgatepass").removeAttr("disabled");
} else {
$("input.groupgatepass").attr("checked", false);
$("input.groupgatepass").attr("disabled", true);
}
});
/*
$('input.groupestimate').click(function() {
if(this.checked) {
$form = $('#globalSearch form');
if($('#globalSearch form[ACTION*="'+this.value+'"]'))
var data = new Object();
data.field = this.value;
var dataString = $.toJSON(data);
$.post('json.php',
{data: dataString},
function(res){
var obj = $.evalJSON(res);
$form.attr('ACTION',$form.attr('action')+''+obj.query);
}
);
}
});*/
$('#globalSearch form').submit(function() {
if($('input.groupheader[type=checkbox]:checked').length > 1) {
alert('Please check only Estimate or Gatepass');
return false;
}
var data = new Object();
$('input.groupheader[type=checkbox]:checked').each(function(){
data.header = this.value;
});
data.fields = new Array();
$header = 'input.group'+data.header;
$($header+'[type=checkbox]:checked').each(function(){
data.fields.push(this.value);
});
var dataString = $.toJSON(data);
$.post('json.php',
{data: dataString},
function(res){
var obj = $.evalJSON(res);
$('input[name=query]').val(obj.query);
}
);
alert($('input[name=query]').val()); //alerts nothing or the old value :(
return false;
});
});
</script>
-------------HTML PART-------------------
<form action="?<?php echo http_build_query(cloneGet(array("server-page"=>$GLOBALS["setting"]["current_folder"], "currpage"=>"0","OrderBy"=>"","ByDirect"=>"","search_flg"=>"-1")));?>" method="post" id="" name="">
<div id="extraSearch">
<table class="stripe" width="100%" id="extraTableList">
<tbody>
<tr class="striped">
<th style="cursor:pointer;text-align:left;"><input type="checkbox" name="estimate" value="estimate" checked="checked" class="groupheader">Estimates</th>
<th style="cursor:pointer;text-align:left;"><input type="checkbox" name="gatepass" value="gatepass" class="groupheader">Gatepass</th>
</tr>
<tr>
<td class="int"><input type="checkbox" name="estimate1" value="customer" class="groupestimate">Customer</td>
<td class="int"><input type="checkbox" name="gatepass1" value="old_serial" class="groupgatepass">Old Serial</td>
</tr>
<tr>
<td class="int"><input type="checkbox" name="estimate2" value="serial_no" class="groupestimate">Serial No</td>
<td class="int"><input type="checkbox" name="gatepass2" value="type" class="groupgatepass">Type</td>
</tr>
<tr>
<td class="int"><input type="checkbox" name="estimate3" value="invoice_no" class="groupestimate">Invoice No</td>
<td class="int"><input type="checkbox" name="gatepass3" value="type_id" class="groupgatepass">Type ID</td>
</tr>
<tr>
<td class="int"><input type="checkbox" name="estimate4" value="salesman" class="groupestimate">Salesman</td>
<td class="int"><input type="checkbox" name="gatepass4" value="loader" class="groupgatepass">Loader</td>
</tr>
<tr>
<td class="int"><input type="checkbox" name="estimate5" value="estimate_no" class="groupestimate">Estimate No</td>
<td class="int"><input type="checkbox" name="gatepass5" value="total" class="groupgatepass">Total</td>
</tr>
<tr>
<td class="int"><input type="checkbox" name="estimate6" value="status" class="groupestimate">Status</td>
<td class="int"> </td>
</tr>
</tbody>
</table>
</div>
<img id="searchicon" src="___images/search-arrow.png" class="toappear" alt="Extra search" title="Extra search"/>
<img id="searchicon2" src="___images/search-arrow.png" class="appear" alt="Extra search" title="Extra search"/>
<input type="text" value="<?php echo $_REQUEST['quicksearch'];?>" id="s" name="quicksearch">
<input type="hidden" value="" id="query" name="query" temp="">
<input type="submit" value="Search" id="b">
<?php if( $_REQUEST['quicksearch'] ) { ?>
<a id="c" href="?<?php echo http_build_query(cloneGet(array("quicksearch"=>"","search_flg"=>"-1")));?>">Cancel</a>
<?php } ?>
</form>
As you can see, before it submits the values I want to insert a string into the 'query' input element value attribute. It works perfectly when doing it inside the callback of $.post but after checking it using alert() outside the $.post its empty.
Is $.post always like that?or am I missing something?
when you are using $.post it is making an async request. The reason alert will contain nothing or the old value is because it is triggered before the $.post can complete its request. When the alert is placed inside of the $.post callback it will have the data you want because it is called after the $.post has completed

Is there any way to create form with multiple submit buttons on Spring MVC using annotations?

I'm trying to create simple add/remove form using annotation based Spring MVC.
'Add' functionality comes smoothly, but when I tried to add another button to form i've got stuck.
Here is my code:
Controller actions:
#RequestMapping(value = "/books/documentType.do", method = RequestMethod.GET)
public String getDocType(
#RequestParam(required = false, value = "id") Long id,
ModelMap model) {
DocTypeDTO docType = new DocTypeDTO();
if (id != null)
docType = docTypeConverter.getDTO(id);
model.addAttribute("docType", docType);
return "/books/documentType";
}
#RequestMapping(value = "/books/documentType.do", method = RequestMethod.POST)
public String setDocType(
#ModelAttribute("docType") DocTypeDTO docType,
BindingResult result,
SessionStatus sessionStatus
) {
docTypeValidator.validate(docType, result);
if (result.hasErrors())
return "/books/documentType";
else {
docTypeConverter.saveDTO(docType);
sessionStatus.setComplete();
return "redirect:/books/documentTypes.do";
}
}
Awfully markuped form:
<form:form method="post" commandName="docType" id="editForm">
<table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#dbdbdb">
<tr>
<td></td>
<td>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td class="spacer"><img src="/images/spacer.gif" width="116" height="1" border="0"/></td>
<td class="spacer"><img src="/images/spacer.gif" width="216" height="1" border="0"/></td>
</tr>
<tr>
<td class="form-cell-text-underlined">Отображать на сайте</td>
<td colspan="2">
<form:checkbox path="shownOnSite"/>
</td>
</tr>
<tr>
<td class="form-cell-text-underlined">Международный</td>
<td colspan="2">
<form:checkbox path="international"/>
</td>
</tr>
<tr>
<td class="form-cell-text-underlined">Внутренний код</td>
<td colspan="2">
<form:input path="internalCode"/>
</td>
</tr>
<tr>
<td class="form-cell-text-underlined">Код</td>
<td colspan="2">
<form:input path="code"/>
<form:errors path="code"/>
</td>
</tr>
<tr>
<td class="form-cell-text-underlined">Код IATA</td>
<td colspan="2">
<form:input path="codeIATA"/>
</td>
</tr>
<tr>
<td class="padded-underlined">Название</td>
<td colspan="2">
<form:input path="name"/>
<form:errors path="name"/>
</td>
</tr>
<tr>
<td class="padded-underlined">Название(Англ.)</td>
<td colspan="2">
<form:input path="nameEn"/>
</td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Сохранить">
</td>
</tr>
</table>
</td>
<td></td>
</tr>
</table>
Thanks!
With Spring MVC 3, this is reasonably straight-forward to do with just JSP and Controller. For example, these two submit buttons handle 'previous' and 'save' actions:
<input value="Save" name="save" type="submit" id="btnSave" class="submit_button">
<input value="Previous" name="previous" type="submit" id="btnPrevious" class="submit_button">
Then, in the controller, you accept the input name as a param in the request mapping, along with the controller 'address':
#RequestMapping(value="thisForm.form", params="save")
public String save() {
// save
}
#RequestMapping(value="thisForm.form", params="previous")
public String doPreviousStuff() {
// get mapping for previous page and return
}
If you really want two submit buttons on your form, you can do it with Javascript like this (using jQuery in this example):
<SCRIPT language=JavaScript>
function remove() {
$('#editForm').attr("action", "documentTypeRemove.do");
$("#editForm").submit();
}
</SCRIPT>
...
<button type="button" onclick="remove();">Remove</button>
Then create another RequestMapping in your controller:
#RequestMapping(value = "/books/documentTypeRemove.do", method = RequestMethod.POST)
public String removeDocType(...