Where do I put this function in my code? jQuery - javascript

Okay, so for class I have to make a CRUD application basically. I have to have a nav bar that links to different "pages" that are loaded in using a server.js file. In that server is where I load a JSON file that holds two arrays, one for pages, or sections, and another for users. The goal is to input information about a user in one section, hit a button and then that user's info will be listed in a different section. You also need to be able to delete each individual user at will, and it's all local.
My problem is that I have this addUser function, and within this function there's a click listener for the add button. Right now, the only thing it does when it's supposed to be clicked it throws a console.log, but I can't get that to work. The addUser function also has a console.log that's running fine, and I believe that my problem is that I don't know where I'm supposed to be adding the addUser function into my code. Just to be safe, I'll go ahead and list all my code. First is the server.js:
var SERVER = (function(){
//variable to store data.users into
var _userData = [];
var _sectionData = [];
//getting the data and putting it into the variables above
var _loadData = function(){
$.getJSON("./data/data.json", function(data){
_userData = data.Users;
_sectionData = data.Sections;
//console.log(_sectionData);
})
}
var _showData = function(){
return _userData;
}
var _getSection = function(sectionYouWant){
let sec = {};
$.each(_sectionData, function(idx, section){
if(section.sectionName == sectionYouWant){
sec = section.sectionContent;
}
});
return sec;
}
_loadData();
return {
loadData: _loadData,
showData: _showData,
getSection: _getSection
}
})()
next is the app.js
function addUser(){
console.log("firing addUser");
$('#addButton').click(function(e){
console.log("are you working????")
e.preventDefault();
})
}
function initNavListeners(){
$("#home").click(function(e){
//console.log('click home');
var sectionData = SERVER.getSection('home');
$('.wrapper').html(sectionData);
});
$("#view").click(function(){
//console.log('click view users');
var userData = SERVER.showData();
var sectionData = SERVER.getSection('view');
$(".wrapper").html(sectionData);
function showUsers(){
$.each(userData, function(idx, user){
$(".wrapper").append(`
<br/><p><b>Name:</b> ${user.fName} ${user.lName}</p>
<p><b>Email Address:</b>
${user.email}</p>
<p><b>Twitter Handle:</b>
${user.twitter}</p>
<button class="delete" id=${idx}>DELETE</button><br/>`)
})
}
showUsers();
});
$("#register").click(function(e){
//console.log('click register');
addUser();
var sectionData = SERVER.getSection('register');
$('.wrapper').html(sectionData);
});
}
$(document).ready(function(){
SERVER.loadData();
initNavListeners();
var sectionData = SERVER.getSection('home');
$('.wrapper').html(sectionData);
})
Finally, the JSON:
{
"Users": [
{
"fName": "Andrea",
"lName": "Trigg",
"email": "at#users.com",
"twitter": "#at"
}
],
"Sections": [
{
"sectionName": "home",
"sectionContent": "<h1>HOME</h1><p>Welcome to the home page for my Homework 5 assignment! In this little application, you can register users and it will be submitted to a local JSON file. Then when you go to the view users page, it will show all the current users registered. You can also delete each individual user by pressing the \"delete user\" button below their information.</p><p>I hope this will work on your machine because it definitely works on mine!</p><p>I'm honestly not sure what else I should put here, so have a gif of a cute kitten trying to eat their own tail.</p><img src=\"https://i.pinimg.com/originals/84/c8/ba/84c8bab01787f2ee1ebef1378e9e8444.gif\"><p>I hope you have a great week! Thank you for taking a look at my Homework 5!</p>"
},
{
"sectionName": "view",
"sectionContent": "<h1>VIEW USERS</h1><p>Scroll below to see all users stored in the database. Click the delete button to delete a user from the database (careful, you won't get the information back if you delete!)</p>"
},
{
"sectionName": "register",
"sectionContent": "<h1>REGISTER</h1><p>Register a new user by using the form below!</p><form><input id=\"first\" type=\"text\" value=\"\" placeholder=\"First Name:\"><br/><input id=\"last\" type=\"text\" value=\"\" placeholder=\"Last Name:\"><br/><input id=\"emailAddress\" type=\"text\" value=\"\" placeholder=\"Email:\"><br/><input id=\"twitterHandle\" type=\"text\" value=\"\" placeholder=\"Twitter Handle\"><br/><input id=\"addButton\" type=\"button\" value=\"SUBMIT\"></form>"
}
]
}
If you see anything that could be causing my click listener to not be working while the function itself is, that would be a tremendous help. I'm really struggling with this so any help would be great! Thank you!

