Suppress global ajax in kendo autocomplete MVC - ajax

I have a kendo autocomplete box, which is bound to remote data.
whenever i type into the search box, my default Ajax loading animation is pop outs
i did some googling and found-->>> this
which says to include global: false in read to suppress this global ajax behavior
how can this be done in MVC wrapper?
#(Html.Kendo().AutoComplete()
.Name("productAutoComplete")
.DataTextField("ProductName")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetProducts", "Home");
})
.ServerFiltering(true);
})
)

I'm using the same scenario. After searching the internet for hours only answer on my hand was "You can't do it with wrappers. You have to initiate the autocomplete by js." But then I saw another solution for another product which make sense.
Here's what I did for my project:
In main js file;
var ajaxStartActive = true;
$(document).ajaxStart(
function () {
if (ajaxStartActive)
$loading.show();
}).ajaxStop(
function () {
$loading.hide();
});
Using with AutoComplete;
#(Html.Kendo().AutoComplete()
.Name("productAutoComplete")
.HtmlAttributes(new { onfocus = "ajaxStartActive = false;", onblur = "ajaxStartActive = true;" })
.DataTextField("ProductName")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetProducts", "Home");
})
.ServerFiltering(true);
})
)
I hope it helps

Related

Blank page after running Cypress tests

Whenever I run a new cypress test, the page that is supposed to show the UI is blank. Even when I click on each part of each test it remains blank. Please see image below.
image
Cypress package version: 10.4.0
Node v16.16.0
Code:
describe("home page", () => {
beforeEach(() => {
cy.visit("http://localhost:3000")
})
context("Hero section", () => {
it("the h1 contains the correct text", () => {
cy.getByData("hero-heading").contains(
"Testing Next.js Applications with Cypress"
)
})
it("the features on the homepage are correct", () => {
cy.get("dt").eq(0).contains("4 Courses")
cy.get("dt").eq(1).contains("25+ Lessons")
cy.get("dt").eq(2).contains("Free and Open Source")
})
})
context("Courses section", () => {
it("CourseL Testing Your First Next.js Application", () => {
cy.getByData('course-0')
.find('a')
.eq(3)
.contains('Get started')
})
})
})
/// <reference types="cypress" />
Cypress.Commands.add('getByData', (selector) => {
return cy.get(`[data-test=${selector}]`);
});
I faced the same issue in Cypress version 12.0.0 and I solved it by adding this configuration to cypress.config.js
testIsolation: false,
Try adding 's' to http; this might solve that else here is similar issue reported which might give you clue to your problem https://github.com/cypress-io/cypress/issues/4235
You might have put the it() describe() statements in the wrong place. Try creating the most simple test file possible or better still use an example test that cypress provides strip it down and continue to test it until it is barebones.
I have a "solution" in my tests - it seems that the it steps lose the URL.
Remove all the it steps:
describe('Register Native', () => {
// it("Verify1", () => {
: a
// })
// it("Verify2", () => {
: b
// })
})
Now I have a structure like this (only one it step):
describe('Registrer Native', () => {
it('Whole test- Without IT parts', () => {
: a
: b
: c
})
})
It is not an optimal solution as I now have a long test without intermediary it sections.

cypress - how to compare href to anchor text

I'm wondering how to test using cypress libary if the href attribute include the text from anchor tag. The code is as follow:
I have a div with a lot of anchors with data attribute.
<div>
#hash1
#hash2
#hash3
// and many more
</div>
I stared testing with check if each element have "#", href attribute with "/tag/" :
describe('Test', () => {
it('should navigate to link from hashtag', () => {
cy.visit('/');
cy.get('[data-cy="hashtag"]').each((item) => {
cy.wrap(item).contains('#').should('have.attr', 'href').and('contain', '/tag/');
})
})
});
but how can I check if href include the displayed text from a tag?
Once you've yielded the element from your cy.get(), you can reference it as a jQuery object. In this case, we'll want to get the text.
describe('Test', () => {
it('should navigate to link from hashtag', () => {
cy.visit('/');
cy.get('[data-cy="hashtag"]').each((item) => {
cy.wrap(item).contains('#').should('have.attr', 'href', `/tag/${item.text().replace('#', '')}`)
})
})
});
If you simply wanted to see if the href contains the text, you could use the jQuery attr function.
describe('Test', () => {
it('should navigate to link from hashtag', () => {
cy.visit('/');
cy.get('[data-cy="hashtag"]').each((item) => {
expect(item.text()).to.contain('#');
expect(item.attr('href')).to.contain(item.text().replace('#', ''));
})
})
});

