How to prevent from data looping in jQuery Ajax? - javascript

This is regarding assigning multiple user using Select2 plugin, Ajax and API. The situation, I have a function that contain of 2 Ajax with different pointed URL. Currently, I have pre-selected user that stored in DB. The selection is using Select2 in a Modal. So what is happen now when Modal is opened, 1st Ajax will load URL /all_user to display all user in DB. After that 2nd Ajax will load URL /activity to get and load information for other fields in the same Modal. Both URLs are running in parallel.
URL /all_user successful to display all user. URL /activity also successful to display pre-selected user. However, when I close the Modal and re-open back the same Modal without refresh page, it will definitely load the same function that contain 2 Ajax as mentioned above.
FYI, in /activity I have doing a function to convert from String to Array since I received in String from DB, so need to convert before displaying in Select.
So the problem is both are the data will be duplicate 2x, when I close and re-open, it will duplicate 3x. How to prevent from the duplication?
Below are the pre-selected Select2 in /activity.
Below are the /all_user that successfully display all user
So when Modal is close and re-open back, duplication happen.
HTML
<select type="text" class="form-control mySelect" id="editOwner" name="editOwner" multiple="multiple"></select>
SELECT2 INIT
var mySelect = $('.mySelect').select2({
allowClear: true,
placeholder: "Search Owner...",
minimumResultsForSearch: -1,
width: 600,
});
JS
<span onclick='editOwner(""+value3.l3_id+"")'></span>
function editOwner(id){
activity_id = id;
$.ajax ({
url: '/all_user',
crossDomain: true,
type: "POST",
dataType : 'json',
cache: false,
processData: true,
data: 'data',
success: function(response){
for (var i = 0; i < response.data.length; i++) {
$("#editOwner").append($("<option>", {
response: response.data[i].fullname,
text: response.data[i].fullname
}));
}
}
});
$.ajax({
url : '/activity',
crossDomain: true,
type: "POST",
dataType : 'json',
cache: false,
processData: true,
data: {task_id: activity_id}},
success: function(response){
if (response.status == "Success"){
$("#editOwner").val(response.data[0]["task_owner"]).attr("readonly",false);
$(response.data).each(function(key,value){
var owners = value.task_owner.split(',');
$(owners).each(function(k,v){
$("#editOwner").append($("<option selected>", {
response: v,
text: v
}));
});
$("#editOwner").val(owners).trigger("change");
});
}
else {}
},
error: function(e){}
});
$('#editOwnerModal').modal('show');
}

This is because you are calling:
editOwner(id);
on the click event of your your span that contains your select with the ID of #editOwner.
Like this:
<body>
<select id="cars" style="display: block">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<script type="text/javascript" src="jquery-3.4.1.min.js"></script>
<script type="text/javascript">
function addCar ()
{
$("#cars").append
(
$("<option>", { response: "Ford", text: "Ford" })
);
}
$("#cars").on
(
"click",
addCar
);
</script>
</body>
Every time you open and close the select element with the ID of #editOwner your appending a new option to the select element. You can easily fix this by adding:
$("#editOwner").unbind();
Like this:
<body>
<select id="cars" style="display: block">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<script type="text/javascript" src="jquery-3.4.1.min.js"></script>
<script type="text/javascript">
function addCar ()
{
$("#cars").append
(
$("<option>", { response: "Ford", text: "Ford" })
);
// Add this to remove the onclick events for #cars so it will only run one time.
$("#cars").unbind();
}
$("#cars").on
(
"click",
addCar
);
</script>
</body>
Or better yet you could only have the function run one time by not calling it with a onclick event at all like this:
<body>
<select id="cars" style="display: block">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<script type="text/javascript" src="jquery-3.4.1.min.js"></script>
<script type="text/javascript">
function addCar ()
{
$("#cars").append
(
$("<option>", { response: "Ford", text: "Ford" })
);
}
</script>
<script type="text/javascript">
addCar();
</script>
</body>
Unless there is a reason you need to call your ajax with a onclick event you really shouldn't, but if you need to you should call $("#editOwner").unbind(); at the end of editOwner(id); like this:
Edit: Saw that you were calling editOwner(id) with a span that had a onclick event. Just add an ID to that and call $("#mySpan").prop("onclick", null).off("click");
<span id="#mySpan" onclick='editOwner(""+value3.l3_id+"")'></span>
function editOwner(id){
activity_id = id;
$.ajax ({
url: '/all_user',
crossDomain: true,
type: "POST",
dataType : 'json',
cache: false,
processData: true,
data: 'data',
success: function(response){
for (var i = 0; i < response.data.length; i++) {
$("#editOwner").append($("<option>", {
response: response.data[i].fullname,
text: response.data[i].fullname
}));
}
}
});
$.ajax({
url : '/activity',
crossDomain: true,
type: "POST",
dataType : 'json',
cache: false,
processData: true,
data: {task_id: activity_id}},
success: function(response){
if (response.status == "Success"){
$("#editOwner").val(response.data[0]["task_owner"]).attr("readonly",false);
$(response.data).each(function(key,value){
var owners = value.task_owner.split(',');
$(owners).each(function(k,v){
$("#editOwner").append($("<option selected>", {
response: v,
text: v
}));
});
$("#editOwner").val(owners).trigger("change");
});
}
else {}
},
error: function(e){}
});
$('#editOwnerModal').modal('show');
// Try adding this.
//$("#editOwner").unbind();
// Or this if you want to use onclick as an attribute.
$("#mySpan").prop("onclick", null).off("click");
}

