search in JSON with AJAX - javascript

I have to search inside a json file with a value from my input, everything is fine capturing the value and the event, but when I iterate something unexpected happens for me.
How can I select an object based on this search?.
the problem is that when doing .each it goes through all the records, even those not found.
$( document ).on('turbolinks:load', common_events)
function common_events(){
$('.rut-input').on('change', function(event){
$rut = $(this).val();
var searchField = $rut;
var expression = new RegExp(searchField, "i");
event.preventDefault();
$.ajax({
type: "GET",
url: '/companies/',
dataType: 'JSON',
success: function(companies){
$.each(companies, function(i, company) {
if (company.rut.search(expression) > -1){
console.log(company.id);
$('.name-input').empty();
$('.name-input').val(company.name);
$('.name-input').addClass('disabled-input');
$('.form-group').removeClass('hide');
console.log(company.address);
if (company.address == null ){
$('.address-input').removeClass('disabled-input');
};
}
else {
console.log('no encuentra');
console.log(company);
$('.form-group').removeClass('hide');
$('.form-control').removeClass('disabled-input');
};
});
},
error: function(companies){
console.log('A ocurrido un error')
},
});
});
}
when executing the event, both the if and else are executed at the same time.

Seems like you don't really want to iterate the companies array with each. You want to find a matching company, and then do something with that record.
success: function(companies){
const company = companies.find(c => c.rut.search(expression) > -1);
if (company) {
console.log(company.id);
$('.name-input').empty();
$('.name-input').val(company.name);
$('.name-input').addClass('disabled-input');
$('.form-group').removeClass('hide');
console.log(company.address);
if (company.address == null ){
$('.address-input').removeClass('disabled-input');
}
} else {
console.log('no encuentra');
console.log(company);
$('.form-group').removeClass('hide');
$('.form-control').removeClass('disabled-input');
}
},

Related

How can I call my validate function before sending my ajax when a button is clicked?

