I'm developing some client side form validation that needs to use a JSON file (that is shared with server side validation) that contains arrays of id keys (to describe the input type) and rules (to define what the validation rules are for the input type).
Here is an example of the JSON structure:
[
{
"id": "search",
"rules": [
{
"name": "min_length",
"value": 5
},
{
"name": "email"
}
]
},
{
"id": "phone-number",
"rules": [
{
"name": "min_length",
"value": 5
}
]
}
]
I am doing the following:
Loading the file and parsing the json and storing as an object.
Looping through the form and storing all id's.
What I need help with
Match each form element "id" with a corresponding "id" value in the json object
Create a function for each "rules" "name".
When a form element with an "id" that is matched in the JSON object, run the functions that match each "rules" "name" for the matched "id". So looking at the JSON I have above I would want to" Check the form for an element with "search" and then run a function to check the min length and run a function that checks the email (check against a regex I have).
Ideally I want to keep this as generic as possible to allow for any id + rules to be dealt with. The rules themselves will be a pre defined list of "min_length", "email" etc so these can be functions that run if the rule exists.
Here is some JS code that I have so far. It's more of a few ideas that haven't got me closer to what I need to do!
// Get the json file and store
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'js/rules.json');
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
// Load json...
loadJSON(rulesData);
// Global vars...
var rules = [];
function rulesData(data) {
// Parse json and create object...
var jsonObj = JSON.parse(data);
// Push objects to rules array for later use
for (var i = 0; i < jsonObj.length; i++) {
rules.push(jsonObj[i]);
}
}
$(function(){
$('#email-submit').click(function(){
var formInputs = new Array();
//Get the form ID
var id = $(this).parent().attr('id');
$('#' + id + ' input').each(function(){
//Get the input value
var inputValue = $(this).val();
//Get the input id
var inputId = $(this).attr('id');
//Add them to the array
formInputs[inputId] = inputValue;
});
console.log(formInputs);
return false;
});
});
var emailRegex = "^[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$";
Related
I am working on creating a file where data can be read from a JSON file.
I can add new names to the file but I am unable to delete. When I enter a name to delete it actually adds the name to the file.
Why is it adding & not deleting? The objective is to be able to delete a specific name from the list that will be generated.
Thank you in advance! Here is my code with comments on what I am attempting to do.
// POST request to add to JSON & XML files
router.post('/post/json', function(req, res) {
// Function to read in a JSON file, add to it & convert to XML
function appendJSON(obj) {
// Read in a JSON file
var JSONfile = fs.readFileSync('Staff.json', 'utf8');
// Parse the JSON file in order to be able to edit it
var JSONparsed = JSON.parse(JSONfile);
// Add a new record into country array within the JSON file
JSONparsed.member.push(obj);
// Beautify the resulting JSON file
var JSONformated = JSON.stringify(JSONparsed, null, 4);
// Delte a specific entry from JSON file
var i = member.indexOf(" ");
if (i != -1) {
member.splice(i,1);
}
// Write the updated JSON file back to the system
fs.writeFileSync('Staff.json', JSONformated);
// Convert the updated JSON file to XML
var XMLformated = js2xmlparser.parse('staff', JSON.parse(JSONformated));
// Write the resulting XML back to the system
fs.writeFileSync('Staff.xml', XMLformated);
}
// Call appendJSON function and pass in body of the current POST request
appendJSON(req.body);
// Re-direct the browser back to the page, where the POST request came from
res.redirect('back');
});
Here is an example of the JSON file
{
"member": [
{
"Full_Name": "",
"Address": "",
"Gender": "",
"Phone_Number": ""
}
]
}
The splice function removes the item from the array and returns the deleted item. So if you want to delete an item by an attribute from your JSON like Full_Name you have to find the index of the item first.
var nameToSearch = "MyName";
var itemIndex = -1;
for(var i = 0; i < JSONparsed.member.length; i++) {
if(JSONparsed.member[i].Full_Name === nameToSearch) {
itemIndex = i;
}
}
And then you can delete the item like you did.
if (itemIndex != -1) {
JSONparsed.member.splice(itemIndex,1);
}
The problem you most likely had was that the itemIndex was allways -1 as indexOf did not know which attribute to check and just checks for the whole object.
Also the following lines have to be after the code above. (So after any changes you make to the json)
// Beautify the resulting JSON file
var JSONformated = JSON.stringify(JSONparsed, null, 4);
I also recomend reading this turtorial about javascript debugging. It makes your live a lot easyier to find mistakes.
I wish to have an attribute called idField in my json object. Now this attribute is either an array if it contains multiple elements or just an object if it contains one element. I wish to create such an attribute from the data in an extjs store. In essence if the store contains just one element I need to insert this idField 'object' in the json object otherwise I need to insert an 'array' called idField in the json object. Please advise as to how to do that.
EDIT:
My store has 2 columns namely 'name' and 'type' in its data. What I wish is that if it contains just one element then my object should look like this:
{
...
idField : {
name : ...
type : ...
}
}
If my store contains 2 rows then my object should look like this :
{
...
idField : [
{
name : ...
type : ...
},
{
name : ...
type : ...
}
]
}
Also I have to INSERT this idField attribute inside the object. There is no currect idField attribute yet in the object.
EDIT 2:
I received this object in the console when I wrote console.log(Ext.getStore("My_store_name").data)
To get the data from the EXT JS store
var data = Ext.getStore("Your_Store_Name").data
In my snippet below I am assuming that you like to get the values from field name called item.
var data = Ext.getStore("Your_Store_Name").data
//imagine your JSON where you need to store is in variable myJSON
if (data.items.length == 1){
myJSON.idField = {type: 'sometype', name: data.item[0]} }
else if (data.item.length > 1)
{ //make an array of JSON
var list = [];
for(var i = 0; i < data.item.length; i++)
{
list.push({type: 'sometype', name: data.item[i]})
}
myJSON.idField = list; //set the array
}
I'm trying to dig into a nested javascript array to grab the first instance of an object. Here's the code:
var utils = require('utils');
var casper = require('casper').create();
casper.start('http://en.wikipedia.org/wiki/List_of_male_tennis_players', function() {
this.echo(this.getTitle());
// Get info on all elements matching this CSS selector
var tennis_info_text = this.evaluate(function() {
var nodes = document.querySelectorAll('table.sortable.wikitable tbody tr');
return [].map.call(nodes, function(node) { // Alternatively: return Array.prototype.map.call(...
return node.textContent;
});
});
// Split the array into an array of object literals
var tennis_data = tennis_info_text.map(function(str) {
var elements = str.split("\n");
var data = {
name : elements[1],
birth : elements[2],
death : elements[3],
country : elements[4]
};
return data;
});
// Dump the tennis_names array to screen
utils.dump(tennis_data.slice(1,5));
});
casper.run();
The result of stdout is this:
{
"name": "Acasuso, JoséJosé Acasuso",
"birth": "1982",
"death": "–",
"country": " Argentina"
},
{
"name": "Adams, DavidDavid Adams",
"birth": "1970",
"death": "–",
"country": " South Africa"
},...
For the name element, I'm getting everything from the tr row, which matches 2 elements when you look at the target url source. What I want is just the second part of the name element with class "fn"; for instance: "David Adams", "José Acasuso". I'm thinking something like name:elements[1].smtg should work, but I've had no luck.
Additionally, how would I print the available object keys from the elements object?
The problem is that the first cell contains two elements which contain the name and first name of the player with different ordering. When taking the textContent of the whole cell, both name representations are put into the same string, but in the browser only one of them is visible. If you want only to access the visible one, you need to explicitly crawl it.
You could write a custom function that removes the duplicate name from the string, but it is easier to just take the correct element's textContent.
This can be easily done in the page context:
var tennis_data = this.evaluate(function() {
var nodes = document.querySelectorAll('table.sortable.wikitable tbody tr');
return [].map.call(nodes, function(node) {
var cells = [].map.call(node.querySelectorAll("td"), function(cell, i){
if (i === 0) {
return cell.querySelector(".fn").textContent;
} else {
return cell.textContent;
}
});
return {
name: cells[0],
birth: cells[1],
...
}
});
});
Additionally, how would I print the available object keys from the elements object?
elements is an array of strings so there are no keys that you can access besides the array indexes and array functions.
I am using wikipedia API my json response looks like,
"{
"query": {
"normalized": [
{
"from": "bitcoin",
"to": "Bitcoin"
}
],
"pages": {
"28249265": {
"pageid": 28249265,
"ns": 0,
"title": "Bitcoin",
"extract": "<p><b>Bitcoin</b>isapeer-to-peerpaymentsystemintroducedasopensourcesoftwarein2009.Thedigitalcurrencycreatedandlikeacentralbank,
andthishasledtheUSTreasurytocallbitcoinadecentralizedcurrency....</p>"
}
}
}
}"
this response is coming inside XMLHTTPObject ( request.responseText )
I am using eval to convert above string into json object as below,
var jsonObject = eval('(' +req.responseText+ ')');
In the response, pages element will have dynamic number for the key-value pair as shown in above example ( "28249265" )
How can I get extract element from above json object if my pageId is different for different results.
Please note, parsing is not actual problem here,
If Parse it , I can acess extract as,
var data = jsonObject.query.pages.28249265.extract;
In above line 28249265 is dynamic, This will be something different for different query
assuming that u want to traverse all keys in "jsonObject.query.pages".
u can extract it like this:
var pages = jsonObject.query.pages;
for (k in pages) { // here k represents the page no i.e. 28249265
var data = pages[k].extract;
// what u wana do with data here
}
or u may first extract all page data in array.
var datas = [];
var pages = jsonObject.query.pages;
for (k in pages) {
datas.push(pages[k].extract);
}
// what u wana do with data array here
you can archive that using two methods
obj = JSON.parse(json)
OR
obj = $.parseJSON(json);
UPDATE
Try this this
var obj = JSON.parse("your json data string");
//console.log(obj)
jQuery.each(obj.query.pages,function(a,val){
// here you can get data dynamically
var data = val.extract;
alert(val.extract);
});
JSBIN Example
JSBIN
How to retrieve the value 100003119917070 and XgXELcliKMkSCcS from below document using preg match:
<script>
window.Env = window.Env || {};
(function(v) {
for (var k in v) { window.Env[k] = v[k]; }
})({
"user": "100003119917070",
"locale": "en_US",
"method": "GET",
"ps_limit": 5,
"ps_ratio": 4,
"svn_rev": 479734,
"static_base": "https:\/\/s-static.ak.facebook.com\/",
"www_base": "http:\/\/www.facebook.com\/",
"rep_lag": 2,
"post_form_id": "6cea66d4118fac268304a538a5004ed7",
"fb_dtsg": "AQAcBeoe",
"ajaxpipe_token": "AXgXELcliKMkSCcS",
"lhsh": "8AQGGa7eN",
"tracking_domain": "https:\/\/pixel.facebook.com",
"retry_ajax_on_network_error": "1",
"ajaxpipe_enabled": "1"
});
</script>
<script>
CavalryLogger=false;
window._incorporate_fragment = true;
window._script_path = "\/home.php";
window._EagleEyeSeed="Se1E";
</script>
Just access window.Env.user and window.env.ajax_token?
You've put(copy) the object into the window.Env, so you can run this code:
console.log(window.Env.user, window.Env.ajaxpipe_token)
and it will print values which you want on console.
Also, you can use window.Env['user'] to reference the value 100003119917070.
if use preg,
var preg_user= /"user":\s?"([0-9]+)/;
var preg_token = /"ajaxpipe_token":\s?"([\d\w]+)/;
and you can get value by:
var user = str.match(preg_user);
var token = str.match(preg_token);
May this can help you.
In the specific example given ajaxpipe_token does not contain values other than text and numbers, but, if your value can contain other values (like it can in facebook), change your match group to look for non-quotes, then terminate with the quotes. This is the full code for extracting the values from the document.
scriptxpath ='//script[contains(.,"ajaxpipe_token")]';
scriptrslt = document.evaluate(scriptxpath,document,null,XPathResult.ANY_TYPE,null);
scriptobj = scriptrslt.iterateNext()
scriptiHTML = script.innerHTML;
user_search = scriptiHTML.match(/"user":\s?"([0-9]+)"/);
ajaxpipe_token_search = script_iHTML.match(/"ajaxpipe_token":\s?"([^"]+)"/)
user = user_search[1];
ajaxpipe_token = ajaxpipe_token_search[1];