I'm using a jeasyui form, inside a xoops module, in which I'm trying to clear all the form fields once the data has successfully submitted.
I've already consulted this question, but it didn't solve the problem in my case.
My HTML:
<div class="easyui-panel" title="Capture Reqs" style "width:100%;
max-width:600px; padding:30px 60px;">
<form action = "captureReqs_Save.php" id ="ff" class = "easyui-form"
method ="post" data-options = "novalidate:true">
<div style="margin-bottom:20px"> Area <br>
<input id="idArea" class="easyui-combobox" style="width:260px" name="idArea"
data-options="
url:'areasJson.php?idZona=<?php echo $idZone; ?>',
label:'Area:',
valueField: 'id',
textField: 'desc',
required:true
">
</div>
<div style="margin-bottom:20px"> Material
<input id="IdMaterial" class="easyui-combobox" style="width:100%"
name="IdMaterial" data-options="
loader: myloader,
mode: 'remote',
valueField: 'code',
textField: 'desc',
required:true
">
<div style="margin-bottom:20px"> Qty
<input class="easyui-textbox" name="quantity" style="width:100%"
data-options="label:'Qty:',required:true, validType:'number'">
</div>
<div style="margin-bottom:20px">
</form>
<div style="text-align:center;padding:5px 0">
<a href="javascript:void(0)" class="easyui-linkbutton"
onClick = "submitForm()" style="width:80px"> Submit</a>
<a href="javascript:void(0)" class="easyui-linkbutton"
onClick = "resetForm()" style = "width:80px"> Clear </a>
</div>
</div>
Script:
<script>
var myloader = function (param, success, error) {
var q = param.q || '';
if (q.length <= 2) {
return false
}
$.ajax({
url: 'materialJson.php?idArea=' + $('#idArea').combobox('getValue'),
dataType: 'json',
data: {
q: q
},
success: function (data) {
var items = $.map(data, function (item, index) {
return {
code: item.code,
desc: item.desc
};
});
success(items);
},
error: function () {
error.apply(this, arguments);
}
});
}
function submitForm() {
$('#ff').form('submit', {
onSubmit: function () {
return $(this).form('enableValidation').form('validate');
}
});
}
function resetForm() {
$('#ff')[0].reset();
}
</script>
Try calling resetForm. I converted to use promise style ajax and added resetForm
var myloader = function (param, success, error) {
var q = param.q || '';
if (q.length <= 2) {
return false
}
$.ajax({
url: 'materialJson.php?idArea=' + $('#idArea').combobox('getValue'),
dataType: 'json',
data: {
q: q
}
}).then(function (data) {
var items = $.map(data, function (item, index) {
return {
code: item.code,
desc: item.desc
};
});
success(items);
}).fail(function () {
error.apply(this, arguments);
});
}
function submitForm() {
$('#ff').submit(function () {
if ($(this).form('enableValidation').form('validate')) {
$.post($(this).attr('action'), $(this).serialize(), function (response) {
clearForm();
});
}
return false;
});
}
function resetForm() {
$('#ff')[0].reset();
}
Related
I am using some javascript to post my form but I dont want to have to submit each form field is there a way I can serlize this to an object in .net so that it will bring in all the form contents.
section Scripts {
<script>
function confirmEdit() {
swal({
title: "MIS",
text: "Case Created your Case Number is " + $("#Id").val(),
icon: "warning",
buttons: true,
dangerMode: true,
}).then((willUpdate) => {
if (willUpdate) {
$.ajax({
url: "/tests/edit/" + $("#Id").val(),
type: "POST",
data: {
Id: $("#Id").val(),
Name: $("#Name").val()
},
dataType: "html",
success: function () {
swal("Done!", "It was succesfully edited!", "success")
.then((success) => {
window.location.href = "/tests/index"
});
},
error: function (xhr, ajaxOptions, thrownError) {
swal("Error updating!", "Please try again", "error");
}
});
}
});
}
</script>
}
asp.net core will automatically bind json data using the [FromBody] attribute.
data: {
id: $("#Id").val(),
name: $("#Name").val()
},
and then in your controller
[HttpPost("/tests/edit/")]
public IActionResult Process([FromBody] MyData data){ ... }
where MyData is
public class MyData
{
public string Id {get;set;}
public string Name {get;set;}
}
section Scripts { function confirmEdit() {
swal({ title: "MIS", text: "Case Created your Case Number is " + $("#Id").val(), icon: "warning", buttons: true, dangerMode: true, }).then((willUpdate) => { if (willUpdate) {
var obj = { Id: $("#Id").val(), Name: $("#Name").val() }
$.ajax({ url: "/tests/edit/" + $("#Id").val(), type: "POST", data: JSON.Stringify(obj), dataType: "html", success: function () { swal("Done!", "It was succesfully edited!", "success") .then((success) => { window.location.href = "/tests/index" }); }, error: function (xhr, ajaxOptions, thrownError) { swal("Error updating!", "Please try again", "error"); } }); } }); } }
in c# use
public ActionResult FormPost(MyData obj)
Please refer to the following methods to submit the form data to action method:
using the serialize() method to serialize the controls within the form.
#model MVCSample.Models.OrderViewModel
<h4>OrderViewModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Showsummary" asp-controller="Home" method="post" class="signup-form">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderId" class="control-label"></label>
<input asp-for="OrderId" class="form-control" />
<span asp-validation-for="OrderId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="OrderName" class="control-label"></label>
<input asp-for="OrderName" class="form-control" />
<span asp-validation-for="OrderName" class="text-danger"></span>
</div>
<div id="packages">
#for (int i = 0; i < Model.Packages.Count; i++)
{
<div class="form-group">
<label asp-for="#Model.Packages[i].Pid" class="control-label"></label>
<input asp-for="#Model.Packages[i].Pid" class="form-control" />
<span asp-validation-for="#Model.Packages[i].Pid" class="text-danger"></span>
<br />
<label asp-for="#Model.Packages[i].PackageTitle" class="control-label"></label>
<input asp-for="#Model.Packages[i].PackageTitle" class="form-control" />
<span asp-validation-for="#Model.Packages[i].PackageTitle" class="text-danger"></span>
</div>
}
</div>
</form>
</div>
</div>
<div>
<input type="button" id="summary" value="Summary" />
<div id="page_3">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(function () {
$("#summary").click(function () {
console.log("calling summary");
event.preventDefault();
$.ajax({
type: "POST",
url: "/Home/Showsummary", //remember change the controller to your owns.
data: $("form.signup-form").serialize(),
success: function (data) {
console.log(data)
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
</script>
Code the the action method:
[HttpPost]
public PartialViewResult Showsummary(OrderViewModel model)
{
try
{
//...
return PartialView("OrderSummary", model);
}
catch
{
return PartialView("OrderSummary", model);
}
}
After clicking the button, the result like this:
As we can see that, we could get the element's value in the form and even the nested entity.
Note: Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button. For a form element's value to be included in the serialized string, the element must have a name attribute. Values from checkboxes and radio buttons (inputs of type "radio" or "checkbox") are included only if they are checked. Data from file select elements is not serialized.
Create a JavaScript object, and post it to action method.
Change the JavaScript script as below:
$(function () {
$("#summary").click(function () {
console.log("calling summary");
event.preventDefault();
//create a object to store the entered value.
var OrderViewModel = {};
//using jquery to get the entered value.
OrderViewModel.OrderId = $("input[name='OrderId']").val();
OrderViewModel.OrderName = $("input[name='OrderName']").val();
var packages = [];
//var count = $("#packages>.form-group").length; //you could use it to check the package count
$("#packages>.form-group").each(function (index, item) {
var package = {}
package.Pid = $(item).find("input[name='Packages[" + index + "].Pid']").val();
package.PackageTitle = $(item).find("input[name='Packages[" + index + "].PackageTitle']").val();
packages.push(package);
});
//add the nested entity
OrderViewModel.Packages = packages;
$.ajax({
type: "POST",
url: "/Home/Showsummary", //remember change the controller to your owns.
data: OrderViewModel,
success: function (data) {
console.log(data)
$('#page_3').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
By using the above code, I could also get the submit entity, you could refer to it.
I'm using select2 to pick out games from a database, however, the file I wish it to search from will change depending on what's selected from a dropdown.
How do I get it so select2 always uses the most up to date "picker_url"?
So if I select a certain option from a select box on a page, it changes the "picker_url" (an ajax file to do the search). The problem is, select2 only seems to use the original value.
Here's my current code:
var picker_url = "test1.php";
$(document).on('change', ".category_select", function(e)
{
var id = $(this).val();
if (id == 16)
{
picker_url = "test2.php";
}
});
$(".game_picker").select2({
selectOnClose: true,
width: '100%',
ajax: {
url: picker_url,
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term // search term
};
},
processResults: function (data) {
return {
results: $.map(data, function(obj) {
return { id: obj.id, text: obj.text };
})
};
},
cache: true,
},
minimumInputLength: 2
});
Found the answer here: https://github.com/select2/select2/issues/1679#issuecomment-280080742
var someCondition
ajax: {
url: function() {
if (someCondition) {
return '/api/1/someFile.json'
} else {
return '/api/1/someOtherFile.json'
}
}
}
I suggest to use dynamic-urls, like the code below:
$('#mySelect2').select2({
ajax: {
url: function (params) {
return '/some/url/' + params.term;
}
}
});
Inside url function you can test other variables than params, like in the following snippet:
$('#category').select2({
placeholder: "Select category...",
width: '100%',
});
$('#category').on('select2:select', function(e) {
var data = e.params.data;
console.log("category", data);
categ = e.params.data.id;
});
var categ = "1";
$('#project').select2({
placeholder: "Select item...",
width: '100%',
ajax: {
type: "GET",
url: function(params) {
console.log("ajax func", params, categ);
var url = 'https://jsonplaceholder.typicode.com/comments?postId=' + categ
return url;
},
cache: true,
processResults: function(data) {
return {
results: $.map(data, function(obj) {
return {
id: obj.id,
text: obj.name
};
})
};
},
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<div class="group">
<select id="category">
<option value="1">cat 1</option>
<option value="2">cat 2</option>
</select>
</div>
<br>
<div class="group">
<select id="project">
<option value=""></option>
</select>
</div>
I would save off your default options and then recreate the select2 whenever you need to by extending your new URL into the default options:
var defaultOptions = {
selectOnClose: true,
width: '100%',
ajax: {
url: "test1.php",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term // search term
};
},
processResults: function (data) {
return {
results: $.map(data, function(obj) {
return { id: obj.id, text: obj.text };
})
};
},
cache: true,
minimumInputLength: 2
};
//Use default to create first time
$(".game_picker").select2(defaultOptions);
//On change, recreate
$(document).on('change', ".category_select", function(e)
{
var options = defaultOptions;
if ($(this).val() == 16)
{
//Create a new options object with the url updated
options = $.extend({}, defaultOptions, { url: 'test2.php' });
}
//Create a select2 with the desired options
$(".game_picker").select2(options);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have the following problem, I have performed a function to update my data with PHP and Codeigniter, using AJAX too .. everything works fine, but it turns out that I want to validate my form using jquery-validate before performing the AJAX request, for that already I have my validation rules and my code is as follows:
function edit(id = null) {
if (!id) {
alert('error');
return;
}
$.ajax({
url: 'roles/get_data_id/' + id,
type: 'post',
dataType: 'json',
success: function(response) {
$("#edit_name").val(response.Name);
$("#edit_description").val(response.Description);
$("#form_edit").unbind('submit').bind('submit', function() {
var form = $(this);
$.ajax({
url: form.attr('action') + '/' + id,
type: 'post',
data: form.serialize(),
dataType: 'json',
success: function(response) {
if(response.success === true) {
$("#modal_edit").modal('hide');
alert('The data were updated');
$("#form_edit")[0].reset();
table_data.ajax.reload(null, false);
} else {
$("#modal_edit").modal('hide');
alert('Error updating data');
}
}// /succes
}); // /ajax
return false;
});
}
});
}
The code works fine .. update my data .. now my question is where to add the following code with my validation rules:
$('#form_edit').validate({
highlight: function (input) {
$(input).parents('.form-line').addClass('error');
},
unhighlight: function (input) {
$(input).parents('.form-line').removeClass('error');
},
errorPlacement: function (error, element) {
$(element).parents('.form-group').append(error);
}
});
This is my current code:
function edit(id = null) {
if (!id) {
alert('error');
return;
}
$.ajax({
url: 'roles/get_data_id/' + id,
type: 'post',
dataType: 'json',
success: function(response) {
$("#edit_name").val(response.Name);
$("#edit_description").val(response.Description);
$('#form_edit').validate({
highlight: function(input) {
$(input).parents('.form-line').addClass('error');
},
unhighlight: function(input) {
$(input).parents('.form-line').removeClass('error');
},
errorPlacement: function(error, element) {
$(element).parents('.form-group').append(error);
},
submitHandler: function() {
$.ajax({
url: form.attr('action') + '/' + id,
type: 'post',
data: form.serialize(),
dataType: 'json',
success: function(response) {
if (response.success === true) {
$("#modal_edit").modal('hide');
alert('The data were updated');
$("#form_edit")[0].reset();
table_data.ajax.reload(null, false);
} else {
$("#modal_edit").modal('hide');
alert('Error updating data');
}
} // /succes
}); // /ajax
return false;
}
});
}
});
}
this code my form:
<div class="modal fade" id="modal_edit" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="smallModalLabel">Edit rol</h4>
</div>
<form id="form_edit" action="<?php echo base_url();?>rol/edit" method="POST">
<div class="modal-body">
<div class="form-group form-float">
<label class="form-label">Name</label>
<div class="form-line">
<input type="text" id="edit_name" name="edit_name" class="form-control" maxlength="20" minlength="5" required>
</div>
</div>
<div class="form-group form-float">
<label class="form-label">Description</label>
<div class="form-line">
<textarea id="edit_description" name="edit_description" rows="3" class="form-control no-resize" required></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-link waves-effect">update</button>
<button type="button" class="btn btn-link waves-effect" data-dismiss="modal">Cancel</button>
</div>
</form>
</div>
</div>
</div>
You can use the submitHandler provided by the jQuery validation, this way the AJAX will fire only when the validation rules are passed:
$('#form_edit').validate({
highlight: function(input) {
$(input).parents('.form-line').addClass('error');
},
unhighlight: function(input) {
$(input).parents('.form-line').removeClass('error');
},
errorPlacement: function(error, element) {
$(element).parents('.form-group').append(error);
},
submitHandler: function() {
//your AJAX code goes here
edit(your_id_param_goes_here);
}
});
I have made you a WORKING DEMO,
I hope you will figure out how to continue from there.
HTML Changes:
<form id="form_edit">
<button id="submitForm" type="submit" class="btn btn-link waves-effect">update</button>
JavaScript:
$(document).ready(function() {
$("#submitForm").on("click", edit);
// introduce the validation rules to the form!
$('#form_edit')
.validate({
highlight: function(input) {
$(input).parents('.form-line').addClass('error');
},
unhighlight: function(input) {
$(input).parents('.form-line').removeClass('error');
},
errorPlacement: function(error, element) {
$(element).parents('.form-group').append(error);
},
submitHandler: function(form) {
//Will execute only when the form passed validation.
OnSubmit(form);
}
});
function OnSubmit(form) {
$.ajax({
url: form.attr('action') + '/' + id,
type: 'post',
data: form.serialize(),
dataType: 'json',
success: function(response) {
if (response.success === true) {
$("#modal_edit").modal('hide');
alert('The data were updated');
$("#form_edit")[0].reset();
table_data.ajax.reload(null, false);
} else {
$("#modal_edit").modal('hide');
alert('Error updating data');
}
} // /success
}); // /ajax
}
function edit(id = null) {
if (!id) {
alert('error');
return;
}
$.ajax({
url: 'roles/get_data_id/' + id,
type: 'post',
dataType: 'json',
success: function(response) {
$("#edit_name").val(response.Name);
$("#edit_description").val(response.Description);
return false;
}
});
}
});
I have this html markup:
<!-- ko foreach: Orders -->
<div class="row">
<div>
<select class="form-control" data-bind="attr: { id: 'prefix_' + $index() }, options: TeacherNames, optionsValue: 'TeacherId', optionsText: 'TeacherName', optionsCaption: 'Choose Teacher', event: { change: $root.teacherChanged }">
</select>
</div>
<div>
<a href='#' data-bind="click: $root.RequestImage" class="green-btn blue pull-right">
<span class="glyphicon glyphicon-cloud-download"></span> Download
</a>
</div>
</div>
<!-- /ko -->
There will be n number of items in the foreach loop, that will not be known in the moment of development.
What I want to do is when the $root.RequestImage is clicked, the code needs to check if there is selection made in the respected dropdown for that row, if the selection is made then proceed further, otherwise display alert box with 'error' message.
So in the RequestImage that action should happen, this is the RequestImage function currently:
self.RequestImage = function () {
};
How can I achieve this?
Update
OrdersVM:
var self = this;
self.Orders = ko.observableArray([]);
$.ajax({
type: "POST", url: "/webservices/InfoWS.asmx/GetOrders",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.d != null) {
var orderIds = [];
ko.utils.arrayForEach(data.d, function (item) {
item._teacherOrders = ko.observable();
$.ajax({
type: "POST",
url: "/webservices/InfoWS.asmx/GetTeachersForMyAccount",
contentType: "application/json; charset=utf-8",
data: "{'orderId': " + JSON.stringify(item.OrderId) + "}",
dataType: "json",
success: function (data) {
if (data) {
return item._teacherOrders(data.d);
}
},
error: function (n) {
alert('Error retrieving teachers for orders, please try again.');
}
});
item.TeacherNames = ko.computed(function () {
return item._teacherOrders();
});
self.Orders.push(item);
orderIds.push(item.OrderId);
});
}
},
error: function (data) {
var response = JSON.parse(data.responseText);
console.log("error retrieving orders:" + response.Message);
}
});
I would do it this way:
add an observable selectedTeacher to every order object
add value: selectedTeacher to your selects:
<select class="form-control" data-bind="attr: { id: 'prefix_' + $index() }, options: TeacherNames, optionsValue: 'TeacherId', ..., value: selectedTeacher"></select>
check that observable in your RequestImage event
if ( !data.selectedTeacher() ) {
alert('Error: select teacher')
} else {
alert('Success')
}
A working demo - Fiddle
Here is a weird race condition happening with knockoutjs. I'm setting two observables independantly using ajax calls. One is a list, the other is a single value. The weird thing is when I load the single value before the list, it won't bind correctly. Any suggestions?
JsFiddle: http://jsfiddle.net/JasonMore/bxfXd/110/
View
<form data-bind='submit:addItem'>
Add item: <input data-bind='value:itemToAdd, valueUpdate: "afterkeydown"' type='text' />
<button data-bind='enable: isAddButtonEnabled' type='submit'>Add</button>
</form>
<p>Your values:</p>
<select data-bind='options:allItems, value:selectedItems' height='5'> </select>
<div>
<button data-bind='click: removeSelected'>Remove</button>
<button data-bind='click: function() { allItems.sort() }, enable: allItems().length > 1'>Sort</button>
</div>
</div>
Code
var betterListModel = function() {
var self = this;
// properties
this.itemToAdd = new ko.observable("");
this.allItems = new ko.observableArray();
this.selectedItems = new ko.observable('');
// computed
this.isAddButtonEnabled = ko.computed(function() {
return self.itemToAdd().length > 0
});
//methods
this.addItem = function() {
if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) this.allItems.push(this.itemToAdd());
this.itemToAdd("");
}
this.removeSelected = function() {
this.allItems.removeAll(this.selectedItems());
this.selectedItems();
} };
var view = new betterListModel();
ko.applyBindings(view);
// load $.ajax({
url: '/echo/json/',
type: 'post',
data: {
json: $.toJSON("Ham"),
delay: 1
},
success: function(data) {
view.selectedItems(data);
} });
$.ajax({
url: '/echo/json/',
type: 'post',
data: {
json: $.toJSON(["Fries", "Eggs Benedict", "Ham", "Cheese"]),
delay: 2
},
success: function(data) {
$.each(data, function(index, value) {
view.allItems.push(value);
});
} });
Try this-->
// Whenever the states changes, reset the selectedState selection
this.allItems.subscribe(function () {
this.selectedItems(arrayOfMySelectedItems);
});