Is it possible to iterate through a list of objects and do dynamic tests for each input? - tdd

I am currently learning cypress.io, and I have 7 checkboxes representing each day of the week Sun-Sat.
{days.map((day, idx) => (
<input
onChange={(e) => {
const { checked, value } = e.target;
setDays(
days => days.map(data => {
if (data.id === day.id) {
return {
...data,
id: value,
select: !data.select,
};
}
return data;
})
);
setDayId(prev => {
return checked
? [...prev, value] // add if checked
: prev.filter(val => val !== value) // remove if not checked
});
console.log("CHECKING CHECKED VALUE", e.target.checked);
// console.log("WHAT IS THE SET VALUE", values)
}}
key={idx}
name={day?.name}
type="checkbox"
value={day?.id}
checked={day.select}
id="habit-frequency"
/>
))}
And I am trying to avoid doing this 7 times, because I am sure that there is a much better way to do it
cy.get("#habit-frequency")
.should("have.attr", "name", "Sun")
.should("have.attr", "value", "1");
I though about doing this:
const DAYS = [
{ id: 1, name: "Sun", select: false },
{ id: 2, name: "Mon", select: false },
{ id: 3, name: "Tue", select: false },
{ id: 4, name: "Wed", select: false },
{ id: 5, name: "Thu", select: false },
{ id: 6, name: "Fri", select: false },
{ id: 7, name: "Sat", select: false },
];
DAYS.map(day => (
it(`Should have a checkbox for ${day.name}`, () => {
cy.get("#habit-frequency")
.should("have.attr", "name", day.name)
.should("have.attr", "value", day.id)
})
))
But it isn't really working. Any advise? Here is the full test I have written so far in case it helps
describe("Create Habit", () => {
beforeEach(() => {
cy.visit("/");
});
it("Should have a 'Habit' button which can be clicked to display a modal", () => {
cy.get("#modal-btn").should("contain", "Habit").click();
cy.get(".modal-title").should("contain", "Add Habit");
});
it("Should have a 'Add Habit' title, 2 inputs, one for name and one for description, a habit type option, a weekly frequency and an option to choose colors", () => {
cy.get("#modal-btn").click();
cy.get(".modal-title").should("contain", "Add Habit");
cy.get("#habit-name")
.should("have.attr", "placeholder", "Habit name");
cy.get("#habit-description")
.should("have.attr", "placeholder", "Habit description");
cy.get("#habit-todo")
.should("have.attr", "name", "To-Do")
.should("have.attr", "value", "1");
cy.get("#habit-nottodo")
.should("have.attr", "name", "Not-To-Do")
.should("have.attr", "value", "2");
DAYS.map(day => (
it(`Should have a checkbox for ${day.name}`, () => {
cy.get("#habit-frequency")
.should("have.attr", "name", day.name)
.should("have.attr", "value", day.id)
})
))
cy.get("#habit-frequency")
.should("have.attr", "name", "Sun")
.should("have.attr", "value", "1");
});
});

