How to find differences in nested JSON objects and highlight them - javascript

I have a problem that I cannot resolve for a long time now. I have two nested JSON objects and I need to what are the additions in the second one and highlight them(add a CSS class).
For instance if I had:
let obj1 = {
blocks: [
{
type: 'paragraph',
data: {
text: 'This is text for my project.',
},
},
{
type: 'paragraph',
data: {
text: 'This is in both and needs no change',
},
},
],
}
let obj2 = {
blocks: [
{
type: 'paragraph',
data: {
text:
'This is text for my project. This is some text that will not be in the first object.',
},
},
{
type: 'paragraph',
data: {
text: 'Things are becoming complicated in programming',
},
},
{
type: 'paragraph',
data: {
text: 'This is in both and needs no change',
},
},
],
}
After they are compared I'd like for the second obj to be like:
let obj2 = {
blocks: [
{
type: 'paragraph',
data: {
text:
'This is text for my project. <span class="new-text">This is some text that will not be in the first object.</span>',
},
},
{
type: 'paragraph',
data: {
text: '<span class="new-text">Things are becoming complicated in programming</span>',
},
},
{
type: 'paragraph',
data: {
text: 'This is in both and needs no change',
},
},
],
}
I tried looking into the diff library from google But can't find to change other things that pure strings or regular objects(not nested)
Any help is appreciated.
Thanks!

you can do something like this,
if I am wrong please correct me, I am a beginner.
let obj1 = {
blocks: [
{
type: 'paragraph',
data: {
text: 'This is text for my project.',
},
},
{
type: 'paragraph',
data: {
text: 'This is in both and needs no change',
},
},
],
}
let obj2 = {
blocks: [
{
type: 'paragraph',
data: {
text:
'This is text for my project. This is some text that will not be in the first object.',
},
},
{
type: 'paragraph',
data: {
text: 'Things are becoming complicated in programming',
},
},
{
type: 'paragraph',
data: {
text: 'This is in both and needs no change',
},
},
],
}
obj2["blocks"].map(item => {
var str = item.data.text;
obj1["blocks"].map(item2 => {
var obj2Str = item2.data.text;
if (str.indexOf(obj2Str) > -1) {
var endStr = str.substr(obj2Str.length);
item.data.text = endStr.length >0 ? obj2Str + '<span class="new-text">'+ endStr +'</span>' : obj2Str;
}
});
});
Hope this helps :)

Related

JQuery Query-Builder adding autocomplete plugin

