Unable to check checkbox in table cell - ruby

I have this table:
<iframe title="ManageLegs">
<table title="Leg Details">
<tr>
<th class="headerRow">
<div>PAX</div>
</th>
<th class="headerRow">
<div>Leg</div>
</th>
</tr>
<tr>
<td>
<input type="text"></input>
</td>
<td>
<input type="checkbox"></input>
</td>
</tr>
</table>
</iframe>
Accessing the textbox is working fine, but I canĀ“t figure out how to check the checkbox.
I use the following code in my PageObject class:
in_iframe(:title => 'ManageLegs') do |frame|
table(:leg_details, title: 'Leg Details', :frame => frame)
text_field(:pax) { leg_details_element['1']['PAX'].text_field_element }
text_field(:aircraft) { leg_details_element['1']['Aircraft'].text_field_element }
text_field(:show_leg_on_quote_pdf) { leg_details_element['1']['Leg'].checkbox_element }
end
Which I am calling like this:
on(CharterInquirySavedPage).pax = "2"
on(CharterInquirySavedPage).check_show_leg_on_quote_pdf
It is working fine for setting the pax-textbox, but fails when trying to check the checkbox:
NoMethodError: undefined method `check_show_leg_on_quote_pdf' for #<CharterInquirySavedPage:0x00000004cfd420>

The text_field accessor is for text fields, which are input elements with type "text" and other text-like input fields such as "email".
Inputs of type "checkbox" are considered checkboxes. It is the checkbox accessor that creates the check_ method. In other words, you want the following definition for the checkbox:
checkbox(:show_leg_on_quote_pdf) { leg_details_element['1']['Leg'].checkbox_element }

Related

: EL1008E: Property or field 'LEVEL' cannot be found on object of type 'java.util.ArrayList' - maybe not public or not valid?

please assist with the below. I am trying to display an arraylist returned from the controller and display it to an Html table but I get the above error.
here is my controller code:
#GetMapping(value="/chart" )
public List<List<CanvasjsChartData.DataPointModel>> chart(Model modelMap) {
List<List<CanvasjsChartData.DataPointModel>> dataPointsList = canvasjsChartService.getCanvasjsChartData();
modelMap.addAttribute("dataPointsList", dataPointsList);
System.out.println("dataPointsList");
return dataPointsList;
}
and this is the table I want to display my list in
<table class="table" id="dataTable" style="width:100%">
<thead>
<th>Level</th>
<th>Occurences</th>
</thead>
<tbody>
<tr th:each="item :${dataPointsList}">
<td th:text="${item.LEVEL}"> </td>
<td th:text="${item.OCCURENCES}"> </td>
</tr>
</tr>
</tbody>
I know for sure the ArrayList has the data I require as shown below I dont know why its giving me the error
Your debug shows you have an List<List<CanvasjsChartData.DataPointModel>> (two Lists inside of each other) -- when your HTML is expecting List<CanvasjsChartData.DataPointModel>. You should fix that in your controller/model by only returning a single list.
You could also display your HTML like this (where you loop over the 0th element of the outer array):
<tr th:each="item :${dataPointsList[0]}">
<td th:text="${item.LEVEL}" />
<td th:text="${item.OCCURENCES}" />
</tr>

When using AjaxHelper to retrieve a partial view, the embedded data is always the same

We use ASP.NET MVC 5's AjaxHelper and Ajax.BeginForm to request a partial view. That request also needs some JSON data in order to update a map control.
The view rendering part of the process works great (a table body is replaced with the strongly-typed partial view), but the JSON data (embedded into the data-json attribute of the div element as described in this answer and retrieved in my OnSuccess function) always has the same value.
To eliminate the controller code or ViewBag as culprit, I replaced the JSON data (originally retrieved from the ViewBag) with a direct call to DateTime.Now. Sure enough, the same DateTime is printed each time in updateMap() (e.g., 2/11/2016+5:24:42+PM)
I've tried disabling caching, and changing the HTML method to Post, in my AjaxOptions.
In the Parent View (changing the ListBox selection submits the form):
#model string
#{
ViewBag.Title = "Project List";
AjaxOptions ajaxOpts = new AjaxOptions
{
UpdateTargetId = "tableBody",
OnSuccess = "updateMap",
HttpMethod = "Post",
AllowCache = false
};
}
#using (Ajax.BeginForm("GetProjectsData", ajaxOpts))
{
<fieldset>
<legend>Project State</legend>
<div class="editor-field">
#Html.ListBox("selectedStates", ViewBag.StatesList as MultiSelectList,
new { #class = "chzn-select", data_placeholder = "Choose States...", style = "width:350px;", onchange = "$(this.form).submit();" })
</div>
</fieldset>
}
<table class="table">
<thead>
<tr>
<th>
Project Name
</th>
<th>
Project Firm
</th>
<th>
Project Location
</th>
<th>
Building Type
</th>
<th>
Project Budget
</th>
<th></th>
</tr>
</thead>
<tbody id="tableBody">
#Html.Action("GetProjectsData", new { selectedStates = Model })
</tbody>
</table>
<script>
function updateMap() {
var jsonData = $("#geoJsonData").attr("data-json");
var decoded = decodeURIComponent(jsonData);
console.log(decoded); // always prints same value
}
</script>
The partial view:
#model IEnumerable<OurModel>
<div id="geoJsonData" data-json="#Url.Encode(DateTime.Now.ToString())"></div>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.COMPANY_NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.STATE)
</td>
<td>
#Html.DisplayFor(modelItem => item.BUILDING_TYPE)
</td>
<td>
#Html.DisplayFor(modelItem => item.BUDGET_AMT)
</td>
</tr>
}
I'm hesitant to jettison the MVC helper classes' pattern of returning a partial view and instead manually render a view into a JSON object. Why is the updated tablebody visible on screen, but when jQuery requests the div element it always has the same data?
Interesting...replacing the div with a good old hidden input element worked. Now fresh data is retrieved each time.
This
<div id="geoJsonData" data-json="#Url.Encode(DateTime.Now.ToString())"></div>
Became this
<input id="geoJsonData" type="hidden" value="#Url.Encode(DateTime.Now.ToString())" />
I wonder why the data-json in the div remained "stale" while the value of the input field did the trick?

Not able to apply slice to viewmodel knockout

I am unable to apply slice or substr to GId due to the following error message:
Uncaught TypeError: Unable to process binding "foreach: function (){return waititem }"
Message: Unable to process binding "style: function (){return { color:GId.slice(0,1) =='TR'?'black':'red'} }"
Message: undefined is not a function
Html
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: waititem">
<tr data-bind="style: { color: GId.slice(0,1) == 'TR'? 'black' : 'red' }">
<td data-bind="text: PId"></td>
<td data-bind="text: PName"></td>
</tr>
</tbody>
</table>
How can I apply slice to check for the presence of a particular substring and style the row respectively?
You are using the slice method in your style binding wrongly. You need to use the syntax of slice as
slice(start, end)
where start has default of 0 for initial position and end will be the end character. In your scenario the slice will return a string of length 1 as you have used slice(0,1) but you are comparing with 'TR' which is of length 2. Instead of that you need to use slice(0, 2) === 'TR'.
<tr data-bind="style: { color: GId.slice(0,2) == 'TR'? 'black' : 'red' }">
<td data-bind="text: PId"></td>
<td data-bind="text: PName"></td>
</tr>
DEMO

Watir Display Content from a table in a text file

I am using watir-webdriver, I am trying to write the content displayed in a table below (RATE CODE SELECTED NOT AVAILABLE THIS LOCATION OR CAR 138DE) into a text file but I can't get it to display the content. Any idea what i doing wrong ? Thanks in advance for your help.
errorMes = browser.select_list(:name => 'seamlessMessages').value
f3=File.open( 'Error Log - Conf Res.txt', 'a')
f3.puts "Cancel Reservation - FAILED - Res ID: " +tasid+" - " + CSAsite + " - Message: " +errorMes
f3.puts "\n"
f3.close
code
<TD><B>Error/Informational Messages</B></TD>
<TD><B>Number of Messages</B></TD>
<TD class="tableData"><span name="nbrOfMessages"/>1</span></TD>
<TD> </TD>
</TR>
<TR>
<TD height="1"></TD>
</TR>
</TABLE>
<TABLE width="100%" class="displaySubsection" cellpadding="0" cellspacing="0">
<TR>
<TD width="5" rowspan="3"></TD>
<TD width="800"></TD>
<TD width="5" rowspan="3"></TD>
</TR>
<TR>
<TD>
<select name="seamlessMessages" size="2" readonly tabIndex="-1" class="readonly wide"><option value="0" selected>RATE CODE SELECTED NOT AVAILABLE THIS LOCATION OR CAR 138DE </option></select>
</TD>
I assume your problem is that you are getting "0" instead of "RATE CODE SELECTED NOT AVAILABLE THIS LOCATION OR CAR 138DE".
When you do errorMes = browser.select_list(:name => 'seamlessMessages').value, it is returning the 'value' attribute of the selected option.
If you want the text, you need to do:
errorMes = browser.select_list(:name => 'seamlessMessages').selected_options.first.text
Yes you're right I was getting "0"
Just to let you know that when i tried
errorMes = browser.select_list(:name => 'seamlessMessages').selected_options.first.text
I got an error message in <main>': undefined methodtext' for "RATE CODE SELECTED
NOT AVAILABLE THIS LOCATION OR CAR 138DE":String (NoMethodError)
By removing .text it did work. Thanks a lot for your help on this.
errorMes = browser.select_list(:name => 'seamlessMessages').selected_options.first

Use Html.RadioButtonFor and Html.LabelFor for the same Model but different values

I have this Razor Template
<table>
<tr>
<td>#Html.RadioButtonFor(i => i.Value, "1")</td>
<td>#Html.LabelFor(i => i.Value, "true")</td>
</tr>
<tr>
<td>#Html.RadioButtonFor(i => i.Value, "0")</td>
<td>#Html.LabelFor(i => i.Value, "false")</td>
</tr>
</table>
That gives me this HTML
<table>
<tr>
<td><input id="Items_1__Value" name="Items[1].Value" type="radio" value="1" /></td>
<td><label for="Items_1__Value">true</label></td>
</tr>
<tr>
<td><input checked="checked" id="Items_1__Value" name="Items[1].Value" type="radio" value="0" /></td>
<td><label for="Items_1__Value">false</label></td>
</tr>
</table>
So I have the ID Items_1__Value twice which is - of course - not good and does not work in a browser when I click on the second label "false" the first radio will be activated.
I know I could add an own Id at RadioButtonFor and refer to that with my label, but that's not pretty good, is it? Especially because I'm in a loop and cannot just use the name "value" with an added number, that would be end up in multiple Dom Ids in my final HTML markup as well.
Shouldn't be a good solution for this?
Don't over-engineer a solution for this. All you are trying to accomplish is to have the radio buttons respond to clicks on the text. Keep it simple and just wrap your radio buttons in label tags:
<table>
<tr>
<td><label>#Html.RadioButtonFor(i => i.Value, "1")True</label></td>
</tr>
<tr>
<td><label>#Html.RadioButtonFor(i => i.Value, "0")False</label></td>
</tr>
</table>
The LabelFor html helper is usually used to bring in the Name from the Display attribute on your View Model (e.g. "[Display(Name = "Enter your Name")]).
With radio buttons, the name isn't particularly useful, because you have a different line of text for each radio button, meaning you are stuck hard coding the text into your view anyway.
I've been wondering how MVC determines "nested" field names and IDs. It took a bit of research into the MVC source code to figure out, but I think I have a good solution for you.
How EditorTemplates and DisplayTemplates determine field names and IDs
With the introduction of EditorTemplates and DisplayTemplates, the MVC framework added ViewData.TemplateInfo that contains, among other things, the current "field prefix", such as "Items[1].". Nested templates use this to create unique names and IDs.
Create our own unique IDs:
The TemplateInfo class contains an interesting method, GetFullHtmlFieldId. We can use this to create our own unique IDs like so:
#{string id = ViewData.TemplateInfo.GetFullHtmlFieldId("fieldName");}
#* This will result in something like "Items_1__fieldName" *#
For The Win
Here's how to achieve the correct behavior for your example:
<table>
<tr>
#{string id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioTrue");}
<td>#Html.RadioButtonFor(i => i.Value, "1", new{id})</td>
<td>#Html.LabelFor(i => i.Value, "true", new{#for=id})</td>
</tr>
<tr>
#{id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioFalse");}
<td>#Html.RadioButtonFor(i => i.Value, "0", new{id})</td>
<td>#Html.LabelFor(i => i.Value, "false", new{#for=id})</td>
</tr>
</table>
Which will give you the following HTML:
<table>
<tr>
<td><input id="Items_1__radioTrue" name="Items[1].Value" type="radio" value="1" /></td>
<td><label for="Items_1__radioTrue">true</label></td>
</tr>
<tr>
<td><input checked="checked" id="Items_1__radioFalse" name="Items[1].Value" type="radio" value="0" /></td>
<td><label for="Items_1__radioFalse">false</label></td>
</tr>
</table>
Disclaimer
My Razor syntax is underdeveloped, so please let me know if this code has syntax errors.
For what its worth
It's pretty unfortunate that this functionality isn't built-in to RadioButtonFor. It seems logical that all rendered Radio Buttons should have an ID that is a combination of its name AND value, but that's not the case -- maybe because that would be different from all other Html helpers.
Creating your own extension methods for this functionality seems like a logical choice, too. However, it might get tricky using the "expression syntax" ... so I'd recommend overloading .RadioButton(name, value, ...) instead of RadioButtonFor(expression, ...). And you might want an overload for .Label(name, value) too.
I hope that all made sense, because there's a lot of "fill in the blanks" in that paragraph.
#Scott Rippey nearly has it, but i guess he must be using a different version of MVC3 to me because for me #Html.LabelFor has no overloads that will take 3 arguments. I found that using the normal #Html.Label works just fine:
#{string id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioButton_True");}
#Html.Label(id, "True:")
#Html.RadioButtonFor(m => m.radioButton, true, new { id })
#{id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioButton_False");}
#Html.Label(id, "False:")
#Html.RadioButtonFor(m => m.radioButton, false, new { id })
this allows you to click on the label and select the associated radiobutton as you'd expect.
Here's an HtmlHelper you can use, though you may with to customize it. Only barely tested, so YMMV.
public static MvcHtmlString RadioButtonWithLabelFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, object value, object htmlAttributes = null)
{
var name = ExpressionHelper.GetExpressionText(expression);
var id = helper.ViewData.TemplateInfo.GetFullHtmlFieldId(name + "_" + value);
var viewData = new ViewDataDictionary(helper.ViewData) {{"id", id}};
if (htmlAttributes != null)
{
var viewDataDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
foreach (var keyValuePair in viewDataDictionary)
{
viewData[keyValuePair.Key] = keyValuePair.Value;
}
}
var radioButton = helper.RadioButtonFor(expression, value, viewData);
var tagBuilder = new TagBuilder("label");
tagBuilder.MergeAttribute("for", id);
tagBuilder.InnerHtml = value.ToString();
return new MvcHtmlString(radioButton.ToHtmlString() + tagBuilder.ToString());
}
Not Perfect but work though,
<table>
<tr>
<td>#ReplaceName(Html.RadioButtonFor(i => i.Value, "1"))</td>
<td>#Html.LabelFor(i => i.Value[0], "true")</td>
</tr>
<tr>
<td>#ReplaceName(Html.RadioButtonFor(i => i.Value, "0"))</td>
<td>#Html.LabelFor(i => i.Value[1], "false")</td>
</tr>
</table>
#functions {
int counter = 0;
MvcHtmlString ReplaceName(MvcHtmlString html){
return MvcHtmlString.Create(html.ToString().Replace("__Value", "__Value_" + counter++ +"_"));
}
}
You can add text with tags
<td>#Html.RadioButtonFor(i => i.Value, true) <text>True</text></td>
<td>#Html.RadioButtonFor(i => i.Value, false) <text>False</text></td>
Apparently there is a good solution
<td>#Html.RadioButtonFor(i => i.Value, true)</td>
<td>#Html.RadioButtonFor(i => i.Value, false)</td>

Resources