The problem you are having is because you are nesting it calls, Never nest them.
just use your code as is without the internal it call
it(`Should have a checkbox for ${day.name}`, () => { /// this should be removed
..
}/// this should be removed

Related

Insert a predefined text for Trumbowyg via dropdown button

I have created a custom dropdown for trumbowyg following this guide, but am stuck on how to really insert a text when a dropdown button is clicked.
$('.editor').trumbowyg({
btnsDef: {
tagSelect: {
fn: () => {
// how to insert test to cursor's position?
},
text: 'Name Tag',
hasIcon: false
},
detailsType: {
dropdown: [
'tagSelect',
],
title: 'Client Tag',
hasIcon: false
}
},
btns: [
['detailsType']
]
})
I did this by using the plugin "mention".
Using that plugin it's as simple as this:
$('#editorid').trumbowyg({
plugins: {
mention: {
source: [
{ mergetag: '[RECIPIENT_NAME]', name: 'Full name of the recipient' },
{ mergetag: '[RECIPIENT_NAME_FIRST]', name: 'First name of the recipient' },
{ mergetag: '[SENDER_NAME]', name: 'Name of sender' },
{ mergetag: '[SENDER_MAIL]', name: 'Sender email' },
{ mergetag: '[SIGNATURE]', name: 'Senders mailsignature' }
],
formatDropdownItem: function (item) {
return item.name + ' ' + item.mergetag;
},
formatResult: function (item) {
return item.mergetag;
}
}
}
});
More info here: https://alex-d.github.io/Trumbowyg/demos/plugins/mention.html

Kendo UI Grid incell edit with client template - Razor view

i am using kendo grid Q2 2014 and i want to use client template in cell edit mode. But it not work as i want . I need to click into that cell in order to get into edit mode.
Here is my grid .
#(Html.Kendo().Grid<AdminProject.Common.ViewModels.ProjectActivityViewModel>()
.Name("gridName")
.Columns(columns =>
{
columns.Bound(d => d.ResourceName);
columns.Bound(d => d.TotalHours).Title("Total Hours").Width(150).ClientFooterTemplate("Sum: #=sum#");
columns.Bound(d => d.TotalCost).Title("Total Cost").Format("{0:c0}").Width(150).ClientFooterTemplate("Sum: #= kendo.toString(sum, 'c0')#");
columns.Bound(d => d.Hours)
.ClientTemplate(Html.Kendo().TextBox().Name("NewHours").ToClientTemplate().ToHtmlString());
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.ToolBar(toolbar =>
{
toolbar.Save(); // The "save" command saves the changed data items
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5)
)
.Sortable()
.Events(e => e.Edit("onEdit"))
.AutoBind(true)
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(10)
.Aggregates(aggregates =>
{
aggregates.Add(p => p.TotalHours).Sum();
aggregates.Add(p => p.TotalCost).Sum();
})
.Events(events => { events.Error("error_handler").Sync("sync_handler"); })
.ServerOperation(true)
.Model(model =>
{
model.Id(product => product.ResourceId); // Specify the property which is the unique identifier of the model
model.Field(product => product.TotalHours).Editable(false);
model.Field(product => product.TotalCost).Editable(false);
model.Field(product => product.ResourceName).Editable(false);
})
.Read(read => read.Action(AdminProject.Common.Constants.ActionNames.GetDetail, AdminProject.Common.Constants.ControllerNames.Project).Data("additionalData"))
.Update(update => update.Action(AdminProject.Common.Constants.ActionNames.UpdateActivity, AdminProject.Common.Constants.ControllerNames.Project).Data("additionalData2"))
.Sort(sort => sort.Add(s => s.ResourceId).Ascending())
))
Sorry , i can not post the photo so i uploaded it into another host .
Before enter link description here
After enter link description here
have look on this http://jsfiddle.net/khNsE/70/ example.
This is kendo ui script you can use this instead of mvc wrapper.
var _roleDataSource = new kendo.data.DataSource({
data: [
{ id: 1, title: "Software Engineer" },
{ id: 2, title: "Quality Assurance Engineer" },
{ id: 3, title: "Team Lead" }
]
});
var _peopleDataSource = new kendo.data.DataSource({
data: [
{ id: 1, name: "John", roleId: 1, roleTitle: "Software Engineer" },
{ id: 2, name: "Dave", roleId: 2, roleTitle: "Quality Assurance Engineer" },
{ id: 3, name: "Aaron", roleId: 3, roleTitle: "Team Lead" }
]
});
var _grid = $("#grid").kendoGrid({
dataSource: _peopleDataSource,
columns: [
{
field: "name",
title: "Name"
},{
field: "roleTitle",
title: "Role",
editor: function(container, options) {
$("<input data-bind='value:roleTitle' />")
// .attr("id", "ddl_roleTitle")
.appendTo(container)
.kendoDropDownList({
dataSource: _roleDataSource,
dataTextField: "title",
dataValueField: "title",
template: "<span data-id='${data.id}'>${data.title}</span>",
select: function(e) {
var id = e.item.find("span").attr("data-id");
var person =_grid.dataItem($(e.sender.element).closest("tr"));
person.roleId = id;
setTimeout(function() {
$("#log")
.prepend($("<div/>")
.text(
JSON.stringify(_grid.dataSource.data().toJSON())
).append("<br/><br/>")
);
});
}
});
}
}
],
editable: true
}).data("kendoGrid");
Hope this helps
Regards
vinit
You may force the last Cell into edit mode through
var grid = $('#gridName').data('kendoGrid');
grid.editCell(grid.tbody.find('tr:eq(0) td:last'));
please refer to this fiddle: http://jsfiddle.net/houssamk/7z0ubup7/1/
NOTE:
Please do not put this call inside the "edit" event handler because it will fire the edit event again. please see http://docs.telerik.com/kendo-ui/api/web/grid#methods-editCell

How can I restrict a number input between 1 to 12 in Kendo Grid Inline Editing

I have a kendo grid and one column should expect a number between 0 to 12. Everything else are working fine except HourTimeHours. I can't put min value smaller than 0 but i can put more than 12 for that. please help.
schema: {
model: {
id: "ID",
fields: {
ID: { editable: false },
TName: { editable: false },
HourTimeHours: { editable: true, type: "number", validation: { required: true, min: 0, max: 12 } },
Comment: { editable: true, nullable: true },
Reason: { editable: false, nullable: true },
ChargeRateText: { defaultValue: { CategoryID: "No Charge", CategoryName: "No Charge" } },
}
},
You will have to specify an editor for that field when creating your grid.
$("#grid").kendoGrid({
dataSource: dataSource,
columns: [
{ field: "HourTimeHours", title: "Hours", editor: hoursDropDownEditor }],
editable: true
});
And then if you want something like a kendo numeric text box, your function will look something like this:
function hoursDropDownEditor(container, options) {
$('<input/>')
.appendTo(container)
.kendoNumericTextBox({
min: 1,
max: 12,
step: 1
});
}
Update: You could also use a template, which makes it clear to the user that the field is editable.
http://jsfiddle.net/amomsen/vcpWD/1/
For Kendo UI MVC you can restrict length of Kendo Grid Inline Editing
$("body").delegate("#percentage", "keyup", function () {
$("#percentage").attr('maxlength', '5');
});
Where #percentage is id of cell to Edit
columns.Bound(p => p.percentage);
All grid:
#(Html.Kendo().Grid<Internal.Models.ExchangeRateData>()
.Name("ExchangeGrid")
.Columns(columns =>
{
columns.Bound(p => p.targetCurrency);
columns.Bound(p => p.percentage);
columns.Command(commands => { commands.Edit(); });
})
.Editable(edit =>
{
edit.Mode(GridEditMode.InLine);
})
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(item => item.targetCurrency);
})
.Events(events =>
{
events.Sync("onSync");
})
.Read(read => read.Action("ExchangeRate_Read", "ExchangeRatesFortius").Data("ReadRequestData"))
.Update(c => c.Action("Currencies_Update", "ExchangeRatesFortius"))
)
)
For kendo mvc, i was able to limit with a template as such:
columns.Bound(m => m.Inches)
.ClientTemplate("<input type=\"number\" value=#= Inches # min=\"0\" max=\"11\" step=\"1\" ></input>")
.Width(60);

