Kendo Scheduler Scrape Recurrence Rule Before Save - kendo-ui

I have a custom edit template for kendo scheduler.
Below all the controls to set dates and the recurrence rule I have a button.
Pressing the button loads a list of people available for that appointment.
To get that list, I am checking conflicts in future visits and I'm checking against a people availability table to make sure they are available on those dates.
All the code works fine except I cannot get the recurrence rule before the Save button is pressed and the data is transported to the server.
The recurrenceRule property is blank even though all the selections are made before pressing my button.
It seems kendo scheduler formats that recurrence rule when you press the save button and then populates the model and transports it to the server.
I could write my own Recurrence Rule by reading the widgets in the kendo recurrence editor control but they didn't put an Id's on the widgets which makes them hard to get. I think you can use css selectors but I haven't done anything like that and would rather not write my own recurrence editor.
Does anyone know how to get the recurrence rule while in the edit template before pressing Save?
FLOW:
1) set start and end date, and recurrence pattern in kendo recurrence editor
2) press button on edit template form to load available employees
--- I need the recurrence rule here.
On the server side I expand the appointment to all it's occurrences
and then I check each potential visit against the employee schedule
3) select one of the employees and save the record.
--- I can't do the check here because the employee has to be selected before saving the record and I only want to provide a list of available employees -- before save.
I tried many things including this:
var recurEditor = $("#RecurrenceRule").data("kendoRecurrenceEditor");
var recurrenceRule = recurEditor.options.recurrenceRule;
alert("recurrenceRule: " + recurrenceRule);
But no luck...

Here's the solution. I knew if I posted the question here, after 2 days of trying to figure it out, that I'd find the solution. Maybe this will help someone else.
On the handler for my button to load available employees, I have this code:
var ruleEditor = $('[id="RecurrenceRule"]').getKendoRecurrenceEditor();
if (ruleEditor) {
vRecurRuleValue = ruleEditor.value();
alert("vRecurRuleValue = " + vRecurRuleValue);
}
My recurrence editor is defined in my edit template as so:
#(Html.Kendo().RecurrenceEditorFor(model => model.RecurrenceRule).HtmlAttributes(new { data_bind = "value:recurrenceRule", data_role = "recurrenceEditor" } ))
And my employee dropdown has a filter as follows:
<div id="EmpAssignedDropdownlist" class="k-edit-field" style="visibility:hidden;">
#(Html.Kendo().DropDownListFor(m => m.VisitEmployeeM.UserId)
.AutoBind(false)
.Text("Please Select") //used to prevent initial datasource.read as AutoBind doesn't work
.DataTextField("name")
.DataValueField("id")
.ValuePrimitive(true)
.OptionLabel(#Localizer["Please Select"].Value)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetEmployeesAvailableForPotentialVisit", "DropDownList").Data("filterAvailableEmployeesNoVisitYet");
}).ServerFiltering(true);
})
)
</div>
the javascript function "filterAvailableEmployeesNoVisitYet" passes the recurrence rule and other data I need to check for conflicts and loads the dropdownlist.

Related

Oracle APEX - I need help to setup dynamic search filter on IG report

I have an IG region where I disabled the toolbar and created my custom search item.
I want user to be able to type the first three characters of a name on the search item (named P8_SEARCH) and the IG report will only show the name(s) that starts with those 3 characters.
This should happen without clicking any button. The IG report query is shown below:
select member_id, first_name, last_name , address, dob, home_phone, cell_phone,
email_address from member_profile where first_name like '%'||:P8_SEARCH||'%';
I also created dynamic action with key release event and True action Execute JavaScript Code shown below:
var keyPressCount=0;
$("#P8_SEARCH").on("keypress", () => {
if (keyPressCount < 2) {
keyPressCount++;
} else {
$s("P8_SEARCH", apex.item( "P8_SEARCH" ).getValue());
}
})
How can I achieve this without submitting the page? I will appreciate any suggestion. Example:
Set an static_id for your IG region, in the dynamic action add apex.region("yourStaticId").refresh();to your JS code, this will refresh only the region.
something like this:
var keyPressCount=0;
$("#P8_SEARCH").on("keypress", () => {
if (keyPressCount < 2) {
keyPressCount++;
} else {
$s("P8_SEARCH", apex.item( "P8_SEARCH" ).getValue());
apex.region("yourStaticId").refresh();
}
})
If the search items are stored in an associated table, my idea is that you could associate a PL/SQL expression to execute using a Process. This process could be executed on a custom action.
Another idea is that you associate the dynamic action with a hidden button press, and make the JavaScript code click on the button. Then, you can 'simulate' the existence of a trigger for your dynamic action with key release event
What do you think?

