I am working on a WebApp Add-on in Google Sheets. Below is the Addon and webapp script. I want to read validation/error message from webapp and display to user.
Like I will send message from doPost(e) like "Check Values" and user should get this as message box.
function copyData() {
var ss_id = SpreadsheetApp.getActive().getId();
//This is the Web App URL.
var url = "https://script.google.com/macros/s/<id>/exec";
var payload = {
"ss_id" : ss_id, // Modified
}
var options = {
"method" : "POST",
"payload" : payload,
"followRedirects" : true,
"muteHttpExceptions" : true,
};
var result = UrlFetchApp.fetch(url, options);
}
function doPost(e) {
var ss_id = e.parameter.ss_id; // Modified
var response = {
"status" : "FAILED",
"ss_id" : ss_id,
};
//var ss_id = ss_id[0];
//Use your spreadsheetID to get Output Sheet
var Manager_SS=SpreadsheetApp.openById('<id>');
var Manager_Sheet=Manager_SS.getSheetByName('Consolidated_Data');
var FrontDesk_ss = SpreadsheetApp.openById(ss_id);
var FrontDesk_sheet = FrontDesk_ss.getSheetByName('Data');
//Get front desk data
var sData = FrontDesk_sheet.getRange("A2:C10").getValues();
//Copy data from Front Desk to Manager Sheet.
Manager_Sheet.getRange("A2:C10").clear();
Manager_Sheet.getRange("A2:C10").setValues(sData);
//Update done after copying data.
FrontDesk_sheet.getRange('D1:D10').setValue('Done');
var response = {
"status" : "SUCCESS",
"sData" : sData,
};
return ContentService.createTextOutput(JSON.stringify(response));
}
For this example I am using a bounded script, but this should be the same for an Editor Add-on
In the spreadsheet we want to validate, we create a custom menu to call a function that makes a POST request to our Web App. Depending on the response, we display one content or another.
const UI = SpreadsheetApp.getUi()
const onOpen = () => {
/* Adds the custom menu */
UI.createMenu('Custom Function').addItem('Is Valid?', 'checkValidity').addToUi()
}
const checkValidity = () => {
const res = UrlFetchApp.fetch
(
/* Change it for your URL */
"https://script.google.com/macros/s/<ID>/exec",
{
"method": "post",
"contentType": "application/json",
/* In this example I only send the ID of the Spreadsheet */
"payload": JSON.stringify(
{
"ss_id": SpreadsheetApp.getActiveSpreadsheet().getId()
}
)
}
)
/* Depending on the response from the Web App */
/* We show different messages */
const { MSG } = JSON.parse(res.getContentText())
UI.alert(MSG === "OK" ? "IS VALID" : "IS NOT VALID")
}
After we create a Web App that validates the ID. In this example I am only validating that the ID is contained in an array of valid IDs, but this should be replaced by whatever you need. As a response I only send a simple "OK" or "NOT OK", but this can be replaced with any kind of data.
const doPost = (e) => {
/* We perform the checks we need */
/* In this example only checking if the id is contained in an array */
/* This should be changed to perform the desired checks */
const validID = ["<VALID_ID_1>","<VALID_ID_2>"]
const { ss_id } = JSON.parse(e.postData.contents)
/* SpreadsheetApp.openById(ss_id).copy("my_new_copy") */
const checker = validID.includes(ss_id)
/* We send back the response */
/* Depending on the checker value */
return ContentService.createTextOutput(JSON.stringify(
{
"MSG": checker ? "OK" : "NOT OK"
}
)).setMimeType(ContentService.MimeType.JSON)
}
Reading Validation Error from Webapp
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form>
<input type="text" id="txt1" name="id" placeholder="Enter Numbers only"/>
<input type="button" value="submit" onClick="processForm(this.parentNode);" />
</form>
<script>
function processForm(obj) {
console.log(obj.id.value);
if(obj.id.value.match(/[A-Za-z]/)) {
google.script.run.displayError("Invalid Characters Found in id field");
} else {
google.script.run.sendData(obj);
}
}
</script>
</body>
</html>
GS:
function doPost(e) {
Logger.log(e.postData.contents);
Logger.log(e.postData.type);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
let data = JSON.parse(e.postData.contents);
let row = [];
Object.keys(data).forEach(k => row.push(data[k]));
Logger.log(JSON.stringify(row))
sh.appendRow(row);
}
function sendData(obj) {
const url = ScriptApp.getService().getUrl();
const params={"contentType":"application/json","payload":JSON.stringify(obj),"muteHttpExceptions":true,"method":"post","headers": {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}};
UrlFetchApp.fetch(url,params);
}
function displayError(msg) {
SpreadsheetApp.getUi().alert(msg);
}
function launchMyDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'),'My Dialog');
}
Related
Below is the code for the popup.js in my chrome extension v3
The parts I commented out are meant to extract previews (of the first few lines) for the respective queries, but when implemented, the search for the extension does not work at all (no errors though).
I tried logging into console to see what happened along the way, and noticed that even the response object did not register anything in the console, needless to say the HTML. Any clues, or perhaps there are better ways to generate the previews?
document.addEventListener("DOMContentLoaded", function () {
// Select the search form and the search results container
var form = document.getElementById("search-form");
var container = document.getElementById("search-results");
// Handle the submit event of the form
form.addEventListener("submit", function (event) {
event.preventDefault(); // Prevent the form from being submitted
// Get the search title from the form
var title = form.elements.title.value;
var title2 = title.replace(/ /g, "+"); // Replace spaces with +
var results = [];
var queries = [
{
url: `https://www.ncbi.nlm.nih.gov/pmc/?term=${title}`,
title: "NCBI PMC"
},
{
url: `https://www.biorxiv.org/search/${title}`,
title: "bioRxiv"
},
{
url: `https://www.medrxiv.org/search/${title}`,
title: "medRxiv"
},
{
url: `https://www.google.com/search?q=${title2}+filetype:pdf`,
title: "PDF Search"
}
];
queries.forEach(function (query) {
fetch(query.url)
.then(function (response) {
return response.text();
console.log(response);
})
// .then(function (html) {
// console.log(query.title);
// console.dir(html); // Inspect the properties of the html variable
// console.table(html); // View the contents of the html variable as a table
// // Parse the HTML using the DOMParser
// var parser = new DOMParser();
// var doc = parser.parseFromString(html, "text/html");
// // Extract the relevant information from the parsed HTML
// var title = doc.querySelector("title").innerText;
// var lines = [];
// var paragraphs = doc.querySelectorAll("p");
// for (var i = 0; i < paragraphs.length; i++) {
// lines.push(paragraphs[i].innerText);
// if (lines.length === 5) {
// break; // Break the loop
// }
// }
results.push({
title: query.title,
url: query.url,
// preview: lines.join("\n")
});
// });
});
// Create the search results HTML
var resultsHTML = "";
results.forEach(function (result) {
resultsHTML += `<div class="result">
<h2>${result.title}</h2>
<p>${result.preview}</p>
</div>`;
});
// Update the container with the search results HTML
container.innerHTML = resultsHTML;
// Handle the click event of the result links
container.addEventListener("click", function (event) {
var target = event.target;
if (target.tagName === "A") {
// Open the URL in a new tab and bring it to the front
var url = target.dataset.url;
var tab = window.open(url, "_blank");
tab.focus();
}
});
});
});```
Notice: New to SharePoint
I was able to get peoplepicker div to work but I need help getting the name value or display name to post inside my SharePoint column named Person. Currently, once the user submits the Person column comes in blank. Sorry for the lack of knowledge, just a bit lost.
$(document).ready(function() {
initializePeoplePicker('peoplePickerDiv');
});
function initializePeoplePicker(peoplePickerElementId) {
// Create a schema to store picker properties, and set the properties.
var schema = {};
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
//This value specifies where you would want to search for the valid values
schema['SearchPrincipalSource'] = 15;
//This value specifies where you would want to resolve for the valid values
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = true;
schema['MaximumEntitySuggestions'] = 50;
// schema['Width'] = '780px';
// Render and initialize the picker.
// Pass the ID of the DOM element that contains the picker, an array of initial
// PickerEntity objects to set the picker value, and a schema that defines
// picker properties.
this.SPClientPeoplePicker_InitStandaloneControlWrapper(peoplePickerElementId, null, schema);
}
function getUserInfo() {
// Get the people picker object from the page.
var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
// Get information about all users.
var users = peoplePicker.GetAllUserInfo();
var userInfo = '';
for (var i = 0; i < users.length; i++) {
var user = users[i];
for (var userProperty in user) {
userInfo += userProperty + ': ' + user[userProperty] + '<br>';
}
}
$('#resolvedUsers').html(userInfo);
// Get user keys.
var keys = peoplePicker.GetAllUserKeys();
$('#userKeys').html(keys);
// Get the first user's ID by using the login name.
getUserId(users[0].Key);
}
// Get the user ID.
function getUserId(loginName) {
var context = new SP.ClientContext.get_current();
this.user = context.get_web().ensureUser(loginName);
context.load(this.user);
context.executeQueryAsync(
Function.createDelegate(null, ensureUserSuccess),
Function.createDelegate(null, onFail)
);
}
function ensureUserSuccess() {
$('#userId').html(this.user.get_id());
}
function onFail(sender, args) {
alert('Query failed. Error: ' + args.get_message());
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="format-detection" content="telephone=no" />
<title>Package Delivery</title>
<link rel="stylesheet" href="../SiteAssets/Package%20Delivery/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="../SiteAssets/Package%20Delivery/css/style.css">
<!--[if IE]>
<script src="http://html5shi../SiteAssets/javier/v.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div id="contact" method="post">
<div class="row">
<div class="col-md-12">
Recipient's Name
<div id="peoplePickerDiv"></div>
<!-- <input class="form-control input-sm" name="Sender" id="sender" placeholder="Enter Person to Notify">-->
</div>
I'm taking they values by using javascript file:
/*=========================================
* SharePoint Repeating Field Form Template
=========================================*/
/*TODO:
Connect Profile Properties
Test Submission
Make everything generic
Post to GitHub
*/
var baseURI = "https://berkeleycollege365.sharepoint.com/sites/"; // root name
var siteName = "central-support-services";
var listName = "PackageDelivery"; // list name
$( document ).ready(function() {
// getUserProperties();
});
function getUserProperties(){
var requestUriCom = "https://berkeleycollege365.sharepoint.com/_api/SP.UserProfiles.PeopleManager/getmyproperties";
$.ajax({
url: requestUriCom,
headers:{"Accept":"application/json; odata=verbose"},
contentType:'application/json; odata=verbose',
Type: 'GET',
success: onSuccessUser,
error: function (data) {console.log(data);}
})
}
function onSuccessUser(data){
//console.log(data);
//Parse the return allll the way down.
var parse = data.d.UserProfileProperties.results[4].Value;
}
$('[data-ssd-dynamic-wrapper]').ssdDynamicRows({
clear_warning: function(row) {
row.find('[data-validation] [data-case]').removeClass('show');
row.find(':input').removeClass('warning');
},
other_elements: {
'[data-validation]' : 'data-validation'
}
});
$('#submit').on('click', function(event) {
console.log("working");
event.preventDefault();
$(this).find('[data-case="required"]').removeClass('show');
$('#result').empty();
var inputs = $(this).find(':input').removeClass('warning');
inputs.each(function() {
if ($(this).val() === '') {
$(this).addClass('warning')
.closest('[data-ssd-dynamic-field]')
.find('[data-case="required"]')
.addClass('show');
}
});
/************************
You probably dont have to edit this.
This will account for any new fields in the repeating section and add the correct key value pairs.
Again, probably dont have to edit this.
Placed all of the stuff you SHOULD edit under the next comment break.
*************************/
var a = [];
var fullString = "";
//We iterate through each row...
$('.itemRow').each(function(i){
//setting up our second array
var b = [];
//We are in our rows, so now we will find and iterate through the inputs within that row
$(this).find(':input').each(function(i, key){
//getting the value
var c = this.value;
//getting the name and splitting off the unique identifier so we can use it as our key name
var d = $(this).attr('name');
d = d.substr(0,d.indexOf('-'));
//pushing the information into our secondary array
b.push([d,c]);
});
var i = 0;
var key;
var val;
var obj = {};
//Here, we will take the values from our secondary array and form our objects
//We also create our string here
for (i;i < b.length;i++){
key = b[i][0];
obj[key] = b[i][1];
val = b[i][1];
fullString += key + ":" + val + " ";
}
//Push the objects into our main array
a.push(obj);
//Toss on a line break for our rich text fields
fullString+="<br>";
});
//Extend our array
var convertedA = $.extend({},a);
//Turn everything into a JSON object so we can store and retrieve it
//var convertedB = JSON.stringify(convertedA);
/*******************************
********************************
Here you can choose what to pass for submission.
********************************
*******************************/
createItem(fullString);
location.reload() // Reloads screen after hitting submit button
});
function createItem(multilineString) {
console.log("First String"+multilineString);
//Setting up the URL to the list we will post to.
var itemUrl = baseURI + siteName + "/_api/web/lists/getByTitle('"+ listName +"')/items";
//This applies the correct content type for this list item. You can find the function for this towards the end of the script.
var itemType = "SP.Data.PackageDeliveryListItem";//getListItemType(listName);
//Hardcoding the metadata we are passing as this can only serve one function.
var item = {
"__metadata": { "type": itemType },
"Title":"Title", //Setup your data here
"date":$("#date").val(),
"from":$("#from").val(),
"departmentChoice":$("#departmentChoice").val(),
"shippedTo":$("#shippedTo").val(),
"shippedFrom":$("#shippedFrom").val(),
"carrier":$("#carrier").val(),
"method":$("#method").val(),
"Date_x0020_Received":$("#ReceivedDate").val(),
"Person": $("#peoplePickerDiv").val(),
//"Person": $.get("getUserInfo()"),
"Details": multilineString,
"Form_x0020_Filled_x0020_By":$("#filledBy").val(),
"Date_x0020_Filled":$("#dateFilled").val(),
"Email_x0020_Sent_x0020_On":$("#emailSent").val(),
"deliveryOther":$("#deliveryOther").val()
};
//Turn everything into a JSON object
var body = JSON.stringify(item);
//Post the item
$.ajax({
url: itemUrl,
type: "POST",
contentType: "application/json;odata=verbose",
data: body,
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function(data){console.log(data);},
error: function (data) {console.log(data);}
});
}
// Getting the item type for the list
function getListItemType(name) {
return"SP.Data." + name[0].toUpperCase() + name.substring(1) + "ListItem";
}
To set user or group field column using REST API, please check the format for user field value as below:
single-valued user field: '<user field name>' : <user id>
multi-valued user field: '<user field name>' : { 'results': [<array of user ids>]}
Example:
Single user field value
var item = {
"__metadata": { "type": itemType },
"Title":"Title", //Setup your data here
"PersonId": 10
};
Multiple user field value
var item = {
"__metadata": { "type": itemType },
"Title":"Title", //Setup your data here
"PersonId": {"results": [10,11,12] } //multi-valued User field value
};
So, please get the users id from People Picker before add list item to list using REST API.
I want to collect the url (var name is 'url') of a webpage into a variable in a chrome extension, together with several user inputs in text inputs, and to send it to a remote php script for processing into an sql database. I am using AJAX to make the connection to the remote server. The popup.html contains a simple form for UI, and the popup.js collects the variables and makes the AJAX connection. If I use url = document.location.href I get the url of the popup.html, not the page url I want to process. I tried using chrome.tabs.query() to get the lastFocusedWindow url - the script is below. Nothing happens! It looks as though it should be straightforward to get lastFocusedWindow url, but it causes the script to fail. The manifest.json sets 'tabs', https://ajax.googleapis.com/, and the remote server ip (presently within the LAN) in permissions. The popup.html has UI for description, and some tags. (btw the response also doesn't work, but for the moment I don't mind!)
//declare variables to be used globally
var url;
// Get the HTTP Object
function getHTTPObject(){
if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) return new XMLHttpRequest();
else {
alert("Your browser does not support AJAX.");
return null;
}
// Change the value of the outputText field THIS PART IS NOT WORKING YET
function setOutput(){
if(httpObject.readyState == 4){
//document.getElementById('outputText').value = httpObject.responseText;
"Bookmark added to db" = httpObject.responseText; // does this work?
}
}
//put URL tab function here
chrome.tabs.query(
{"active": true, "lastFocusedWindow": true},
function (tabs)
{
var url = tabs[0].url; //may need to put 'var' in front of 'url'
}
);
// Implement business logic
function doWork(){
httpObject = getHTTPObject();
if (httpObject != null) {
//get url? THIS IS OUTSTANDING - url defined from chrome.tabs.query?
description = document.getElementById('description').value;
tag1 = document.getElementById('tag1').value;
tag2 = document.getElementById('tag2').value;
tag3 = document.getElementById('tag3').value;
tag4 = document.getElementById('tag4').value;
httpObject.open("GET", "http://192.168.1.90/working/ajax.php?url="+url+"&description="+description+"&tag1="+tag1+"&tag2="+tag2+"&tag3="+tag3+"&tag4="+tag4, true);
httpObject.send(null);
httpObject.onreadystatechange = setOutput(); //THIS PART IS NOT WORKING
finalString = httpObject.responseText; //NOT WORKING
return finalString; //not working
} //close if
} //close doWork function
var httpObject = null;
var url = null;
var description = null;
var tag1 = null;
var tag2 = null;
var tag3 = null;
var tag4 = null;
// listens for button click on popup.html
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('button').addEventListener('click', doWork);
});
Having no responses I first used a bookmarklet instead. The bookmarklet passes the url and title to a php script, which enters them into a db before redirecting the user back to the page they were on.
javascript:(function(){location.href='http://[ipaddress]/bookmarklet.php?url='+encodeURIComponent(location.href)+'&description='+encodeURIComponent(document.title)})()
Then I found this code which works a treat.
var urlOutput = document.getElementById('bookmarkUrl');
var titleOutput = document.getElementById('bookmarkTitle');
if(chrome) {
chrome.tabs.query(
{active: true, currentWindow: true},
(arrayOfTabs) => { logCurrentTabData(arrayOfTabs) }
);
} else {
browser.tabs.query({active: true, currentWindow: true})
.then(logCurrentTabData)
}
const logCurrentTabData = (tabs) => {
currentTab = tabs[0];
urlOutput.value = currentTab.url;
titleOutput.value = currentTab.title;
}
I am using a custom slash command in Slack to add data to a Google Doc via Google Apps Scripts, however, when the script finishes running (successfully), Google Script sends this to Slack, which users will interpret as an error:
<DOCTYPE html><html><head><link rel="shortcut icon" href="//ssl.gstatic.com/docs/script/images/favicon.ico"><title>Error</title><style type="text/css">body {background-color: #fff; margin: 0; padding: 0;}.errorMessage {font-family: Arial,sans-serif; font-size: 12pt; font-weight: bold; line-height: 150%; padding-top: 25px;}</style></head><body><div><img src="//ssl.gstatic.com/docs/script/images/logo.png"></div><center>The script completed but did not return anything.</center></body></html>
How can I prevent this message from being sent to Slack?
function doPost(request) {
var sheets = SpreadsheetApp.openById('id-would-go-here');
var params = request.parameters;
var nR = getNextRow(sheets) + 1;
if (params.token == "token-would-go-here") {
// FALL BACK TO DEFAULT TEXT IF NO ORDER PROVIDED
var order = params.text || "No Order Entered";
var employee = params.user_name || "Name Error";
// RECORD TIMESTAMP AND USER NAME IN SPREADSHEET
sheets.getRangeByName('date').getCell(nR,1).setValue(new Date());
sheets.getRangeByName('employee').getCell(nR,1).setValue(employee);
// RECORD UPDATE INFORMATION INTO SPREADSHEET
sheets.getRangeByName('order').getCell(nR,1).setValue(order);
var channel = "lunch-orders";
postResponse(channel,order,employee);
var eph_url = params.response_url;
var eph_response = UrlFetchApp.fetch(eph_url,200);
} else {
return;
}
}
function postResponse(channel, order, employee) {
var payload = {
"channel": "#lunch-orders",
"username": "Lunch Order",
"link_names": 1,
"attachments":[
{
"fallback": "A lunch order was placed, but the display here is a little messed up. Check the Google Doc to view the order.",
"mrkdwn_in": ["pretext"],
"color": "good",
"fields":[
{
"title":"" + employee + "'s Lunch Order",
"value": "" + order + "",
"short":false
}
]
}
]
};
var url = 'incoming-webhook-url-goes-here';
var options = {
'method': 'post',
'payload': JSON.stringify(payload)
};
var response = UrlFetchApp.fetch(url,options);
}
Your setup is a little off. You don't POST the data back, you return it using ContentService. Now a small issue is that you have to run the webapp as anonymous authentication. What I do is save the slack token in the script property services and make sure the requesting Slack app's token matches.
Here is an example webhook that simply writes the parameters passed to the switch command to a spreadsheet.
function doPost(e) {
var returnMessage;
var slackToken = PropertiesService.getScriptProperties().getProperty("SlackToken") ;
var postData = parseParams(e.postData.getDataAsString());
if(postData.token === slackToken){
SpreadsheetApp.openById('.....').getSheetByName("Log").appendRow([postData]);
returnMessage = "Your record has been logged."
}else{
returnMessage = "Invalid Token"
}
return ContentService.createTextOutput(JSON.stringify({text:returnMessage})).setMimeType(ContentService.MimeType.JSON);
}
function parseParams(postData){
var postObj = {}
postData.split("&").map(function(param){var thisParam = param.split("="); postObj[thisParam[0]] = thisParam[1]});
return postObj;
}
Here i am getting my Error Messages from a separate page and i am displaying it in a a div called #stage_error
$('#stage_error').html(error_string);
So, the errors will be displayed like this
The bus no field is required.
The comp id field is required.
The total seats field is required.
But what i want is to display the errors in its respective div's
i.e., the Bus no should be displayed near the div <div id='busno'> like this.
How can i do that ?
Json :
{"busno":["Bus No field is required"],"Comp Id":["Comp Id is required."]}
Update :
Script for request and showing error :
<script>
$(document).ready(function() {
$("#driver").click(function(event) {
var BusNo = $("#BusNo").val();
var CompID = $("#CompID").val();
var TotalSeats = $("#TotalSeats").val();
var _token = $("#_token").val();
$.post("managebus_register", {
_token: _token,
BusNo: BusNo,
CompID: CompID,
TotalSeats: TotalSeats
},
function(data) {
if (data != '') {
obj = JSON.parse(data);
var error_string = '';
$.each(obj, function(entry) {
error_string += obj[entry] + '<br/>';
});
$('#stage_error').html(error_string);
} else {
$('#stage_success').text('Resistered Succesfully');
$("#stage_error").hide();
}
});
});
});
</script>
Laravel Controller :
public function managebusregister()
{
$BusNo = Input::get('BusNo');
$CompID = Input::get('CompID');
$TotalSeats = Input::get('TotalSeats');
$data = Input::except(array('_token')) ;
$rule = array(
'BusNo' => 'required|unique:company_bus',
'CompID' => 'required',
'TotalSeats' => 'required|max:50'
) ;
$validator = Validator::make($data,$rule);
if ($validator->fails())
{
$messages = $validator->messages();
return json_encode($validator->messages()); //php encoded value
}
else
{
DB::insert('insert into company_bus (BusNo, CompID, TotalSeats) values (?, ?, ?)',
array($BusNo, $CompID, $TotalSeats));
return '';
}
}
Html Code :
<div id="stage_error" style="color:red;font-size:15px"></div>
<div id="stage_success" style="color:green;font-size:20px"></div>
and beyond that i have each field input boxes,
<input type="text" id="BusNo" name="BusNo"/>
<input type="text" id="CompID" name="CompID"/>
How can i throw error messages near the respective fields
Below is the approach: Observe I've added spans with error after text boxes.
CSS
<style>
.error { color:red; font-size:15px; }
</style>
Html
<input type="text" id="BusNo" name="BusNo" /><span class="error"></span>
<input type="text" id="CompID" name="CompID" /><span class="error"></span>
JavaScript I did some changes as per the jQuery standard, it should work well, if you're not interested then you can ignore all the changes but can take only below mentioned if logic block.
The error display added in if (!data) {...}
$(function () {
$(document).on("click", "#driver", function (event) {
var BusNo = $("#BusNo").val(),
CompID = $("#CompID").val(),
TotalSeats = $("#TotalSeats").val(),
_token = $("#_token").val();
$.post("managebus_register", {
_token: _token,
BusNo: BusNo,
CompID: CompID,
TotalSeats: TotalSeats
}).done(function (data) {
$("span.error").empty();//All previous error messages cleared here.
if (!data) {
var obj = JSON.parse(data);
//obj = {"busno":["Bus No field is required"],"Comp Id":["Comp Id is required."]}
$.each(obj, function (entry) {
var targetSelector='';
if (entry == "busno") {
targetSelector = "#BusNo";
}
if (entry == "Comp Id") {
targetSelector = "#CompID";
}
if(targetSelector) //Here we're setting error message for respective field
$(targetSelector).next("span.error").html(obj[entry]);
});
} else {
$('#stage_success').text('Resistered Succesfully');
$("#stage_error").hide();
}
});
});
});
you can try like this:
var json = JSON.parse('{"busno":["Bus No field is required"],"Comp Id":["Comp Id is required."]}');
// alert(json['busno']);
$("#busno").html(json.busno);// like this for others also.
change here:
obj = JSON.parse(data);
var error_string = '';
$.each(obj, function(entry) {
error_string += obj[entry] + '<br/>';
if(entry == 'busno'){
$("#busno").html(obj[entry]);// like this for others also.
}
if(entry == 'Comp Id'){
$("#compid").html(obj[entry]);// like this for others also.
}
});
$('#stage_error').html(error_string);