Related

When sending multi select value jquery/ajax data is incorrect?

I have multi select drop down menu. When user selects values jquery/ajax request should be sent to the server. Here is example of my code:
$("#send").on("click", function() {
var elem$ = $("#cars"),
elemVal = elem$.val();
console.log(elemVal);
if (elemVal) {
$.ajax({
type: 'POST',
url: 'requestTest.html?fn=saveCar',
data: {'cars': elemVal},
dataType: 'json'
}).done(function(obj) {
console.log(obj);
}).fail(function(jqXHR, textStatus, errorThrown) {
alert("An error has occured.");
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="cars" id="cars" multiple>
<option value="">--Select Car--</option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button type="button" name="send" id="send">Send</button>
The code ajax call returned an error. It was telling me that cars element is required in my function but it's not passed in. I checked my developer tools and here is what I found under Params:
{"cars[]":["volvo","saab"]}
It looks that data is not structured properly. I'm wondering what is causing cars to get an array in front? What is the best way to fix this issue? Thank you.
With this code is going to work better:
<script type="text/javascript">
$("#send").on("click", function() {
var elem$ = $("#cars").val();
//elemVal = elem$.val();
console.log(elem$);
if (elem$) {
$.ajax({
type: 'POST',
url: 'requestTest.html?fn=saveCar',
data: {'cars': elem$},
dataType: 'json'
}).done(function(obj) {
console.log(obj);
}).fail(function(jqXHR, textStatus, errorThrown) {
alert("An error has occured.");
});
}
});
</script>
This give you an array, this array you can manage it from php:
Image of my console with this code

select2 set option attributes manually for each option

i have select2 dropdown like:
<select class="form-control validateblank txtSelectChallan" id="txtSelectChallan" />
and i am setting dropdown data by ajax call like:
$.ajax({
type: "POST",
url: "/Account/MaterialSheet.aspx/GetMaterialSheetByLedgerId",
data: '{LedgerId: "' + AccId + '"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.d.Result == "OK") {
var challanresults = [];
$.each(data.d.Records, function (index, challn) {
challanresults.push({
id: challn.MaterialSheet_ID,
text: challn.Challan_No,
Amount: challn.Total_Amount
});
});
eachtr.find('.txtSelectChallan').select2({
placeholder: "Select Challan",
data: challanresults,
multiple: true
});
swal.close();
challanresults = null;
}
},
error: function (err) {
swal(
'Oops...',
'Error occured while retrieving data',
'error'
);
}
});
and i get dropdown like :
<select class="form-control validateblank txtSelectChallan select2 hidden-accessible" id="txtSelectChallan" tabindex="-1" aria-hidden="true" multiple="">
<option value="1006">123123</option>
<option value="1007">32123</option>
i have tried to set option attribute using:
challanresults.push({
id: challn.MaterialSheet_ID,
text: challn.Challan_No,
Amount: challn.Total_Amount
});
but i cant get amout as option attribute any idea how to set custom attribute for all option in select2?
Try like this inside foreach loop, and set the trigger after that.
var data = {
id: challn.MaterialSheet_ID,
text: challn.Challan_No
};
var newOption = new Option(data.text, data.id, false, false);
$('#txtSelectChallan').append(newOption).trigger('change');
Check this link for further solution on custom attributes
Or Simply you can do like this in a loop for the result set
var option = "<option value="+challn.MaterialSheet_ID+" amount="+challn.Total_Amount+">"+challn.Challan_No+"</option>
This is what Select2 Official Site has to say about custom-data-fields
$('#mySelect2').select2({
// ...
templateSelection: function (data, container) {
// Add custom attributes to the <option> tag for the selected option
$(data.element).attr('data-custom-attribute', data.customValue);
return data.text;
}
});
// Retrieve custom attribute value of the first selected element
$('#mySelect2').find(':selected').data('custom-attribute');
Click here for the above reference link

Append selected after ajax call

I have a Select 2 drop down search function. I am trying to load the results from an ajax call as the selected/default values. I am not sure where I am going wrong? What is the syntax I need to change here so that when I click my modal it shows results preset.
$(document).ready(function() {
$('.editApptModal-button').click(function() {
var appointmentID = $(this).attr('data-appointmentID');
$('#editApptModal').find('input[name="appointmentID"]').val(appointmentID);
$.ajax({
type: 'ajax',
method: 'get',
url: '/ajax',
async: false,
dataType: 'json',
success: function(response) {
console.log(JSON.stringify(response));
$.each(response.employees.data, function(key, value) {
$('select').append($("<option selected></option>",
//<HERE Selected is not working.
//If I remove selected results load in dropdown
{
value: value.id,
text: value.name
}));
});
$('#editApptModal').modal('show');
},
error: function(response) {
alert('Could not displaying data' + response);
}
});
$('#editApptModal').modal('show');
});
});
<select multiple="multiple" name="employees[]" id="form-field-select-4" class="form-control search-select">
<option selected value=""></option>
First you should try to append only once because it's an heavy operation.
And by setting attributes directly seems to work here.
var datas = [
{value: 'toto', text: 'Toto'},
{value: 'titi', text: 'Titi'}
];
var options = '';
$.each(datas, function(key, value) {
options += '<option selected>'+value.text+'</option>';
});
$('#select').append(options);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select multiple id="select"></select>
You have to issue the refresh command after you are done. Here a quick snippet of it working doing the same thing for one of my projects. TransportRecord_TransportCarrierID is the ID for my select element.
$('#TransportRecord_TransportCarrierID').empty();
$.each(jsonResponse, function (key, item) {
var option = $('<option selected>').text(item.Text).val(item.Value);
$('#TransportRecord_TransportCarrierID').append(option);
});
$('#TransportRecord_TransportCarrierID').selectpicker('refresh');
Html
<select class="form-control selectpicker" data-live-search="true" data-style="btn-defaultWhite" multiple="multiple" id="TransportRecord_TransportCarrierID" name="TransportRecord.TransportCarrierID">//your initial options</select>

How to get value to the controller from view

I am struggling hard to get value to my controller. Please can some one suggest a way to get value to controller from view. Application is in .Net3.5 and MVC 2 for .Net3.5
The view with jquery and controller is:
The jquery and the html is:
<tr>
<td style ="width: 313px">
<label for="Product Code"> Product
Code
</label>
<select id ="prodList" style = "width:150px">
<option value ="GL ">GL </option>
<option value ="Property" selected="selected">Property </option>
<option value ="Package" >Package </option>
<option value ="Island" >Island </option>
</select>
</td>
<td style="width: 313px"><input type ="button" id="addProd" value ="Add Product" /></td>
</tr>
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script src="/Scripts/jquery-1.4.1.min-vsdoc.js" type="text/javascript"></script>
<script src="/Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$("#addProd").click(function() {
//alert("here");
var selectedID = $("#prodList").val();
alert("me 1" + selectedID);
$.ajax({
url: "/WorkFlowTest/ProductSubmission/",
type: 'POST',
data: { productID: $("#prodList").val() },
contentType: 'application/json; charset=utf-8',
success: function(data) {
//alert(data.success);
alert("success");
},
error: function() {
alert("error");
}
});
});
});
</script>
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ProductSubmission(string productID, ViewModels.WorkFlowTestViewModel SubmissionModelView)
{
SubmissionModelView.selectedProd = prodSelected ;
return View("Submission", SubmissionModelView);
}
In the jquery function the alert has the selected value, but
for the SubmissionModelView has all properties null and the productId is null too.
Though in browser console I get Source {"productId":"Property"} , but I can not understand why my post does not get any value in the Action ProductSubmission.
Can any one help , I just need the controller to get the selected option value on Post or even a text value on Post. I am not able to get any value from view to controller and my model has also all properties null in POST. Please help
You should convert the object to JSON string by using the JSON.stringify function.
$.ajax({
url: "/WorkFlowTest/ProductSubmission/",
type: 'POST',
data: JSON.stringify({ productID: $("#prodList").val() }),
contentType: 'application/json; charset=utf-8',
success: function(data) {
//alert(data.success);
alert("success");
},
error: function() {
alert("error");
}
});

