How to get a value of a property in JSON array from extjs store? - json

I have been trying to dynamically generate a check box from a value which is in JSON array from a JSON store.
{"MODULECATOGERY":[{"Menu":"MSU"},{"Menu":"SCHEDULE"},{"Menu":"MARKET_DASHBOARD"},{"Menu":"FE_REFERENCE"},{"Menu":"QC_TOOLS"},{"Menu":"QUICKQC_VOICE"},{"Menu":"QUICKQC_DATA"},{"Menu":"MARKETQC_VOICE"},{"Menu":"MARKETQC_DATA"},{"Menu":"SURGERY"},{"Menu":"FILE_INVENTORY"},{"Menu":"MARKET_TRACKER"},{"Menu":"DRIVE_ROUTE_TRACKER"},{"Menu":"TICKETS"},{"Menu":"TICKET_TRACKER"},{"Menu":"ASSETS"},{"Menu":"METRICS"},{"Menu":"DAILY_STATUS"},{"Menu":"DAILY_PROCESSING"},{"Menu":"WEEKLY_WORKFLOW"},{"Menu":"CUSTOMER_QUESTIONS"},{"Menu":"KPI_PERFORMANCE_METRICS"},{"Menu":"COLLECTION_METRICS"},{"Menu":"OPERATIONS_DASHBOARD"},{"Menu":"PRODUCTION_DASHBOARD"},{"Menu":"SUPPORT_DASHBOARD"},{"Menu":"REVENUE_TRACKER"},{"Menu":"DEPLOYMENT_TRACKER"},{"Menu":"TICKETS"},{"Menu":"TICKET_TRACKER"},{"Menu":"ASSET_MANAGEMENT"},{"Menu":"GENERATE_SHIPMENT"},{"Menu":"SHIPMENT_TRACKER"},{"Menu":"RESOURCES"},{"Menu":"SCHEDULE"},{"Menu":"TRACKER"}]}
How can a get values associated with "Menu" in the above JSON.? If i can have each and every value into an array then i can dynamically assign these to generate a check box group.
Thanks in Advance.

You can iterate your store:
store.each(function(record) {
var menu = record.get('Menu');
});
Edit:
Since you're saying this doesn't work with dynamic data I think you iterate it before it has completed loading. To be sure to handle the iteration after the load you can do the following:
store.on({
//Listener that fires everytime after your store has loaded
load: function() {
store.each(function(record) {
var menu = record.get('Menu');
//do stuff
});
}
});
store.load();
If you only want to execute the code the first time your store loads you can use the callback function on the load() method:
store.load(function() {
store.each(function(record) {
var menu = record.get('Menu');
//do stuff
});
});

Related

how to trigger a function in vuejs after the page is loaded?