Protractor expect direct to a page with specific url

I have a button on my page, I want to write an e2e test using Protractor. What I want to implement is that when clicking the button, page change to http://localhost:8100/#/booking. How can I implement that?
describe('booking function', function() {
it('should go to booking page', function() {
broswer.get(localHostCruises);
element(by.css('.button.button-stable.button-block')).click();
//sudo code
expect(page change to "http://localhost:8100/#/book" );
})
})
you need to use the browser.getCurrentUrl() method, so something like this:
element(by.css('.button.button-stable.button-block')).click().then(function () {
expect(browser.getCurrentUrl()).toEqual("http://localhost:8100/#/book");
})
You can achieve this with below code.
let targetLocation = 'your/target/location';
browser.get('localHostCruises'); // Login page.
element(by.css('.button.button-stable.button-block')).click(); // click on button.
browser.setLocation(targetLocation);
// If Login takes some time, so wait until it's done.
browser.wait(() => {
return browser.getCurrentUrl().then((url) => {
let isMatch = url.match(targetLocation);
if (isMatch) {
page = new Page; // I assume you writing test cases in page object.
} else {
browser.setLocation(targetLocation);
}
return isMatch;
});
}, 2000, 'Should throw an error message.');

What's missing in this Kendo Grid / DropDownList combination?

Seems to be the usual problem with Kendo grids, but a dropdown being rendered into the toolbar needs to fire an Ajax request to the server and refresh the grid from the returned data. I can see in Fiddler that the Ajax call is successfully being actioned and data is definitely being returned but we're not getting anything refreshed on the grid.
Here's the View code:
<div class="grid-validation-error" id="unitgrid-validation-error">
</div>
#(Html.Kendo()
.Grid(Model)
.Name("WheelchairAlertsGrid")
.Sortable()
.Scrollable(scr => scr.Height("100%"))
.Filterable()
.ToolBar(t => t.Template(
#<text>
<div class="toolbar">
<label class="category-label" for="category">Show alerts for:</label>
#(Html.Kendo().DropDownList()
.Name("filter-periods")
.DataTextField("Text")
.DataValueField("Value")
.OptionLabel("Month")
.Events(e => e.Change("filterPeriodChange"))
.BindTo(new List<SelectListItem>(){
new SelectListItem{ Text = "Day", Value = "Day" },
new SelectListItem{ Text = "Week", Value = "Week" },
new SelectListItem{ Text = "Month", Value = "Month" } })
)
</div>
</text>
))
.Pageable(paging => paging.Messages(msg => msg.Display(ResourceManager.RetrieveResource("PagingFormat"))))
.Columns(
col =>
{
col.Bound(um => um.SerialNumber).Width(150).Title("Wheelchair").ClientTemplate
(
"<a href='" +
Url.DealerGroupAction("Index", "Wheelchair") +
"/#= WheelchairDataAssignmentId #'>#= SerialNumber #" + "</a>"
);
col.Bound(um => um.Name).Width(150);
col.Bound(um => um.ChargeAlert).Width(60);
col.Bound(um => um.BatteryAbuse).Width(60);
col.Bound(um => um.Flash).Width(60);
col.Bound(um => um.Transmission).Width(60);
col.Bound(um => um.DealerGroup).Width(100);
})
)
And here's the JS code to refresh the data (with assorted variations commented out that have also been tried but failed to yield results):
function filterPeriodChange(e) {
var ddl = $('#filter-periods').data('kendoDropDownList');
var grid = $('#WheelchairAlertsGrid').data("kendoGrid");
$.getJSON('#Url.DealerGroupWheelChairAlertsApiUrl("WheelchairAlerts")', { filterPeriod: ddl.value() }, function (data) {
grid.dataSource = data;
});
}
There's always something really simple causing these sorts of problems but I can't see the forest for the trees. Any assistance appreciated.
Cracked it.
The Kendo Grid data source needs to be told to expect Ajax content. So the code should look like the following:
... other stuff as above
.DataSource(ds => ds
.Ajax()
.PageSize(20)
)
The next piece of the puzzle is to ensure the data source is being set correctly after picking up the data:
function filterPeriodChange(e) {
var ddl = $('#filter-periods').data('kendoDropDownList');
var grid = $('#WheelchairAlertsGrid').data("kendoGrid");
$.getJSON('#Url.DealerGroupWheelChairAlertsApiUrl("WheelchairAlerts")', { filterPeriod: ddl.value() }, function (data) {
var dataSource = new kendo.data.DataSource({
data: data.Data,
pageSize: 20
});
grid.setDataSource(dataSource);
});
}
That seems to have sorted the issue. Now, changing my dropdown list at the top level calls my filterPeriodChange method, fires off an Ajax request and re-binds the data.

