Access Selected Date from dynamically created Calendar Control asp/javascript/VB.net - javascript

UPDATE: To anyone who still may read this, I used a completely different way of doing this. With AjaxToolkit's Calendar Extender, I was able to easily add a calendar dynamically and use Javascript to change the format of different date inputs so that calendar extender could read it. Highly recommend you go the AjaxToolkit route if you are trying to do something similar to me.
I have dynamically created a Calendar control(asp:Calendar), Buttons, and dropdown lists for a Comment Class. The Comment Class will always have a textbox in it, but if the ID/attribute label of the textbox is DOB or birthday or something similar, these other controls get dynamically created.
So far, the calendar, dropdown lists, and one of the buttons works, but I am have trouble with the last button. Currently, I dynamically add a script that is used for one of the buttons to show and hide the div that contains that Calendar, dropdown lists, and relevant buttons, which works amazingly. I am trying to add another script trigger on a button press to take the selected date from the Calendar and put it in the textbox.
Right now, I am just trying to get access to the Calendar. I am using code that looks like this:
function use_calendarDate(){
var calendarDate = '<%=question128_Cal1.SelectedDate%>';
alert(calendarDate);
}
I found this function in another question similar to this, but instead of getting the date, it just puts <%=question128_Cal1.SelectedDate%> as a string into the alert box.
This LINK shows exactly what I am trying to do, but I get a different result. Can anyone help me with what I am doing wrong here?
Interestingly, when I use
var calendarDate = question128_Cal1.SelectedDate;
OR
var calendarDate = question128_Cal1.value;
My alert box tells me undefined.
Thanks in advance.
In case it is needed, my calendar control is created like this:
In Page_Init
Dim calendar1 As New Calendar
Call BuildCalendar(calendar1)
calendarDiv.Controls.Add(calendar1)
Here is the function referenced above.
Private Sub BuildCalendar(ByRef calendar1 As Calendar)
calendar1.ID = "Cal1"
calendar1.SelectedDate = DateTime.Today
calendar1.Attributes.Add("runat", "server")
calendar1.Attributes.Add("OnClientDateChanged", "onDateChange")
calendar1.Attributes.Add("borderwidth", "2px")
calendar1.Attributes.Add("BackColor", "White")
calendar1.Attributes.Add("width", "200px")
calendar1.Attributes.Add("ForeColor", "Black")
calendar1.Attributes.Add("Height", "180px")
calendar1.Attributes.Add("Font-Size", "8pt")
calendar1.Attributes.Add("Font-Names", "Verdana")
calendar1.Attributes.Add("BorderColor", "#999999")
calendar1.Attributes.Add("BorderStyle", "Outset")
calendar1.Attributes.Add("DayNameFormat", "FirstLetter")
calendar1.Attributes.Add("CellPadding", "4")
calendar1.Attributes.Add("ShowNextPrevMonth", "True")
calendar1.Attributes.Add("SelectionMode", "Day")
calendar1.Attributes.Add("ShowTitle", "false")
calendar1.Attributes.Add("OnSelectionChanged", "Calendar_SelectionChanged")
calendar1.TodayDayStyle.ForeColor = Drawing.Color.Black
calendar1.Attributes.Add("todaydaystyle-backcolor", "#cccccc")
calendar1.Attributes.Add("selectorstyle-backcolor", "#cccccc")
calendar1.NextPrevStyle.VerticalAlign = VerticalAlign.Bottom
calendar1.Attributes.Add("dayheaderstyle-font-size", "7pt")
calendar1.Attributes.Add("dayheaderstyle-font-bold", "true")
calendar1.Attributes.Add("dayheaderstyle-backcolor", "#cccccc")
calendar1.Attributes.Add("selecteddaystyle-font-bold", "true")
calendar1.Attributes.Add("selecteddaystyle-forecolor", "White")
calendar1.Attributes.Add("selecteddaystyle-backcolor", "#666666")
calendar1.Attributes.Add("titlestyle-font-bold", "true")
calendar1.TitleStyle.BorderColor = Drawing.Color.Black
calendar1.Attributes.Add("titlestyle-backcolor", "#999999")
calendar1.Attributes.Add("weekenddaystyle-backcolor", "#ffffcc")
calendar1.OtherMonthDayStyle.BackColor = Drawing.Color.Gray
End Sub