Hello everyone I have a table that's dynamically generated from database.
This is the table.
I have all the code that works fine,but I only need proper timing of execution
1) Check if all mandatory fields are populated on button click, if not don't send ajax.
2) When all mandatory fields are populated on button click then call ajax and send proper values to c# and later to database.
First I need to check if all mandatory fields are filled in(check Mandatory column(yes or no values):
$(function () {
$("#myButton").on("click", function () {
// Loop all span elements with target class
$(".IDMandatory").each(function (i, el) {
// Skip spans which text is actually a number
if (!isNaN($(el).text())) {
return;
}
// Get the value
var val = $(el).text().toUpperCase();
var isRequired = (val === "TRUE") ? true :
(val === "FALSE") ? false : undefined;
// Mark the textbox with required attribute
if (isRequired) {
// Find the form element
var target = $(el).parents("tr").find("input,select");
if (target.val()) {
return;
}
// Mark it with required attribute
target.prop("required", true);
// Just some styling
target.css("border", "1px solid red");
}
});
})
});
If not don't call ajax and send values. If all fields are populated then call ajax to send values to c#.
This is the ajax code that takes values from filed and table and send's it to c# WebMethod and later to database.
$(function () {
$('#myButton').on('click', function () {
var ddl = $('#MainContent_ddlBusinessCenter').val()
var myCollection = [];
$('#MainContent_gvKarakteristike tbody').find('tr:gt(0)').each(function (i, e) {
var row = $(e);
myCollection.push({
label: valuefromType(row.find(row.find('td:eq(1)').children())),
opis: valuefromType(row.find(row.find('td:eq(3)').children()))
});
});
console.log(myCollection);
function valuefromType(control) {
var type = $(control).prop('nodeName').toLowerCase();
switch (type) {
case "input":
return $(control).val();
case "span":
return $(control).text();
case "select":
('Selected text:' + $('option:selected', control).text());
return $('option:selected', control).text();
}
}
var lvl = $('#MainContent_txtProductConstruction').val()
if (lvl.length > 0) {
$.ajax({
type: "POST",
url: "NewProductConstruction.aspx/GetCollection",
data: JSON.stringify({ 'omyCollection': myCollection, 'lvl': lvl, 'ddl': ddl }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (parseInt(response.d) > 0)
alert("Saved successfully.");
else
alert("This object already exists in the database!");
console.log(response);
location.reload(true);
},
error: function (response) {
alert("Not Saved!");
console.log(response);
location.reload(true);
}
});
}
else {
alert("Please fill in the Product Construction field!")
}
});
});
I need code to execute first mandatory fields and when they are all filled in then call ajax part of the code!
Can anyone please help !
If you need more explanation just ask !
Thanks in advance !
Update Liam helped allot me but ajax is not working on button click.
function validate() {
// Loop all span elements with target class
$(".IDMandatory").each(function (i, el) {
// Skip spans which text is actually a number
if (!isNaN($(el).text())) {
return;
}
// Get the value
var val = $(el).text().toUpperCase();
var isRequired = (val === "TRUE") ? true :
(val === "FALSE") ? false : undefined;
// Mark the textbox with required attribute
if (isRequired) {
// Find the form element
var target = $(el).parents("tr").find("input,select");
if (target.val()) {
return;
}
// Mark it with required attribute
target.prop("required", true);
// Just some styling
target.css("border", "1px solid red");
}
});
}
function sendAjax() {
var ddl = $('#MainContent_ddlBusinessCenter').val()
var myCollection = [];
$('#MainContent_gvKarakteristike tbody').find('tr:gt(0)').each(function (i, e) {
var row = $(e);
myCollection.push({
label: valuefromType(row.find(row.find('td:eq(1)').children())),
opis: valuefromType(row.find(row.find('td:eq(3)').children()))
});
});
console.log(myCollection);
function valuefromType(control) {
var type = $(control).prop('nodeName').toLowerCase();
switch (type) {
case "input":
return $(control).val();
case "span":
return $(control).text();
case "select":
('Selected text:' + $('option:selected', control).text());
return $('option:selected', control).text();
}
}
var lvl = $('#MainContent_txtProductConstruction').val()
if (lvl.length > 0) {
$.ajax({
type: "POST",
url: "NewProductConstruction.aspx/GetCollection",
data: JSON.stringify({ 'omyCollection': myCollection, 'lvl': lvl, 'ddl': ddl }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (parseInt(response.d) > 0)
alert("Saved successfully.");
else
alert("This object already exists in the database!");
console.log(response);
location.reload(true);
},
error: function (response) {
alert("Not Saved!");
console.log(response);
location.reload(true);
}
});
}
else {
alert("Please fill in the Product Construction field!")
}
}
$(function () {
$('#myButton').on('click', function () {
if (validate()){
sendAjax();
}
})
});
If you want to execute these in order why don't you just add one click handler that calls each function:
function validate(){
// Loop all span elements with target class
$(".IDMandatory").each(function (i, el) {
// Skip spans which text is actually a number
....etc.
}
function sendAjax(){
var ddl = $('#MainContent_ddlBusinessCenter').val()
var myCollection = [];
..etc.
}
$(function () {
$('#myButton').on('click', function () {
validate();
sendAjax();
}
});
Seems it would make sense if your validate function actually returns true or false if your form was valid too. then you could:
$(function () {
$('#myButton').on('click', function () {
if (validate()){
sendAjax();
}
}
});
I'm not really sure why your doing this:
// Mark it with required attribute
target.prop("required", true);
when you validate? If you just add this into your HTML it will handle required. adding it here seems a bit strange. I'm guessing your not actually submitting the form? It'd make more sense to add the validation message yourself rather than use this attribute.
Your codes not working because your not returning anything from your validate function. It's not 100% clear to me what is valid and what isn't so I can't alter this. But you need to add return true; for valid cases and return false;for invalid cases for the if statement if (validate()){ to work.

Cannot POST more than one value with AJAX

I stucked on one thing. I have a 2 grid inside checkboxes. When I selected that checkboxes I want to POST that row data values like array or List. Actually when i send one list item it's posting without error but when i get more than one item it couldn't post values.
Example of my grid
Here my ajax request and how to select row values function
var grid = $("#InvoceGrid").data('kendoGrid');
var sel = $("input:checked", grid.tbody).closest("tr");
var items = [];
$.each(sel, function (idx, row) {
var item = grid.dataItem(row);
items.push(item);
});
var grid1 = $("#DeliveryGrid").data('kendoGrid');
var sel1 = $("input:checked", grid1.tbody).closest("tr");
var items1 = [];
$.each(sel1, function (idx, row) {
var item1 = grid1.dataItem(row);
items1.push(item1);
});
$.ajax({
url: '../HeadOffice/CreateInvoice',
type: 'POST',
data: JSON.stringify({ 'items': items, 'items1': items1, 'refnum': refnum }),
contentType: 'application/json',
traditional: true,
success: function (msg) {
if (msg == "0") {
$("#lblMessageInvoice").text("Invoices have been created.")
var del = $("#InvoiceOKWindow").data("kendoWindow");
del.center().open();
var del1 = $("#InvoiceDetail").data("kendoWindow");
del1.center().close();
$("#grdDlvInv").data('kendoGrid').dataSource.read();
}
else {
$("#lblMessageInvoice").text("Problem occured. Please try again later.")
var del = $("#InvoiceOKWindow").data("kendoWindow");
del.center().open();
return false;
}
}
});
This is my C# part
[HttpPost]
public string CreateInvoice(List<Pm_I_GecisTo_Result> items, List<Pm_I_GecisFrom_Result> items1, string refnum)
{
try
{
if (items != null && items1 != null)
{
//do Something
}
else
{
Log.append("Items not selected", 50);
return "-1";
}
}
catch (Exception ex)
{
Log.append("Exception in Create Invoice action of HeadOfficeController " + ex.ToString(), 50);
return "-1";
}
}
But when i send just one row it works but when i try to send more than one value it post null and create problem
How can i solve this? Do you have any idea?
EDIT
I forgot to say but this way is working on localy but when i update server is not working proper.
$.ajax({
url: '../HeadOffice/CreateInvoice',
type: 'POST',
async: false,
data: { items: items, items1: items1 }
success: function (msg) {
//add codes
},
error: function () {
location.reload();
}
});
try to call controller by this method :)

How to save var value outside ajax success function?

I am trying to make some form validation functions. Here is what I have:
<script>
$(document).ready(function() {
var myObj = {};
$('#username').keyup(function () {
id = $(this).attr('id');
validateUsername(id);
});
function validateUsername(id){
var username = $("#"+id).val();
$.ajax({
url : "validate.php",
dataType: 'json',
data: 'action=usr_id&id=' + username,
type: "POST",
success: function(data) {
if (data.ok == true) {
$(myObj).data("username","ok");
} else {
$(myObj).data("username","no");
}
}
});
} // end validateusername function
$('#submit').click(function(){
if (myObj.username == "ok") {
alert("Username OK");
} else {
alert("Username BAD");
}
});
}); // end doc ready
So you can see, when a key is pressed in the textbox, it checks if it's valid. The "data.ok" comes back correctly. The problem is based on the response, I define $(myObj).username. For some reason, I can't get this value to work outside the validateusername function. When clicking the submit button, it has no idea what the value of $(myObj).username is.
I need to use something like this, because with multiple form fields on the page to validate, I can do something like:
if (myObj.username && myObj.password && myObj.email == "ok")
... to check all my form fields before submitting the form.
I know I must just be missing something basic.... any thoughts?
EDIT: SOLVED
All I had to do was change var myObj = {}; to myObj = {}; and it's working like a charm. I think I've been staring at this screen waaaaay too long!
You're not accessing the data that you stored properly. Access the username value this way:
$(myObj).data("username")
Resources:
Take a look at jQuery's .data() docs.
Very simple jsFiddle that shows how to properly set and retrieve data with jQuery's .data() method.
I would store the promise in that global variable and then bind an event to the done event within your submit button click.
$(document).ready(function() {
var myObj = false;
$('#username').keyup(function () {
id = $(this).attr('id');
validateUsername(id);
});
function validateUsername(id){
var username = $("#"+id).val();
myObj = $.ajax({
url : "validate.php",
dataType: 'json',
data: 'action=usr_id&id=' + username,
type: "POST",
success: function(data) {
$('#username').removeClass('valid invalid');
if (data.ok == true) {
$('#username').addClass('valid');
}
else {
$('#username').addClass('invalid');
}
}
});
} // end validateusername function
$('#submit').click(function(){
// if myObj is still equal to false, the username has
// not changed yet, therefore the ajax request hasn't
// been made
if (!myObj) {
alert("Username BAD");
}
// since a deferred object exists, add a callback to done
else {
myObj.done(function(data){
if (data.ok == true) {
alert("Username BAD");
}
else {
alert("Username OK");
}
});
}
});
}); // end doc ready
you may want to add some throttling to the keyup event though to prevent multiple ajax requests from being active at once.

my javascript code will not proceed to delete my data from jqGrid

just want to ask regarding my javascript code. I have a function that will delete and edit a data in my jqgrid. But everytime i run my code, it will not delete and edit if I dont put an alert in some portion of the code. Why is it happening? How can i make my program run without the alert?
Below is my delete function:
function woodSpeDelData(){
var selected = $("#tblWoodSpe").jqGrid('getGridParam', 'selrow');
var woodID='';
var woodDesc='';
var codeFlag = 0;
var par_ams = {
"SessionID": $.cookie("SessionID"),
"dataType": "data"
};
//this part here will get the id of the data since my id was hidden in my jqgrid
$.ajax({
type: 'GET',
url: 'processjson.php?' + $.param({path:'getData/woodSpecie',json:JSON.stringify(par_ams)}),
dataType: primeSettings.ajaxDataType,
success: function(data) {
if ('error' in data)
{
showMessage('ERROR: ' + data["error"]["msg"]);
}
else{
$.each(data['result']['main']['rowdata'], function(rowIndex, rowDataValue) {
$.each(rowDataValue, function(columnIndex, rowArrayValue) {
var fldName = data['result']['main']['metadata']['fields'][columnIndex].name;
if (fldName == 'wood_specie_id'){
woodID = rowArrayValue;
}
if (fldName == 'wood_specie_desc'){
woodDesc = rowArrayValue;
alert($('#editWoodSpeDesc').val() +' '+ woodDesc); //program will not delete without this
if(selected == woodDesc){
codeFlag =1;
alert(woodID); //program will not delete without this
};
}
});
if (codeFlag == 1){
return false;
}
});
if (codeFlag == 1){
return false;
}
}
}
});
alert('program will not proceed without this alert');
if (codeFlag == 1) {
var datas = {
"SessionID": $.cookie("SessionID"),
"operation": "delete",
"wood_specie_id": woodID
};
alert(woodID);
alert(JSON.stringify(datas));
$.ajax({
type: 'GET',
url: 'processjson.php?' + $.param({path:'delete/woodSpecie',json:JSON.stringify(datas)}),
dataType: primeSettings.ajaxDataType,
success: function(data) {
if ('error' in data)
{
showMessage('ERROR: ' + data["error"]["msg"]);
}
else{
$('#tblWoodSpe').trigger('reloadGrid');
}
}
});
}
}
EDIT
My main purpose of putting an alert was just to know if my code really get the right ID of the description, and if would really go the flow of my code... But then i realized that it really wont work with it.

jQuery UI AutoComplete: Only allow selected valued from suggested list

I am implementing jQuery UI Autocomplete and am wondering if there is any way to only allow a selection from the suggested results that are returned as opposed to allowing any value to be input into the text box.
I am using this for a tagging system much like the one used on this site, so I only want to allow users to select tags from a pre-populated list returned to the autocomplete plugin.
You could also use this:
change: function(event,ui){
$(this).val((ui.item ? ui.item.id : ""));
}
The only drawback I've seen to this is that even if the user enters the full value of an acceptable item, when they move focus from the textfield it will delete the value and they'll have to do it again. The only way they'd be able to enter a value is by selecting it from the list.
Don't know if that matters to you or not.
I got the same problem with selected not being defined. Got a work-around for it and added the toLowerCase function, just to be safe.
$('#' + specificInput).autocomplete({
create: function () {
$(this).data('ui-autocomplete')._renderItem = function (ul, item) {
$(ul).addClass('for_' + specificInput); //usefull for multiple autocomplete fields
return $('<li data-id = "' + item.id + '">' + item.value + '</li>').appendTo(ul);
};
},
change:
function( event, ui ){
var selfInput = $(this); //stores the input field
if ( !ui.item ) {
var writtenItem = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val().toLowerCase()) + "$", "i"), valid = false;
$('ul.for_' + specificInput).children("li").each(function() {
if($(this).text().toLowerCase().match(writtenItem)) {
this.selected = valid = true;
selfInput.val($(this).text()); // shows the item's name from the autocomplete
selfInput.next('span').text('(Existing)');
selfInput.data('id', $(this).data('id'));
return false;
}
});
if (!valid) {
selfInput.next('span').text('(New)');
selfInput.data('id', -1);
}
}
}
http://jsfiddle.net/pxfunc/j3AN7/
var validOptions = ["Bold", "Normal", "Default", "100", "200"]
previousValue = "";
$('#ac').autocomplete({
autoFocus: true,
source: validOptions
}).keyup(function() {
var isValid = false;
for (i in validOptions) {
if (validOptions[i].toLowerCase().match(this.value.toLowerCase())) {
isValid = true;
}
}
if (!isValid) {
this.value = previousValue
} else {
previousValue = this.value;
}
});
This is how I did it with a list of settlements:
$("#settlement").autocomplete({
source:settlements,
change: function( event, ui ) {
val = $(this).val();
exists = $.inArray(val,settlements);
if (exists<0) {
$(this).val("");
return false;
}
}
});
i just modify to code in my case & it's working
selectFirst: true,
change: function (event, ui) {
if (ui.item == null){
//here is null if entered value is not match in suggestion list
$(this).val((ui.item ? ui.item.id : ""));
}
}
you can try
Ajax submission and handling
This will be of use to some of you out there:
$('#INPUT_ID').autocomplete({
source: function (request, response) {
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: autocompleteURL,
data: "{'data':'" + $('INPUT_ID').val() + "'}",
dataType: 'json',
success: function (data) {
response(data.d);
},
error: function (data) {
console.log('No match.')
}
});
},
change: function (event, ui) {
var opt = $(this).val();
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: autocompleteURL,
data: "{'empName':'" + name + "'}",
dataType: 'json',
success: function (data) {
if (data.d.length == 0) {
$('#INPUT_ID').val('');
alert('Option must be selected from the list.');
} else if (data.d[0] != opt) {
$('#INPUT_ID').val('');
alert('Option must be selected from the list.');
}
},
error: function (data) {
$(this).val('');
console.log('Error retrieving options.');
}
});
}
});
I'm on drupal 7.38 and
to only allow input from select-box in autocomplete
you only need to delete the user-input at the point,
where js does not need it any more - which is the case,
as soon as the search-results arrive in the suggestion-popup
right there you can savely set:
**this.input.value = ''**
see below in the extract from autocomplete.js ...
So I copied the whole Drupal.jsAC.prototype.found object
into my custom module and added it to the desired form
with
$form['#attached']['js'][] = array(
'type' => 'file',
'data' => 'sites/all/modules/<modulname>_autocomplete.js',
);
And here's the extract from drupal's original misc/autocomplete.js
modified by that single line...
Drupal.jsAC.prototype.found = function (matches) {
// If no value in the textfield, do not show the popup.
if (!this.input.value.length) {
return false;
}
// === just added one single line below ===
this.input.value = '';
// Prepare matches.
=cut. . . . . .
If you would like to restrict the user to picking a recommendation from the autocomplete list, try defining the close function like this. The close function is called when the results drop down closes, if the user selected from the list, then event.currentTarget is defined, if not, then the results drop down closed without the user selecting an option. If they do not select an option, then I reset the input to blank.
//
// Extend Autocomplete
//
$.widget( "ui.autocomplete", $.ui.autocomplete, {
options: {
close: function( event, ui ) {
if (typeof event.currentTarget == 'undefined') {
$(this).val("");
}
}
}
});
You can actually use the response event in combination to the change event to store the suggested items like so:
response: function (event, ui) {
var list = ui.content.map(o => o.value.toLowerCase());
},
change: function (event, ui) {
if (!ui.item && list.indexOf($(this).val().toLowerCase()) === -1 ) { $(this).val('');
}

Categories

Resources