I have a javascript calendar on an HTML website, and I'm new to javascript. One of the features of the calendar is the ability to add events for a certain day.
this is my script tag:-
<script>
$(function (e) {
var calendar = $("#calendar").calendarGC({
dayBegin: 0,
prevIcon: '<',
nextIcon: '>',
onPrevMonth: function (e) {
console.log("prev");
console.log(e)
},
onNextMonth: function (e) {
console.log("next");
console.log(e)
},
events: [
{
date: new Date("2022-09-26"),
eventName: "Holiday",
className: "badge bg-danger",
onclick(e, data) {
console.log(data);
},
dateColor: "red"
}
],
onclickDate: function (e, data) {
console.log(e, data);
}
});
})
</script>
I want to dynamically add my custom values inside that events:[] array. Of course, I can edit it and add, but I want to create a function that takes values from me and adds them into it. I know how to create a function to get information from me, but I'm not sure how to push my information into that array. Thank in Advance :)
Additionally, if you require this calendar for additional study, I obtained it from this git: https://github.com/nggepe/calendar-gc
using events.push()
https://www.w3schools.com/jsref/jsref_push.asp
calender.events.push({date:"2022-01-01",eventName:"new years day",className:"badge bg-danger",onclick(e,data){console.log(data)},dateColour:"green"})
Related
I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();
I need to pass an object to some jQuery plugin. The plugin is applied to multiple elements. The data passed is obtained from the element the plugin is applied to.
How can I pass such an object to a Query plugin which includes data from the element applied to (i.e. $(this).parent().parent().data('id'))?
EDIT. without iterating over the results and applying the plugin each time.
$('#main').find('tr a.upload').fileupload({
formData: {id:$(this).parent().parent().data('id'),foo:'bar'}, //id is not included
start: function() {
//Doesn't work
$(this).fileupload({
formData: {example: 'test'}
});
},
done: function(e, data) {
console.log(this); //Am able to access element
},
});
Try this:
$('#main').find('tr a.upload').fileupload({
formData: function(form) {
return {
id: form.parent().parent().data('id'),
foo:'bar'
};
},
done: function(e, data) {
console.log(this); //Am able to access element
},
});
The function is received the form as a parameter, not as the this context.
I have an MVC ListBoxFor control that I'm trying to bind data to and update using a Kendo MultiSelectFor.
The idea being that there is a list of users in the ListBox, and a list of available users in the MultiSelect box. When users are selected from the MultiSelect box and the add button clicked, an Ajax call is made to an action that updates the users list server side (through various API calls, which all work fine) and client side JavaScript is used to update the users and available users array object and the binding keeps the controls up to date with the updated lists.
I wish I could pin this down to just one issue, but honestly every time I try something I come up with different errors, so I'll just go with the latest iteration.
Model:
public IEnumerable<UserInformation> Users { get; set; }
public IEnumerable<UserInformation> AvailableUsers { get; set; }
JavaScript ViewModel:
var viewModel = kendo.observable({
availableUsersSelected: [],
users: #(Html.Raw(Json.Encode(this.Model.Users))),
availableUsers: #(Html.Raw(JsonConvert.SerializeObject(this.Model.AvailableUsers))),
moveToUsers: function () {
this.availableUsersSelected = this.get('availableUsersSelected');
this.users.push(this.availableUsers);
if (this.availableUsersSelected.length > 0) {
var formAction = '#Url.Combine(Url.Content("~/"), ControllerActions.Groups.GroupDefault, ControllerActions.Groups.AddUser)';
$.ajax({
url: formAction,
type: 'POST',
data: {
model: JSON.stringify(
{
groupId: $('#GroupId').val(),
users: this.availableUsersSelected
}
)
},
success: function (result) {
if (result) {
this.users.remove(this.availableUsersSelected);
}
}
});
}
}
});
MultiSelectFor control
#(Html.Kendo()
.MultiSelectFor(u => u.AvailableUsers)
.Placeholder("Please select")
.BindTo(new SelectList(Model.AvailableUsers, "Id", "Name"))
.HtmlAttributes(new { data_bind = "value: availableUsersSelected" })
)
ListBox control
#(Html.EditorLine(Language.Fields.Users, Html.ListBoxFor(u => u.Users, new SelectList(Model.Users, "Id", "Name"), new { #class = "form-control", data_bind = "source: users", data_value_field ="Id", data_text_field = "Name" })))
Add control
<img src="~/Content/images/up-arrow.jpg" alt="Move to users" width="30" data-bind="events: {click: moveToUsers}" />
To reiterate, the Ajax call and updating server side all work fine, it's the client side control binding that I'm struggling to understand.
The errors I'm getting are 1) a syntax error with the comma on this line users: #(Html.Raw(Json.Encode(this.Model.Users))), and the line after it (same thing, effectively), and 2) a "ReferenceError: Id is not defined" on the moveToUsers function call when the add button is pressed.
(I can honestly say that the amount of frustration I'm experiencing with this is driving me insane, so sorry if it came across in the question)
So after calming down a bit, reading a few more bits of the documentation about data binding and observable arrays, I realised I was making a few fundamental errors.
JavaScript ViewModel:
var viewModel = {
availableUsersSelected: new kendo.data.ObservableArray([]),
users: new kendo.data.ObservableArray(#(Html.Raw(Json.Encode(this.Model.Users)))),
availableUsers: new kendo.data.ObservableArray(#(Html.Raw(Json.Encode(this.Model.AvailableUsers)))),
moveToUsers: function () {
if (viewModel.availableUsersSelected.length > 0) {
var formAction = '#Url.Combine(Url.Content("~/"), ControllerActions.Groups.GroupDefault, ControllerActions.Groups.AddUser)';
$.ajax({
url: formAction,
type: 'POST',
data: {
model: JSON.stringify(
{
groupId: $('#GroupId').val(),
users: viewModel.availableUsersSelected
}
)
},
success: function (result) {
if (result) {
removeFromAvailableUsers();
}
else
alert('add failed!');
},
failure: function () {
alert('ajax failed!');
}
});
}
}
};
function removeFromAvailableUsers() {
for (var i = 0; i < viewModel.availableUsersSelected.length; ++i) {
viewModel.users.push(viewModel.availableUsersSelected[i]);
viewModel.availableUsers.remove(viewModel.availableUsersSelected[i]);
}
var ele = $('#AvailableUsers').data("kendoMultiSelect");
ele.value("");
ele.input.blur();
};
The main differences are instead of declaring the entire object as a kendo observable are declaring each array as an observable array, then referencing them through the viewModel object instead of assuming that the "this" scope will encapsulate them.
Then, as D_Learning mentioned in the comments above, I was unnecessarily using two bindings for the MultiSelect control, so that then became:
#(Html.Kendo()
.MultiSelectFor(u => u.AvailableUsers)
.Placeholder("Please select")
.HtmlAttributes(new { data_bind = "source: availableUsers, value: availableUsersSelected", data_value_field = "Id", data_text_field = "Name" })
)
(Notice no ".BindTo" property)
Aside from that, the MVC side of things stayed the same and it all words perfectly.
If you wish to remove or add data to the Kendo Multiselect then you will need to add them via the DataSource as:
$("#AvailableUsers").data("kendoMultiSelect").dataSource.add({"text": "new Item", "value": 1000});
For more detail about Adding or removing Items to Multiselect (Kendo DataSrouce) see: Kendo DataSource Adding Removing Items
Similarly you can remove the item from the Listbox as below:
var selectedIndex = ListBox1.selectedIndex();
clearSelection();
if (selectedIndex != -1) {
ListBox1.options.remove(selectedIndex);
For more detail about Adding or removing Items from HTML Listbox see: HTML Listbox Items Manipulation.
Please let me know if you have any error after this.
I have written an event to save the data in a widget.js file & the handler is on the page. There is no error or exception is coming but the handler is not getting called. Please help.
Widget.js :
(function ($, undefined) {
$.widget('ui.discussionwidget', {
options: {
userID: 'arti.agarwa',
title: "",
width: "",
containerClass: ".ui-content-gutter"
},
saveData: function (userName, msg, parentID) {
//Save Discussion History
$.event.trigger({
type: "sendMessage",
userName: userName,
message: msg,
parentID: parentID,
timeStamp: new Date()
});
},
});})(jQuery);
Page Script :
$(document).ready(function () {
$('#discussionwidget').live("sendMessage", sendMessageHandler);
// sendMessage event handler
function sendMessageHandler(e) {
debugger;
alert(1);
}});
Looks like event delegation is not working fine with global events
$('#discussionwidget').on("sendMessage", sendMessageHandler);
Demo: Fiddle
I can see two possible problems:
Your widget has class discussionwidget but you are binding with id discussionwidget.
You are creating the widget dynamically with javascript? May be the event is being bound before the widget is created.
Try to fix both.
I'm working with a UI that has a (YUI2) JSON DataSource that's being used to populate a DataTable. What I would like to do is, when a value in the table gets updated, perform a simple animation on the cell whose value changed.
Here are some relevant snippets of code:
var columns = [
{key: 'foo'},
{key: 'bar'},
{key: 'baz'}
];
var dataSource = new YAHOO.util.DataSource('/someUrl');
dataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
dataSource.connXhrMode = 'queueRequests';
dataSource.responseSchema = {
resultsList: 'results',
fields: [
{key: 'foo'},
{key: 'bar'},
{key: 'baz'}
]
};
var dataTable = new YAHOO.widget.DataTable('container', columns, dataSource);
var callback = function() {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
And here's what I'd like to do with it:
dataTable.subscribe('cellUpdateEvent', function(record, column, oldData) {
var td = dataTable.getTdEl({record: record, column: column});
YAHOO.util.Dom.setStyle(td, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(td, {
backgroundColor: {
to: '#ffffff';
}
});
animation.animate();
};
However, it doesn't seem like using cellUpdateEvent works. Does a cell that's updated as a result of the setInterval callback even fire a cellUpdateEvent?
It may be that I don't fully understand what's going on under the hood with DataTable. Perhaps the whole table is being redrawn every time the data is queried, so it doesn't know or care about changes to individual cells?. Is the solution to write my own specific function to replace onDataReturnReplaceRows? Could someone enlighten me on how I might go about accomplishing this?
Edit:
After digging through datatable-debug.js, it looks like onDataReturnReplaceRows won't fire the cellUpdateEvent. It calls reset() on the RecordSet that's backing the DataTable, which deletes all of the rows; it then re-populates the table with fresh data. I tried changing it to use onDataReturnUpdateRows, but that doesn't seem to work either.
Edit2:
To achieve the control that I wanted, I ended up writing my own <ul>-based data list that made a bit more sense for the problem I was trying to solve. Jenny's answer below should help solve this for most others, so I've accepted it as the solution.
cellUpdateEvent only fires in response to a call to updateCell(). What you want is to subscribe to the cellFormatEvent. There were a couple other issues in your code, so this should work:
dataTable.subscribe('cellFormatEvent', function(o) {
YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(o.el, {
backgroundColor: {
to: '#ffffff'
}
});
animation.animate();
});
var callback = {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
dataTable.subscribe('cellFormatEvent',
function(o) {
YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(o.el, {
backgroundColor: {
to: '#ffffff'
}
});
animation.animate();
});
var callback = {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
This example will not work beceause you added an interval and this is not the right solution. Because the function will be called each time.