I have a radio button list (rblCategories) and when selected value is changed I create a checkbox list using ajax and populate it. I need to update my datatable when any checkbox is checked/unchecked but I can't get it to respond to to change in state.
This is what i have and what I have tried (I removed all unnecessary stuff like styling, etc.)
<div class="row">
<div class="col-sm-2">
<label for="ddlYear">Select Year</label>
<asp:DropDownList runat="server" ID="ddlYear" ClientIDMode="Static">
</asp:DropDownList>
</div>
<div class="col-sm-4">
<label for="rblCategories">Categories</label>
<asp:RadioButtonList runat="server"
ID="rblCategories"
ClientIDMode="Static"
DataTextField="Name"
DataValueField="TypeID"
AppendDataBoundItems="true">
</asp:RadioButtonList>
</div>
<div class="col-sm-6" id="divSubCategory">
</div>
</div>
//Using the selected values of ddlYear and rblCategories, populate table
function bindDataTable() {
var year = $('#ddlYear').val();
var selCategoryID = $('#rblCategories input:checked').val()
var url = "";
var params = "";
// -1 refers to "All" categories
if ('-1' == selCategoryID) {
url = "../services/exp.asmx/GetExpenseByYear";
params = JSON.stringify({ "Year": year });
}
else {
url = "../services/exp.asmx/GetExpenseByYearByCategory";
params = JSON.stringify({ "Year": year, "CategoryID": selCategoryID });
}
populteTable(url, params, tblExpenses);
}
//for testing
function bindDataTable(subCategories) {debugger
}
// create and populate sub-category checkbox list based on selected category
function updateSubTypes(typeID) {
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: '<%=ResolveUrl("~/services/exp.asmx/GetExpenseSubTypeItems") %>',
cache: false,
data: "{ 'TypeID': '" + typeID + "' }",
success: AjaxSucceeded,
error: AjaxFailed
});
}
function AjaxFailed(result) {
alert('Failed to load checkbox list');
}
function AjaxSucceeded(result) {
BindCheckBoxList(result);
}
function BindCheckBoxList(result) {
$('#divSubCategory').empty();
var items = JSON.parse(result.d);
if (items.length > 0)
CreateCheckBoxList(items);
}
function CreateCheckBoxList(checkboxlistItems) {
var lbl = $('<label></label>').text('Sub-Categories');
$('#divSubCategory').append(lbl);
var table = $('<table></table>').attr({ id: 'cblSubCategory', class: 'form-control' });
var row = table.append($('<tr></tr>'));
var counter = 0;
$(checkboxlistItems).each(function (i) {
row.append($('<td></td>').append($('<input>').attr({
type: 'checkbox', name: 'chklistitem', value: this.ExpenseSubTypeID, id: 'chklistitem' + counter
})).append(
$('<label>').attr({
for: 'chklistitem' + counter++
}).text(this.Name)));
});
$('#divSubCategory').append(table);
}
$(document).ready(function () {
$('#rblCategories input').change(function () {
var selCategoryID = $(this).val();
if (selCategoryID != null) {
updateSubTypes(selCategoryID)
}
bindDataTable();
});
// This never gets hit; I tried chklistitem instead of cblSubCategory too
$('#cblSubCategory input').change(function () {debugger
var selCategoryID = $('#rblCategories input:checked').val()
var names = $('.parent input:checked').map(function () {
return this.name;
}).get();
bindDataTable(names);
});
})
$('#cblSubCategory input').change(function () {
TO
$('#cblSubCategory').on('change','input', function () {
Use jQuerys .on() method when loading elements dynamically, which will look for any new elements added to the DOM that match that selector. Otherwise jQuery will only parse the DOM once on initial execution.
$(document).ready(function () {
$('#rblCategories').on('change','input', (function () {
var selCategoryID = $(this).val();
if (selCategoryID != null) {
updateSubTypes(selCategoryID)
}
bindDataTable();
});
// This never gets hit; I tried chklistitem instead of cblSubCategory too
$('#cblSubCategory').on('change','input', function () {debugger
var selCategoryID = $('#rblCategories input:checked').val()
var names = $('.parent input:checked').map(function () {
return this.name;
}).get();
bindDataTable(names);
});
})
The following changes fixed the issue; However, I marked cantucket's reply as answer cause he put me in the right direction.
I added an attr line to "createCheckBoxList" function; right after I append the resulting table to div:
function createCheckBoxList(checkboxlistItems) {
var lbl = $('<label></label>').text('Sub-Categories');
$('#divSubCategory').append(lbl);
var table = $('<table></table>').attr({ id: 'cblSubCategory', class: 'form-control' });
var row = table.append($('<tr></tr>'));
var counter = 0;
$(checkboxlistItems).each(function (i) {
row.append($('<td></td>').append($('<input>').attr({
type: 'checkbox', name: 'cblSubCategory', value: this.ExpenseSubTypeID, id: 'cblSubCategory' + counter
})).append(
$('<label>').attr({
for: 'cblSubCategory' + counter++
}).text(this.Name)));
});
$('#divSubCategory').append(table);
// added this line
$('#divSubCategory').attr({ onclick: "onSubCatChange()" });
}
I added "onSubCatChange()" function:
function onSubCatChange() {
// Both following methods work to get list o checked items
var names = [];
$('#cblSubCategory input:checked').each(function() {
names.push(this.value);
});
var names2 = $('#cblSubCategory input:checked').map(function () {
return this.value;
}).get();
bindDataTable(names);
}
And I removed the checkbox list's on change handler in document.ready() function.
Related
I'm working on a ASP .Net Core project where for the first time I'm using Select2.
I have one page where I'm passing the ID's that I need by ViewModel like this:
Controller:
public async Task<IActionResult> MyPage()
{
var model = new MyViewModel()
{
selectedUSerId = 1,
selectedEmployeeId =1
};
return View(model);
}
View:
#model MyViewModel
<select class="form-select" id="User" name="User" data-url="#Url.Action("MyUserAction","MyUserController")" data-placeholder="#Localizer["SelectUser"].Value">
<option></option>
</select>
<select class="form-select" id="Employee" name="Employee" data-url="#Url.Action("MyEmployee","MyEmployeeController")" data-placeholder="#Localizer["SelectUser"].Value">
<option></option>
</select>
#section Scripts{
<script type="text/javascript">
var userId = "#Model.selectedUSerId";
var emplyeeId = "#Model.selectedEmployeeId";
$(document).ready(function () {
$('select').each(function () {
InitSelect2(this.id);
});
if(userId){
$('#User').val(userId).trigger('change');
}
if(emplyeeId){
$('#User').val(emplyeeId).trigger('change');
}
});
function InitSelect2(selector, selectedId = 0) {
var url = $("#" + selector).data('url');
var placeholder = $("#" + selector).data('placeholder');
const type = "POST";
const dataType = "json";
if (!url) {
console.error("Selector: " + selector + " Unspecified URL");
return;
}
if (placeholder === "") {
console.error("Selector: " + selector + " Unspecified Placeholder");
return;
}
try {
$("#" + selector).select2({
theme: "bootstrap-5",
width: $(this).data('width') ? $(this).data('width') : $(this).hasClass('w-100') ? '100%' : 'style',
placeholder: placeholder,
allowClear: true,
minimumInputLength: 3,
ajax: {
url: url,
type: type,
dataType: dataType,
delay: 250,
data: function (params) {
var query = {
id: selectedId,
searchFullName: params.term,
}
return query;
},
processResults: function (data) {
console.log(data)
return {
results: data.results
};
},
}
})
} catch (ex) {
console.error(ex);
}
}
</script>
}
So far it works perfectly.
But when I try to do:
$('#User').val(userId).trigger('change'); or
$('#Employee').val(emplyeeId ).trigger('change');
nothing happened.
I think its gonna work only when I retrieve the data the first time when I click the drop donw list, instead of doing it every time when it is clicked.
In that way I will have the <option>s and I can use the jQuery to select the <option> by Id.
I don't like to follow this approach, becouse the data should be load and setted dynamically. Theres no another way to do it?
If you want to do something only when first time the selected value is changed,you can try to use a js variable,change the value of it when first time the selected value is changed.Here is a sample,only when first time the selected value is changed,alert(1) will be called.
var UserCount = 0;
var EmplyeeCount = 0;
$('#User').change(function() {
if (UserCount == 0) {
UserCount++;
alert(1);
}
});
$('#Employee').change(function() {
if (EmplyeeCount == 0) {
EmplyeeCount++;
alert(1);
}
});
I have written a code in Javascript in which I have attached an input type submit to a form. On form submit the listener gets called.
The problem is that on when I click the button once, one ajax call occurs. When I click it again two calls occur while only one call should occur on each click. Similarly on clicking 3 times 3 calls occur and so on...(the calls get increasing). If I refresh the page then the number gets reset. I have tried everything but I had no luck. If anyone found out what is wrong here it would be awesome. Thanks in advance.
javascript code:
$('input.create-discounts-quotations').click(function () {
var discount_quotation_type = $('input.quotation-discount-type').val();
if (discount_quotation_type == "value") {
var total = $('input.discount-input-quotation').val();
var discounted_price = product_price - total;
$('#final_discounted_amount').val(discounted_price);
$("table.product-response-table tr").each(function () {
var row = $(this).index() + 1;
var td = $(this).find('td.quotation-response-discounts');
$(td).each(function () {
$(this).html(total);
});
});
$("table.product-response-table tr").each(function () {
var row = $(this).index() + 1;
var td = $(this).find('td.product_final_price_discounted');
$(td).each(function () {
$(this).html(discounted_price);
});
});
var form1 = $('form#quotation_discount_update_form');
form1.on("submit", function (e) {
var form_data1 = form1.serialize();
$.ajax({
type: 'POST',
url: form1.attr('action'),
data: form_data1,
dataType: "json",
success: function (data) {
$('.quotation-discount-status-update').empty();
$('.quotation-discount-status-update').append('<div class="alert alert-success">Discount Added</div>');
}
});
e.preventDefault();
});
}
if (discount_quotation_type == "percentage") {
var total = $('input.discount-input-quotation').val();
var temp_first = product_price;
var temp1 = total / 100;
var temp2 = temp1 * product_price;
var discounted_price = product_price - temp2;
$('#final_discounted_amount').val(discounted_price);
$("table.product-response-table tr").each(function () {
var row = $(this).index() + 1;
var td = $(this).find('td.quotation-response-discounts');
$(td).each(function () {
$(this).html(total);
});
});
$("table.product-response-table tr").each(function () {
var row = $(this).index() + 1;
var td = $(this).find('td.product_final_price_discounted');
$(td).each(function () {
$(this).html(discounted_price);
});
});
var form1 = $('form#quotation_discount_update_form');
form1.on("submit", function (e) {
var form_data1 = form1.serialize();
$.ajax({
type: 'POST',
url: form1.attr('action'),
data: form_data1,
dataType: "json",
success: function (data) {
$('.quotation-discount-status-update').empty();
$('.quotation-discount-status-update').append('<div class="alert alert-success">Discount Added</div>');
}
});
e.preventDefault();
});
}
if (discount_quotation_type == "not_selected") {
$('.quotation-discount-status-update').empty();
$('.quotation-discount-status-update').append('<div class="alert alert-danger">Discount Method Not Selected</div>');
return false;
}
// return false;
});
That happen because every time you click your code will reattach the submit event so it will be duplicated in every click.
You should never attach the events inside other events, please put the submit event outside of the click event and the code should work, example :
var form1 = $('form#quotation_discount_update_form');
form1.on("submit", function (e) {
var form_data1 = form1.serialize();
$.ajax({
type: 'POST',
url: form1.attr('action'),
data: form_data1,
dataType: "json",
success: function (data) {
$('.quotation-discount-status-update').empty();
$('.quotation-discount-status-update').append('<div class="alert alert-success">Discount Added</div>');
}
});
e.preventDefault();
});
Else you have to remove the event handler every time using .off(), like :
form1.off("submit").on("submit", function (e) {
I am still learning jQuery/json and am struggling to figure out how to include optgroups when building my DropDownList via jQuery using json data.
Here is an example of the json data:
0:
Disabled: false
Group:
Disabled: false
Name: "Property Overview"
Selected: false
Text: "Number of Floors"
Value: "277"
Currently, I am able to populate the DropDownList with the Text and Value. That is fairly straight forward. Here is my code for that:
$(document).ready(function () {
$("#PropertyList").on('change', function () {
$("#Options_Question").empty();
var id = $("#PropertyList").val();
var url = '#Url.Action("GetPropertyTypeSpecificQuestions", "Report", new { id = "replaceToken" })';
url = url.replace("replaceToken", id);
$.getJSON(url, null, function (data) {
$("#Options_Question").addQuestions(data);
});
});
$.fn.addQuestions = function (data) {
return this.each(function () {
var list = this;
$.each(data, function (index, questionData) {
var option = new Option(questionData.Text, questionData.Value);
list.add(option);
});
});
}
});
How can I edit my jQuery to include the values from Group.Name and group the questions into their respective optgroups?
I was able to get this working using information found in various places around stackoverflow. Here is the working jQuery:
$(document).ready(function () {
$("#PropertyList").on('change', function () {
$("#Options_Question").empty();
var id = $("#PropertyList").val();
var url = '#Url.Action("GetPropertyTypeSpecificQuestions", "Report", new { id = "replaceToken" })';
url = url.replace("replaceToken", id);
$.getJSON(url, null, function (data) {
$("#Options_Question").addQuestions(data);
});
});
$.fn.addQuestions = function (data) {
var prevGroup, prevGroupName;
$.each(data, function () {
if (this.Group.Name == null) {
$("<option />").val(this.Value).text(this.Text).appendTo("#Options_Question");
}
else if (prevGroupName != this.Group.Name) {
prevGroup = $('<optgroup />').prop('label', this.Group.Name).appendTo('#Options_Question');
}
$("<option />").val(this.Value).text(this.Text).appendTo(prevGroup);
prevGroupName = this.Group.Name;
});
}
});
i made a function that sends data (ajax) to the database and depending on the response from the server i need to alert a message but it seems like whenvever i change the select option i get the alert message for each change(if i change the select four times when i click i get the alert four times ) , but if i remove my ajax function and replace it simply by an alert i get it once not repeating itself here is my JS
$('.select_ids').change(function () {
var id = $(this).val();
var form = $('#form_widget_ids_' + id);
var container = form.parent('.ewb_forms');
var box = container.parent('.edit_widget_box');
container.children('.selected').fadeOut(300, function () {
$(this).removeClass('selected');
form.fadeIn(300, function () {
$(this).addClass('selected');
});
});
Widget.updateSSOUrl(box);
$.ajax({
type: "POST",
url: window.location + "",
data: {'id': id}
}).done(function (msg) {
$(".red").on('click', function (evt) {
if ('done' == msg) {
evt.preventDefault();
alert('NOP');
}
})
});
});
the event that you are binding i think is wrong. For newly append items is better in your case to use
$(document).on('click', ".red", function (evt) {
})
And it must be moved outside the ajax success because now you are triggering it every time
----- Edited ---
If you want just to alert the output of the ajax you dont need the onClick event
$('.select_ids').change(function () {
var id = $(this).val();
var form = $('#form_widget_ids_' + id);
var container = form.parent('.ewb_forms');
var box = container.parent('.edit_widget_box');
container.children('.selected').fadeOut(300, function () {
$(this).removeClass('selected');
form.fadeIn(300, function () {
$(this).addClass('selected');
});
});
Widget.updateSSOUrl(box);
$.ajax({
type: "POST",
url: window.location + "",
data: {'id': id}
}).done(function (msg) {
if (msg === 'done') {
evt.preventDefault();
alert('NOP');
}
});
});
If you want to show the latest result on a button click you can store the msg on a global variable and on click of a div show that like
var globalMsg = "";
$('.select_ids').change(function () {
var id = $(this).val();
var form = $('#form_widget_ids_' + id);
var container = form.parent('.ewb_forms');
var box = container.parent('.edit_widget_box');
container.children('.selected').fadeOut(300, function () {
$(this).removeClass('selected');
form.fadeIn(300, function () {
$(this).addClass('selected');
});
});
Widget.updateSSOUrl(box);
$.ajax({
type: "POST",
url: window.location + "",
data: {'id': id}
}).done(function (msg) {
globalMsg = msg
});
});
$(".div").click(function() { alert(globalMSG); });
I want to update textbox's value(that contains cookie's value) using Ajax in asp.net MVC5 . I'm very new in JavaScript and I wrote these codes , but my code didn't work . I didn't get any error but it's not working. I wrote JavaScript in foreign file 'UpdateTxtBox.js' and I added <script src="~/Scripts/UpdateTxtBox.js"></script> to Layout .
Could anyone tell me what's the problem ?
$(function () {
$("textCountProduct").change(function () {
var count = $(this).val();
var id = $(this).attr("productid");
$.ajax({
url: "/Goods/AddToCart",
data: { Id: id, Count: count },
type: "Post",
dataType: "Json",
success: function (result) {
if (result.Success) {
alert(result.Html);
$("#CartItems").html(result.Html);
}
eval(result.Script);
},
error: function () {
alert("error....");
}
});
});
});
a part of Basket.cshtml
#using (Html.BeginForm("AddToCart", "Goods", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.TextBoxFor(modelItem => item.Count, new { #class="text textCountProduct" , style="width:40px;" , productid=item.GoodDetails.DetailsGoodID})
}
Good controller
public ActionResult AddToCart (int Id , int Count)
{
try
{
if (Request.Cookies.AllKeys.Contains("NishtmanCart_" + Id.ToString()))
{
//Edit cookie
var cookie = new HttpCookie("NishtmanCart_" + Id.ToString(), (Convert.ToInt32(Request.Cookies["NishtmanCart_" + Id.ToString()].Value) + 1).ToString());
cookie.Expires = DateTime.Now.AddMonths(1);
cookie.HttpOnly = true;
Response.Cookies.Set(cookie);
}
else
{
//Add new cookie
var cookie = new HttpCookie("NishtmanCart_" + Id.ToString(), Count.ToString());
cookie.Expires = DateTime.Now.AddMonths(1);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
}
List<HttpCookie> lst = new List<HttpCookie>();
for (int i = 0; i < Request.Cookies.Count; i++ )
{
lst.Add(Request.Cookies[i]);
}
bool isGet = Request.HttpMethod == "GET";
int CartCount = lst.Where(p => p.Name.StartsWith("NishtmanCart_") && p.HttpOnly != isGet).Count();
return Json(new MyJsonData()
{
Success = true,
Script = MessageBox.Show("Good added successfully", MessageType.Success).Script,
//Script = "alert('Good added successfully');",
Html = "cart items (" + CartCount.ToString() + ")"
}
);
}
Update post :
I added [HttpPost] to controller action result and add some alert to javascript
$(function () {
alert("aleeeert");
$(".textCountProduct").change(function () {
var count = $(this).val();
var id = $(this).attr("productid");
alert(count);
alert(id);
$.ajax({
url: "/Goods/AddToCart",
data: { Id: id, Count: count },
type: "Post",
dataType: "Json",
success: function (result) {
if (result.Success) {
alert(result.Html);
$("#CartItems").html(result.Html);
}
eval(result.Script);
},
error: function () {
alert("error....");
}
});
});
});
it's working fine but when I refresh page , data didn't saved
Since you have specified textCountProduct as CSS class, you need to prefix it with . to use Class Selector (“.class”), As of now its looking for Element textCountProduct which obviously doesn't exists.
Use
$(".textCountProduct").change(
You have made mistake here $("textCountProduct") use . as selector.
It should be $(".textCountProduct")
and
Check path of your script included
<script src="~/Scripts/UpdateTxtBox.js"></script>