I have a problem with share parameters from one object to other
I have one LatestVideos object with options my video galleries and other object with methods to Paginate, Render, Categories and LocalStorage, witch handup all functionality but I use this to many this I need this as separete object
(function (window, document, none) {
"use strict";
var LatestVideos = window.LatestVideos = function (option) {
/* object to init puglin data JSON FORMAT keys Jsondata or url , container,
actual page wrapper on paggination, number of item per page, categorywrapper*/
this.fragments = document.createDocumentFragment();
this.categories = ["Favorite"];
this.statusLoad = 0;
this.allid = [];
this.categoryid = [];
this.actual = [];
//this.categoryChecked=[];
this.page = 0;
loadJSON(option.url,this.initData.bind(this));
this.settings = { /// init data from options object from parameter constructor
JsonData :option.data || 0,
container : option.container,
actpage : option.actpage || 1,
buttonwrapper : option.paginationwrapper,
categorywrapper : option.categorywrapper,
itemperpage : option.itemperpage, // get value from prev Selection or default
};
};
LatestVideos.prototype.initData = function (data) { // assinchrounous call json with ajax
this.settings.JsonData = data;
this.settings.lengthData = data.length;
Render.setData(this);
Render.getCategories();
};
var Render = { // need this data from LASTESTVIDEOS data,conteiner,paginationwrapper,categorywrapper
/// object with method to render articles to my website
};
var Pagination = function(){
// from LASTESTVIDEOS I need JsonData, actPage overide page and paginatorwrapper
// object with method to calculate number of pages and paginate my articles
};
var Cateogry = function(){
// from LASTESTVIDEOS categoryid change actual and allid
// object with method to changeCategory and get category from data atribut
};
var LocalStoraget = function (){
// I JSON data from LASTESTVIDEOS
// object with method to getFavorite item form localstorage and add to localstorage
};
})(window, document);
function loadJSON(url, callback) {
/* function to load ajax from url input(url- form and callback function),
output function call and post (ARRAY JSON OBJECTS)*/
var xmlhttp =0;
if (typeof XMLHttpRequest !== 'undefined') {
xmlhttp = new XMLHttpRequest();
} else {
var versions = ["Microsoft.XmlHttp",
"MSXML2.XmlHttp",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.5.0"];
var len = versions.length;
for (var i = 0; i < len; i++) {
try {
xmlhttp = new ActiveXObject(versions[i]);
break;
}
catch(e){}
}
}
xmlhttp.onreadystatechange = ensureReadiness;
function ensureReadiness(){
if (xmlhttp.readyState === 4 && xmlhttp.status === 200)
{
JSONObject = JSON.parse(xmlhttp.responseText);
callback (JSONObject);
}else{
return;
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
var options = {url:"someURL",container:"videox",paginationwrapper:"pages"};
var opp = new LatestVideos(options);
and this is a plugin witch I need create xtimes with differend options and sometimes I need separetly render or paginate object or localstorage
I would probably change it a bit:
var Render = function (options) {
this.options = $.extend({ //default options
data: [],
container: null
}, options);
// use internal logic here
var getCategories = function(){
...
};
// and return public methods
return {
getCategories: getCategories
};
};
and change the code in LatestVideos to the following:
LatestVideos.prototype.initData = function (data) { // assinchrounous call json with ajax
this.settings.JsonData = data;
this.settings.lengthData = data.length;
var renderer = new Render({
data: this.settings.JsonData,
container: this.settings.container
});
renderer.getCategories();
};
Related
I have a modular libray javascript file where I am exposing two functions
init to initalise variables from my main.html file.
execValidation function to run based on those three variables collections initialised through main file.
For example:
var libraryModule = (function () {
var arVals = {};
var webFormData = {};
var rules = [];
function init(arVals, webFormData, rules) {
//init all variables to global variables to use in execute Validations
this.arVals = arVals;
this.webFormData = webFormData;
this.rules = rules;
}
//only passing RuleID, but it has dependencies of other variables, which I
//do not want to pass here
function execValidation(ruleID) {
//debugger;
//Load arVals, webFormData and Rules from init
var webFormData = this.webFormData;
var arVals = this.arVals;
var arVal = arVals[ruleID];
var rules = this.rules;
var rule = rules[ruleID]
console.log(arVal);
console.log(webFormData);
console.log(rules);
}
return {
execValidation: execValidation,
init : init
}
})(); // IIFE function
In My html file, I am calling like this
var arVals = {};
//calling json file using call back
ruleConfigModule.init(function (data) {
arVals = data;
});
//passing the arVals, webFormData and rules collection to init
libraryModule.init(arVals, webFormData, rules);
Only passing the ruleID
var result = libraryModule.execValidation("Rule1");
I only want to pass one variable which is RuleID from execValidation function, but the init function should setup those variables inside the js library itself. Please can anyone help, as it does not work or help to re-organise it.
JSON calling method to populate arVals
var ruleConfigModule = (function () {
function init(callback) {
loadJSON(function (json) {
callback(json);
});
}
// Let's hide this function
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'http://localhost/test/config.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(JSON.parse(xobj.responseText));
}
};
xobj.send();
}
return {
//loadJSON: loadJSON,
init: init
}
})();
Updated:
Blockquote
How do I ensure that arVals populated before the init method gets called?
This should work
function LibraryModule() {
var arVals = {};
var webFormData = {};
var rules = [];
}
LibraryModule.prototype.init = function init(arVals, webFormData, rules) {
//init all variables to global variables to use in execute Validations
this.arVals = arVals;
this.webFormData = webFormData;
this.rules = rules;
}
LibraryModule.prototype.execValidation = function execValidation(ruleID) {
//debugger;
//Load arVals, webFormData and Rules from init
var webFormData = this.webFormData;
var arVals = this.arVals;
var arVal = arVals[ruleID];
var rules = this.rules;
var rule = rules[ruleID]
console.log(arVal);
console.log(webFormData);
console.log(rules);
return rules;
}
let libraryModule = new LibraryModule();
libraryModule.init({
rule: 'TEST'
}, {
rule: 'TEST'
}, {
rule: 'TEST'
})
var result = libraryModule.execValidation("rule");
console.log(result);
In my SAPUI5 application I have a JS Fragment that does not update my data. If I refresh the window I get the data correctly, but I need to use window.location.reload().
You can check the code below:
onInit: function () {
var oRouters = sap.ui.core.UIComponent.getRouterFor(this);
oRouters.getRoute("chartContainer").attachPatternMatched(this._onObjectMatched, this);
},
_onObjectMatched: function (oEvent) {
var sYear = oEvent.getParameter("arguments").Year;
var sMonth = oEvent.getParameter("arguments").Month;
var sGroup = oEvent.getParameter("arguments").Group;
var sCurrency = oEvent.getParameter("arguments").Currency;
if (sYear === undefined && sMonth === undefined && sGroup === undefined && sCurrency === undefined){
var oStartupParameters = this.getOwnerComponent().getComponentData().startupParameters;
sYear = oStartupParameters.Year;
sMonth = oStartupParameters.Month;
sGroup = oStartupParameters.Group;
sCurrency = oStartupParameters.Currency
}
var sServiceUrl = "/sap/opu/odata/sap/Z_TEST/";
var filterYear = new sap.ui.model.Filter("Year", sap.ui.model.FilterOperator.EQ, sYear);
var filterMonth = new sap.ui.model.Filter("Month", sap.ui.model.FilterOperator.EQ, sMonth);
var filterGroup = new sap.ui.model.Filter("Group", sap.ui.model.FilterOperator.EQ, sGroup);
var filterCurrency = new sap.ui.model.Filter("Currency", sap.ui.model.FilterOperator.EQ, sCurrency);
var oModelOdata = new sap.ui.model.odata.v2.ODataModel(sServiceUrl, {
json: true,
loadMetadataAsync: true
});
var oModel = new sap.ui.model.json.JSONModel();
oModelOdata.read("/DataSet",{
filters: [filterYear, filterMonth, filterGroup, filterCurrency],
success: function(oData, response) {
var oResults = oData.results;
oModel.setData(oData);
var oView = sap.ui.getCore().byId("__xmlview0");
if (oView !== undefined){
oView.setModel(oModel);
}else{
window.location.reload(); // It works correctly butI would like not to have to reload the whole page.
}
}
});
},
How could I refresh the view without refreshing the whole page?
Thanks in advance for your support
Sergio
You should refresh your model by using the refresh() method:
oModelOdata.read("/DataSet",{
filters: [filterYear, filterMonth, filterGroup, filterCurrency],
success: function(oData, response) {
var oResults = oData.results;
oModel.setData(oData);
var oView = sap.ui.getCore().byId("__xmlview0");
if (oView !== undefined){
oView.setModel(oModel);
}else{
oModel.refresh(); // refresh new model data bindings
}
}
});
You should also use promises when making the API call to get the data.
I have a search form to call a Solr index, filled with geolocations:
jQuery('.form-submit', element).click(function (e) {
e.preventDefault();
search();
});
function search() {
useBBOX = false;
combinedExtent = ol.extent.createEmpty();
data.map.getLayers().forEach(function (layer, index, array) {
if (layer.getSource() instanceof ol.source.Vector) {
var source = layer.getSource().getSource();
var url = data.opt.urls[source.get('machineName')];
var newSource = new ol.source.Vector({
loader: getLoader(data, url),
format: new ol.format.GeoJSON(),
strategy: ol.loadingstrategy.bbox,
reloadOnZoomChange: true,
reloadOnExtentChange: true
});
newSource.set('machineName', source.get('machineName'));
var newCluster = new ol.source.Cluster({
source: newSource,
distance: 200
});
layer.setSource(newCluster);
}
});
}
function getLoader(data, url) {
return function (extent, resolution, projection) {
var bbox = ol.proj.transformExtent(extent, data.map.getView().getProjection(), 'EPSG:4326');
var params = {};
if (data.opt.paramForwarding) {
var get_params = location.search.substring(location.search.indexOf('?') + 1).split('&');
jQuery.each(get_params, function (i, val) {
if (val.length) {
var param = val.split('=');
params[decodeURIComponent(param[0])] = (param[1] !== undefined) ? decodeURIComponent(param[1].replace(/\+/g, ' ')) : '';
}
})
}
if (useBBOX == true) {
params.bbox = bbox.join(',');
params.zoom = data.map.getView().getZoom();
}
var searchQuery = jQuery('#input-search-address').val();
if (searchQuery != 'undefined' && searchQuery != null) {
url = url.substr(0, url.lastIndexOf("/") + 1);
url = url + searchQuery;
}
jQuery(document).trigger('openlayers.bbox_pre_loading', [{
'url': url,
'params': params,
'data': data
}]);
var that = this;
jQuery.ajax({
url: url,
data: params,
success: function (responsdata) {
var features = that.getFeaturesInExtent(extent);
jQuery(features).each(function (i, f) {
that.removeFeature(f);
});
var format = new ol.format.GeoJSON();
var features = format.readFeatures(responsdata, {featureProjection: projection});
that.addFeatures(features);
that._loadingFeatures = false;
if (!ol.extent.isEmpty(that.getExtent())) {
combinedExtent = ol.extent.extend(combinedExtent, that.getExtent());
if (useBBOX == false) {
useBBOX = true;
}
}
}
});
};
}
Basically, it fetches 3 layers, each containing a number of markers. I'ld like to autozoom the map based on those markers. Therefore I'm looking for the extent. The combinedExtent does contain all correct extents...
... but when I add data.map.getView().fit(combinedExtent, data.map.getSize()) INSIDE the getLoader function, it's not working. I looks like only 1 extent get plotted on the map.
Whenever I try to log the combinedExtent in the search() function, I get a weird error...
Google told me I had to wait until the getState() of newSource was ready, but that didn't work out...
So, I'm looking for a solution. My guess would be the use of the ajax return in getLoader...
I just had this issue, so I have a function to listen until the source is ready and finished loading before giving a count of features (otherwise it would update the log with every iteration). Just change my source name (any variable with "parcelquery in it) with yours and hopefully it will at least put you in the right direction.
var listenerKey = wfsSource_parcelquery.on('change', function(e) {
if (wfsSource_parcelquery.getState() == 'ready') { //says source is done loading
var featureCount = wfsSource_parcelquery.getFeatures().length; //getting number of features resulting from query
ol.Observable.unByKey(listenerKey);
// use vectorSource.unByKey(listenerKey) instead
// if you do use the "master" branch of ol3
}
alert("Your query returned "+ featureCount + " results.");
var extent = lyr_parcelquery.getSource().getExtent();
console.log(extent);
map.getView().fit(extent, map.getSize());
});
I have a class called TileStreamer that I am currently defining as follows:
function TileStreamer {
};
This class has constants, which I define as follows:
// Tiles are 256 x 256 pixels
TileStreamer.prototype.TILE_SIZE = 256;
// Header size in bytes
TileStreamer.prototype.HEADER_SIZE = 28;
// Various table entry sizes in bytes
TileStreamer.prototype.RESOLUTION_ENTRY_SIZE = 12;
TileStreamer.prototype.TILE_COUNT_SIZE = 4;
TileStreamer.prototype.TILE_ENTRY_SIZE = 12;
// Offsets within header
TileStreamer.prototype.WIDTH_OFFSET = 3;
TileStreamer.prototype.HEIGHT_OFFSET = 4;
TileStreamer.prototype.NUM_TABLES_OFFSET = 7;
TileStreamer.prototype.UNPOPULATED_OFFSET = 12092;
There also other variables. These variables are important because they need to be accessible from other classes. They get their values within the methods of this class. This is what I am unsure of as far as structure. What I'm currently trying is:
TileStreamer.prototype.header;
TileStreamer.prototype.resolutionEntry;
TileStreamer.prototype.resolutionTable;
TileStreamer.prototype.filepath;
TileStreamer.prototype.s3;
TileStreamer.prototype.level;
TileStreamer.prototype.ncols;
TileStreamer.prototype.nrows;
TileStreamer.prototype.nlevels;
TileStreamer.prototype.toffset;
TileStreamer.prototype.tsize;
TileStreamer.prototype.modifiedTime;
TileStreamer.prototype.tile;
TileStreamer.prototype.host;
TileStreamer.prototype.bucket;
This class also has methods such as:
TileStreamer.prototype.Init = function(filepath, index, s3config){
var retval = false;
AWS.config.update({accessKeyId: s3config.access_key, secretAccessKey: s3config.secret_key});
var blc = new BlockLibraryConfigs();
var awsConfig = blc.awsConfig;
AWS.config.update({region: awsConfig.region});
var aws = new AWS.S3();
var params = {
Bucket: s3config.bucket,
Key: s3config.tile_directory + filepath,
Range: 'bytes=0-' + (this.HEADER_SIZE - 1)
};
aws.getObject(params, function(err, data){
if(err == null){
TileStreamer.modifiedTime = data.LastModified;
var header = bufferpack.unpack('<7I', data.Body);
TileStreamer.header = header;
TileStreamer.nlevels = header[TileStreamer.NUM_TABLES_OFFSET];
if(TileStreamer.nlevels == 5){
TileStreamer.level = 0;
TileStreamer.ncols = Math.ceil((header[TileStreamer.WIDTH_OFFSET] * 1.0) / TileStreamer.TILE_SIZE);
TileStreamer.nrows = Math.ceil((header[TileStreamer.HEIGHT_OFFSET] * 1.0) / TileStreamer.TILE_SIZE);
}
}
});
};
The method above should set some of the values of the variables, such as modifiedTime so that I can access it in another class such as:
TileStreamer = require('tilestreamer.js');
var ts = new TileStreamer();
ts.Init(parPath, index, config);
var last_modified = ts.modifiedTime;
Just put any public properties you want to initialise when the object is created, directly in the init function. Here's a small example...
function TileStreamer() {
};
TileStreamer.prototype.Init = function() {
this.modifiedTime = new Date();
};
var ts = new TileStreamer();
ts.Init();
console.log(ts);
jsfiddle example
https://jsfiddle.net/v6muohyk/
To get around the issue you're having with setting the object properties in a callback from an asynchronous function, just create a locally accessible variable to reference the object that you are creating at that time...
TileStreamer.prototype.Init = function() {
var thisTileStreamer = this;
asynchFunction(function(err, data) {
thisTileStreamer.modifiedTime = data.lastModified;
});
};
To take it one step further, if you need to execute some code after the init function has completed, then that will require waiting for the asynchronous function to complete, as well. For that, pass a further parameter to init, that is a function to be executed after all the work is done...
TileStreamer.prototype.Init = function(callback) {
var thisTileStreamer = this;
asynchFunction(function(err, data) {
thisTileStreamer.modifiedTime = data.lastModified;
callback();
});
};
var ts = new TileStreamer();
ts.Init(function() {
// put code here that needs to be executed *after* the init function has completed
alert(ts.modifiedTime);
});
may be you can help me. How can I create global object and function that return object values by id?
Example:
var chat = {
data : {
friends: {}
}
}
....
/*
JSON DATA RETURNED:
{"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
*/
onSuccess: function(f){
chat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends.push(f.users[i])
}
}
How can I create a new function (It will return values by friend_id)?
get_data_by_id: function (what, friend_id) {
/*obj.what = getfrom_globalobject(chat.data.friends???)*/
}
Example of use:
var friend_name = get_data_by_id(name, 62);
var friend_username = get_data_by_id(username, 62);
var friend_avatar = get_data_by_id(thumb, 62);
Try:
get_data_by_id: function (what, friend_id) {
return chat.data.friends[friend_id][what];
}
... but use it like:
var friend_name = get_data_by_id('name', 62);
...and set up the mapping with:
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i];
}
You cannot .push() to an object. Objects are key => value mappings, so you need to use char.data.friends[somekey] = f.users[i];
If you really just want a list with numeric keys, make x5fastchat.data.friends an array: x5fastchat.data.friends = [];
However, since you want to be able to access the elements by friend_id, do the following:
onSuccess: function(f){
x5fastchat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i]
}
}
get_data_by_id: function (what, friend_id) {
obj[what] = chat.data.friends[friend_id][what];
}
Note the obj[what] instead of your original obj.what: When writing obj.what, what is handled like a string, so it's equal to obj['what'] - but since it's a function argument you want obj[what].
Take a look at the following code. You can simply copy paste it into an HTML file and open it. click "go" and you should see the result. let me know if I did not understand you correctly. :
<script>
myObj = { "field1" : { "key1a" : "value1a" }, "field2" : "value2" }
function go()
{
findField(myObj, ["field2"])
findField(myObj, ["field1","key1a"])
}
function findField( obj, fields)
{
var myVal = obj;
for ( var i in fields )
{
myVal = myVal[fields[i]]
}
alert("your value is [" + myVal + "]");
}
</script>
<button onclick="go()">Go</button>
I would recommend using the friend objects rather than getting them by id and name.
DATA = {"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
// simple data store definition
Store = {items:{}};
NewStore = function(items){
var store = Object.create(Store);
store.items = items || {};
return store
};
Store.put = function(id, item){this.items[id] = item;};
Store.get = function(id){ return this.items[id]; };
Store.remove = function(id){ delete this.items[id]; };
Store.clear = function(){ this.items = {}; };
// example
var chat = {
data : {
friends : NewStore()
}
}
// after data loaded
chat.data.friends.clear();
for( var i = 0; i < DATA.users.length; i += 1 ){
var user = DATA.users[i];
chat.data.friends.put( user.friend_id, user );
}
getFriend = function(id){ return chat.data.friends.get( id ); }
var friend = getFriend(66);
console.log(friend.name);
console.log(friend.username);
console.log(friend.thumb);