Why does the KendoUI Grid not rollback a delete when the options.error function is called?

I have put a fiddle here that demonstrates the issue.
http://jsfiddle.net/codeowl/fmzay/1/
Just delete a record, and it should rollback the delete as I am calling options.error from inside the destroy function.
Why is it that the grid doesn't roll back?
Regards,
Scott
Markup:
<div id="KendoGrid"></div>
JS:
var _data = [
{ Users_ID: 1, Users_FullName: 'Bob Smith', Users_Role: 'Administrator' },
{ Users_ID: 2, Users_FullName: 'Barry Baker', Users_Role: 'Viewer' },
{ Users_ID: 3, Users_FullName: 'Bill Cow', Users_Role: 'Editor' },
{ Users_ID: 4, Users_FullName: 'Boris Brick', Users_Role: 'Administrator' }
],
_dataSource = new kendo.data.DataSource({
data: _data,
destroy: function (options) {
options.error(new Error('Error Deleting User'));
}
});
$('#KendoGrid').kendoGrid({
dataSource: _dataSource,
columns: [
{ field: "Users_FullName", title: "Full Name" },
{ field: "Users_Role", title: "Role", width: "130px" },
{ command: ["edit", "destroy"], title: " ", width: "180px" }
],
toolbar: ['create'],
editable: 'popup'
});
Signaling the error is not enough. Lets say that having an error on removing a record is not enough since KendoUI doesn't know if the record has actually been removed in the server and the reply is the one producing the error. So KendoUI approach is a conservative approach: You have to decide what to do and explicitly say it:
So what you should do is add an error hander function that invokes a cancelChanges in the grid.
The code would be:
_dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
options.success(_data);
console.log('Read Event Has Been Raised');
},
destroy: function (options) {
options.error(new Error('Error Deleting User'));
console.log('Destroy Event Has Been Raised');
}
},
schema: {
model: {
id: "Users_ID",
fields: {
Users_ID: { editable: false, nullable: true },
Users_FullName: { type: "string", validation: { required: true } },
Users_Role: { type: "string", validation: { required: true } }
}
}
},
error: function(a) {
$('#KendoGrid').data("kendoGrid").cancelChanges();
}
});
And the updated JSFiddle in here: http://jsfiddle.net/OnaBai/fmzay/3
The ASP.NET-MVC equivalent solution to the OnaBai answer would be:
<script type="text/javascript">
function cancelChanges(e) {
e.sender.cancelChanges();
}
</script>
#Html.Kendo().Grid<MyClass>()
.DataSource(dataSource =>
dataSource
.Ajax()
.Read(read => read.Action("Read", "MyController"))
.Destroy(destroy => destroy.Action("Destroy", "MyController"))
.Events(evt => evt.Error("cancelChanges"))
)
[...]
Please be aware that the cancelChanges event will be called upon an error on every CRUD request.