I am trying to trigger a function which hides or show the images on the basis of data i have written two function one which calls the api which is in created hook and second function which renders the image . The problem is how do i call that second function after the dom is loaded , right now when i am trying to call in the first function or created it is returning me error that css cannot be changed of null.I have tried using mounted function with newtick but its still firing the render_badges function first and hence values are null inside
created:function(){
this.loadlike()
},
methods:{
loadlike:function(){
var self = this
this.$http.get('/api/user_profile').then(function (res) {
self.tasksdata = res.body
self.badges = self.tasksdata.data2
console.log(self.badges)
console.log(this.tasksdata)
console.log(this.max)
})
},
getHumanDate : function (date) {
return moment(date, 'YYYY-MM-DD hh-mm-ss').locale("en-gb").format('LL');
},
render_badges:function(){
var self = this
var counter = 0;
self.badges.map(function(e){
counter ++;
console.log(counter)
if(counter <=self.max){
document.getElementById("i").style.display = "initial";
}
else{
document.getElementById("i").style.display = "none";
}
})
},
mounted: function () {
this.$nextTick(function () {
this.render_badges();
})
}
Rather than manipulating the DOM, you should use v-if on the element itself that turns it on or off based on data. It is a different way of thinking than direct DOM manipulation learned in the jQuery days. Read more in the Vue docs about conditional rendering.
If you are wanting to trigger once the DOM is available, use mounted()

Data not being fetched from json file

I am trying to fetch data from the static json file but the data is not getting displayed at all. What could be the possible reason for it.
Below is my code:
var Collection = Backbone.Collection.extend({
url: "names_of_people.json",
initialize: function() {
this.fetch();
}
});
collections = new Collection();
console.log("the length "+collections.length);
for (i=1;i<collections.length;i++)
{
console.log("done "+ collections.at(i).get("name"));
}
The problem is that this code:
console.log("the length "+collections.length);
for (i=1;i<collections.length;i++)
{
console.log("done "+ collections.at(i).get("name"));
}
ends up being executed before this.fetch() has completed. You'll need to either put your code in this.fetch's success callback, like this:
var Collection = Backbone.Collection.extend({
url: '/data.json',
initialize: function() {
this.fetch({
success: function() {
console.log(collections, 'the length ' + collections.length);
for (var i = 0; i < collections.length; i++) {
console.log('done ' + collections.at(i).get('name'));
}
}
});
}
});
var collections = new Collection();
or by listening to the collection's sync event, which occurs when this.fetch has completed successfully. This pattern is more commonly used in Backbone applications.
var Collection = Backbone.Collection.extend({
url: '/data.json',
initialize: function() {
this.listenTo(this, 'sync', this.syncExample);
this.fetch();
},
syncExample: function() {
console.log(collections, 'the length ' + collections.length);
for (var i = 0; i < collections.length; i++) {
console.log('done ' + collections.at(i).get('name'));
}
}
});
var collections = new Collection();
You can read more about Backbone's event system and the listenTo function here.
check backbone parse function. after fetch it will also call vlidate and parse if they exist.
EDIT: more detail
The key thing here I think is, the fetch() is asynchronous, so by the time you start loop, the data is not here yet. So you need to execute the code when you are sure the collection is ready. I usually listen to a "reset" event, and let the fetch to fire a reset event by collection.fetch({reset:true}).
Backbone Collection, whenever fetch, and get an array of data from server in a format
[obj1,obj2],
it will pass each of these into a parse function, described here
For debug purpose you can simply do:
var MyCollection=Backbone.Collection.extend({
parse:function(response){
console.log(response);
return response;
}
})
This can check if the fetch indeed get the json.
On a side note, it is always a good practise to fetch it after you initialized the collection, means you don't put the this.fetch() inside initialize(), you do this outside.
for example, if you want to print out all the element name, you can do
var c=MyCollection();
c.fetch({reset:true}); // this will fire 'reset' event after fetch
c.on('reset',printstuff());
function printstuff(){
_.forEach(c,function(e){
console.log(e.get('name'));
});
}
Note this 'reset' event fires after all the collection is set, means it is after the parse() function. Apart from this parse(), there is also a validate function that is called by model. You collection must have a model parameter, you can make your own model, and give it a validate(), it also print out stuff.

Clicking, pasting text and uploading files from extension

So I'm basically developing an automated click-paste-and-upload system for mutiple texts and files inside a google page.
This method helped me get the instances of objects that I'm looking for: buttons, textboxes, richtextboxes, etc.
Now I want to work with them.
So for example I know the id of a button , and the function subscribed to its click event. How do I trigger the click event from the extension ? I've tried injecting a script with the click event handler (discovered with DOM inspector) at "document_startup" but I don't get an error or anything else.
Here's the content script! The loggerhead function should have inserted the script but I don't think it did. What might be the reason for the blow code not giving anything?
// Runs a function for every added DOM element that matches a filter
// filter -- either function(DOM_node){/*...*/}, returns true or false
// OR a jQuery selector
// callback -- function(DOM_node){/*...*/}
function watchNodes(filter, callback){
observer = new MutationObserver( function (mutations) {
mutations.forEach( function (mutation){
if(typeof filter === "function"){
$(mutation.addedNodes).filter(
function(i){ return filter(this); }
).each(
function(i){ callback(this); }
);
} else {
$(mutation.addedNodes).filter(filter).each(
function(i){ callback(this); }
);
}
});
});
// For every added element, a mutation will be processed
// with mutation.taget == parent
// and mutation.addedNodes containing the added element
observer.observe(document, { subtree: true, childList: true });
}
function loggerhead(node) {
console.log("passhead");
//also inject jquery
var jqueryEl = document.createElement('script');
jqueryEl.setAttribute('src', chrome.extension.getURL('jquery-1.11.1.min.js'));
jqueryEl.setAttribute('type', 'text/javascript');
var scriptEl = document.createElement('script');
scriptEl.setAttribute('src', chrome.extension.getURL('script.js'));
scriptEl.setAttribute('type', 'text/javascript');
node.appendChild(jqueryEl);
node.appendChild(scriptEl);
}
watchNodes("head", loggerhead);
// method not working
//var gmailHead = jQuery("head", document).get(0);
script.js contains the function of subscribed to the click event of the button that I've managed to find through the DOM inspector:
function Cdb(b){return function(){if(Vbb()){return Ddb(b,this,arguments)}else{var a=Ddb(b,this,arguments);a!=null&&(a=a.val);return a}}}
You should try to call the existing click handler like
buttonElement.click()

Custom binding to return the last Json record

I'm using the following code to load all Json data.
$.getJSON("/Home/GetSortedLists", function (allData) {
var mappedSortedLists = $.map(allData, function (item) { return new SortedLists(item) });
viewModel.sortedlists(mappedSortedLists);
});
I also need to load a single record from the same Json data; the record with the highest SortedListsID value (i.e. the last record entered).
Can anybody suggest the best way to do this? I've considered adding viewModel.lastsortedlist and amending the above code somehow. I've also considered creating a last custom binding to do something like:
<tbody data-bind="last: sortedlists.SortedListID">
All advice welcome.
Unless you want to do more ui-related stuff with the record, I don't think you need the custom binding.
It should be enough to compute it in the getJSON callback and save it in the viewModel:
$.getJSON("/Home/GetSortedLists", function (allData) {
var mappedSortedLists = $.map(allData, function (item) { return new SortedLists(item) });
viewModel.sortedlists(mappedSortedLists);
//correct the sort function if it's bad, or drop it if allData is already sorted
var sortedData = allData.sort(function(a,b){ return a.SortedListID - b.SortedListID})
viewModel.lastSortedList(sortedData[sortedData.length - 1])
});
Or, if it can change outside the getJSON callback, you could also make it a computed observable:
viewModel.lastSortedList = ko.computed(function(){
//correct the sort function if it's bad, or drop it
var sortedData = mappedSortedLists().sort(function(a,b){ return a.SortedListID - b.SortedListID})
return sortedData[sortedData.length - 1]
}, this)

JSON object does not update correctly

First of all, I'm not sure if my title describes the problem correctly... I did search but didn't find anything that helped me out...
The project I'm working on has an #orderList. All orders have a delete option. After an order gets deleted the list is updated.
Sounds simple... I ran into a problem though.
/**
* Data returned at the end of selecting some options
*/
$.post(myUrl, $('#myForm').serialize(), function(data) {
// I build the orderlist
// The data returned is a JSON object holding session data (including orders)
buildOrderList(data);
...
// Do some other work
});
/*
* function to build the html list
*/
function buildOrderList(data) {
// Empty list
$('#orderList').empty();
// The click handler for the delete button is in here because it needs the data object
$(document).on('click', '[id^=delete_]', function() {
// Get the orderId from the delete button
var orderId = $(this).attr('id').split('_');
orderId = orderId['1'];
// I call the delete function
deleteOrder(orderId, data);
});
var html = '';
// Loop the data object
$.each(data, function(key,val){
...
// Put html code needed in var html
...
});
$('#orderList').append(html);
}
/*
* function to delete an order
*/
function deleteOrder(orderId, data) {
// Because of it depends on other 'products' in the list if the user can
// simply delete it, I use a jQuery dialog to give him some options.
// These options I send to a php script so it knows what should be deleted.
// This fires when a user clicks on the 'delete' button from a dialog.
// The dialog uses data to show options but does not change the value of data.
switch(data.type) {
case 'A':
delMsg += '<p>Some message for case A</p>';
delMsg += '<select>with some options for case A</select>';
$('#wizard_dialog').append(delMsg);
$('#wizard_dialog').dialog('option', 'buttons', [
{ text: "Delete", click: function() {
$.post(myUrl, $('#myDeleteOptions').serialize(), function(newData) {
// Now the returned data is the updated session data
// So I build the orderList again...
buildOrderList(newData);
...
// Do some other work
});
$( this ).dialog( "close" );
$(this).html(''); }},
{ text: "Cancel", click: function() { $( this ).dialog("close"); $(this).html(''); }}
] );
break;
case 'B':
// Do the same thing but different text and <select> elements
break;
}
}
The orderList updates correctly, however if I try to delete another order, the jQuery dialog gives me the option for the current (correct product) AND the option for the product that previously owned the id of the current. (Hope I didn't loose anyone in my attempt to explain the problem)
The main question is how to 'refresh' the data send to buildOrderList.
Since I call the function in a new $.post with fresh data object returned it should work, shouldn't it?
/**
* Enable the JQuery dialog
* (#wizard_dialog)
* this is the init (note that I only open the dialog in deleteOrder() and set text and buttons according to the data send to deleteOrder() )
*/
$('#wizard_dialog').dialog({
autoOpen: false,
resizable: false,
modal: true,
dialogClass: "no-close",
open: function() {
$('.ui-dialog-buttonpane').find('button:contains("Annuleren")').addClass('cancelButtonClass');
$('.ui-dialog-buttonpane').find('button:contains("Verwijderen")').addClass('deleteButtonClass');
$('.ui-dialog :button').blur(); // Because it is dangerous to put focus on 'OK' button
$('.ui-widget-overlay').css('position', 'fixed'); // Fixing overlay (else in wrong position?)
if ($(document).height() > $(window).height()) {
var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
$('html').addClass('noscroll').css('top',-scrollTop); // Prevent scroll without hiding the bar (thus preventing page to shift)
}
},
close: function() {
$('.ui-widget-overlay').css('position', 'absolute'); // Brake overlay again
var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll'); // Allow scrolling again
$('html,body').scrollTop(-scrollTop);
$('#wizard_dialog').html('');
}
});
EDIT:
Because the problem could be in the dialog I added some code.
In the first code block I changed deleteOrder();
ANSWER
The solution was rather simple. I forgot to turn the click handler off before I added the new one. This returned the previous event and the new event.
$(document).off('click', '[id^=delete_]').on('click', '[id^=delete_]', function() {
// Get the orderId from the delete button
var orderId = $(this).attr('id').split('_');
orderId = orderId['1'];
// I call the delete function
deleteOrder(orderId, data);
});