I'm using FullCalendar 2.0 to display availability of a user. The user can select when they're available and the information will then be stored into the database.
I've edited fullcalendar.js to display a checkbox on every day of the month, and once the save button is clicked all checked days will be stored.
return '' +
'<td class="' + classes.join(' ') + '" data-date="' + date.format() + '">' + '<input type="checkbox" name="cal[]" id="checkbox-2-' + date.format() + '" class="regular-checkbox big-checkbox" value="' + date.format() +'" /><label for="checkbox-2-' + date.format() + '">' + date.date() + '</label>'
+
'</td>';
},
However when the next or prev button is pressed everything is unchecked. IS there a way to keep the checkboxes checked when the user navigates months?
First of all it's not recomended to alter the content of fullcalendar.js
You should use dayRender method if you want to change the way that td is displayed:
dayRender: function (date, cell) {
cell.append('<input type="checkbox"............../>');
}
To repoulate checkboxes after month changed you should use an array to store each checkbox checked and then using checkbox changed event pop/push them from that array.
Related
I'm learning and trying to put together a little bit of jquery. Admittedly I'm finding it difficult to find a good basics guide, particularly, when adding multiple actions to one page.
I read somewhere that the document listener should only be used once. I believe I'm using it twice here, but not 100% sure how to bring it into one listener.
Also because I've been hacking bits of script together, I think I'm using parts of javascript and parts of jQuery. Is this correct?
A critique of the code below [which does work] and any advice on how best to approach learning jQuery would be most helpful. Thanks.
Script 1 styles a group of 3 radio buttons depending on which one is clicked.
Script 2 appends new inputs to the bottom of a form.
var stateNo = <?php echo $HighestPlayerID; ?> + 1;
$(document).on('click', 'input', function () {
var name = $(this).attr("name");
if ($('input[name="' + name + '"]:eq(1)')[0].checked) {
$('label[name="' + name + '"]:eq(1)').addClass('nostate');
$('label[name="' + name + '"]').removeClass('selected');
}
else {
$('label[name="' + name + '"]').removeClass('nostate selected');
if ($('input[name="' + name + '"]:eq(0)')[0].checked) {
$('label[name="' + name + '"]:eq(0)').addClass('selected');
}
else {
$('label[name="' + name + '"]:eq(2)').addClass('selected');
}
}
});
$(document).on('click', 'button[name=btnbtn]', function () {
var stateName = 'state[' + stateNo + ']';
var newPlayerAppend = `` +
`<tr><td>` +
`<input type="hidden" name="state['` + stateNo + `'][PlayerID]" value="` + stateNo + `" /></td>` +
`<td><input name="` + stateName + `[Name]" value="Name"></td>` +
`<td><input name="` + stateName + `[Team]" type="radio" value="A">` +
`<td><input name="` + stateName + `[Team]" type="radio" value="">` +
`<td><input name="` + stateName + `[Team]" type="radio" value="B">` +
`</td></tr>`;
$("tbody").append(newPlayerAppend);
stateNo++;
});
HTML for the 3 radio button inputs
<td class="Choice">
<label name="state[1][Team]" class="teampick Astate ">A
<input name="state[1][Team]" type="radio" value="A" />
</label>
<label name="state[1][Team]" class="smallx nostate ">X
<input name="state[1][Team]" type="radio" value="" checked />
</label>
<label name="state[1][Team]" class="teampick Bstate">B
<input name="state[1][Team]" type="radio" value="B" />
</label>
</td>
Some of the code can be written more concisely, or more the jQuery way, but first I want to highlight an issue with your current solution:
The following would generate invalid HTML, if it were not that browsers try to solve the inconsistency:
$("tbody").append(newPlayerAppend);
A tbody element cannot have input elements as direct children. If you really want the added content to be part of the table, you need to add a row and a cell, and put the new input elements in there.
Here is the code I would suggest, that does approximately the same as your code:
$(document).on('click', 'input', function () {
$('label[name="' + $(this).attr('name') + '"]')
.removeClass('nostate selected')
.has(':checked')
.addClass(function () {
return $(this).is('.smallx') ? 'nostate' : 'selected';
});
});
$(document).on('click', 'button[name=btnbtn]', function () {
$('tbody').append($('<tr>').append($('<td>').append(
$('<input>').attr({name: `state[${stateNo}][PlayerID]`, value: stateNo, type: 'hidden'}),
$('<input>').attr({name: `state[${stateNo}][Name]`, value: 'Name'}),
$('<input>').attr({name: `state[${stateNo}][Team]`, value: 'A', type: 'radio'})
)));
stateNo++;
});
There is no issue in having two handlers. They deal with different target elements, and even if they would deal with the same elements, it would still not be a real problem: the DOM is designed to deal with multiple event handlers.
There are 2 places you are using anonymous functions. If the code block moves to a named function, the entire code becomes more maintainable. It also helps better in debugging by telling you upfront which function name the error may lie in.
Once you have named functions you will realise that you really do have 2 event listeners for click. So there isn't much benefit of moving them in one listener (or one function you may be referring to). These both event listeners attach on document object and listen to a click event.
Class names are always better when hyphenated. a-state over Astate.
If it works it is correct code, for once you asked about correctness.
It is absolutely fine to have multiple listeners but I usually prefer making everything under one roof. Consider making code as simple as possible which saves lot of time during maintenance.
you can use $(function() {}) or document.ready().
$(document).ready(function() {
$('input[type="radio"]').click(function() {
var thisa = $(this).parent();
var name = $(this).attr("name");
// Remove :selected class from the previous selected labels.
$('label[name="' + name + '"]').removeClass('selected');
// Add conditional class with tenary operator.
thisa.parent().hasClass("smallx") ? thisa.addClass('nostate') : thisa.addClass('selected');
});
$('button[name=btnbtn]').click(function() {
var stateName = 'state[' + stateNo + ']';
// Add TR and TD before appending the row to tbody
var newPlayerAppend = `<tr><td>` +
`<input type="hidden" name="state['` + stateNo + `'][PlayerID]" value="` + stateNo + `" />` +
`<input name="` + stateName + `[Name]" value="Name">` +
`<input name="` + stateName + `[Team]" type="radio" value="A"></td></tr>`;
$("tbody").append(newPlayerAppend);
stateNo++;
});
});
Hope this helps.
I've been looking an answer, but I don't find anything.
I got a JSF page with a button. This button call a JavaScript function :
function postAdd(id) {
var quant = document.getElementById("hell:quantite");
$('<form action="addto.xhtml" method="POST">' +
'<input type="hidden" name="productkey" value="' + id + '">' +
'<input type="hidden" name="howmany" value="' + quant.value + '">' +
'</form>').submit();
}
This works fine, I've tested it.
But in my addto.xhtml page, when I call param.productkey and param.howmany, I got nothing.
I used this method on other page and works fine but here, it doesn't work...
Any idea ?
Thanks.
The answer was to add to form inside the JSF page directly and get all parameters with #{function(param[form:idOfInput]}
I have a simple ui which has a link that says "add item". When this is clicked, a pair of input boxes appears below it. If it is clicked again, yet another pair appears. I'm trying to think of the best way to generate these elements and turn it into some sort of json array of key value pairs (the first input element in each pair being the key and the second input element being the value).
Right now I just have a counter and I generate the ids using it, such as (in the click event of the "add item" link):
$('#features').append('<input id="feature-name-' + self.featureCount + '" type="text" name="asdf" /><a class="delete-feature" data-id="' + self.featureCount + '">Delete</a><input id="feature-description-' + self.featureCount + '" type="text" name="asdf" />');
I don't know what to use as the "name" attributes in order to make it easy to create a json array from them.
you can do something like this without using id attributes.
$('#features').append('<div><input type="text" />
<a class="delete-feature" data-id="' + self.featureCount + '">Delete</a><input type="text" /></div>');
And your javascript,
var yourArray=[];
$('#yourButton').click(function(){
$('#features div').each(function(){
var div=$(this);
var k=$('input:first',div).val();
var v=$('input:first',div).next().val();
yourArray.push({key:k, value: v});
});
});
It doesn't matter what you use for a name attribute, so long as there name and description names are different. Let's say that these elements are all appended to a form with the id myform. Give each pair its own wrapper object. Here, I've used a div, but a fieldset is equally appropriate.
$('#features').append(
'<div class="feature-div">
'<input id="feature-name-' + self.featureCount + '" type="text" name="asdf" />' +
'<a class="delete-feature" data-id="' + self.featureCount + '">Delete</a>' +
'<input id="featurena-description-' + self.featureCount + '" type="text" name="asdf" />' +
'</div>');
Now, it's possible to extract each pair sensibly:
var myarray = [];
$('#myform .feature-div').each(function(i, v) {
myarray.push([
$('input[name=name]', v).val(), $('input[name=description]', v).val()]);
});
Or however you want the data to be presented.
I render a table using javascript that has a checkbox and a radiobutton on each row of data. Here is a snippet of the code that renders the radiobutton and checkbox.
htmlResult += '<td><input type="checkbox" name="checkBoxes" class="selectLink" id="chkbxRow' + rowCounter + '"style="vertical-align: sub;"/></td>';
htmlResult += '<td><input type="radio" name="isLoanRecipient" value="' + rowCounter + '" id="radioRow' + rowCounter + '"style="vertical-align: sub;"/></td>';
The table is displayed however when I click on the radiobutton, if the checkbox on the same row is previously checked, it unchecks it. Did anyone encountered the same problem? Does anyone know what might be the cause of this? Thanks.
By the way, I'm referencing jquery scripts(1.5.1, validate, validate.unobtrusive, ui)
maybe the solution is simply to insert a space:
id="chkbxRow' + rowCounter + '"style="vertical-align: sub;"
id="chkbxRow' + rowCounter + '" style="vertical-align: sub;"
The same would go for the line with the radios.
I have this HTML code for radios:
<input type='radio' name='a_27' value='Yes' id='a_27_0' />
<input type='radio' name='a_27' value='No' id='a_27_1' />
I'm trying to set the selected value of the radio using this code:
var field="a_" + this.id;
$('[name="' + field + '"]').val(this.value);
console.log("name is " + field + ", val is " + this.value);
However it doesn't work, nothing happens when this runs. Here's the output from Firebug's console which occurs after the 3rd line:
name is a_27, val is Yes
Any ideas?
I would prefer a method which would also work on <select>s, so I wouldn't need to write additional/seperate code for radios and selects.
Edit: A weird problem I've noticed that although my html code gives a different value (yes/no), in firebug it shows both radios as having the value 'yes'. If I select no and click save, the javascript function still receives 'yes' instead of no. Am I doing something wrong?
Edit 2: The full function:
function processMultiOptAnswers()
{
$.each(multiOpts,function()
{
var field="a_" + this.id;
console.log("name is " + field + ", val is " + this.value);
$('[name="' + field + '"]').val(this.value);
}
);
}
your log should be if this.value is different.
$('[name="' + field + '"]').val(this.value);
console.log("name is " + field + ", val is " + $('[name="' + field + '"]').val());
To make it selected
$('[name="' + field + '"]').attr("checked", "checked");
I haven't tested this, but you might have to remove that attribute from the other ones.