Kendo toolbar AddNew button doesn't work when the grid is filtered

I have a small Kendo Grid, set up as below. In an inccredibly mysterious fashion, the Controller action for "Add New", i.e. BatchCreate is only invoked if when you click another command button after clicking "Add New". E.g. a) Click "Add New", nothing at all happens. b) Reload the page, and click "Add New", and have nothing happen, then click "Save Changes", then the BatchCreatemethod is finally invoked.
My grid looks like this, copied nearly straight from an example of theirs:
#(Html.Kendo().Grid<LocationIndexItem>()
.Name("index-grid")
.Columns(columns =>
{
columns.Bound(p => p.Name);
columns.Bound(p => p.IsActive).ClientTemplate(
"<input type='checkbox' value='#= IsActive #' " +
"# if (IsActive) { #" +
"checked='checked'" +
"# } #" +
"/>").Width(70);
columns.Bound(p => p.Remarks);
columns.Command(cmd => cmd.Destroy());
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
//.Events(e => e.Edit("gridEdit"))
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Filterable()
.Pageable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Batch(true)
.PageSize(20)
.Events(events => events.Error("errorHandler"))
.Model(model => model.Id(p => p.Id))
.Read(read => read.Action("Read", "Location"))
.Update(update => update.Action("BatchUpdate", "Location"))
.Create(create => create.Action("BatchCreate", "Location"))
.Destroy(destroy => destroy.Action("BatchDelete", "Location"))
)
)
Another grid exactly the same, except for one extra field, works perfectly.
JUST IN: Filtering the grid with the following code seems to cause the above behaviour. When I comment the commented line, $("#ParkadeId").change() out, the grid behaves as normal:
$(function() {
$("#ParkadeId").change(function () {
var value = $(this).val();
var grid = $("#index-grid").data("kendoGrid");
if (value) {
grid.dataSource.filter({ field: "ParkadeId", operator: "eq", value: parseInt(value) });
} else {
grid.dataSource.filter({});
}
});
//$("#ParkadeId").change();
});
It would seem setting a filter on a Kendo grid breaks the Add New functionality.
According to Kendo Ui Support Forum - this is expected behaviour when the filtering / sorting are applied on the client side, because when the new record is created outside the current view, it cannot be edited.
Possible solutions is to enable server sorting / filtering or implement custom "Add record" button which first clears the data source current filter and sort and then add new record using grid API.
This is an example of a function that clears current filters and sorting before adding a new record:
function createNew() {
var grid = $("#grid").data("kendoGrid");
grid.dataSource.filter({});
grid.dataSource.sort({});
//add record using Grid API
grid.addRow();
}
I found a good solution to this in the Kendo forums:
What I did was create a zero filter which accepts data with primary key equal to zero (since a row you just added with have zero as its primary key), and anywhere I need to set a custom filter I just include the zero filter as well:
var zeroFilter = {
field: "FieldID",
operator: "eq",
value: 0
};
function filterData() {
var ds = $("#Grid").data("kendoGrid").dataSource;
ds.filter({
logic: "or",
filters: [
{
field: "MyField",
operator: "eq",
value: someValue
},
zeroFilter
]
});
}
This can be done by custom "create" toolbar
$("#grid").kendoGrid({
...
toolbar: [{
name: "my-create",
text: "Add new record"
}],
..
)};
on load
$(".k-grid-my-create", grid.element).on("click", function(e) {
var grid = $("#grid").data("kendoGrid");
grid.dataSource.filter({});
grid.dataSource.sort({});
//add record using Grid API
grid.addRow();
});

Resources