KendoGrid doesn't work in kendoTabStrip

I'm using kendoTabStrip as is shown on KendoUI Page. In my case in each div I have rendered partial view. In a few of my partial views I have additionaly kendoGrid.
Problem
When I reload page in any tab and go to tab which contain kendoGrid then it do not work correctly. For example: I'm on tab#0 and go for tab#3 which contain kendoGrid with pagination, then pagination is not display. But when I reload it then pagination works fine.
What can I do to my Grids works inside TabStrip?
Any help would be appreciated.
UPDATE
My implementation of tabstrip
$("#tabStrip").kendoTabStrip({
animation: { open: { effects: false} },
select: function (e) {
document.location.hash = 'tab-' + $(e.item).index();
}
});
var tabStrip = $('#tabStrip').data('kendoTabStrip');
var tabId = 0;
var scheduledId = 0;
if (document.location.hash.match(/tab-/) == 'tab-') {
tabId = document.location.hash.substr(5);
}
if (document.location.hash.match(/scheduled-/) == 'scheduled-') {
tabId = 1;
scheduledId = document.location.hash.substr(11);
editSchedule('/admin/Course/Scheduled/' + scheduledId + '/Edit/' );
}
tabStrip.select(tabStrip.tabGroup.children('li').eq(tabId));
So I need it to make some rewrites from controller.
To fix this problem we must change :
$("#tabStrip").kendoTabStrip({
animation: { open: { effects: false} },
select: function (e) {
document.location.hash = 'tab-' + $(e.item).index();
}
});
for:
$("#tabStrip").kendoTabStrip({
animation: { open: { effects: false} },
select: function (e) {
document.location.hash = 'tab-' + $(e.item).index();
},
activate: function(e) {
$(e.contentElement).find('.k-state-active [data-role="grid"]').each(function() {
$(this).data("kendoGrid").refresh();
});
}
});
Event activate is 'Triggered just after a tab is being made visible, but before the end of the animation'. So we must refresh our grids then becouse js counts widths of hidden elements wrong.
I put together an example of Grids working inside of a TabStrip: http://jsfiddle.net/dpeaep/SJ85S/. Maybe, I am missing part of what you are asking in your question. If so, you can modify the jsfiddle to clarify what the problem is.
HTML
<div id="tabstrip">
<ul>
<li>Grid 1</li>
<li>Grid 2</li>
<li>Grid 3</li>
</ul>
<div><div id="grid1"></div></div>
<div><div id="grid2"></div></div>
<div><div id="grid3"></div></div>
</div>
Javascript
var tabstrip = $("#tabstrip").kendoTabStrip().data("kendoTabStrip");
tabstrip.select(0);
$("#grid1").kendoGrid({
columns: [
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" }
],
dataSource: {
data: [
{ FirstName: "Joe", LastName: "Smith" },
{ FirstName: "Jane", LastName: "Smith" }
]
}
});
$("#grid2").kendoGrid({
columns: [
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" }
],
dataSource: {
data: [
{ FirstName: "Betty", LastName: "Lakna" },
{ FirstName: "Fumitaka", LastName: "Yamamoto" },
{ FirstName: "Fred", LastName: "Stevenson" }
]
}
});
$("#grid3").kendoGrid({
columns: [
{ field: "Title", title: "Title" },
{ field: "Year", title: "Year" }
],
dataSource: {
data: [
{ Title: "Lost in Domtar", Year: "2012" },
{ Title: "Evergreen", Year: "2012" },
{ Title: "Fields of Yellow", Year: "2010" },
{ Title: "Where the Whistle Blows", Year: "2008" }
]
}
});

Resources