Is it question128_Cal1 or question128_Calendar1 ? Your function use_calendarDate() refers to the first. Typo ?
Interestingly, when I use
var calendarDate = question128_Calendar1.SelectedDate;
OR
var calendarDate = question128_Calendar1.value;
My alert box tells me undefined.
That's because the client script has no knowledge of what 'question128_Calendar1' is. That is a server-side ID.
Is there a reason why you can't use markup to define the calendar instead that rather large 'BuildCalendar' function? You're making a bit of a maintenance nightmare by doing that, IMO.

Related

PHP dynamic id attribute of <a> element

I have a drop-down menu in a form with elements retrieved from a database. Something like this :
for($i=0;$i<count($resq);$i++){
print("<li><a class=\"dropdown-item\" href=\"#\" id=\"$i\">{$resq[$i][0]}</a></li>");
}
$resq being an array containing the result of the query (i used mysqli_fetch_all).
As you can see I tried to dynamically generate the id of the items(first item has id=0, second has id=1 and so on till the final value of $i) but I think this is not correct.
Previously, I had the following JS code(which worked) which I used to set the drop-down value to the one selected by the user and to set the value of a hidden input to that value.(I know the code isn't elegant but I just wanted to test the logic in the first place)
var x=document.getElementById('dropdownMenuButton1slct');//dropdown
var c1=document.getElementById("0");//i - categories(IDs of the dropdown elements)
var c2=document.getElementById('1');
var c3=document.getElementById('2');
var c4=document.getElementById('3');
var c5=document.getElementById('4');
var p=document.getElementById('iaval');//hidden input from form
function clic(z){
z.onclick=function () {
x.innerHTML=z.innerHTML;
p.value=x.innerHTML;
};
}
clic(c1);
clic(c2);
clic(c3);
clic(c4);
clic(c5);
But now the same method won't work. If you can, please suggest me a different way or something, I am kinda stuck. I can provide more info if this seems vague or something like that. Thanks.

How to set datepicker using webdriverIO?

I have a task where I need to automate the booking.com page, and one of the tasks is to select check-in and check-out dates. How I can do this? I automated , that I can open calendar, but I don't know how to select dates.
Here is my code
Cucumber step
And user selects dates from "2020-06-16" to "2020-06-26"
BookingStep
When('user selects dates from {string} to {string}',()=>{
BookingPage.checkInOut.click();
browser.debug(); });
Booking page
class BookingPage{
get whereAreYouGoingTextBox(){return $('#ss')};
get checkInOut(){return $('div.xp__dates-inner')}; }export default new BookingPage();
Note: My answer is a solution for the ability to set a value in the date field, and only interact with the cancel link on the date picker object.
I battled this for a while and came up with a solution that works for me, I hope it works for you also.
First when I inspect the datepicker object, it generates a random XPATH/CSS Selector. As a result if you inspect & copy the selector and try to use it in your next test, it will fail since the xpath/selector is randomly generated. I got around this issue by identifying a unique css ID that lived above the datepicker element, and used that as my starting point. Then I looked at the html path from that point to the datepicker input tag, and I appended that path. This solved the first problem of not being able to set a value in the date picker text field. Here is an example using xpath:
//*[#id="filtersSideBar"] - This is the unique ID found above the datepicker
/div[2]/div/input - This is the path to the date picker from the unique ID
$('//*[#id="filtersSideBar"]/div[2]/div/input').waitForClickable(3000);
$('//*[#id="filtersSideBar"]/div[2]/div/input').setValue('2020-01-01');
Now that you have a date inside the date picker field, you have to close the datepicker object. I had to use Javascript to accomplish this. First open the datepicker object, then inspect the 'Cancel' link element. Copy the CSS Selector ID. Lets say it ends up being #cancelLink
Now you run this code:
browser.execute(() => document.querySelector('#cancelLink').click());
Which will then close the datepicker object so that you can proceed with your testing.
Here is my actual code:
class DataSearchSortAndDateRangePage {
get startDate() { return $('//
[#id="filtersSideBar"]/div[2]/div/div[2]/div[1]/div/input'); }
setStartDate(date) {
this.startDate.waitForClickable( { timeout: browser.config.timeOutValue } );
this.startDate.setValue(date);
browser.execute(() => document.querySelector('body > div.md-datepicker-dialog.md-theme-default > div.md-datepicker-body > div.md-dialog-actions.md-datepicker-body-footer > button > div > div').click());
}
}
export default new DataSearchSortAndDateRangePage();
I hope this helps out =)

Angular event detection for datepicker close

I have just started using angular and in general love it. I have a UI requirement to show a date as text, then when you click on the text, it shows a date picker instead. Then when you select a date it goes back to text. Sounds simple.
I have tried a few variations on the below code the object being edited holds a value called editdate, clicking on the text box changes this to true and hides the text and shows the editor. This works fine, the problem is hiding the date picker. I tried adding ng-blur to the datepicker to cause the box to hide when it looses focus, but this was very intermittent as to if it worked. I then tried ng-Mouseleave but the box closed when I moved the mouse pointer into the date picker from the text box.
<td colspan="7">
Required Date : <span ng-click="item.editdate=true; item.delayeditclose = true;" ng-show="!item.editdate">{{item.dueDate.toDateString()}}</span>
<input type="date" ng-blur="item.editdate=false" ng-click="item.switcheditdate(item.delayeditclose)" ng-show="item.editdate" class="datepick" ng-model="item.dueDate" ng-focus="selectPart(item.partNumber)" />
</td>
The javascript is initialized as:
for (var i = 0; i < data.items.length; i++) {
item = data.items[i];
item.showExpanded = false;
item.editdate = false;
item.delayeditclose = true;
item.switcheditdate = function (delayclose) {
if (!delayclose) {
this.editdate = !this.editdate;
this.delayeditclose = true;
}
this.delayeditclose = false;
};
items.push(item);
}
I have now moved onto the above which almost does the job. The new issue being html5 date pickers seem to have a x to close them down. This hides the whole box and not just the picker part. If this happens I want to show the text of the date rather than what I get now which is nothing. Does anyone know of how I can capture this close event and revert back to the text or suggest a better approach to the problem?
I have lots of items each one is in its own row in a table
I am using angular 1.3 beta 8
thanks for looking
Andy
The reason why you are getting nothing is because when you click x what happens is that the date value gets cleared so then your date view is an empty string. What you can do is set a condition to display a string such as "Click to Edit" when the date is empty.
Taking just what you have above, one way of doing it is by adding an element and a flag in your date "view". So change this:
Required Date : <span ng-click="item.editdate=true; item.delayeditclose = true;" ng-show="!item.editdate">{{item.dueDate.toDateString()}}</span>
To:
Required Date :
<span ng-click="item.editdate=true; item.delayeditclose = true;" ng-show="!item.editdate">
<span>{{item.dueDate.toDateString()}}</span>
<span ng-show="!item.dueDate">Click to Edit</span>
</span>
The directive way
Now in my opinion I think it's much better to use a directive for this. It would simplify your logic and is much easier to re-use. I created a plunker which shows my implementation using a directive.
Answer to question in title
To answer the question posed by your title, when using the html5 date picker, you can't detect when it is closed (or even when it is opened). See this answer and the linked Quick FAQs on input[type=date]

How to make all the fields visible in the new Task form of Tasks List in SharePoint?

I have created a Tasks List in SharePoint. When I try to add a new Task, it opens a form with few visible fields like TaskName, StartDate, DueDate, Description, AssignedTo. When I click on 'ShowMore', then it is showing all the remaining fields like %complete, TaskStatus, Priority, Comments, ExpectedDueDate.
Issue: I want all the fields to be visible from the start without clicking on 'ShowMore', because some people might get confused with this option and may skip filling these fields. Can someone please kindly suggest how to achieve this. Any help is greatly appreciated. Thank you!
Unfortunately there is no such setting that allows to configure fields visibility in tasks form AFIK.
But task form could be customized in order to display all the fields as demonstrated below.
Since it is a SharePoint 2013 environment, the following approach is suggested:
Create rendering template to display all the fields in New & Edit forms
Update Task web part in New & Edit forms pages
Template file
The following example demonstrates how to display all the fields of Task form:
(function () {
function preTaskFormRenderer(renderCtx) {
rlfiShowMore();
}
function registerRenderer()
{
var ctxForm = {};
ctxForm.Templates = {};
ctxForm.OnPreRender = preTaskFormRenderer;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctxForm);
}
ExecuteOrDelayUntilScriptLoaded(registerRenderer, 'clienttemplates.js');
})();
How to apply changes
Upload the specified script (lets name it TaskForm.js) into SharePoint Site Assets library
Open New Form page in edit mode and go to Tasks web part properties
Specify JS Link property located under Miscellaneous group: ~sitecollection/SiteAssets/TaskForm.js (see pic. 1)
Save changes and repeat steps 2-4 for Edit form
I prefer other methods to the JavaScript workaround to really solve the problem:
1. You can change the list form assigned to the local Task content type, for example via PowerShell:
$web = Get-SPWeb http://YourSharePointSite
$list = $web.Lists["Tasks"]
$ct = $list.ContentTypes[0]
$ct.DisplayFormTemplateName = "ListForm"
$ct.NewFormTemplateName = "ListForm"
$ct.EditFormTemplateName = "ListForm"
$ct.Update()
You can set the list form assigned to the ListFormWebPart via SharePoint Designer
Create your own control template and add the ShowExpanded="true" attribute to the TaskListFieldIterator control
Pass the Expanded=1 in the request query string like NewForm.aspx?Expanded=1
Change the default column order of the local Task content type
All of these have the effect of displaying all the fields without the "Show More" button. You can read more about these methods here:
http://pholpar.wordpress.com/2014/11/01/no-more-show-more-in-tasks-lists/

button adds a row and inputs cell values from text fields

i asked a similar question before however the solution no longer works for my application, i need a button click to create a new row (FailureInstance) in a table (failuretable) and i need it to populate three of the cells with data from fields that are elsewhere filled in. here is my code: form1.failuretable.AddFailureButton::click - (JavaScript, client)
xfa.host.messageBox("Failure Recorded and Added To Table Below. Please Continue Filling Out the Form Until All Failures Have Been Recorded. Then Please Save and Submit the Form.", "Continue/Save/Submit", 3);
if (xfa.host.version < 8) {
xfa.form.recalculate(1);
}
var newRow = failuretable._FailureInstance.addInstance(1);
newRow.FailureCode.rawValue = form1.FailureType.rawValue;
newRow.Location.rawValue = form1.CellLocation.rawValue;
newRow.Comments.rawValue = form1.AdditionalComments.rawValue;
right now this doesn't even create a new row for my table... any help is appreciated!
You should check whether multiple instances for a row are allowed. Select FailureInstance in hierarchy view and then in Object->Binding (if you dont see it go to window menu and select Object) check wheter "Repeat Row for Each Data Item" is selected. If not then select it and your code should work fine.
I advice also to enable JavaScript debugging in your Adobe Reader because it than you should see when error appears and what is it about. Open Reade go to Edit->Preferences->JavaScript and select "Show console on errors and messages". Then you will need to restart Designer.
At design time remember to enable:
Object > Data Binding > Repeat Table For Each Data Item
In code, I believe that lack invoking "instaceManager":
...
var newRow = failuretable.FailureInstance.instanceManager.addInstance(1);
...
http://help.adobe.com/en_US/livecycle/9.0/designerHelp/index.htm?content=000178.html

Categories