I'm using jquery-querybuilder to build out a query. I'm currently having an issue with adding in selectize as a plugin to allow for autocomplete inside the select inputs. I'm logging the data in the for loop and it prints out the correct data so I know its physically getting the data, but when typing in the input box, there is still no autocomplete and I'm not quite sure where I went wrong.
let totalMachines = [];
var rules_basic = {
condition: 'AND',
rules: [{
}, {
condition: 'OR',
rules: [{
}, {
}]
}]
};
let options = {
plugins: [],
allow_empty: true,
filters: [
{
id: 'machineName',
label: 'Machine Name',
type: 'string',
input: 'text',
operators: ['equal'],
plugin: 'selectize',
values: {
},
plugin_config: {
valueField: 'id',
labelField: 'machineName',
searchField: 'machineName',
sortField: 'machineName',
create: false,
maxItems:3,
plugins: ['remove_button'],
onInitialize: function() {
var that = this;
totalMachines.forEach(function(item) {
that.addOption(item);
console.log(item)
});
}
},
valueSetter: function(rule, value) {
rule.$el.find('.rule-value-container input')[0].selectize.setValue(value);
}
},
]
}
$.ajax({
url: '/api-endpoint',
type: 'GET',
contentType: 'application/json',
dataType: 'json',
success: function(response){
console.log(response)
response.forEach((res) => {
totalMachines.push(res[0])
})
console.log(totalMachines)
}
})
.then(() => {
// Fix for Selectize
$('#builder').on('afterCreateRuleInput.queryBuilder', function(e, rule) {
if (rule.filter.plugin == 'selectize') {
rule.$el.find('.rule-value-container').css('min-width', '200px')
.find('.selectize-control').removeClass('form-control');
}
});
$('#builder').queryBuilder(options)
})
It would be extremely helpful if someone could help me figure out how to properly configure this plugin, I've looked at every thread and haven't been able to figure it out.
Here is a simple example, using a local datasource, the namesList array
<script>
$(document).ready(function() {
let namesList = [{ id: '1', name: 'andrew' }, { id: '2', name: 'bob' }, { id: '3', name: 'charles' }, { id: '4', name: 'david' }];
let pluginConfig = {
preload: true,
valueField: 'id',
labelField: 'name',
searchField: 'name',
options: namesList,
items: ['2'],
allowEmptyOption: true,
plugins: ['remove_button'],
onInitialize: function () { },
onChange: function (value) {
console.log(value);
},
valueSetter: function (rule, value) {
rule.$el.find('.rule-value-container input')[0].selectize.setValue(value);
},
valueGetter: function (rule) {
var val = rule.$el.find('.rule-value-container input')[0].selectize.getValue();
return val.split(',');
}
}
let filterList = [{
id: 'age',
type: 'integer',
input: 'text'
},
{
id: 'id',
label: 'name',
name: 'name',
type: 'string',
input: 'text',
plugin: 'selectize',
plugin_config: pluginConfig
}];
let options = {
allow_empty: true,
operators: ['equal', 'not_equal', 'greater', 'greater_or_equal', 'less', 'less_or_equal'],
filters: filterList
}
$('#builder').queryBuilder(options);
// Fix for Selectize
$('#builder').on('afterCreateRuleInput.queryBuilder', function (e, rule) {
if (rule.filter.plugin == 'selectize') {
rule.$el.find('.rule-value-container').css('min-width', '200px').find('.selectize-control').removeClass('form-control');
}
});
});

How to create lists within lists in JavaScript using Pure DOM and Vanilla JavaScript?

How My List Should Look
I am trying to create multiple lists within another list using pure DOM and vanilla JavaScript using an array of objects that I have been provided.
Array of Objects
var directory = [
{ type: 'file', name: 'file1.txt' },
{ type: 'file', name: 'file2.txt' },
{
type: 'directory',
name: 'HTML Files',
files: [
{ type: 'file', name: 'file1.html' },
{ type: 'file', name: 'file2.html' }
]
},
{ type: 'file', name: 'file3.txt' },
{
type: 'directory',
name: 'JavaScript Files',
files: [
{ type: 'file', name: 'file1.js' },
{ type: 'file', name: 'file2.js' },
{ type: 'file', name: 'file3.js' }
]
}
];
Any help would be greatly appreciated. Thanks! :)
Use recursive function and dom element creater createElement() function
var directory = [{type: 'file', name: 'file1.txt' }, { type: 'file', name: 'file2.txt' }, { type: 'directory', name: 'HTML Files', files: [{ type: 'file', name: 'file1.html' }, { type: 'file', name: 'file2.html' } ] }, { type: 'file', name: 'file3.txt' }, { type: 'directory', name: 'JavaScript Files', files: [{ type: 'file', name: 'file1.js' }, { type: 'file', name: 'file2.js' }, { type: 'file', name: 'file3.js' } ] } ];
function creater(arr) {
var str = '';
var last="";
arr.forEach(function(a, b) {
var ul = document.createElement('UL')
var li = document.createElement('LI')
if (a.files) {
if (a.name) {
li.innerHTML = a.name;
last =li;
}
last.append(ul)
ul.innerHTML = creater(a.files);
str += last.outerHTML;
} else {
li.innerHTML = a.name;
last = li;
str += li.outerHTML;
}
});
return str
}
document.body.innerHTML = creater(directory);
li ul{
list-style-type:circle;
}
You can create a recursive function.
var directory = [{
type: 'file',
name: 'file1.txt'
},
{
type: 'file',
name: 'file2.txt'
},
{
type: 'directory',
name: 'HTML Files',
files: [{
type: 'file',
name: 'file1.html'
},
{
type: 'file',
name: 'file2.html'
}
]
},
{
type: 'file',
name: 'file3.txt'
},
{
type: 'directory',
name: 'JavaScript Files',
files: [{
type: 'file',
name: 'file1.js'
},
{
type: 'file',
name: 'file2.js'
},
{
type: 'file',
name: 'file3.js'
}
]
}
];
let list = '';
// recursive function
function createList(array) {
array.forEach(function(item) {
if (item.type === 'file' && !item.files) {
// template literals
list += `<li>${item.name}</li>`
}
// check if the files is an array then call the recursive function
else if (item.files && item.files.length > 0) {
list += `<li>${item.name}</li>`
createList(item.files)
}
})
return list;
}
document.getElementById('liContainer').innerHTML = createList(directory);
<ul id='liContainer'></ul>