How to get the selected index from a dropdown menu in d3

I have a dropdown menu in d3.js, and I would like to get the index from the selected option. It's a list of a bit more than 50 flight companies, and right now I have this :
function choixCompagnie(){
let compagnieChoisie = d3.select(this).property('value')
}
This function activates whenever there is a change on the drop down, like so :
d3.select("#selectCompagnie")
.on("change",choixCompagnie)
The property('value') means that for instance if I click the first line of my drop down menu, which is Aer Lingus, my compagnieChoisie variable will get the value Aer Lingus instead of 0.
I need it because I then need to access some properties company by company, and my objects are in an array. So in my database I need to access the properties like this data[index].randomProperty and not like this data["Company Name"].randomProperty, since the company name is already a property.
I don't know if this makes sense, sorry if I'm using the wrong terms I'm fairly new to coding.
Thanks for the help !
edit : here is a working example http://blockbuilder.org/ArnaudStephanUNIL/a18332a561579eb929091faaff91fb6f, where the drop down gets the value but not the index
You should access your data like this:
function choixCompagnie(){
let compagnieChoisie = d3.select(this).property('value')
console.log(data.find(d => d.compagnie === compagnieChoisie).accidents);
}
I found a better, easier way to get the index from a drop down menu :
<select id="selectOptions"></select>
Once you initialized your drop down menu, you simply have to do this :
var options = ["option1","option2"];
options.forEach(function(d,i){
d3.select("#selectOptions")
.append("option")
.attr("value",i)
.text(d);
})

Populating dropdown list with two columns from database

I'm working on MVC3 project.
At my controller I already have a code that gets the Descr column from StockClass table. After that I fill a ViewBag with this list in order to retrieve it from the view and populate the dropdown list.
Currently is working fine but only shows Descr field (obviously). What i want is populate the dropdown list with two fields (Code and Descr) in this format: "code - descr".
I tried several ways but i cannot find the way to code the #Html helper correctly.
In my controller...
var oc = dba.StockClass.OrderBy(q => q.Code).ToList();
ViewBag.OrderClass = new SelectList(oc, "StockClassId", "Descr");
In my view....
#Html.DropDownList("StockClassID", (SelectList)ViewBag.OrderClass)
Could you please help me?
I don't believe there is an HTML Helper which will do that for you, but you can get what you're after like this:
var oc = dba.StockClass
.OrderBy(q => q.Code)
.ToDictionary(q => q.StockClassId, q => q.Code + " - " + q.Descr);
ViewBag.OrderClass = new SelectList(oc, "Key", "Value");
This also has the advantage of making the uses of StockClassId, Code and Descr refactor-friendly - if you rename those properties you won't be able to compile without updating this bit of code to match.

Handling parameters from dynamic form for one-to-many relationships in grails