Wow okay so after working on this for three hours, I finally figured it out.
So basically, you take the addUser function and instead of having it be global, you put it into the #register click listener that's in the initNavListener. It should look something like this:
$("#register").click(function(e){
//initListeners();
//console.log('click register');
var userData = SERVER.showData();
var sectionData = SERVER.getSection('register');
$('.wrapper').html(sectionData);
function addUser(){
console.log("firing addUser");
$('#addButton').click(function(e){
console.log("are you working????")
e.preventDefault(); )}
I feel like the biggest idiot right now :'D
ETA: If anyone wants to help me figure out how to delete these users that would be cool, but it's not listed in the rubric as something that I need to do, so I'm not putting major emphasis on it atm.

Related

AngularJS Voting System - Preventing Multi-Votes

I'm trying to create a voting system using AngularJS with the Ionic Framework. I'm using ng-repeat to loop over a series of user posts from a JSON array. Each post has an upvote and a downvote button. After one is selected, I have the button on that post disabled. The problem I'm currently experiencing is keeping that button disabled regardless if the user reopens the app. My goal is to prevent multi-voting. Currently, I'm using this method to disable the button after it's been clicked:
<button class="button button-small button-light" ng-click="upThread({{thread.id}})" ng-disabled="upDisabled[thread.id]">
<i class="icon ion-thumbsup"></i>
</button>
<button class="button button-small button-light" ng-click="downThread({{thread.id}})" ng-disabled="downDisabled[thread.id]">
<i class="icon ion-thumbsdown"></i>
</button>
$scope.upDisabled = {};
$scope.downDisabled = {};
$scope.upThread = function(id) {
...
$scope.upDisabled[id] = true;
$scope.downDisabled[id] = false;
}
$scope.downThread = function(id) {
...
$scope.downDisabled[id] = true;
$scope.upDisabled[id] = false;
}`
And this works great for disabling the buttons. Now, the problem is, I require Cache for the controller to be false, otherwise my new posts do not update in the view when added. This means, when reloading the app or switching between routes/views, the buttons become enabled again, which is not what I want. Additionally, setting cache to true doesn't keep the buttons disabled after the app has been reopened either.
I have tried using localstorage to store the $scope.upDisabled and $scope.downDisabled, but it ruins the JSON formatting. I have tried remote storage and received the same result. For example, the $scope.upDisabled and $scope.downDisabled store data like so:
{"2":true, "3":false, "4":true}
and so on. But because storing in localstorage or a database requires me to use JSON.stringify, you can guess that those quotes cause trouble and I end up with nested JSON as well. So, the data from localstorage does not return the correct format.
My known problems/options are twofold.
Is there a better solution to persistently disabling those
buttons?
How would I correctly format the JSON coming out of
localstorage?
Something else to note: Since this is a mobile/hybrid app using Ionic, I am not using cookies, but I did create a token system to act similarly.
Edit: Thanks to those who replied and your suggestions. I am currently using a MySQL database to keep track of the votes (May switch to SQLite later) #aorfevre: I've taken a look at the SQLite plugin before and will probably use it down the road. I finally got everything working how I want it to.
$scope.upDisabled = {};
$scope.downDisabled = {};
$scope.upCheck = {};
$scope.downCheck = {};
...Votes Loading function up here
...Thread loading Function up here
.finally(function(){
angular.forEach($scope.threads,function(value,index){
angular.forEach($scope.upCheck,function(value2,index){
if(value.id == value2.threadID)
{
$scope.upDisabled[value.id] = true;
$scope.downDisabled[value.id] = false;
}
})
})
angular.forEach($scope.threads,function(value,index){
angular.forEach($scope.downCheck,function(value2,index){
if(value.id == value2.threadID)
{
$scope.downDisabled[value.id] = true;
$scope.upDisabled[value.id] = false;
}
})
})
}
$scope.loadVotes();
$scope.loadThreads();
As for the server side (PHP with Laravel Framework):
public function upvoteThread($id, $token)
{
$thread = Thread::find($id);
$score = $thread->score;
$score = $score + 1;
$thread->score = $score;
$thread->save();
$voted = ThreadVote::where('threadID','=',$id)->where('token','=',$token)->get();
if($voted->isEmpty())
{
$upVote = new ThreadVote;
$upVote->threadID = $id;
$upVote->token = $token;
$upVote->upVote = 'true';
$upVote->downVote = 'false';
$upVote->save();
}
else
{
DB::table('thread_votes')
->where('threadID', '=', $id)
->where('token','=',$token)
->update(array('upVote' => 'true', 'downVote' => 'false')
);
}
return Response::json(array('status'=>1))->setCallback(Input::get('callback'));
}
public function getUpVotes($token)
{
$votes = ThreadVote::where('token','=',$token)
->where('upVote','=','true')
->select('threadID','upVote')
->get();
return Response::json($votes)->setCallback(Input::get('callback'));
}
...Similar downVote Function...
So as it stands. When the button is pushed, it saves the user's token, threadID, and vote to the database. When the view is loaded, that information, based on the token and threadID is loaded as a JSON array, associated with the Thread array and if a threadID and thread.id matches, it's pushed into the up/downdisabled scope as "threadID":bool ("1":true for example).
I'll recommand you to implement a DB if you manage huge volume of post.
I personnaly use localStorage for several preferences not for storing a db.
Therefore, if you target only for ios / android, I recommand you https://github.com/litehelpers/Cordova-sqlite-storage
If you target windows phone 8.1, the implementation is not trivial and I'm facing some issues regarding the structure of WindowsPhone & C++ compilation librairy ( more details here : https://issues.apache.org/jira/browse/CB-8866 )

Updating related data in firebase

If I had a structure that looks like the below in firebase, how do I update the comment for a particular link
link1 node:
{
links: {
link1: {
title: "Example",
href: "http://example.org",
submitted: "user1",
comments: {
comment1: true
}
}
}
}
Comment 1 node:
comment1: {
link: "link1",
body: "This is awesome!",
author: "user2"
}
I just need to update link1 by adding more comments, note that in real application, auto ids are generated for the nodes and makes it difficult to keep track of them. comment1 and link would be replace with auto generated ids.
----------------------------Edit----------------------------------------
Ok I have tried nesting the comments into the link so I can update the comment like this:
$scope.addComment = function(id){
var cRef = $firebase(new Firebase("https://musicfs.firebaseio.com/comments"));
var pRef = $firebase(new Firebase("https://musicfs.firebaseio.com/posts/"+id+"/comments"));
var data = {body:$scope.commentBody, maker:Auth.$getAuth().facebook.displayName, post:id};
pRef.$push(data)
}
and that is all I have tried doing. But I dont have an idea at all on how I can isolate update the comments after isolating it from the links
------ EDit 2--------
I was able to put some code dowm:
$scope.addPost = function(){
console.log($scope.category.name)
var cat = ref.child('categories');
var post = ref.child('posts');
post.child($scope.post.title).set($scope.post)
cat
.child($scope.category.name)
.child('posts')
.set({$scope.post.title: 'true'});
}
I just need to get the id of the last created post and set it to true in the category node.
Thanks

Edit Item from Firebase

This is sort of a follow-up to my previous question. I'm trying to figure out how to edit an existing item that is stored in my Firebase. My items are repeated on the page, and each of them have an "Edit" button next to them.
HTML
<h3>Editing {{ editedProvider.title }}</h3>
<form>
<input ng-model="editedProvider.title">
<button type="submit" ng-click="updateProvider()">Submit</button>
</form>
<div ng-repeat="provider in providers">
<h3>{{ provider.title }}</h3>
<button type="button" ng-click="setEditedProvider()">Edit</button>
</div>
</div>
This is how I'm currently adding an item to my list:
JS
var rootRef = new Firebase(FBURL);
var providersRef = rootRef.child('providers');
$scope.newProvider = {};
$scope.providers = [];
providersRef.on('child_added', function(snapshot) {
$timeout(function() {
var snapshotVal = snapshot.val();
console.log(snapshotVal);
$scope.providers.push({
title: snapshotVal.title,
name: snapshot.name()
});
});
});
$scope.createProvider = function() {
var newProvider = {
title: $scope.title
};
providersRef.push(newProvider);
};
I've then created a function setEditedProvider and binded it to the edit button, that when clicked brings up the edit form for that particular item. When I've made my changes however, I need to run a function called updateProvider, and I'm having problems creating that function.
$scope.editedProvider = null;
$scope.setEditedProvider = function(provider) {
$scope.editedProvider = angular.copy(provider);
}
$scope.updateProvider = function(provider) {
// need to take that edited function and push the updated version inside here
}
Can I utilise Firebase's data snapshot for this, like I am for creating the item?
Some of this is finally clicking for me, I think I understand how it needs to be done, I just can't work out how to achieve it.
Any help with this problem is appreciated. Thanks in advance!
$scope.updateProvider = function(provider) {
providersRef.child(provider.$id).update({tile:Provider.title});
}

How reload the helper once i change the values

Im trying to filter information in my page after the user select an option, so i made a "change" event and passed values ​​through the helper by sessions and its ok console log looks like the values passed ok, but it seems like the helper doesn't refresh or something because dont return the find with the new values, actually don't do anything, obviously there is something wrong, sorry for my ultra basic english, i hope you understand and help me, thanks for your time!
Template
<select id="mostrarTiposMenu" class="form-control">
{{#each mostrarMenus}}
<option value="{{nuevoTipoMenu}}" onchange="getMenu()">{{nuevoTipoMenu}}</option>
{{/each}}
</select>
Events and helpers
Template.main.events({
"change #mostrarTiposMenu": function(evt) {
var newValue = $(evt.target).val();
Session.set("valueMenu", newValue);
console.log("yo estoy en el event " + newValue);
}
});
Template.main.helpers({
mostrarMenus : function(){
return Menu.find();
},
mostrarPrimerDia: function(){
var searchMenu = Session.get("valueMenu")
console.log("Yo estoy en el helper " + searchMenu)
var server = TimeSync.serverTime()
var diaDeHoy = moment(server).locale("es").add(0,'days').format('dddd');
return Promociones.find({'metadata.diaOferta' : { $in: [diaDeHoy] } },{'metadata.tipoMenu' : { $in: [searchMenu] } });
}
});
did you tried using refresh option
$('selectmenu).refresh();

use values submitted in a form to publish and subscribe results of a mongodb query in meteor

I want a user to be able to type 2 inputs into a form, hit submit, and have the database send back documents with field values that match the values that were typed into the form.
If I hard code values for 'name' and 'code' variables on the last line, I get the right results and everything renders fine. So I think the problem has to do with how I'm using the variables / variable scope, or something of that nature.
more detailed description below...
I am using Meteor.
I have a form with 2 input fields, for example, product and brand
I want to send a query of the following form:
PriceList.find({'name': name, 'brandCode': code});
I have a template that renders based on the results of this query. This relies on publishing the results of the query:
if (Meteor.isServer) {
Meteor.publish('byProductAndBrand', function(){
var name = product;
var code = brand;
return PriceList.find({'name': name, 'brandCode': code});
});
}
I'm trying to use Meteor.subscribe() to change dynamically based on the form inputs:
if (Meteor.isClient) {
Template.dataSelectionForm.events({
'submit form#addDataSelectionForm': function(event, template){
event.preventDefault();
product = template.find([name='product_name']).value;
brand = template.find([name='brandCode']).value;
}
});
Meteor.subscribe('byProductAndBrand');
}
Here's the relevant code (duplicates what I wrote above, but may be less annoying to read...)
PriceList = new Meteor.Collection('PriceList');
product = 'dummyProduct';
brand = 'dummyBrandCode';
if (Meteor.isClient) {
Template.dataSelectionForm.events({
'submit form#addDataSelectionForm': function(event, template){
event.preventDefault();
product = template.find([name='product_name']).value;
brand = template.find([name='brandCode']).value;
}
});
Meteor.subscribe('byProductAndBrand');
}
if (Meteor.isServer) {
Meteor.publish('PriceList', function(){
return PriceList.find();
});
Meteor.publish('byProductAndBrand', function(){
var name = product;
var code = brand;
return PriceList.find({'name': name, 'brandCode': code});
});
}
Pass params to Meteor.subscription :
if(Meteor.isServer){
Meteor.publish('byProductAndBrand', function(product, brand){
var name = product;
var code = brand;
return PriceList.find({'name': name, 'brandCode': code});
});
}
}
if (Meteor.isClient) {
Template.dataSelectionForm.events({
'submit form#addDataSelectionForm': function(event, template){
event.preventDefault();
product = template.find([name='product_name']).value;
brand = template.find([name='brandCode']).value;
var instance = Template.instance();
if(instance.byProductAndBrandHandle != null){
instance.byProductAndBrandHandle.stop();
}
instance.byProductAndBrandHandle = Meteor.subscribe('byProductAndBrand', product ,brand);
}
});
}
It seems to me that you would be better off using dependencies instead of subscriptions. This makes sense to me in this circumstance because only the one client viewing the page is looking at this particular price list, you are not publishing this price list for multiple users as far as I can tell.
For ex:
In declarations, before if(Meteor.isClient) and if(Meteor.isServer):
var byProductAndBrandDep = new Tracker.Dependency;
Inside of priceList helper:
byProductAndBrandDep.depend();
In "submit form#addDataSelectionForm".events: function(event, templates) {
byProductAndBrandDep.changed();
Then, every time the form is submitted, every helper that has the byProductAndBrandDep.depend() function inside it automatically updates.

Categories

Resources