How to bind the local and Remote data together to Kendo DataSource

I want to bind the Local and Remote Datas to the same Kendo UI Control.
Here I am using Kendo treeview.
Here First 2 nodes are Hardcoded(Local data) and the third needs to from Database(Remote Data).So now how to handle this.
$("#AftermarketTreeView").kendoTreeView({
dataTextField: ["text", "text", "MC_ANALYSIS_NAME"],
dataSource: {
data: [
{
text: "Initiate",
items: [
{ text: "Parts Selection", haschildren: false },
{ text: "Assumptions", haschildren: false },
{ text: "Team", haschildren: false },
]
},
{
text: "Analyze",
items: [
{ text: "Part Attributes", haschildren: false },
{ text: "Aftermarket Evaluation", haschildren: false }
]
},
{
text: "Monto Carlo",
items: [
{ text: "Monto Carlo", haschildren: true }
]
}
],
schema: {
model: {
hasChildren: "items",
children: {
schema: {
data: "items",
model: {
hasChildren: "haschildren",
children: {
schema: {
// override the schema.data setting from the parent
data: function (response) {
return response;
}
},
transport: {
read: {
url: ResolveUrl("/CreateMaintainAnalysis/GetMontoCarloData/"),
dataType: "jsonp",
data:onDataSendAnalysisID,
}
},
}
}
}
}
}
}
}
});
So How to bind it using Kendo TreeView ?
You can't have both a local and remote data source on the same element. The best option would be a remote data source only and have it return all of the options you're looking for.

Sencha Javascript Insert to Array First Index

I requesting products from my web service. And i want insert to object array's first index the new item.
my lounch function :
NewMobile.globals = {
mesaj: 'selam',
action: '',
server: '192.168.50.70',
branchCode: '0',
activeTable: '',
activeFolio: '0',
activeTableGroup: '',
activeMustGroup: -1,
activePid: 0,
activeMustGroupString: 0,
activeMustDesc: '',
activeMustArray: [],
activeCampProduct: '',
products: undefined,
rePrint: '',
activePax: 1,
uuid: 'tanimsiz',
activeSkin: 'Krem',
version:undefined,
minVersion:132
};
Its my request.
NewMobile.globals.products = Ext.create('NewMobile.store.PorductStore');
NewMobile.globals.products.setProxy({url: "http://" + NewMobile.globals.server + ':1002/zulu/newmobile/data.aspx?act=getAllProducts'});
NewMobile.globals.products.getProxy();
NewMobile.globals.products.load(function(a, records, c, d, e){
if (c !== true)
{
Ext.Viewport.setMasked(false);
Ext.Msg.alert('uyarı', NewMobile.message.connectionError, Ext.emptyFn);
return;
}
else
{
if(NewMobile.globals.version!==undefined)
{
if(NewMobile.globals.version.MinorRevision>=NewMobile.globals.minVersion)
{
var PopulerProducts=Ext.create('NewMobile.model.Products',
{ id:-65000,
name:"SIK KULLANILANLAR",
groupId:200000,
color:"#FFC673",
type:1,
order:-1,
mustModGroups:0,
mustModGrpCount:0
}
);
NewMobile.globals.products.unshift(PopulerProducts);
}
}
}
});
Product Model :
Ext.define('NewMobile.model.Products', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'name',
type: 'string'
},
{
name: 'groupId',
type: 'int'
},
{
name: 'price',
type: 'float'
},
{
name: 'color'
},
{
name: 'type',
type: 'int'
},
{
name: 'mustModGrpCount'
},
{
name: 'mustModGroups'
},
{
name: 'order',
type: 'int'
},
{
name: 'campCount',
type: 'int'
},
{
name: 'stockCode'
},
{
name: 'populer',
type: 'boolean'
}
]
}
});
Chrome console giving this error.
Object [object Object] has no method 'unshift'
I assume that your NewMobile.store.PorductStore is extending Ext.store.Store. To add items to a store you can either use the add or insert method.
add will add the items to the end of the store so what you want to use is insert and specify the index to be 0. Something like this:
myStore.insert(0, newRecord)
To keep the sorting use addSorted. Inserts the passed Record into the Store at the index where it should go based on the current sort information.
myStore.addSorted(newRecord)
You can read more about how to use stores in Ext.js here: http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.data.Store