My main question here is dealing with the pramas map when having a one-to-many relationship managed within one dynamic form, as well as best practices for dealing with one-to-many when editing/updating a domain object through the dynamic form. The inputs for my questions are as follows.
I have managed to hack away a form that allows me to create the domain objects shown below in one Dynamic form, since there is no point in having a separate form for creating phone numbers and then assigning them to a contact, it makes sense to just create everything in one form in my application. I managed to implement something similar to what I have asked in my Previous Question (thanks for the people who helped out)
class Contact{
String firstName
String lastName
// ....
// some other properties
// ...
static hasMany = [phones:Phone]
static mapping = {
phones sort:"index", cascade: "all-delete-orphan"
}
}
class Phone{
int index
String number
String type
Contact contact
static belongsTo = [contact:Contact]
}
I basically managed to get the values from the 'params' map and parse them on my own and create the domain object and association manually. I.e. i did not use the same logic that is used in the default scaffolding, i.e.
Contact c = new Contact(params)
etc...., i just looped through all the params and hand crafted my domain objects and saved them and everything works out fine.
My controller has code blocks that look like this (this is stripped down, just to show a point)
//create the contact by handpicking params values
def cntct = new Contact()
cntct.firstName = params.firstName
cntct.lastName = params.lastName
//etc...
//get array of values for number,type
def numbers = params['phone.number']
def types = params['phone.type']
//loop through one of the arrays and create the phones
numbers.eachWithIndex(){ num, i ->
//create the phone domain object from
def phone = new Phone()
phone.number = num
phone.type = types[i]
phone.index = i
cntct.addToPhones(phone)
}
//save
My questions are as follows:
What is the best practice of handeling such a situation, would using Command objects work in this case, if yes where can i found more info about this, all the examples I have found during my search deal with one-to-one relationships, I couldn't find an example for one-to-many?
What is the best way to deal with the relatiohsips of the phones in this case, in terms of add/removing phones when editing the contact object. I mean the creation logic is simple since I have to always create new phones on save, but when dealing with updating a contact, the user might have removed a phone and/or editing an exiting one and/or added some new phones. Right now what I do is just delete all the phones a contact has and re-create them according to what was posted by the form, but I feel that's not the best way to do it, I also don't think looping over the existing ones and comparing with the posted values and doing a manual diff is the best way to do it either, is there a best practice on how to deal with this?
Thanks, hopefully the questions are clear.
[edit] Just for more information, phone information can be added and deleted dynamically using javascript (jquery) within the form [/edit]
disclaimer: i do not know if the following approach works when using grails. Let me know later.
See better way for dynamic forms. The author says:
To add LineItems I have some js that calculates the new index and adds that to the DOM. When deleting a LineItem i have to renumber all the indexes and it is what i would like to avoid
So what i do
I have a variable which stores the next index
var nextIndex = 0;
When the page is loaded, i perform a JavaScript function which calculates how many child The collection has and configure nextIndex variable. You can use JQuery or YUI, feel free.
Adding a child statically
I create a variable which store the template (Notice {index})
var child = "<div>"
+= "<div>"
+= "<label>Name</label>"
+= "<input type="text" name=\"childList[{index}].name\"/>"
+= "</div>"
+= "</div>"
When the user click on the Add child button, i replace {index} - by using regex - by the value stored in the nextIndex variable and increment by one. Then i add to the DOM
See also Add and Remove HTML elements dynamically with Javascript
Adding a child dinamically
Here you can see The Paolo Bergantino solution
By removing
But i think it is the issue grow up when deleting. No matter how many child you remove, does not touch on the nextIndex variable. See here
/**
* var nextIndex = 3;
*/
<input type="text" name="childList[0].name"/>
<input type="text" name="childList[1].name"/> // It will be removed
<input type="text" name="childList[2].name"/>
Suppose i remove childList1 What i do ??? Should i renumber all the indexes ???
On the server side i use AutoPopulatingList. Because childList1 has been removed, AutoPopulatingList handles it as null. So on the initialization i do
List<Child> childList = new AutoPopulatingList(new ElementFactory() {
public Object createElement(int index) throws ElementInstantiationException {
/**
* remove any null value added
*/
childList.removeAll(Collections.singletonList(null));
return new Child();
}
});
This way, my collection just contains two child (without any null value) and i do not need to renumber all the indexes on the client side
About adding/removing you can see this link where i show a scenario wich can gives you some insight.
See also Grails UI plugin
Thanks,
Your answer brought some insight for me to do a wider search and I actually found a great post that covers all the inputs in my question. This is just a reference for anyone reading this. I will write a blog entry on how I implemented my case soon, but this link should provide a good source of ino with a working exmaple.
http://www.2paths.com/2009/10/01/one-to-many-relationships-in-grails-forms/
Most of the time I use ajax to manage such problem.
So when the user clicks add new phone I get the template UI from the server for manageability purpose ( the UI just same GSP template that I use to edit, update the phone), so this way you are not mixing your UI with your js code, whenever you want to change the UI you have to deal only with our GSP code.
Then after getting the UI I add it to the page using jquery DOM manipulation. Then after filling the form when they hit add(save) the request is sent to the server via ajax and is persisted immediately.
When the user clicks edit phone the same UI template is loaded from the server filled with existing phone data, then clicking update will update the corresponding phone immediately via ajax, and same thing applies to delete operation.
But one day I got an additional scenario for the use case that says, "until I say save contact no phone shall be saved on the backend, also after adding phones to the contact on the ui if navigate away to another page and come back later to the contact page the phones I added before must be still there." ugh..
To do this I started using the Session, so the above operations I explained will act on the phone list object I stored on the session instead of the DB. This is simple perform all the operation on the phonesInSession but finally dont forget to do this(delete update):
phonesToBeDeleted = phonesInDB - phonesInSession
phonesToBeDeleted.each{
contact.removeFromPhones(it)
it.delete()
}
I know I dont have to put a lot of data in session but this is the only solution I got for my scenario.
If someone has got similar problem/solution please leave a comment.
First, in all your input fields names you add an #:
<input type="text" name="references[#].name"/>
Second, add call a function before submitting:
<g:form action="save" onsubmit="replaceAllWildCardsWithConsecutiveNumbers();">
Third, this is the code for the function that you call before submitting the form:
function replaceAllWildCardsWithConsecutiveNumbers(){
var inputs = $('form').find("[name*='#']");
var names = $.map(inputs, function(el) { return el.name });
var uniqueNames = unique(names);
for (index in uniqueNames) {
var uniqueName = uniqueNames[index];
replaceWildCardsWithConsecutiveNumbers("input", uniqueName);
replaceWildCardsWithConsecutiveNumbers("select", uniqueName);
}
}
function unique(array){
return array.filter(function(el, index, arr) {
return index === arr.indexOf(el);
});
}
function replaceWildCardsWithConsecutiveNumbers(inputName, name){
counter = 0;
$(inputName + "[name='" + name + "']").each(function (i, el) {
var curName = $(this).attr('name');
var newName = curName.replace("#", counter);
$(this).attr('name', newName);
counter += 1;
});
}
Basically, what the code for replaceAllWildCardsWithConsecutiveNumbers() does, is to create a list for all input (or select) elements whose name contains an #. Removes the duplicates. And then iterates over them replacing the # with a number.
This works great if you have a table and you are submitting the values to a command object's list when creating a domain class for the first time. If you are updating I guess you'll have to change the value of counter to something higher.
I hope this helps someone else since I was stuck on this issue for a while myself.

