How to convert javascript data attributes as array - custom-data-attribute

I am trying to develop a library object for slick carousel that passes the parameters in a data object. However I found that data objects can only be a string. I have found similar posts, but only for string to json.
Eval or split(",") does not work, btw...
Here is my code:
html:
<div class="carousel container-fluid no-margin" data-params="{dots: true, arrows: true, autoplay: true, autoplaySpeed: 4000}">
JS:
var loadCarousel = function(element) {
var carousel = $(element).find('.carousel');
var params;
if($(carousel).find('.single-item').length && !$(carousel).find('.single-item').hasClass('slick-initialized')) {
params = $(carousel).data('params'); // need to convert from a string to an array
$(carousel).find('.single-item')
.slick(
params
);
}
}
Thanks!

You have to use JSON.parse() to convert string into object but in your case you have to done some pre-processing to the string because for JSON.parse(), the string should be like '{"hello":"world"}'. Currently the string is in this form '{hello:world}'. I coded a small script in plain JS which convert string into the correct form for JSON.parse(). You can do it like this.
var a = document.getElementById("c");
var dataParams = a.getAttribute('data-params');
var newStr = "";
for (var i = 0; i<dataParams.length; i++){
if(dataParams[i]=="{"){
newStr = newStr+'{"';
}
else if(dataParams[i]==":"){
newStr = newStr+'":';
}
else if(dataParams[i]==" "){
newStr = newStr+' "';
}
else if(dataParams[i]==","){
newStr = newStr+'",';
}
else if(dataParams[i]=="}"){
newStr = newStr+'"}';
}
else{
newStr = newStr + dataParams[i];
}
}
var p = JSON.parse(newStr);
console.log(p.dots);
<div id ="c" class="carousel container-fluid no-margin" data-params="{dots: true, arrows: true, autoplay: true, autoplaySpeed: 4000}">

Related

Dialogflow fulfillment - How to add multiple agent.add() responses?

I have a list of firestore snapshot that I want to be as responses to an intent. I declare it into "res" varible and pass it into agent.add but it doesn't work. The "res" variable doesn't print anything.
Here is my code:
async function handlerReadFromDB(agent) {
let uId = agent.originalRequest.payload.uId;
console.log(uId);
const dataRef = db.collection('users').doc(`${uId}`).collection('medic_reminder');
const snapshot = await dataRef.get();
var med={};
var medObj = [];
var medRef={};
snapshot.forEach(doc => {
med=doc.data();
medObj.push({data: med});
});
var i;
var str="You need to take ";
for( i in medObj){
str = str +`${medObj[i].data.medName} at ${medObj[i].data.hour}:${medObj[i].data.min},`;
i++;
}
console.log(str);
return agent.add(`Yes, `+str);
}

Javascript AES with CryptoJS does not completely decrypt

