telerik mvc grid with one master and two detail grid - telerik-mvc

I have one master but two detail grids (detail grids on the same level). But telerik mvc grid is not able to render the same.
So I just tried master grid with detail to be simple template as below.
#(Html.Telerik().Grid<VIDEO_MASTER>()
.Name("Videos")
.Columns(col =>
{
col.Bound(t => t.VIDEO_ID).Hidden(true);
col.Bound(t => t.VIDEO_NAME).Width(200).Title("Video Name");
col.Bound(t => t.VIDEO_SHORT_NAME).Width(150).Title("Video Short Name");
col.Bound(t => t.VIDEO_ALTERNATE_NAME).Width(200).Title("Video Alternate Name");
col.Bound(t => t.PART_NUMBER).Width(60).Title("Part No");
col.Bound(t => t.DURATION).Width(80).Title("Duration");
col.Command(cmd =>
{
cmd.Edit().ButtonType(GridButtonType.Image);
cmd.Delete().ButtonType(GridButtonType.Image);
}).Width(100).Title("Cmd");
})
.ToolBar(commands =>
{
commands.Insert().ButtonType(GridButtonType.ImageAndText).HtmlAttributes(new { id = "masterAddBtn" });
commands.Custom().HtmlAttributes(new { id = "export" }).Text("Export").Action("Video_Export", "Video");
commands.Custom().HtmlAttributes(new { id = "exportdet" }).Text("Export Detail").Action("Video_ExportDet", "Video");
})
.DataKeys(keys => keys.Add(tkey => tkey.VIDEO_ID).RouteKey("id"))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("Select_Videos", "Video")
.Insert("Insert_Videos", "Video")
.Update("Update_Videos", "Video")
.Delete("Delete_Videos", "Video")
)
.ClientEvents(events => events.OnDataBound("onDataBound").OnEdit("onEdit"))
.Pageable(pagezie => pagezie.PageSize(5))
.Filterable()
.Scrollable(s => s.Height(440))
.DetailView(details => { details.ClientTemplate("<p>Hello</p>");
details.ClientTemplate("<p>Hi</p>");
})
)
What is going wrong? MVC telrik grid does not support two details row?

Caliing the ClientTemplate second time overwrites the first one. Just append the elements into single string.
.DetailView(details => { details.ClientTemplate("<p>Hello</p><p>Hi</p>");

Related

Adding Extended Identity User Properties to Profile Management Page (ABP Commercial)

I have a new ABP Commercial project generated with the Suite: Blazor Server UI, Entity Framework with SQL Database, using tiered deployment. I'm attempting to extend the default Identity User entity with extra properties. I have added the new properties in the ModuleExtensionConfigurator.cs and EfCoreEntityExtensionMappings.cs files, like so...
In ModuleExtensionConfigurator.cs (IdentityUserExtraProperties holds the properties' string names):
private static void ConfigureExtraProperties()
{
ObjectExtensionManager.Instance.Modules()
.ConfigureIdentity(identity =>
{
identity.ConfigureUser(user =>
{
user.AddOrUpdateProperty<string>(
IdentityUserExtraProperties.MiddleName,
property =>
{
property.Attributes.Add(new StringLengthAttribute(64));
}
).AddOrUpdateProperty<string>(
IdentityUserExtraProperties.StreetAddress,
property =>
{
property.Attributes.Add(new StringLengthAttribute(256));
}
).AddOrUpdateProperty<string>(
IdentityUserExtraProperties.SuiteNumber,
property =>
{
property.Attributes.Add(new StringLengthAttribute(256));
}
).AddOrUpdateProperty<string>(
IdentityUserExtraProperties.City,
property =>
{
property.Attributes.Add(new StringLengthAttribute(128));
}
).AddOrUpdateProperty<State>(
IdentityUserExtraProperties.State
).AddOrUpdateProperty<string>(
IdentityUserExtraProperties.ZIP,
property =>
{
property.Attributes.Add(new StringLengthAttribute(11));
}
);
});
});
}
In EfCoreEntityExtensionMappings.cs:
public static void Configure()
{
WebAppGlobalFeatureConfigurator.Configure();
WebAppModuleExtensionConfigurator.Configure();
OneTimeRunner.Run(() =>
{
ObjectExtensionManager.Instance
.MapEfCoreProperty<IdentityUser, string>(
IdentityUserExtraProperties.MiddleName,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(64);
}
)
.MapEfCoreProperty<IdentityUser, string>(
IdentityUserExtraProperties.StreetAddress,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(256);
}
)
.MapEfCoreProperty<IdentityUser, string>(
IdentityUserExtraProperties.SuiteNumber,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(256);
}
)
.MapEfCoreProperty<IdentityUser, string>(
IdentityUserExtraProperties.City,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(128);
}
)
.MapEfCoreProperty<IdentityUser, State>(
IdentityUserExtraProperties.State
)
.MapEfCoreProperty<IdentityUser, string>(
IdentityUserExtraProperties.ZIP,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(11);
}
);
});
}
These properties have their columns in the database table, show up on the default CRUD page, and I'm able to access and save these values through the entity's ExtraProperties dictionary. However, now I would like to have these properties show up on the profile management page (select profile pic in top right, choose My Account, select Personal Info tab). They aren't added there by default.
What steps would I go through to override the Personal Info tab on the Profile Management page and add fields for changing these extra properties?

