I'm using ajax for paging so Sammy.js is great choice. But I'm also using checkboxes which filters results. This is ok for Sammy: I have to define route which Sammy will intercept. Problem is :I don't want some filters(parameters) to show on URL if they are not checked but Sammy does not support optional parameters.
var samm = $.sammy(function () {
this.defaultCheckFormSubmission = this._checkFormSubmission;
this._checkFormSubmission = function (form) {
var $form, path, verb;
$form = $(form);
path = $form.attr("action");
verb = this._getFormVerb($form);
var index = path.indexOf("#");
if (verb === "get" && path.indexOf("#") == -1) {
return true;
}
else {
return this.defaultCheckFormSubmission(form);
}
};
this.get('#/Page=:page', function (context) {
alert("sammy");
});
});
samm.run('#');
I don't want all my URLs look like www.something.com#/Page=5%Filter1=0?Filter2=0?Filter3=0?Filter4=1...........
If you don't want Sammy to handle extra filters (like unchecked checkbox values), just don't put them in your route. Instead just grab the parameters from the controls via jquery and do the ajax request like that. So Something like this:
this.get('#/Page=:page', function (context) {
var page = this.params['page'];
var filter1 = $("#chkFilter1").is(':checked');
var filter2 = $("#chkFilter2").is(':checked');
var filter3 = $("#chkFilter3").is(':checked');
//etc..
//do work here
});
If you need the URL to be different for deep linking or google tracking and you know the max number of variables you need, then you can plan out your routes for the amount of variables you have. You must put the most variables first, because otherwise Sammy will match the URLs incorrectly. This is how you would make the URL only show checked values but still grab the unchecked values via JQuery:
this.get('#/Page=:page%filter1=:filter1?filter2=:filter2?filter3=:filter3', function (context) {
var page = this.params['page'];
var filter1 = this.params['filter1'];
var filter2 = this.params['filter2'];
var filter3 = this.params['filter3'];
});
this.get('#/Page=:page%filter1=:filter1?filter2=:filter', function (context) {
var page = this.params['page'];
var filter1 = this.params['filter1'];
var filter2 = this.params['filter2'];
var filter3 = $("#chkFilter1").is(':checked');
});
this.get('#/Page=:page%filter1=:filter1', function (context) {
var page = this.params['page'];
var filter1 = this.params['filter1'];
var filter2 = $("#chkFilter1").is(':checked');
var filter3 = $("#chkFilter2").is(':checked');
});
Another option is to ditch the querystring variables and just use a URL structure like this www.something.com#/5/0/1/0/1. Which would look like this:
this.get('#/:page/:filter1/:filter2/:filter3/:filter4', function (context) {
var page = this.params['page'];
var filter1 = this.params['filter1'];
var filter2 = this.params['filter2'];
var filter3 = this.params['filter3'];
var filter4 = this.params['filter4'];
});
Having said all those options, if you have an unknown possible variables you would have to do something more dynamic which is explained here: sammyjs optional parameters
Related
I have two functions what sets a window.location.href tag in the url, but when I set the first one and then select the other one, the first one disappears. So how should I do? These functions are in a form that makes a selection of 1. project name and 2. package. And then you submit the form (php) the fields adds to the database.
function jsFunction(){
var myselect = document.getElementById("projektnamn");
window.location.href = "?projektnamn=" + myselect.options[myselect.selectedIndex].value;
}
function services(){
var select = document.getElementById("paket");
window.location.href = "?paket=" + select.options[select.selectedIndex].value;
}
I want the result to be like this:
domain.com?projektnamn=Something?paket=Something
What I get today is:
domain.com?projektnamn=Something
Or I get:
domain.com?paket=Something
I would store the link in a variable
let query = "";
function jsFunction(){
var myselect = document.getElementById("projektnamn");
query += "?projektnamn=" + myselect.options[myselect.selectedIndex].value;
}
function services(){
var select = document.getElementById("paket");
query += "?paket=" + select.options[select.selectedIndex].value;
window.location.assign(query);
}
Both of your functions are resetting the URL.
What you can do is use URLSearchParams to generate the query string.
function jsFunction(params) {
var myselect = document.getElementById("projektnamn");
params.set('projektnamn', myselect.options[myselect.selectedIndex].value);
}
function jsFunction2(params) {
var select = document.getElementById("paket");
params.set('paket', select.options[select.selectedIndex].value);
}
const params = new URLSearchParams();
jsFunction(params);
jsFunction2(params);
window.location.href = `${location.pathname}?${params}`;
From what it looks like you are trying to build a single function, not two separate functions. I would replace these 2 functions with one generic.
function jsFunction(params, id, name) {
var myselect = document.getElementById(id);
params.set(name, myselect.options[myselect.selectedIndex].value);
}
const params = new URLSearchParams();
jsFunction(params, "projektnamn", 'projektnamn');
jsFunction(params, "paket", 'paket');
window.location.href = `${location.pathname}?${params}`;
I have a function prototype that loads data from a path. The trick is that I need to change the path afterward. I tried call, apply, bind and even assign but as I am a novice I did not find the solution.
Here a sample of my code :
Chat.prototype.loadMessages = function() {
this.messagesRef = this.database;
var setMessage = function(data) {
var val = data.val();
this.displayMessage(data.key, val.name, val.text);
}.bind(this);
};
var chat = new Chat
function setPath (newpath) {
chat.loadMessages.messageRef = newpath; // I guess, it is where I'm wrong...
chat.loadMessages(); // It should load messages from the new path in my chat container.
}
As I said I also tried :
chat.loadMessages.call(newpath);
or
var setPath = function(newpath) {
chat.loadMessages(newpath);
}.bind(chat);
setPath();
chat.loadMessages();
But the chat container continues to disclose messages from the old path...
This looks a bit convoluted. Just pass messagesRef as a parameter and make it default to this.database:
Chat.prototype.loadMessages = function(messagesRef = this.database) {
// do whatever is needed with messagesRef
};
chat = new Chat();
chat.loadMessages(); // load from the default location
chat.loadMessages('foobar'); // load from this specific location
It looks like you are creating a function with loadMessages, which is fine but you need to pass in a value to set the new path. Is this more of what you were thinking?
Chat.prototype.loadMessages = function (newPath) {
this.messagesRef = newPath || this.database; // if newPath is empty than default to this.database
var setMessage = function(data) {
var val = data.val();
this.displayMessage(data.key, val.name, val.text);
};
var chat = new Chat
function setPath (newpath) {
chat.loadMessages(newpath);
}
I am trying to enter a number of shifts under their date. This is working fine for the 19-01 but then when I try to enter the 20-01 that saves and deletes the entry of the 19-01.
Anyone know what the problem is and why it can't allow me to have more that one tree?
//ROSTERS SAVING
//ROSTERS FOR MONDAYS
$(function Monday(){
// CREATE A REFERENCE TO FIREBASE
var dateMondayRef = new Firebase('https://shiftsapp.firebaseio.com/roster');
// REGISTER DOM ELEMENTS
var date1Field = $('#date1Input');
var emp1put1Field = $('#emp1Input1');
var enter1Field = $('#enter1');
// LISTEN FOR KEYPRESS EVENT
enter1Field.keypress(function (e) {
if (e.keyCode == 13) {
//FIELD VALUES
var dateMonday = date1Field.val();
var emp1put1 = emp1put1Field.val();
var enter1 = enter1Field.val();
//SAVE DATA TO FIREBASE AND EMPTY FIELD
var obj1 = {};
obj1[dateMonday] = {
emp1:emp1put1,
}
dateMondayRef.set(obj1);
enter1Field.val('');
}
});
});
$(function Tuesday(){
// CREATE A REFERENCE TO FIREBASE
var dateTuesdayRef = new Firebase('https://shiftsapp.firebaseio.com/roster');
// REGISTER DOM ELEMENTS
var date2Field = $('#date2Input');
var emp1put2Field = $('#emp1Input2');
var enter2Field = $('#enter2');
// LISTEN FOR KEYPRESS EVENT
enter2Field.keypress(function (e) {
if (e.keyCode == 13) {
//FIELD VALUES
var dateTuesday = date2Field.val();
var emp1put2 = emp1put2Field.val();
var enter2 = enter2Field.val();
//SAVE DATA TO FIREBASE AND EMPTY FIELD
var obj = {};
obj[dateTuesday] = {
emp1:emp1put2
}
dateTuesdayRef.set(obj);
enter2Field.val('');
}
});
});
This happens because you use Firebase's set method instead of update on the same ref (your dateMondayRef and dateTuesdayRef both point to the same Firebase node).
As described in the docs, set will
write or replace data
In other words, when you call set on your ref, you instruct firebase to write at this location (or replace any data that might be stored there with) the object you pass as an argument.
You can either use update on this ref (but that would preserve any child key that was present at roster/$dateMonday but that is not included in your new object) or grab a reference to your dateMonday node, and call set on that.
dateMondayRef.update(obj1)
dateTuesdayRef.update(obj2)
// or
dateMondayRef.child(dateMonday).set({emp1: ...})
dateTuesdayRef.child(dateTuesday).set({emp1: ...})
I am developing a project with the Kendo UI Framework, using more specically the Scheduler widget and I have the current issue:
On my database I have two tables one called Events and the other one called TypeOfEvents. Each type of event has got a specific color, a specific title plus defined values for startHour and endHour fields.
When the pop-up window to create an event is called, I can choose on two kendoMultiSelect the correspondent user and the type of event.
I can also choose the startDate and endDate. The default behavior of a Scheduler widget has got two datetimepickers also, however, I don't want that option on my pop-up window because the events will have defined hours that an user can't change.
My idea would be the following one:
Once I click save after choosing a specific event on my MultiSelectList, there would be some way to concatenate the startHour and endHour values I have defined in my database with the startDate and endHour field that I choosed on the pop-up window.
Right now, all my events startDate/endDate fields are saved on my DB with this format: 2015-03-01 00:00:00.000
I would like to substitute all those zeros with the values I defined in advance in my startHour/endHour fields of my TypeOfEvents table.
Here's my current CREATE script:
create: function (createEvent) {
var typeOfEventID = $("#selectEvent").val();
var usernameID = $("#selectUsername").val();
var dataStartTemp = $("#dataStart").val();
var dataEndTemp = $("#dataEnd").val();
var note = $("#note").val();
var res = $("#customViewScheduler").data("kendoScheduler");
var res1 = res.resources[1].dataSource.data();
var dataStart = convertToJSONDate(dataStartTemp);
var dataEnd = convertToJSONDate(dataEndTemp);
var changeSet = [];
var id = 0;
usernameID.forEach(function (userID) {
typeOfEventID.forEach(function (eventID) {
var titletemp = $.grep(res1, function (elem) {
if (elem.TypeOfEventID == eventID) {
return true;
}
})
if (titletemp.length > 0) {
note = titletemp[0].title;
}
var entityChange = {};
entityChange.Id = id;
entityChange.Entity = {
'__type': "Events:#BlahBlahWeb",
'UsernameID': userID,
'TypeOfEventID': eventID,
'startDate': dataStart,
'endDate': dataEnd,
'Title': note
};
entityChange.Operation = 2;
changeSet.push(entityChange);
id++
})
})
var changesetPayload = JSON.stringify({
"changeSet": changeSet
});
//Create jQuery ajax request
var Params = {}
Params.type = "POST";
Params.url = "./../Services/BlahBlahWeb-BlahDomainService.svc/JSON/SubmitChanges";
Params.dataType = "json";
Params.data = changesetPayload;
Params.contentType = "application/json";
Params.error = function (httpRequest, textStatus, errorThrown) {
//SendErrorByEmail(errorThrown, httpRequest.responseText)
}
Params.success = function (data) {
//createEvent.success(data);
var scheduler = $("#customViewScheduler").data("kendoScheduler");
var elem = tratanewelem(data.SubmitChangesResult[0].Entity)
scheduler.dataSource.read();
}
//Make the ajax request
$.ajax(Params);
},
Any idea of how can I accomplish that?
Based On : Blackberry Wiki Screen
With my full code : My Full Code
If i user onscreenready function to PASS MY PARAMETER from page A like this :
ondomready: function(element, id) {
if (id == 'UPDATE') {
UPDATE_initialLoad(element, params);
}
}
For pages that I would give / throw parameters (Let's just say page B), how do I win or get results / parameters provided by the previous form. I want to make a form update the data in the form, and will be filled all the time throwing fieldnya parameter data.
Im using like this in my Page B :
function UPDATE_initialLoad(element, params) {
setTimeout(UPDATE_loadAfterTimeout,100);
}
function UPDATE_loadAfterTimeout() {
var id = data_id
var nmDepan = data_depan
var nmBelakang = data_belakang
var phone = data_phone
var email = data_email
document.getElementById('txtID').value = id
document.getElementById('txtNMDEPAN').value = nmDepan
document.getElementById('txtNMBELAKANG').value = nmBelakang
document.getElementById('txtPhone').value = phone
document.getElementById('txtEmail').value = email
}
But result is failed...
Please help me
You'll want to push data to the page:
bb.pushScreen("myPage.html", "UPDATE", myParams);
Then this will fire when the page is loaded:
ondomready: function(element, id, params) {
if (id == 'UPDATE') {
UPDATE_initialLoad(element, params);
}
}
Make sure to pass the parameters to your delayed function:
function UPDATE_initialLoad(element, params) {
setTimeout(UPDATE_loadAfterTimeout(params),100);
}
function UPDATE_loadAfterTimeout(params) {
var id = params['data_id'];
var nmDepan = params['data_depan'];
var nmBelakang = params['data_belakang'];
var phone = params['data_phone'];
var email = params['data_email'];
document.getElementById('txtID').value = id
document.getElementById('txtNMDEPAN').value = nmDepan
document.getElementById('txtNMBELAKANG').value = nmBelakang
document.getElementById('txtPhone').value = phone
document.getElementById('txtEmail').value = email
}
I hope this helps.