Trouble with Dojo Dgrid

I wanted to replace dojox.grid.DataGrid with new Dgrid but I have trouble with it. I'm using Dojo 1.9.1 and here is excerpts of my code:
HTML:
<script type="text/javascript"><!--
require({
baseUrl: "/res/js/",
packages: [
{ name: "dojo", location: "dojo/dojo" },
{ name: "dijit", location: "dojo/dijit" },
{ name: "dojox", location: "dojo/dojox" },
{ name: "put-selector", location: "put-selector" },
{ name: "xstyle", location: "xstyle" },
{ name: "dgrid", location: "dgrid" },
{ name: "allwins", location: "allwins" }
]
},[
"allwins/Admin",
"dojo/parser",
"dojo/domReady!"
],function(admin, Parser){
admin.initUi(/*...*/);
});
</script>
<!-- ... -->
<div data-dojo-id="invoicesTab2"
data-dojo-type="dijit.layout.BorderContainer"
data-dojo-props="region: 'center',
title: 'Faktury 2'">
<div id=invoicesGridTab2"></div>
</div>
JavaScript:
request(invoicesDataUrl, {
handleAs: "json"
}).then(function (response) {
var store = new Memory({ data: response });
var grid = new OnDemandGrid({
region: "center",
store: store,
columns: {
invoice_id: { label: "FID" },
user_id: { label: "UID" },
invoice_no: { label: "Číslo" },
user_fullname: { label: "Plátce" },
created_formatted: { label: "Vystavena" },
payment_date_formatted: { label: "Splatnost" },
payment_total: { label: "Částka" }
}
}, "invoicesGridTab2");
grid.startup();
});
I can add few more things:
List item
I have no errors at the JavaScript console
data source is already tested with using older dojox.grid.DataGrid
it seems that main problem is with the rendering
Thanks for any help or advice!
You need to specify the field attribute in your columns that match with the response data object, for example:
request(invoicesDataUrl, {
handleAs: "json"
}).then(function (response) {
var store = new Memory({ data: response });
var grid = new OnDemandGrid({
region: "center",
store: store,
columns: {
invoice_id: { label: "FID", field: "invoice_id" },
user_id: { label: "UID", field: "user_id" },
invoice_no: { label: "Číslo", field: "invoice_no" },
user_fullname: { label: "Plátce", field: "user_fullname" },
created_formatted: { label: "Vystavena", field: "created_formatted" },
payment_date_formatted: { label: "Splatnost", field: "payment_date_formatted" },
payment_total: { label: "Částka", field: "payment_total" }
}
}, "invoicesGridTab2");
grid.startup();
});
I do not know if those field names are correct, but I assume you would. :)

Categories

Resources