Cypress assert is element inside array

Can someone please, assist in following:
Short explanation: opened one page, taken text element, then opened second page nd among 4 or 5 elements, need to assert that element from page one, is inside created array of those several elements. Wrote this code:
Cypress.Commands.add(
'assertForOpenedElementVisible',
(list1, list2, notDisplayedElementMsg) => {
const textsArray = []
cy.get('body').then((body) => {
if (body.find(list1).length > 0) {
cy.get(list1).each(($el, index) => {
const text1 = $el.text().replace(', ', '')
cy.get(list1).eq(index).click()
cy.wait(1000)
cy.get(list2)
.each(($el, index) => {
const text = $el.text().replace(', ', '')
textsArray.push(text)
cy.log(textsArray)
cy.log(text)
})
.then(() => {
cy.wrap(expect(textsArray).to.include(text1))
})
})
} else {
cy.log(notDisplayedElementMsg)
}
})
}
)
And when check Test runner - I got elements, but test fails:
How to correctly assert that? Thank you in advance
You can do an assertion like:
expect(text1).to.be.oneOf(textsArray)
OR, you can directly assert without using each() as well like:
cy.get(list2).should(($list2) => {
expect($list2.eq(3)).to.contain('49') //If you know the position
})
cy.get(list2)
.invoke('text')
.then((text) => {
expect(text).to.contain('49') //If you don't know the position
})

Deleting document from Firestore based on array key

I'm making a web app to help people create graphs. When a user creates two graphs and deletes the first one, the index in the array changes to 0 and so the second graph (graph1) doesn't get deleted from Firestore. Any ideas on how to approach this? Thanks
Adds Graph
onClick={ () => {
const clientDb = firebaseClient.firestore();
// Adding Graph Options NOTICE HERE SITTING DOCUMENT NAME TO graph${i}
for(var i = 0 ; i < numberofGraphs.length ; i++ ){
clientDb.collection("Users").doc(props.uid).collection("Dashboard").doc(`graph${i}`).set({
type:numberofGraphs[i].type,
title:numberofGraphs[i].type,
seriestitle:numberofGraphs[i].seriestitle,
legend:numberofGraphs[i].legend,
xAxis:numberofGraphs[i].xAxis,
yAxis:numberofGraphs[i].yAxis,
color:numberofGraphs[i].color,
tooltipcolor:numberofGraphs[i].tooltipcolor,
tooltiptextcolor:numberofGraphs[i].tooltiptextcolor,
axisColor:numberofGraphs[i].axisColor,
})
}
}}
Deletes Graph
numberofGraphs.map( (si, k) => (
<>
<CloseIcon
onClick={ () => {
if(window !== "undefined") {
console.log("lets see it")
const clientDb = firebaseClient.firestore();
//NOTICE HERE DELETING Graph with index from map
clientDb.collection("Users").doc(props.uid).collection("Dashboard").doc(`graph${k}`).delete();
}
const newgraphs = numberofGraphs.filter( (object, kk) => k!== kk )
setnumberofGraphs(newgraphs);
}}
/>
<CreateGraph2 type={si.type} title={si.title} seriestitle={si.seriestitle}/>
</>
))
If you absolutely have to do it this way you could "mark doc as deleted" by doing collection('Dashboard').doc('<doc-to-delete>').set({ deleted: true }) and then just filter it out in the client by this property and don't display it.
More generally - use collection().add() to create new documents and let firestore auto-generate IDs for you. Then access your documents by ID, instead of trying to keep track of indices on the front end.
I solved my issue doing the following:
Adds Graph
// Took #samthecodingman's advice by moving all graphs to their own /Graphs collection.
// Which also resonated with #Brian's answer to use
// collection().add() to add documents with Auto-generated ID's instead of adding graphs based
// on index no. of array.
onClick={ () => {
if(window !== "undefined") {
const clientDb = firebaseClient.firestore();
clientDb.collection("Users").doc(props.uid)
.collection("Dashboard")
.doc("First").collection("Graphs").add({
type:type, title:title, seriestitle:seriestitle,
legend:legend,
xAxis:xAxis,
yAxis:yAxis,
color:color,
tooltipcolor:tooltipcolor,
tooltiptextcolor:tooltiptextcolor,
axisColor:axisColor,
//passed an id filed to the object I'm saving
id:type+title
})
}
}}
Deletes Graph
//mapping through an array of objects (si) and then using the get() method with
a query to check for matching ID. Then used the id in the delete method
if(window !== "undefined") {
const clientDb = firebaseClient.firestore();
const docref = clientDb.collection("Users").doc(props.uid)
.collection("Dashboard").doc("First").collection("Graphs");
docref.where("id" , "==", `${si.type}${si.title}`)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
docref.doc(doc.id).delete()
console.log(doc.id, " => ", doc.data() );
});
})
}

