I'm trying to create a card view to loop products from the "product" table in the database
ProductImage
I'd like to use Unit Price for the card title
Category for Subtitle and Content for Description
I've tried couple of ways but cant seem to make it work, kindly assist.
I want to create something like this with one button that opens a dialog box containing a editform to submit
|
<div class="col-lg-12 control-section card-control-section">
<div class="row card-layout">
<div class="col-lg-6 col-md-6">
@foreach (var data in mobileData)
{
<SfCard Orientation="CardOrientation.Horizontal" ID="Phone">
<img src="//ej2.syncfusion.com/demos/src/card/images/iphone.png" alt="iPhone X" style="width:50%; height:360px">
<CardStacked>
<CardHeader Title="@data.ProductUnitPrice" SubTitle="@data.CategoryName" />
<CardContent Content="@data.ProductDesription" />
<CardFooter>
<CardFooterContent>
<SfButton @onclick="@OnBtnClick" CssClass="e-outline">check</SfButton>
</CardFooterContent>
</CardFooter>
</CardStacked>
</SfCard>
}
</div> <SfDialog Target="#target" Width="500px" ShowCloseIcon="true" @bind-Visible="Visibility">
<DialogTemplates>
<Header> Form</Header>
<Content>
<EditForm Model="@exampleModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary /> <label for="fname">Data</label>
<input type="text" id="fname" @bind-value="exampleModel.Name" placeholder="Your data..">
<br />
<button class="e-btn" type="submit">Submit</button>
</EditForm>
</Content>
</DialogTemplates> </SfDialog>
</div>
</div>
@code { private bool Visibility { get; set; } = false;
private bool ShowButton { get; set; } = false; public class MobileData
{
public string ProductCode { get; set; }
public string ProductDesription { get; set; }
public string ProductUnitPrice { get; set; }
public string CategoryName { get; set; }
} private IEnumerable<MobileData> mobileData = new[] {
new MobileData { ProductCode="1000" , ProductDesription=
"The iPhone is the first smartphone designed and marketed by Apple Inc.
After years of rumors and speculation, it was officially announced in January 2007,
and was released in the United States in June." ,
ProductUnitPrice="10,000" ,CategoryName="Mobile" },
new MobileData { ProductCode="1001" , ProductDesription=
"The iPhone is the first smartphone designed and marketed by Apple Inc.
After years of rumors and speculation, it was officially announced in January 2007,
and was released in the United States in June." ,
ProductUnitPrice="20,000" ,CategoryName="Mobile" }
}; private void OnBtnClick()
{
this.Visibility = true;
} public class ExampleModel
{
[Required]
[StringLength(10, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
} private ExampleModel exampleModel = new(); private void HandleValidSubmit()
{
// Process the valid form
} |
Hello Gunasekar, thanks for your response.
So i created a card view successfully per my liking.
Now the problem is, i have many list in my product database and all are showing as a long list..
How can i include paging to the sfcard component so it shows at least 10 products in each page
And another issue im trying to figure out is how to get the ProductID from a card which a user clicks on it button
the button opens a dialog containing an edit form to submit. I'd want to submit the data including the selected ProductID into a database using an insert stored procedure i already have
My code so far below
<div class="col-lg-12 control-section card-control-section"> <div class="row card-layout"> <div class="col-lg-6 col-md-6"> <div class="left"> <br /> @foreach (var cardview in products) { <SfCard @ref="ProductCard" Orientation="CardOrientation.Horizontal" ID="Products"> <img src=@cardview.ProductImage alt="cake" style="width:10%; height:250px"> <CardStacked > <CardHeader Title=@String.Format("{0:C2}",cardview.ProductUnitPrice) SubTitle=@cardview.CategoryName /> <CardContent Content=@cardview.ProductDescription /> <CardContent Content=@cardview.ProductCode /> <CardFooter> <CardFooterContent> <SfButton CssClass="e-btn e-outline e-primary" @onclick="OnClick">Order</SfButton> </CardFooterContent> </CardFooter> </CardStacked> </SfCard> } <br /> </div> </div> </div> </div> <SfDialog @ref="DialogAddEditOrderLine" IsModal="true" Width="600px" ShowCloseIcon="true" Visible="false"> <DialogTemplates> <Header> @dialogHeaderText </Header> </DialogTemplates> <EditForm Model="@addeditOrderLine" OnValidSubmit="@OrderLineSave"> <DataAnnotationsValidator /> <SfTextBox Enabled="true" Placeholder="Customer Name" FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderCustomerName"></SfTextBox> <ValidationMessage For="@(() => addeditOrderLine.OrderCustomerName)" /> <SfTextBox Enabled="true" Placeholder="Customer Phone Number" FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderCustomerPhoneNumber"></SfTextBox> <ValidationMessage For="@(() => addeditOrderLine.OrderCustomerPhoneNumber)" /> <SfTextBox Enabled="true" Placeholder="Customer Delivery Address" FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderDeliveryAddress"></SfTextBox> <ValidationMessage For="@(() => addeditOrderLine.OrderDeliveryAddress)" /> <SfTextBox Enabled="true" Placeholder="Cake Inscription" FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderInscription"></SfTextBox> <SfTextBox Enabled="true" Placeholder="Order Instruction" FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderInstruction"></SfTextBox> <SfDatePicker TValue="DateTime" Placeholder='Delivery Date' FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderDeliveryDate"></SfDatePicker> <ValidationMessage For="@(() => addeditOrderLine.OrderDeliveryDate)" /> <SfTimePicker TValue="DateTime" Placeholder='Select Pickup Time' FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderPickupTime"></SfTimePicker> <ValidationMessage For="@(() => addeditOrderLine.OrderPickupTime)" /> <SfTextBox Enabled="true" Placeholder="Recipient Details if Any" FloatLabelType="@FloatLabelType.Auto" @bind-Value="addeditOrderLine.OrderRecepient"></SfTextBox> <SfMultiSelect DataSource="@flavor" TItem="Flavor" TValue="string" Text="FlavorName" AllowFiltering="true" Placeholder="Indicate Flavors" @bind-Value="addeditOrderLine.OrderFlavor" FloatLabelType="@FloatLabelType.Auto" Enabled="true" Mode="@VisualMode.CheckBox" PopupHeight="350px"> <MultiSelectFieldSettings Text="FlavorName" Value="FlavorName"></MultiSelectFieldSettings> </SfMultiSelect> <div class="e-footer-content"> <div class="button-container"> <button type="submit" class="e-btn e-normal e-primary">Save</button> <button type="button" class="e-btn e-normal" @onclick="@CloseDialog">Cancel</button> </div> </div> </EditForm> </SfDialog> <WarningPage @ref="Warning" WarningHeaderMessage="@WarningHeaderMessage" WarningContentMessage="@WarningContentMessage" /> <style> .left { position: absolute; left: -10px; width: 400px; padding: 10px; font-size: 20px; font-weight: bold; } </style> @code { IEnumerable<Product> cardviewByProduct; IEnumerable<Flavor> flavor; Product productCard = new Product(); [Parameter] public int ProductID { get; set; } bool Clicked = false; string dialogHeaderText = ""; SfDialog DialogAddEditOrderLine; SfCard ProductCard; WarningPage Warning; string WarningHeaderMessage = ""; string WarningContentMessage = ""; public CustomerOrder addeditOrderLine = new CustomerOrder(); public List<Product> products = new List<Product>(); protected override async Task OnInitializedAsync() { productCard = await ProductService.Product_GetOne(ProductID); //cardviewByProduct = ProductService.ProductList; cardviewByProduct = await ProductService.ProductList(); products = cardviewByProduct.ToList(); //Convert from IEnumable to List addeditOrderLine.OrderDeliveryDate = DateTime.Now; addeditOrderLine.OrderPickupTime = DateTime.Now; } private void onToggleClick(Microsoft.AspNetCore.Components.Web.MouseEventArgs args) { } private async Task OrderLineSave() { } public async Task OnClick() { Clicked = !Clicked; if (Clicked) { dialogHeaderText = "Please Fill in Details"; //Opens Dialog addeditOrderLine = new CustomerOrder(); // Ensures a blank form when adding await this.DialogAddEditOrderLine.Show(); } else { // } } private async Task CloseDialog() { await this.DialogAddEditOrderLine.Hide(); } }
For better clarification if needed . I want that during the opening of the dialog box, a code should run to pick the ProductID of that specific Card view product that the end user clicked on its button to make an order. and when the user fills in details and clicks on "Place Order". the "Place Order" button calls an insert stored procedure and inserts the details filled in the edit form INCLUDING the ProductID of the product selected.
|
<div class="col-lg-12 control-section card-control-section">
<div class="row card-layout">
<div class="col-lg-6 col-md-6">
@foreach (var data in newData)
{
<SfCard Orientation="CardOrientation.Horizontal" ID="Phone">
<img src="//ej2.syncfusion.com/demos/src/card/images/iphone.png" alt="iPhone X" style="width:50%; height:360px">
<CardStacked>
<CardHeader Title="@data.ProductUnitPrice" SubTitle="@data.CategoryName" />
<CardContent Content="@data.ProductDesription" />
<CardFooter>
<CardFooterContent>
<SfButton @onclick="() => CardClick(data.ProductCode)" CssClass="e-outline">Click</SfButton>
</CardFooterContent>
</CardFooter>
</CardStacked>
</SfCard>
}
</div>
<SfDialog Target="#target" Width="500px" ShowCloseIcon="true" @bind-Visible="Visibility">
<DialogTemplates>
<Header> Form</Header>
<Content>
<EditForm Model="@exampleModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary /> <label for="fname">Data</label>
<input type="text" id="fname" @bind-value="exampleModel.Name" placeholder="Your data..">
<br />
<button class="e-btn" type="submit">Submit</button>
</EditForm>
</Content>
</DialogTemplates>
</SfDialog>
</div> <SfPager @bind-CurrentPage="@CurPage" PageSize="1" TotalRecordsCount="5">
<PagerEvents Click="click"></PagerEvents>
</SfPager>
</div>
@code {
public double CurPage { get; set; } = 1;
public string currentProduct { get; set; }
private bool Visibility { get; set; } = false;
private bool ShowButton { get; set; } = false; public class MobileData
{
public string ProductCode { get; set; }
public string ProductDesription { get; set; }
public string ProductUnitPrice { get; set; }
public string CategoryName { get; set; }
}
protected override void OnInitialized()
{
newData = mobileData.Take(3);
} private IEnumerable<MobileData> newData { get; set; }
private IEnumerable<MobileData> mobileData = new[] {
new MobileData { ProductCode="1000" , ProductDesription="The iPhone is the first smartphone designed and marketed by Apple Inc. After years of rumors and speculation, it was officially announced in January 2007, and was released in the United States in June." , ProductUnitPrice="10,000" ,CategoryName="Mobile" },
. . .
new MobileData { ProductCode="1015" , ProductDesription="The iPhone is the first smartphone designed and marketed by Apple Inc. After years of rumors and speculation, it was officially announced in January 2007, and was released in the United States in June." , ProductUnitPrice="20,000" ,CategoryName="Mobile" }
}; private void CardClick(string id)
{
currentProduct = id;
this.Visibility = true;
} public class ExampleModel
{
[Required]
[StringLength(10, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
} private ExampleModel exampleModel = new(); private void HandleValidSubmit(EditContext context)
{
ExampleModel contextModel = (ExampleModel)context.Model;
var code = currentProduct;
//You can get the selected item product code and entered details here.
} //pager click event
public void click(PageChangedEventArgs args)
{
newData = mobileData.Skip((int)(3 * (args.CurrentPage - 1))).Take(3);
// updte the currentpage
CurPage = args.CurrentPage;
} } |
Hi Gunasekar
I wanted to check if the ProductID number was picked by the press of the button
<CardFooterContent> <SfButton CssClass="e-btn e-outline e-primary" @onclick="() => CardClick(cardview.ProductID)">Order</SfButton> </CardFooterContent>
so i added a numberic textbox to view it in the editform
<SfNumericTextBox Enabled="false" Placeholder="Product ID" FloatLabelType="@FloatLabelType.Always" ShowSpinButton="false" Format="n0" @bind-Value="addeditOrderLine.OrderProductID" CssClass="e-style"> </SfNumericTextBox>
and i passed currentproduct which i presume should contain the ProductID to the numeric textbox bind value
private async Task CardClick(int id) { currentProduct = id; addeditOrderLine.OrderProductID = currentProduct; //Opens Dialog dialogHeaderText = "Please Fill in Details"; addeditOrderLine = new CustomerOrder(); // Ensures a blank form when adding await this.DialogAddEditOrderLine.Show(); }
number but it comes back as 0 for any card selected
I'd like to know if i'm doing something wrong.
and with the paging i get an error 'Product' does not contain a definition for 'Skip'
IEnumerable<Product> cardviewByProduct;
//pager click event public void nextpage(PageChangedEventArgs args) { products = Product.Skip((int)(3 * (args.CurrentPage - 1))).Take(3); // updte the currentpage CurPage = args.CurrentPage; }
Hi, i just figured why the productID wasnt working and was coming as 0 . I had a code beneath that ensures a blank form when the dialog opens. So i commented it out and i now get the ProductID. Thanks for your help Gunasekar
private async Task CardClick(int id) { currentProduct = id; addeditOrderLine.OrderProductID = currentProduct; //Opens Dialog dialogHeaderText = "Please Fill in Details"; //*ddeditOrderLine = new CustomerOrder(); // Ensures a blank form when adding*/ await this.DialogAddEditOrderLine.Show(); }
Hi Gunasekar,
I'd like to inform you again that the paging for the sfcard doesnt work. Can you kindly help me resolve it ?
IEnumerable <Product> cardviewByProduct; private IEnumerable<Product> newData { get; set; }
//pager click event public void nextpage(PageChangedEventArgs args) { newData = cardviewByProduct.Skip((int)(3 * (args.CurrentPage - 1))).Take(3); // updte the currentpage CurPage = args.CurrentPage; }
Hello
Indrajith Srinivasan
<SfPager @bind-CurrentPage="@CurPage" PageSize="1" TotalRecordsCount="5">
<PagerEvents Click="click"></PagerEvents>
</SfPager>
TotalRecordsCount="5"
Which means the pages are limited to the number i put there..
How can i change that so it auto gives the total number pages due to the total number of products the sfcard is displaying by the
mobileData.Take(3);
?
|
<SfPager @bind-CurrentPage="@CurPage" PageSize="1" TotalRecordsCount="@RecordCount">
<PagerEvents Click="click"></PagerEvents>
</SfPager>
@code {
private double RecordCount { get; set; }
protected override void OnInitialized()
{
newData = mobileData.Take(3);
RecordCount = newData.Count();
}
} |
Hi
Indrajith Srinivasan,
Thanks for your feedback, was really helpful.
But i believe with
RecordCount = newData.Count(); what it means is that, it will make RecordCount value = 3 or perhaps it will make the value any number we set
mobileData.Take() because we are assigning that to newData.
for instance, if
protected override void OnInitialized()
{
newData = mobileData.Take(3);
RecordCount = newData.Count();
}
then RecordCount value will be 3
so if i have 16 cards in total, it means i'll only get 3 pages which will be only 9 cards to display (3 per page)
But i cant seem to get the count of the number of cards that should be displayed in total.
if i do, what i'll then do is divide the count by the number in Take() so i will get the accurate value for RecordCount.
|
@code {
protected override void OnInitialized()
{
newData = mobileData.Take(3);
RecordCount = mobileData.Count() / newData.Count();
}
} |
Hi
Indrajith
That helped .
thanks
HI
Indrajith Srinivasan
private async Task OnChangeCategory(Syncfusion.Blazor.DropDowns.ChangeEventArgs<int, Category> args)
{
productCard = await ProductService.Product_GetOne(ProductID);
cardviewByProduct = await ProductService.ProductListbyCategoryAndImage(args.ItemData.CategoryID);
CurPage = 1;
products = cardviewByProduct.Take(4);
RecordCount = cardviewByProduct.Count() / products.Count() + 1;
}
After i query products by category and select a product, enter details in the dialog box and save with the below method
private async Task OrderLineSave()
{
// Insert customer inputed details into customer order table
await CustomerOrderService.CustomerOrderInsert(addeditOrderLine);
// insert details into POheader table to create an order header
await OrderHeaderLineSave();
//hide addedit dialog box
await this.DialogAddEditOrderLine.Hide();
await this.ToastObj.Show(Toast[1]);
// clear data in addedit dialong
addeditOrderLine = new CustomerOrder();
await this.ToastObj.Show(Toast[3]);
}
I get an error in
private async Task OnChangeCategory(Syncfusion.Blazor.DropDowns.ChangeEventArgs<int, Category> args)
saying (args.ItemData.CategoryID); is null. I understand the problem, but i'd like to understand why after i use private async Task OrderLineSave() it goes back to make my category ID null in
private async Task OnChangeCategory(Syncfusion.Blazor.DropDowns.ChangeEventArgs<int, Category> args)
Hi
Indrajith
Ive figured out why i was getting the error and fixed it.
Thanks very much for all the su
Hi Boot,
We are glad that your issue has been resolved. Please get back to us if you need any further assistance.
Regards,
Vinitha