All information i got are encrypted data (AES) and a key. The data must be a URL. I 've tried so many code-snippets (from stackoverflow) and found one snippets that worked for me partially.
// Decode the base64 data so we can separate iv and crypt text.
var rawData = atob(data);
var iv = btoa(rawData.substring(0,16));
var crypttext = btoa(rawData.substring(16));
// Decrypt...
var plaintextArray = CryptoJS.AES.decrypt(
{
ciphertext: CryptoJS.enc.Base64.parse(crypttext),
salt: ""
},
CryptoJS.enc.Hex.parse(key),
{ iv: CryptoJS.enc.Base64.parse(iv) }
);
// Convert hex string to ASCII.
function hex2a(hex) {
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
console.log(hex2a(plaintextArray.toString()));
The URL must be
http://test-example.com/hjhdsdfuisd
but the output is only
-example.com/hjhdsdfuisd.
I changed
var crypttext = btoa(rawData.substring(16));
to
var crypttext = btoa(rawData);
and got
­ô#XÍäÜ7±H4-example.com/hjhdsdfuisd.
What is my mistake?

NativeScript - how can I filter an observable array with SearchBar?

Hi I'm trying to filter an observable array of data fetched via a HTTP request on keypress of the SearchBar.
I managed to get the SearchBar property change to work but I can't seem to figure out what I'm doing wrong in the filtering logic.
Ideally I want to update the list as I type in the search term in the SearchBar. I've searched the API on the Telerik site, there wasn't really any examples I could find.
XML
<Page loaded="pageLoaded">
<ActivityIndicator busy="{{ isLoading }}" />
<ActionBar title="People">
</ActionBar>
<GridLayout>
<StackLayout>
<SearchBar id="searchBar" hint="Search for someone"></SearchBar>
<ListView items="{{ peopleList }}" itemTap="showDetail">
<ListView.itemTemplate>
<StackLayout>
<Label text="{{ fullName }}" horiztonalAlignment="left" verticalAlignment="center"></Label>
<Label text="{{ company }}" class="info"></Label>
</StackLayout>
</ListView.itemTemplate>
</ListView>
</StackLayout>
</GridLayout>
</Page>
JS
var frames = require("ui/frame");
var Observable = require("data/observable").Observable;
var PeopleListViewModel = require("../../shared/people-viewModel");
var activityIndicatorModule = require("ui/activity-indicator");
var page;
var userkey;
var peopleList = new PeopleListViewModel([]);
var pageData = new Observable({ peopleList: peopleList });
exports.pageLoaded = function(args) {
page = args.object;
page.bindingContext = pageData;
userkey = userkey || page.navigationContext.userkey;
peopleList.load(userkey); // fetch data from the backend
var searchBar = page.getViewById("searchBar");
searchBar.on("propertyChange", function (args) {
var searchText = args.object.text;
if (searchText === "") {
// NOT SURE WHAT TO DO HERE.
} else {
peopleList.filter(function (element, index, array) {
// DOESN"T WORK PROPERLY
console.log("element: ", JSON.stringify(element));
return element.fullName == searchText;
});
console.log("Text types: ", searchText);
}
});
};
exports.showDetail = function(args) {
var person = peopleList.getItem(args.index);
var navigateEntry = {
moduleName: "views/people/people-detail",
context: { person: person },
animated: false
};
frames.topmost().navigate(navigateEntry);
};
PeopleListViewModel.js
var config = require("./config");
var fetchModule = require("fetch");
var ObservableArray = require("data/observable-array").ObservableArray;
function PeopleListViewModel(people) {
var viewModel = new ObservableArray(people);
viewModel.load = function (userKey) {
return fetchModule.fetch(config.baseUrl + "/api/people/all/" + userKey)
.then(function (response) {
return response.json();
})
.then(function (data) {
data.forEach(function (person) {
viewModel.push(person);
});
}, function (error) {
console.log("Error: ", error);
});
};
viewModel.empty = function () {
while (viewModel.length) {
viewModel.pop();
}
};
return viewModel;
}
function handleErrors(response) {
if (!response.ok) {
console.log("Error occurred");
}
}
module.exports = PeopleListViewModel;
Updated people-list
var frames = require("ui/frame");
var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;
var PeopleListViewModel = require("../../shared/people-viewModel");
var activityIndicatorModule = require("ui/activity-indicator");
var page;
var userkey;
var peopleList = new PeopleListViewModel([]);
var pageData = new Observable({ peopleList: peopleList });
var resultList = new ObservableArray([]);
exports.pageLoaded = function(args) {
page = args.object;
page.bindingContext = pageData;
userkey = userkey || page.navigationContext.userkey;
peopleList.load(userkey);
var searchBar = page.getViewById("searchBar");
searchBar.on("propertyChange", function (args) {
var searchText = args.object.text;
if (searchText === "") {
} else {
while (resultList.length > 0) {
resultList.pop();
}
peopleList.forEach(function (element) {
if (element.fullName === searchText) {
resultList.push(element);
}
});
}
});
};
I had the same issue. If you want to filter your data after every character has changed in search-bar you can try my solution.
Definitions
My playerList is your peopleList. This is the data from view-model.
resultList is an array where the data will be pushed.
var observableArrayModule = require("data/observable-array").ObservableArray;
var playerList = new PlayerListViewModel([]);
var resultList = new observableArrayModule([]);
var pageData = new observableModule.Observable({
resultList: resultList,
player: ""
});
Inside expors.loaded()
page = args.object;
searchBar = page.getViewById("search-bar");
page.bindingContext = pageData;
Load Initial Data - inside expors.loaded()
We are loading initial data when user navigates to the screen for the first time. We are also pushing the same data to resultList since we are using {{resultList}} in xml. You can add loadingIndicator while the list is populated.
playerList
.load()
.then(function() {
setTimeout(function() {
playerList.forEach(function (element) {
pageData.resultList.push(element);
});
}, 1000);
})
.catch(function(error) {
dialogsModule.alert({
message: "An error occurred while loading players.",
okButtonText: "OK"
});
});
Clear autofocus - inside expors.loaded()
This is to prevent keyboard from opening on initial screen navigation.
if (searchBar.ios) {
searchBar.ios.endEditing(true);
} else if (searchBar.android) {
searchBar.android.clearFocus();
}
Search data when character has changed - inside expors.loaded()
I am calling filter functionality. Lodash _.debounce function is used to delay looping through resultList array. Without it, the app would loop every time letter is typed. Now we are waiting for user to stop typing to start looping.
searchBar.on('propertyChange', _.debounce(searchList, 500));
searchList Function
This is the actual loop. You can change element.name for your needs.
function searchList(args) {
var searchText = args.object.text;
while(resultList.length > 0) {
resultList.pop();
}
playerList.forEach(function (element) {
if (element.name.toLowerCase().indexOf(searchText) >= 0) {
resultList.push(element);
}
});
}
Hide keyboard if search-bar is cleared - inside exports.loaded()
And finally we want to hide the keyboard if user clears the search-bar.
searchBar.on(searchBarModule.SearchBar.clearEvent, function (args) {
setTimeout(function() {
searchBar.dismissSoftInput();
}, 10);
});
PS
You probably solved your issue, but this could help someone else in the future.
Okay so your problem is a Javascript problem than a NativeScript problem. For the sake of this problem, think of observable arrays as just your ordinary arrays.
In your JS you're creating a new PeopleListViewModel which you're then attaching to the bindingContext via the pageData object. So far so good. Then you're calling the load method on the PeopleListViewModel (It returns a promise which you're not really doing anything with but for this specific problem it doesn't matter).
However, when text is inputed you're not really doing anything. This is your code:
peopleList.filter(function (element, index, array) {
// DOESN"T WORK PROPERLY
console.log("element: ", JSON.stringify(element));
return element.fullName == searchText;
});
peopleList is an instance of PeopleListViewModel which returns an ObservableArray. The ObservableArray does indeed have a method called filter (which works just like filter of a regular array. Check out the NativeScript documentation and Javascript documentation of filter).
What you need to understand here is that filter returns a new array with the filtered results. Doing peopleList.filter() will send that new array into empty space. You want to var yourNewFilteredArray = peopleList.filter(). But you don't really want to redefine the array bound to the binding context, you want to modify the content of it.
Here's an example of how you could do that:
/*
* Attach a new obsersable array to the binding context.
* you can prepopulate it with the data from the
* PeopleListViewModel if you want to
*/
var resultList = new ObservableArray([]);
var pageData = new Observable({ resultList: resultList });
/*
* Then on search/filter you want to modify this new
* array. Here I first remove every item in it and then
* push matching items to it.
*/
searchBar.on("propertyChange", function (args) {
var searchText = args.object.text;
// ...
while(resultList.length > 0) {
resultList.pop();
}
peopleList.forEach(function (element) {
if (element.fullName === searchText) {
resultList.push(element);
}
});
});

Append divs changing his content dynamic

I have a dif called cdefualt that has some inputs from a form inside of it and I want to do something like this to clone it and change that input names:
var i = 2;
function add() {
var item = $('#cdefault').clone();
item.attr({'style': ''});
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
item.id = $xpto;
$('#'+$xpto+' input[id="gtitle1"]').attr('name', $xpto);
$('#'+$xpto+' textarea[id="gmessage1"]').attr('name',$xpto2);
$(item).appendTo('#ccontainer');
i++;
}
But this doesnt work. I've tried this already as well but it only works twice (for the original and first clone):
var i = 2;
function add() {
var item = $('#cdefault').clone();
item.attr({'style': ''});
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
$('#cdefault input[id="gtitle1"]').attr('id', $xpto);
$('#cdefault textarea[id="gmessage1"]').attr('id',$xpto2);
$('#cdefault input[name="gtitle1"]').attr('name', $xpto);
$('#cdefault textarea[name="gmessage1"]').attr('name', $xpto2);
$(item).appendTo('#ccontainer');
i++;
}
Even tryed this way:
function add() {
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
var div = document.getElementById('cdefault');
clone = div.cloneNode(true); // true means clone all childNodes and all event handlers
clone.id = $xpto;
clone.style.display = '';
$("#"+$xpto+" input[id='gtitle1']").attr('name', $xpto);
$("#"+$xpto+" textarea[id='gmessage1']").attr('name',$xpto2);
document.getElementById('ccontainer').appendChild(clone);
i++;
}
http://jsfiddle.net/Theopt/xNfSd/
fixed. changed cdefault id to id0 and this java script:
var i = 2;
var c = 0;
function add() {
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
var klon = $( '#id'+ c );
klon.clone().attr('id', 'id'+(++c) ).insertAfter( '#inserthere' );
document.getElementById('id'+(c)).style.display = '' ;
$("#id"+(c)+" input[id='gtitle1']").attr('name', $xpto);
$("#id"+(c)+" textarea[id='gmessage1']").attr('name',$xpto2);
i++;
}

TinyMCE strip_tags function like php?

how can I accept just certain tags and strip_tags all others when paste text to editor? just like php's strip_tags function?
and how can I remove all styles from that tags?
input is a string.
i have a function to this
var strip_tags = function(str,tags,attrs){
var reg2 = /\s*(\w+)=\"[^\"]+\"/gm;
var reg = /<\s*(\w+).*?>/gm;
str = str.replace(reg,function(match, i) {
var r_ = match;
var reg_ = /<\s*(\w+).*?>/gm;
var m_ = reg_.exec(match);
if(m_!=null){
if(tags.indexOf(m_[1])>=0){
r_ = match.replace(reg2,function(match_, i) {
var reg2_ = /\s*(\w+)=\"[^\"]+\"/gm;
var m = reg2_.exec(match_);
if(m!=null){
if(attrs.indexOf(m[1])>=0){
return match_;
}
}
return '';
});
}else{
r_ = '';
}
}else{
r_ = '';
}
return r_;
});
var reg3 = /<\/\s*(\w+).*?>/gm;
str = str.replace(reg3,function(match, i) {
var r_ = match;
var reg_ = /<\/\s*(\w+).*?>/gm;
var m_ = reg_.exec(match);
if(m_!=null){
if(tags.indexOf(m_[1])>=0){
return match;
}
}
return '';
});
return str;
};
tinyMCE.init(
...
plugins: "paste...
paste_preprocess : function(pl, o) {
var allowed_tags = ['ul','li','b','p','table','tr','td'];
var allowed_attributes = ['href','colspan','rowspan'];
o.content = strip_tags(o.content,allowed_tags,allowed_attributes);
},
...
);