Dynamic bind in Lift framework

I am newbie to Lift and I have a question on using bind, Ajax in Lift.
I want to create three dropdown menus using Ajax in a dynamic fashion. I use "Address" as an example to describe what I am trying to achieve. At fist, I only have to display "Country" menu with default set to "None". The user at this point can choose to submit if she wishes to and the address is taken as default. If not, she can provide the precise address. Once she selects the country, the "State" menu should get displayed, and once she selects "State", the "County" menu should be displayed.
With the help of lift demo examples, I tried to create static menus as follow. I created three snippets <select:country/>, <select:state/>, <select:county/> in my .html file and in the scala code, I bind as follows:
bind("select", xhtml,
"system" -> select(Address.countries.map(s => (s,s)),
Full(country), s => country = s, "onchange" -> ajaxCall(JE.JsRaw("this.value"),s => After(200, replaceCounty(s))).toJsCmd),
"state" -> stateChoice(country) % ("id" -> "state_select"),
"county" -> countyChoice(state) % ("id" -> "county_select"),
"submit" -> submit(?("Go!"),()=>Log.info("Country: "+country+" State: "+state + " County: "+ county)
The corresponding replaceCounty, stateChoice, countyChoice are all defined in my class. However, when the country is selected, only the state is refreshed through Ajax call and not the county.
Q1) Is there a way to refresh both the menus based on the country menu?
Q2) How to create the menu's dynamically as I explained earlier?
There is an excellent example code that does just this available at:
http://demo.liftweb.net/ajax-form
If you want to update multiple dropdowns as a result of an AJAX update, you'll want to return something like:
ReplaceOptions(...) & ReplaceOptions(...)
Use SHtml.ajaxSelect for your first select, and static elements for the other two. When the first select changes, you'll return javascript to populate the next select with the result of another SHtml.ajaxSelect call.
def countrySelect : NodeSeq = {
val countryOptions = List(("",""),("AR","AR"))
SHtml.ajaxSelect(countryOptions, Empty, { selectedCountry =>
val stateOptions = buildStateOptions(selectedCountry)
SetHtml("state-select", SHtml.ajaxSelect(stateOptions, Empty, { selectedState =>
// setup the county options here.
}))
})
}
bind(namespace, in,
"country" -> countrySelect,
"state" -> <select id="state-select"/>,
"county" -> <select id="county-select"/>)
In the callbacks for #ajaxSelect you'll probably want to save the values of whatever has been selected, but this is the general approach I'd take.

Resources