Related
<form class="col-xs-12"> <script type="text/javascript">
var stocks = {
"938975": true,
"938977": true,
"938979": true,
"938981": true,
"938983": true,
"938985": true,
"938987": false,
"938989": true,
"938991": true,
"938993": true,
"938995": true,
"938997": false,
"938999": true,
"939001": true,
"939003": true,
"939005": true,
"939007": true
};
How do I get and loop it, that if there is a true value in var stocks for any variable bot goes further but when there is false it stops?
For now I'm using something like that, hope you understand:
div = soup.find("form",("class"=="col-xs-12")).find("script",("type"=="text/javascript"
I’m doing bot in python
See if this can help!
Have added the code so if we have some entries at the end, even if we do not have false, they also get added. Its outside the loop and can be removed if not needed.
var stocks = {"938975":true,"938977":true,"938979":true,"938981":true,"938983":true,"938985":true,"938987":false,"938989":true,"938991":true,"938993":true,"938995":true,"938997":false,"938999":true,"939001":true,"939003":true,"939005":true,"939007":true};
var arraysOfStocks = [],tempArray = [];
for (let [key, value] of Object.entries(stocks)) {
//console.log(key +":"+value);
if(value){
tempArray.push(key);
} else {
arraysOfStocks.push(tempArray);
tempArray = [];
}
}
arraysOfStocks.push(tempArray);
tempArray = [];
console.log(arraysOfStocks);
I am using select2 in an express app to make an input box where users can select subjects from a list, and can update this list with any newly added options.
The thing I'm struggling with is that select2 runs client-side, whereas any data I use to seed my <option> tags (that I want to append new options to) is server-side.
I want users to be able to add subjects that don't exist in the original list, so that future users will be presented with newly added options (as well as the original ones)
These are the options I've considered for achieving this (in increasing desirability):
Add new <option>Subject</option> html tags for each added tag
Push new tags to an array, and seed the <option>s from this array
Seed the <option> from a json object, and update this object on tag creation
Seed the <option> from an external database (e.g. mongoose), and update this on tag creation
As far as I can see, all of these options require that my client-side code (select2-js) talks to server-side code (where my array, .json file or mongoose schema would be), and I have no idea how to go about doing this.
In my current approach I am attempting to to specify a "local" json file as my data source in my select2 call (see here). However, this doesn't seed the database with any options, so this isn't working as I expected.
I then check if each new tag exists in an array (dataBase), and add it to the database if not:
// Data to seed initial tags:
var dataBase = [
{ id: 0, text: 'Maths'},
{ id: 1, text: 'English'},
{ id: 2, text: 'Biology'},
{ id: 3, text: 'Chemistry'},
{ id: 4, text: 'Geography'}
];
$(document).ready(function() {
$('.select2-container').select2({
ajax: {
url: '../../subjects.json',
dataType: 'json',
},
width: 'style',
multiple: true,
tags: true,
createTag: function (tag) {
var isNew = false;
tag.term = tag.term.toLowerCase();
console.log(tag.term);
if(!search(tag.term, dataBase)){
if(confirm("Are you sure you want to add this tag:" + tag.term)){
dataBase.push({id:dataBase.length+1, text: tag.term});
isNew = true;
}
}
return {
id: tag.term,
text: tag.term,
isNew : isNew
};
},
tokenSeparators: [',', '.']
})
});
// Is tag in database?
function search(nameKey, myArray){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].text.toLowerCase() === nameKey.toLowerCase()) {
return true
}
}
return false
};
However, this approach will add the new tags to an array that is destroyed once I refresh the page, and new tags are not stored.
How can I modify this to load server-side data (json, mongoose document or anything else that is considered a best practice), and update this data with newly added options (that pass my tests)?
On your server-side, you can have an api that maintains and returns the tag array.
If you want the array to persist even after server shutdown, you can store the tags array in a database.
Server side:
let dataBase = [
{ id: 0, text: 'Maths'},
{ id: 1, text: 'English'},
{ id: 2, text: 'Biology'},
{ id: 3, text: 'Chemistry'},
{ id: 4, text: 'Geography'}
];
//Assuming you have a nodejs-express backend
app.get('/tags', (req,res) => {
res.status(200).send({tags: dataBase});
} );
Client Side:
$(document).ready(function() {
dataBase=[];
$.get("YOUR_SERVER_ADDRESS/tags", function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
dataBase = data;
});
$('.select2-container').select2({
data: dataBase,
placeholder: 'Start typing to add subjects...',
width: 'style',
multiple: true,
tags: true,
createTag: function (tag) {
var isNew = false;
tag.term = tag.term.toLowerCase();
console.log(tag.term);
if(!search(tag.term, dataBase)){
if(confirm("Are you sure you want to add this tag:" + tag.term)){
dataBase.push({id:dataBase.length+1, text: tag.term});
isNew = true;
//Update the tags array server side through a post request
}
}
return {
id: tag.term,
text: tag.term,
isNew : isNew
};
},
tokenSeparators: [',', '.']
})
});
// Is tag in database?
function search(nameKey, myArray){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].text.toLowerCase() === nameKey.toLowerCase()) {
return true
}
}
return false
};
You can use select2:select and select2:unselect event for this.
var dataBase = [{
id: 0,
text: 'Maths'
},
{
id: 1,
text: 'English'
},
{
id: 2,
text: 'Biology'
},
{
id: 3,
text: 'Chemistry'
},
{
id: 4,
text: 'Geography'
}
];
$(document).ready(function() {
$('.select2-container').select2({
data: dataBase,
placeholder: 'Start typing to add subjects...',
width: 'style',
multiple: true,
tags: true,
createTag: function(tag) {
return {
id: tag.term,
text: tag.term,
isNew: true
};
},
tokenSeparators: [',', '.']
})
$(document).on("select2:select select2:unselect", '.select2-container', function(e) {
var allSelected = $('.select2-container').val();
console.log('All selected ' + allSelected);
var lastModified = e.params.data.id;
console.log('Last Modified ' + lastModified);
var dbIdArray = dataBase.map((i) => i.id.toString());
var allTagged = $('.select2-container').val().filter((i) => !(dbIdArray.indexOf(i) > -1))
console.log('All Tagged ' + allTagged);
});
});
.select2-container {
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<select class="select2-container"></select>
Here's what I've ended up with (thanks to both answers):
1. Set up a Mongoose DB to hold subjects:
models/subjects.js
var mongoose = require("mongoose");
var SubjectSchema = new mongoose.Schema({
subject: { type: String },
});
module.exports = mongoose.model("Subjects", SubjectSchema);
2. Set up api routes in node js express backend:
routes/api.js
var express = require("express");
var router = express.Router();
var Subjects = require("../models/subjects");
// GET route for all subjects in db
router.get("/api/subjects/all", function(req, res){
Subjects.find().lean().exec(function (err, subjects) {
return res.send(JSON.stringify(subjects));
})
});
// POST route for each added subject tag
router.post("/api/subjects/save", function(req, res){
var newSubject = {};
newSubject.subject = req.body.subject;
console.log("Updating db with:" + newSubject);
var query = {subject: req.body.subject};
var options = { upsert: true, new: true, setDefaultsOnInsert: true };
// Find the document
Subjects.findOneAndUpdate(query, options, function(error, subject) {
if (error) return;
console.log("Updated db enry: " + subject);
});
return res.send(newSubject);
});
3. Set up select2 input field:
public/js/select2.js
var dataBase=[];
$(document).ready(function() {
// Get all subjects from api (populated in step 2) and push to dataBase array
$.getJSON('/api/subjects/all')
.done(function(response) {
$.each(response, function(i, subject){
dataBase.push({id: subject._id, text: subject.subject});
})
console.log("dataBase: " + dataBase);
})
.fail(function(err){
console.log("$.getJSON('/api/subjects/all') failed")
})
// Get data from api, and on 'selecting' a subject (.on("select2:select"), check if it's in the dataBase. If it is, or the user confirms they want to add it to the database, send it to POST route, and save it to our Subjects db.
$('.select2-container')
.select2({
ajax: {
url : "/api/subjects/all",
dataType: 'json',
processResults: function (data) {
return {
results: $.map(data, function(obj) {
return { id: obj._id, text: obj.subject };
})
};
}
},
placeholder: 'Start typing to add subjects...',
width: 'style',
maximumSelectionLength: 5,
multiple: true,
createTag: function(tag) {
return {
id: tag.term,
text: tag.term.toLowerCase(),
isNew : true
};
},
tags: true,
tokenSeparators: [',', '.']
})
.on("select2:select", function(e) {
if(addSubject(dataBase, e.params.data.text)){
console.log(e.params.data.text + " has been approved for POST");
ajaxPost(e.params.data.text)
} else {
console.log(e.params.data.text + " has been rejected");
var tags = $('#selectSubject select').val();
var i = tags.indexOf(e.params.data.text);
console.log("Tags: " + tags);
if (i >= 0) {
tags.splice(i, 1);
console.log("post splice: " + tags);
$('select').val(tags).trigger('change.select2');
}
}
})
function ajaxPost(subject){
console.log("In ajaxPost");
var formData = {subject : subject}
$.ajax({
type : "POST",
contentType : "application/json",
url : "/api/subjects/save",
data : JSON.stringify(formData),
dataType : 'json'})
.done(console.log("Done posting " + JSON.stringify(formData)))
.fail(function(e) {
alert("Error!")
console.log("ERROR: ", e);
});
}
function addSubject(subjects, input) {
if (!input || input.length < 3) return false
var allSubjects = [];
$.each(subjects, function(i, subject){
if(subject.text) allSubjects.push(subject.text.toLowerCase())
});
console.log("Here is the entered subject: " + input);
if(allSubjects.includes(input)){
console.log(input + " already exists")
return true
}
if(confirm("Are you sure you want to add this new subject " + input + "?")){
console.log(input + " is going to be added to the database");
return true
}
console.log(input + " will NOT to added to the database");
return false
}
});
This works, but I would love to hear feedback on this approach!
My issue is very specific. How I can add series dynamically in highcharts, through Angular JS, without button, otherwise, without function click.
This is my controller:
var deserialize = angular.fromJson(data.dataContent); //Específico para el dataContent
for(var i =0; i < deserialize.length; i++){
var url = deserialize[i];
$http.get(url).success(function(data){
var n_scope = [];//NOMBRES PARA LA SERIE
var e_scope = []; //EMPLEADOS
for (var i = 0; i < data.length; i++) {
var nombre_scope = n_scope.push(data[i].nombre);
var empleados_scope = e_scope.push(parseInt(data[i].empleados));
}
var chart = {};
chart.addSeries({
name: n_scope[i],
data: e_scope[i]
});
HERE GOES THE CHART:
$scope.renderChart = {
chart: {
type: typeArray[2]
},
title: {
text: titleArray[2]
},
xAxis:{
categories: yAxisTiArray[2],
title: {
enabled: false
},
labels: {
enabled: false
}
},
yAxis:{
title: {
text: yAxisTiArray[2]
}
},
series: chart,
legend: {
enabled: true
},
credits: {
enabled: false
},
lang: {
printChart: 'Imprimir gráfico',
downloadPNG: 'Descargar en PNG',
downloadJPEG: 'Descargar en JPG',
downloadPDF: 'Descargar en PDF',
downloadSVG: 'Descargar en SVG',
contextButtonTitle: 'EXPORTAR'
}
};
I was taking this fiddle as example: http://jsfiddle.net/engemasa/WEm4F/, but I don't want a button click function, I want that series add it to chart dynamically
You are almost there, just put your code inside success blockof your API (angularjs api call ). here is an example (how I used to plot series on data change)
var metricData = $http.get(url);
metricData.success(function(value) {
var data = value.responseData;
var graph = [];
angular.forEach(data.datatimeseries, function(metric) {
graph.push([ metric.timestamp, metric.value ]);
// Assuming that datatimeseries is the timeseiries
});
var chartX = $('#yourDivId').highcharts();
chartX.addSeries({
id : graph_id, // some id
data : graph
});
setYaxisExtremes(chartX); // must use it to reflect added series
});
**RESOLVED**
Altough have button, I could resolve this issue.
I have created a repository that integrates Angular.js, PHP, and Highcharts, with Materialize.css, adding series dynamically from external JSON.
link: https://github.com/Nullises/DynamicSeriesHighchartsAngular
I need to show/hide a particular field in jtable jquery depending upon selection in edit window (updateAction:).
I have tried doing so by css show/hide, but its showing / hiding only input box , and it leaves the title of input, which looks weird.
What i really want is to hide whole "jtable-input-field-container", but just for a particular field/input.
here is the snippet:
fields: {
contentType: {
title: 'Content Type',
list: false,
options: { '1': 'message', '2': 'Image'},
onchange : 'select_function(this)',
edit:true
},
title: {
title: 'Title',
width: '8%',
edit:true
},
message: {
title: 'Message',
width: '8%',
list: true,
edit: true
},
imageurl: {
title: 'image URL',
width: '8%',
edit: true
},
......
}
Here i want , if contentType is set to image, then imageurl field should be shown otherwise hidden, in edit window , which we define under updateAction.
Please help.
I found a solution, which is working fine :).
What I am doing is based on selection, i iterate over all .jtable-input-field-container' , and check if innerText is same as in given in title of field.
Based on that , i hide/show that div.
Iteration can be avoided if you are sure that indexenter code here of field will not change.
Code Snippet:
function select_function(target){
var myselect = target.value;
if(myselect=='1')
{
var data = $('.jtable-input-field-container');
for (j = 0; j< data.length ;j++)
{
console.log(j);
console.log("+"+data[j].innerText+"+");
if (data[j].innerText.indexOf("image URL") != -1)
{
$(data[j]).hide();
console.log(data[j]);
}
}
console.log(data);
}
else
{
var data = $('.jtable-input-field-container');
for (j = 0; j< data.length ;j++)
{
console.log(j);
console.log("+"+data[j].innerText+"+");
if (data[j].innerText.indexOf("image URL") != -1)
{
$(data[j]).show();
console.log(data[j]);
}
}
}
I do understand that filter is being used to display more specific results. But is there a way that I can use it to exclude a specific user or image instead? Or do instafeed.js have another option for me to do this?
var feed = new Instafeed({
target: 'instafeed',
get: 'tagged',
tagName: 'hashtag',
limit: '10',
sortBy: 'most-recent',
resolution: 'standard_resolution',
clientId: 'xxxxx',
template:'<img class="item" src="{{image}}">',
filter: function(image) {
//filter to exclude specific user
}
});
Appreciate any feedbacks.
Many thanks!
Yes. If you return false from the filter function, it will exclude the image from the results.
So to block images from a specific user, you can check the image.user.username property:
filter: function(image) {
var blockedUsernames = [
'reallybaduser',
'otherreallybaduser'
];
// check for blocked users
for (var i=0; i<blockedUsernames.length; i++) {
if (image.user.username === blockedUsernames[i]) {
return false;
}
}
return true;
}
You can expand the filter function to check any property of image. So if you know a specific id of an image to block, you can check that property as well.
Did Stevens answer solved your problem soulefay?
It does not work for me =/. Tested with model.user.username (which I use when I print out the uploaders username) as well but that did not work.
<script type="text/javascript">
var feed = new Instafeed({
get:'tagged',
tagName: 'horizon',
clientId: 'xxxxxxx',
limit:'16',
sortBy: 'most-liked',
resolution:'low_resolution',
template: '<img src="{{image}}" class="imagen" <p>Likes: {{likes}} User: {{model.user.username}} </p> ',
/* filter: function(image) {
var blockedUsernames = [
'reallybaduser',
'otherreallybaduser'
];
// check for blocked users
for (var i=0; i<blockedUsernames.length; i++) {
if (image.user.username === blockedUsernames[i]) {
return false;
}
}
return true;
}, */
after:function(){
var images = $('#instafeed').find('a');
}
});
feed.run();
/*==== GET MORE PICTURES.. ======*/
$(function() {
$("#load-more").click( function()
{
feed.next();
}
);
});
</script>
In reply to Dahak, Steven's code works for me! Here's the full code on my website:
<script type="text/javascript">
var feed = new Instafeed({
get: 'tagged',
tagName: 'hashtag',
clientId: 'xxxxxxxx',
template: '<img src="http:{{image}}" class="insta" />',
limit: 20,
filter: function(image) {
var blockedUsernames = [
'baduser',
'otherreallybaduser'
];
// check for blocked users
for (var i=0; i<blockedUsernames.length; i++) {
if (image.user.username === blockedUsernames[i]) {
return false;
}
}
return true;
}
});
feed.run();
</script>
Did you exclude the comment tag /* and */ when you test your code?
Sorry, I've limited javascript knowledge. =/