AJAX - After success clean input value and set dropdown to selected

I have a page with a dropdown list and a input with type="text".
I'm trying to filter the results of my table via AJAX when I select an option in my dropdown list.
It should clean the value of the input when the option is selected (after the success).
It's working fine.
The problem is that I need it to for my input. It should send the value of the input to AJAX and then filter the results when I submit the form.
I can't put it to work after the suceess. It sets the dropdown list to "selected". I don't know why.
HTML code:
<form action="#Url.Action("a","b")" id="filter-date" onsubmit="javascript:return false">
<label for="from" class="label-datepicker">from:</label>
<input type="text" id="from" name="from" class="dateinput">
<label for="to" class="label-datepicker">to:</label>
<input type="text" id="to" name="to" class="dateinput">
<button type="submit" name="submit" id="submit-date">
OK
</button>
</form>
<select name="Assunto" id="select-a">
<option value="" selected="selected">--Select--</option>
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</select>
JavaScript code:
$("#select-a").change(function () {
var selected = $("#select-a").val();
var Keyword = { data: $("#select-a").val() };
$.ajax({
cache: false,
type: 'GET',
async: false,
url: '#(Url.Action("bo", "b"))',
data: { Keyword: selected },
dataType: 'html',
success: function (data) {
$(".dateinput").val('');
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.responseText);
}
});
});
$("#filter-date").submit(function () {
var from = $("#from").val();
var to = $("#to").val();
$.ajax({
cache: false,
type: 'GET',
async: false,
url: '#(Url.Action("update", "b"))',
data: { From: from, To: to },
dataType: 'html',
success: function (data) {
$("#bodylist").html(data);
$("#select-a").val(selected);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.responseText);
}
});
});
Try this
As #Anto rightly said
var selected = $("#select-a").val();
scope of this above statement should be in form-submit also
$("#select-a option[selected]").removeAttr("selected");
$("#select-a option[value=" + selected+ "]").attr('selected', 'selected');
Try:
$("#filter-date").submit(function () {
var from = $("#from").val();
var to = $("#to").val();
$.ajax({
cache: false,
type: 'GET',
async: false,
url: '#(Url.Action("update", "b"))',
data: { From: from, To: to },
dataType: 'html',
success: function (data) {
$("#bodylist").html(data);
// $("#select-a").val(selected); //should remove this line because we use ajax, the page is not refreshed, not need to restore the state.
//or $("#select-a").val(""); if you need to reset
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.responseText);
}
});
return false; //return false at the end to prevent form submitting
});
And remove onsubmit="javascript:return false". And should not use - in id attribute.
i have found a solution.. and its solved now.
its more easier if i thought.
the ajax call on .submit doesn´t allow me to do something after success like what i need..
this i don´t know it.
what i have done is to set the value of the option from my dropdownlist to selected before the ajax section.
and the magic is done..
its working now.
this is my new code:
$("#filter-date").submit(function () {
var from = $("#from").val();
var to = $("#to").val();
$('#select-a').val('selected');
$.ajax({
cache: false,
type: 'GET',
async: false,
url: '#(Url.Action("update", "b"))',
data: { From: from, To: to },
dataType: 'html',
success: function (data) {
$("#bodylist").html(data);
$("#select-a").val(selected);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.responseText);
}
});
Try use jQuery function .data(name, value) to store selected value like this:
$('#select-a').data('selectedValue', $('#select-a').val());
Then in submit handler get it:
var selected = $('#select-a').data('selectedValue');
And use #Nitin's code to set selected option:
$("#select-a option[selected]").removeAttr("selected");
$("#select-a option[value=" + selected+ "]").attr('selected', 'selected');
Just make selected global:
(function(){
var selected;
$("#select-a").change(function () {
selected = $("#select-a").val();
// rest of your script
})(); // close the wrapper
EDIT: Wrapping it up in a self-executing anonymous function will keep the global namespace clean (thanks to #jameslafferty).

Categories