Select from table where both columns have same value

I have the code that selects all articles. What I am doing is, I think, wrong. I am selecting all values and then I am executing them.
Article::all()->each(function($article) {
if ($article->created_at == $article->published_at && $article>published) {
$article->update(['published_at' => null]);
}
});
What I need to do is select only those articles that have the mentioned created_at and updated_at the same.
How could I do that on the database level?
I need sth like that:
Article::where('created_at', '=', 'published_at')->where('published')->get()->each(function($article) {
$article->update(['published_at' => null]);
}
});
This code sure does not work, its just for imagine.
edit your code
Article::all()->each(function($article) {
if ($article->created_at == $article->published_at && $article->published) {
$article->update(['published_at' => null]);
}
});
You only need to search on the two columns for the one value:
Article::where(['created_at' => $date, 'updated_at' => $date ])->get();
Edit:
Use whereRaw for this
Article::whereRaw('created_at = updated_at')->get();

Perl: Merging Hash elements

I have 2 hashes.
my %hash1 = (
'1.3.6.1.2.1.7.1.0' => 'switch_stuff1',
'1.3.6.1.2.1.6.3.0' => 'switch_stuff4',
'1.3.6.1.2.1.6.5.0' => 'switch_stuff5',
'1.3.6.1.2.1.7.4.0' => 'switch_stuff2',
'1.3.6.1.2.1.6.2.0' => 'switch_stuff3'
);
my %hash2 = (
'1.3.6.1.2.1.7.1.0' => 125858,
'1.3.6.1.2.1.6.3.0' => 120000,
'1.3.6.1.2.1.6.5.0' => 23766,
'1.3.6.1.2.1.7.4.0' => 115336,
'1.3.6.1.2.1.6.2.0' => 200
);
As you can see, the key values for both hashes are the same.
What I need to do is take the values from %hash1 and use them as keys for the %hash2.
Output:
$VAR1 = {
'switch_stuff1' => 125858,
'switch_stuff4' => 120000,
'switch_stuff5' => 23766,
'switch_stuff2' => 115336,
'switch_stuff3' => 200
};
Note: The number of keys/value pairs in both hashes will always be the same.
Alternatively, the only important thing to me about %hash1 are the values.
'switch_stuff1',
'switch_stuff4',
'switch_stuff5',
'switch_stuff2',
'switch_stuff3'
So if merging the hashes in the way I described is not possible, I can instead turn the %hash1 into an array that contains only the values.
Can anybody please help a Perl Newbie out or at least point me in the right direction? Any help would be greatly appreciated.
Thank you.
ETA:
Ah, I think I misunderstood you.. You wanted to join the two separate values into a hash. Easily done with map:
my %hash3 = map { $hash1{$_} => $hash2{$_} } keys %hash1;
my $hash1 = {
'1.3.6.1.2.1.7.1.0' => 'switch_stuff1',
'1.3.6.1.2.1.6.3.0' => 'switch_stuff4',
'1.3.6.1.2.1.6.5.0' => 'switch_stuff5',
'1.3.6.1.2.1.7.4.0' => 'switch_stuff2',
'1.3.6.1.2.1.6.2.0' => 'switch_stuff3'
};
my $hash2 = {
'1.3.6.1.2.1.7.1.0' => 125858,
'1.3.6.1.2.1.6.3.0' => 120000,
'1.3.6.1.2.1.6.5.0' => 23766,
'1.3.6.1.2.1.7.4.0' => 115336,
'1.3.6.1.2.1.6.2.0' => 200
};
my $hash3 = {}:
foreach $key (keys %$hash1) {
$hash3->{$hash1->{$key}} = $hash2->{$key};
}

Resources