I am using a Functions class written in VB on my Razor Page. The page does what it is asked to do but the Next Date calculation is stuck on the first row.
#page
#model Moderate.Pages.DanceList.ThisCityModel
#using VB_Stuff.VB_Stuff;
Then I am building a table and displaying the data with a For Each loop.
<tbody>
#foreach (var item in Model.Dances_Moderated)
{
That is all fine and dandy and each new value per row is displayed except when I get to the column that calls the VB functions to calculate the "Next Date".
Only the first row's data is sent to the Next Date functions so as the For Each iterates through the numerous rows, the data does not change, only the first row's data is sent to the functions resulting in all rows displayed having that first value for that column. Other columns change base on data changing.
<td>
#{
DateStuff obj = new DateStuff();
string strTodayTomorrow = obj.fTodayTomorrow(Model.Dances_Moderated[0].RecurYesNo, Model.Dances_Moderated[0].SingleDate, Model.Dances_Moderated[0].RecurWeekOfMonth, Model.Dances_Moderated[0].RecurDayOfWeek);
if (strTodayTomorrow == "")
{
string NextEvent = obj.fNextEvent(Model.Dances_Moderated[0].RecurYesNo, Model.Dances_Moderated[0].SingleDate, Model.Dances_Moderated[0].RecurWeekOfMonth, Model.Dances_Moderated[0].RecurDayOfWeek);
#Html.Raw(NextEvent)
}
else
{
#Html.Raw(strTodayTomorrow)
}
}
</td>
Oh, and these Data math functions work flawlessly in several other VB.Net apps I have.
I want to pass other value when checkBox is clicked.
my code is as below
foreach (var item in Model) {
<td>
#Html.CheckBox("Project", false, new { item.ProjectId})
</td>
}
Controller is
[HttpPost]
public ActionResult Test(FormCollection collection)
{
var test = collection["Project"]; }
in Var test i am getting True or False
Is there any way to get ProjectId??
The CheckBox and CheckBoxFor helpers are meant for bool and bool? properties (In fact, if you look at the source code you will see they force a casting of the property value to bool?. Check the method InputHelper here in the source code).
In the case of the CheckBox helper, the output will be something like this:
<input id="Foo" name="Foo" type="checkbox" value="true">
<input name="Foo" type="hidden" value="false">
As you can see, the values are hardcoded to true/false boolean values. You could override the value attribute but that would only apply to the checkbox and not to the hidden field with the value for when the checkbox is unchecked. Using the helper with non-boolean fields would also lead you to trouble because of the casting to bool? I mentioned above.
One possible solution would be to manually create the desired html. (You need to be carefull with the name attribute here as it is what the MVC model binder will use to populate your model). Writing something like this in your view:
<input id="Foo" name="Foo" type="checkbox" value="#item.ProjectId">
#* you could add another hidden input for when the checkbox is not checked *#
If you are using the model metadata or if you have complex bindings, this may be a problem as you would need to manually set the html attributes and be careful with the name attribute.
Another option is to create your own html helper. This could allow you to use other types not just booleans and should expect a value for when the checkbox has been checked. The idea is to create something like this:
public static class CustomHelpers
{
public static MvcHtmlString CheckBoxNonBooleanFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object checkedValue)
{
var fieldName = ExpressionHelper.GetExpressionText(expression);
var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var value = metadata.Model;
TagBuilder tag = new TagBuilder("input");
tag.Attributes.Add("name", fullBindingName);
tag.Attributes.Add("id", fieldId);
tag.Attributes.Add("type", "checkbox");
tag.Attributes.Add("value", (checkedValue ?? true).ToString());
if ((checkedValue != null && checkedValue.Equals(value))
||(checkedValue == null && value == null ))
{
tag.Attributes.Add("checked", "checked");
}
var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
foreach (var key in validationAttributes.Keys)
{
tag.Attributes.Add(key, validationAttributes[key].ToString());
}
return new MvcHtmlString(tag.ToString());
}
}
This helper can be used in your view as in the following example (Don´t forget to include your helper namespace into the views namespaces settings of the web.config in the views folder):
#Html.CheckBoxNonBooleanFor(m => m.Foo, 132)
And it will generate the following html, taking care of things like the metadata attributes, the name, the checked attribute, etc for you.
<input id="Foo" name="Foo" type="checkbox" value="132" data-val="true" data-val-number="The field Foo must be a number.">
If needed, you could easily extend it adding another parameter uncheckedValue that will add a hidden input field with the desired value for when the checkbox remains unchecked. You could also add the htmlAttributes parameter to allow you passing additional random html attributes.
As a final comment, just double check that radio buttons won´t be a fit for your requirements, as you could easily have multiple radio buttons for the same field with different int values.
I'm assuming you want the projectid given a checkbox is checked?
<td>
#Html.Hidden("projectId", item.ProjectId)
#Html.CheckBox("selected", false)
</td>
[HttpPost]
public ActionResult Test(int projectId, bool selected)
{
if (selected)
{
///use your projectId
I have a DefaultDataTable that gets its columns programmatically.
The markup is simple:
<table wicket:id="dataTable" border="0" cellpadding="1" cellspacing="1" width="90%" />
All of the columns are dynamically generated from a passed in LinkedHashMap of labels and attributes:
for (Entry<String, String> entry : entrySet) {
final String label = entry.getKey();
final String attribute = entry.getValue();
columns.add(new PsPropertyColumn(label, attribute) {
#Override
public void populateItem(Item cellItem, String componentId, IModel model)
{
final Object modelObject = model.getObject();
final Object value = PropertyResolver.getValue(attribute, modelObject);
// Add an edit link
BookmarkablePageLink link = new ...;
...
cellItem.add(link);
}
}
}
DefaultDataTable table = new DefaultDataTable("dataTable", columns, dataProvider, MAX_ROWS) {
...
}
add(table);
As many posts have mentioned, this is rendered as a cell with an onclick handler rather than an anchor (<a href="..." />) tag. I want the anchor tag for a couple of reasons, one if which is that I want to add my own onclick handler without having an existing onclick handler in the way.
I have seen the generally accepted solution that says to put an anchor tag inside a panel in the HTML markup, and to add the link inside of a Panel subclass. However, that doesn't give the entire html markup (inside the table), and I think the column () tags must be a part of this markup, which I don't think works with my strategy of dynamically generating the columns (I don't even know or care how many will be asked for). Is there a way to render my dynamically generated columns as anchor tags without specifying in the markup how many there?
Thank you for any help.
I have used nested ListView components to be able to have more control over the layout as below:
html:
<table wicket:id="listViewContainer">
<tr>
<th wicket:id="columnHeaderListView">
<span wicket:id="columnHeaderLabel">Header Label</span>
</th>
</tr>
<tr wicket:id="rowListView">
<td wicket:id="rowColumnListView">
<a href="#" wicket:id="link">
<span wicket:id="linkLabel">Link Label</span>
</a>
</td>
</tr>
</table>
Java:
WebMarkupContainer listViewContainer = new WebMarkupContainer("listViewContainer");
listViewContainer.setOutputMarkupId(true);
add(listViewContainer);
ListView columnHeaderListView = new ListView("columnHeaderListView", columnHeaderList) {
#Override
protected void populateItem(ListItem listItem) {
ColumnHeader ch = (ColumnHeader) listItem.getModelObject();
listItem.add(new Label("columnHeaderLabel", new Model(ch.getLabel())));
}
};
listViewContainer.add(columnHeaderListView);
ListView rowListView = new ListView("rowListView", rowList) {
#Override
protected void populateItem(ListItem listItem) {
Row row = (Row) listItem.getModelObject();
listItem.add(new ListView("rowColumnListView", getRowColumnList(row)){
#Override
protected void populateItem(ListItem li) {
RowColumn rowColumn = (RowColumn) li.getModelObject();
Link link = new BookmarkablePageLink("link",...
li.add(link);
link.add(new Label("linkLabel", new Model(rowColumn.getLabel())));
}
});
}
}
listViewContainer.add(rowListView);
I want the user to be able to construct a list of items client-side in a form and then send the entire list to the server when the form is submitted.
Each item has several properties that can be set. For example, here's an Order model:
class Order
{
int Id;
string Description;
Guid UserId;
string Product;
}
The user should be able to add and configure as many orders as they want before submitting the form.
I thought I could do this with the Telerik grid using InCell editing. Unfortunately, the list of available options for each field will change based on the value chosen for other fields. I couldn't make this work with InCell editing because I couldn't access the other ui elements from my javascript event handlers.
I also tried to do this with normal InLine editing, but the only item returned is the new Order to be added. I couldn't access the GridModel to add the new Order. I don't want to persist the Order list until the user is done editing.
Any help would be greatly appreciated.
EDIT: If I go with the solution of making my own list, I have this problem with cascading comboboxes. Each combobox has a name like "UserId_0" based on what index it is in the list.
But now how do I get the downstream list?
Here's my two comboboxes:
<td>
#(Html.Telerik().ComboBox()
.Name("UserId_" + i.ToString())
.BindTo(new SelectList(Model.UserIds, "Id", "Name"))
.Placeholder("Select UserId...")
.AutoFill(true)
.CascadeTo("Product_" + i.ToString())
.SelectedIndex(0))
</td>
<td>
#(Html.Telerik().ComboBox()
.Name("Product_" + i.ToString())
.AutoFill(true)
.DataBinding(binding => binding.Ajax().Select("GetProducts", "Order"))
.Placeholder("Select Product...")
.SelectedIndex(0))
</td>
And my Controller method looks like this. It's hacky as hell, but how do I access the value otherwise?
public JsonResult GetProducts(Guid? UserId)
{
// Hack!
ValueProviderResult userResult = ValueProvider.GetValue("UserId");
for (int i=0; i < 10; i++)
{
userResult = ValueProvider.GetValue("UserId_" + i);
if (userResult != null)
{
break;
}
}
if (userResult != null)
{
// Get list of products based on value
return Json(new SelectList(productList, "Id", "Name"));
}
else
{
return Json(null);
}
}
Do not waste your time to achieve this with the some widget - better check how to send collection of items to the server and implement your own form with checkboxes or so.
If you want to go with some of the widgets - you can try the Grid in a way similar to this demo.
How can I check the checkboxes using an id or XPath expression? Is there a method similar to select by visibletext for a dropdown?
Going through the examples given for all other related questions, I could not find a proper solution that works in a concise way that by few line or method I can check a chekbox or radio button.
A sample HTML section is below:
<tbody>
<tr>
<td>
<span class="120927">
<input id="ctl00_CM_ctl01_chkOptions_0" type="checkbox" name="ctl00$CM$ctl01$chkOptions$0"/>
<label for="ctl00_CM_ctl01_chkOptions_0">housingmoves</label>
</span>
</td>
</tr>
<tr>
<td>
<span class="120928">
<input id="ctl00_CM_ctl01_chkOptions_1" type="checkbox" name="ctl00$CM$ctl01$chkOptions$1"/>
<label for="ctl00_CM_ctl01_chkOptions_1">Seaside & Country Homes</label>
</span>
</td>
</tr>
</tbody>
Selecting a checkbox is similar to clicking a button.
driver.findElement(By.id("idOfTheElement")).click();
will do.
However, you can also see whether the checkbox is already checked. The following snippet checks whether the checkbox is selected or not. If it is not selected, then it selects.
if ( !driver.findElement(By.id("idOfTheElement")).isSelected() )
{
driver.findElement(By.id("idOfTheElement")).click();
}
It appears that the Internet Explorer driver does not interact with everything in the same way the other drivers do and checkboxes is one of those cases.
The trick with checkboxes is to send the Space key instead of using a click (only needed on Internet Explorer), like so in C#:
if (driver.Capabilities.BrowserName.Equals(“internet explorer"))
driver.findElement(By.id("idOfTheElement").SendKeys(Keys.Space);
else
driver.findElement(By.id("idOfTheElement").Click();
If you want to click on all checkboxes at once, a method like this will do:
private void ClickAllCheckboxes()
{
foreach (IWebElement e in driver.FindElements(By.xpath("//input[#type='checkbox']")))
{
if(!e.Selected)
e.Click();
}
}
Solution for C#
try
{
IWebElement TargetElement = driver.FindElement(By.XPath(xPathVal));
if (!TargetElement.Selected)
{
TargetElement.SendKeys(Keys.Space);
}
}
catch (Exception e)
{
}
You can use the following code:
List<WebElement> checkbox = driver.findElements(By.name("vehicle"));
((WebElement) checkbox.get(0)).click();
My HTML code was as follows:
<.input type="checkbox" name="vehicle" value="Bike">I have a bike<br/>
<.input type="checkbox" name="vehicle" value="Car">I have a car<br/>
To get the checkbox for 'Seaside & Country Homes', use this XPath:
//label[text()='Seaside & Country Homes']/preceding-sibling::input[#type='checkbox']
To get the checkbox for 'housingmoves', use this XPath:
//label[text()='housingmoves']/preceding-sibling::input[#type='checkbox']
The principle here is to get the label with the text you want, then get the checkbox that is before the label, since that seems to be how your HTML is laid out.
To get all checkboxes, you would start a little higher up and then work down, so that is to say get the table, and then get any checkbox within a span:
//table/descendant::span/input[#type='checkbox']
I found that sometimes JavaScript doesn't allow me to click the checkbox because was working with the element by onchange event.
And that sentence helps me to allow the problem:
driver.findElement(By.xpath(".//*[#id='theID']")).sendKeys(Keys.SPACE);
This should help -
IWebElement elementToClick = driver.findElement(By.xpath(""//input[contains(#id, 'lstCategory_0')]"));
elementToClick.Click();
You can also pass an id.
If you want something like visible text you can "find element" by name if they have names.
The below code will first get all the checkboxes present on the page, and then deselect all the checked boxes.
List<WebElement> allCheckbox = driver.findElements(By
.xpath("//input[#type='checkbox']"));
for (WebElement ele : allCheckbox) {
if (ele.isSelected()) {
ele.click();
}
}
A solution using WebDriver and C# is below. The key idea is to get the ID of the checkbox from the labels' 'for' attribute, and use that to identify the checkbox.
The code will also set the checkbox state only if it needs to be changed.
public void SetCheckboxStatus(string value, bool toCheck)
{
// Get the label containing the checkbox state
IWebElement labelElement = this.Driver.FindElement(By.XPath(string.Format("//label[.='{0}']",value)));
string checkboxId = labelElement.GetAttribute("for");
IWebElement checkbox = this.Driver.FindElement(By.Id(checkboxId));
if (toCheck != checkbox.Selected)
{
checkbox.Click();
}
}
Maybe a good starting point:
isChecked = driver.findElement((By.id("idOftheElement"))).getAttribute("name");
if(!isChecked.contains("chkOptions$1"))
{
driver.FindElement(By.Id("idOfTheElement")).Click();
}
Running this approach will in fact toggle the checkbox; .isSelected() in Java/Selenium 2 apparently always returns false (at least with the Java, Selenium, and Firefox versions I tested it with).
The selection of the proper checkbox isn't where the problem lies -- rather, it is in distinguishing correctly the initial state to needlessly avoid reclicking an already-checked box.
To select a checkbox, use the "WebElement" class.
To operate on a drop-down list, use the "Select" class.
Step 1:
The object locator supposed to be used here is XPath. So derive the XPath for those two checkboxes.
String housingmoves="//label[contains(text(),'housingmoves')]/preceding-sibling::input";
String season_country_homes="//label[contains(text(),'Seaside & Country Homes')]/preceding-sibling::input";
Step 2:
Perform a click on the checkboxes
driver.findElement(By.xpath(housingmoves)).click();
driver.findElement(By.xpath(season_country_homes)).click();
For a partial match, do the following:
getDriver().findElement(By.cssSelector("<tag name>[id*='id pattern to look for']")).click();
Here is the C# version of Scott Crowe's answer. I found that both IEDriver and ChromeDriver responded to sending a Key.Space instead of clicking on the checkbox.
if (((RemoteWebDriver)driver).Capabilities.BrowserName == "firefox")
{
// Firefox
driver.FindElement(By.Id("idOfTheElement")).Click();
}
else
{
// Chrome and Internet Explorer
driver.FindElement(By.Id("idOfTheElement")).SendKeys(Keys.Space);
}
I tried with various approaches, but nothing worked. I kept getting "Cannot click element" or ElementNotVisibleException.
I was able to find the input, but I couldn't check it. Now, I'm clicking on the div that contains the checkbox and it works with following HTML (CSS based on Bootstrap).
#foreach (var item in Model)
{
<tr>
<td>
<div id="#item.Id" class="checkbox">
<label><input type="checkbox" class="selectone" value="#item.Id"></label>
</div>
</td>
<td val="#item.Id">
#item.Detail
</td>
<td>
<div>#item.Desc
</div>
</td>
<td>
#Html.ActionLink("Edit", "Create", new { EditId = item.Id })
</td>
</tr>
}
This is the code for WebDriver:
var table = driver.FindElement(By.TagName("table"));
var tds = table.FindElements(By.TagName("td"));
var itemTds = tds.Where(t => t.Text == itemtocheck);
foreach (var td in itemTds)
{
var CheckBoxTd = tds[tds.IndexOf(td) - 1];
var val = td.GetAttribute("val");
CheckBoxTd.FindElement(By.Id(val)).Click();
}
In this approach, I give the item id as id for the div and also add an attribute for td with that id. Once I find the td of the item that needs to be checked, I can find the div before that td and click it. We can also use the XPath query that supports before (here is the example http://learn-automation.com/how-to-write-dynamic-xpath-in-selenium/).