Basic Ajax Form
The form control aims to provide the best form processing with minimal custom javascript:
  1. Easily enable the common save-on-change setup.
  2. Automaticaly use jQuery unobtrusive validation. Validation rules configured on the models.
  3. Use and asp-action="" tags to automate form processing.
  4. Controls should be created and updated to present form data C# can process nativly.
  5. Validation featuers can be added including Regex and Server Side validation calls.
  6. Callbacks for fd-ajax-begin, fd-ajax-success, fd-ajax-error can be added or chained as needed.
HTML
<form data-fd-control="form" data-fd-onchange="false" asp-action="SaveForm"
		fd-ajax-begin="" fd-ajax-success="FD.Page.handleSaveForm">
	// Form fields go here

	<div class="form-group row">
		<label class="col-form-label col-md-3">Submit Button</label>
		<div class="col-md-9">
			<div class="btn-group">
				<button type="reset" class="btn btn-default">Reset</button>
				<button type="submit" class="btn btn-info">Submit</button>
			</div>
		</div>
	</div>
</form>
JavaScript
FD.Page.handleSaveForm = function (result, textStatus, xhr) {
	var self = $(this);
	notify.confirm('Form Submitted!
Name: ' + result.name + '
Option: ' + result.option + '
Number: ' + result.number); self.closest('.row').find('.output-data').text(self.serialize()); self.closest('.row').find('.output-event').text(event.type); self.trigger('reset'); }
Injected Ajax Form
HTML
<a class="btn btn-primary fa fa-edit" asp-action="GetEditForm" fd-ajax-update="#EDIT_FORM" fd-ajax-success="FD.Utility.enableControls"></a>
JavaScript
FD.Page.handleUpdateForm = function (result, textStatus, xhr) {
	var self = $(this);
	notify.confirm('Form Submitted!
Name: ' + result.name + '
Option: ' + result.option + '
Number: ' + result.number); self.closest('.row').find('.output-data').text(self.serialize()); self.closest('.row').find('.output-event').text(event.type); self.control_form('setClean'); }
Other Features
Other form capabilities:
  1. Disabled fields won't be psoted.
  2. asp-for can be used on submit buttons.
  3. Repeating data can be written to post directly without needing custom JS. New items can be added by adding a template and calling to add $('#TEMPLATE').clone().insertBefore('#TEMPLATE').removeClass('d-none'). If items are removed or sorted run FD.Utility.resetSequence($('#TEMPLATE').siblings()) to ensure fields post in the correct order.
  4. [CustomValidation] and [Remote] can be used to easily do ajax calls on validation.
HTML
<form data-fd-control="form" data-fd-onchange="false" asp-action="SaveForm"
	  fd-ajax-begin="" fd-ajax-success="FD.Page.handleSaveForm">
	<fieldset>
		<div class="form-group row">
			<label class="col-form-label col-md-3" asp-for="Number"></label>
			<div class="col-md-9">
				<input type="number" class="form-control" asp-for="Number" value="12" disabled />
				<span asp-validation-for="Number" class="text-danger"></span>
			</div>
		</div>
		@foreach (var (field, i) in Model.RepeatingField.WithIndex())
		{
			<div class="form-group row">
				<label class="col-form-label col-md-3" asp-for="RepeatingField[i].JobTitle"></label>
				<div class="col-md-9">
					<input type="text" class="form-control" asp-for="RepeatingField[i].JobTitle" />
					<span asp-validation-for="RepeatingField[i].JobTitle" class="text-danger"></span>
				</div>
			</div>
		}
		<div class="form-group row">
			<label class="col-form-label col-md-3" asp-for="CategoryName"></label>
			<div class="col-md-9">
				<input type="text" class="form-control" asp-for="CategoryName" />
				<span asp-validation-for="CategoryName" class="text-danger"></span>
			</div>
		</div>

		<div class="form-group row">
			<label class="col-form-label col-md-3">Submit Button</label>
			<div class="col-md-9">
				<div class="btn-group">
					<button type="submit" class="btn btn-info" asp-for="Name" value="Bob">Submit</button>
				</div>
			</div>
		</div>
	</fieldset>
</form>
JavaScript

                    
Basic Form with ChangeCallback
The form control aims to support two common scenarios:
  1. Easily enable the common save-on-change setup
  2. Adding data-fd-setvalidation=true to a dynamically added form will automatically setup jQuery unobtrusive validation
HTML
<form data-fd-control="form" data-fd-callback="setOutputText" data-fd-changecallback="changeCallback">
	// Form fields go here
</form>
		
JavaScript
FD.Page.setOutputText = function (data, event) {
	event.preventDefault();
	this.element.closest('.row').find('.output-data').text(this.element.serialize());
	this.element.closest('.row').find('.output-event').text(event.type);
	this.setClean();
};

FD.Page.changeCallback = function (data, event) {
	var label = data.elem.closest('.form-group').find('label')
	label.addClass('text-info', 500);
	setTimeout(function () {
		label.removeClass('text-info', 100);
	}, 2000)
};
		
Submit Button-Only Form
HTML
<form data-fd-control="form" data-fd-callback="submitForm" data-fd-onchange="false">
	// Form fields go here
</form>
		
JavaScript
FD.Page.setOutputText = function (data, event) {
	event.preventDefault();
	this.element.closest('.row').find('.output-data').text(this.element.serialize());
	this.element.closest('.row').find('.output-event').text(event.type);
	this.setClean();
};

FD.Page.submitForm = function (data, event) {
	if (!this.element.valid()) {
		return;
	}
	$.fdAjax({
		url: baseUrl +  "SaveForm",
		params: this.element.serialize(),
		contentTypeHelper: 'form',
		callback: function (result) {
			notify.confirm('Form Submitted!
Name: ' + result.data.name + '
Option: ' + result.data.option + '
Number: ' + result.data.number); } }); event.preventDefault(); };