Dynamically list data in dynamic repeater (Asp.Net) - c#

In my project, i've been trying something for a while. User must select the Group from select. This Add button runs asp repeater so i can list groups. There are 2 button in group line. Right one delets the group and left one opens dynamic divs. (As you can see) There are some Javascript works so i set the id's dynamically. It's ok until here. Now, if the user want to check fixed questions, i need to show the questions that in that group. And user must be able to add question under the group dynamically. I tryed to use GridView but i couldnt handle. So any advice?
Here is what i want to do:
<ul>
<asp:Repeater ID="GroupRepeater" runat="server">
<ItemTemplate>
<li class="groupli">
<div style="width:100%; float:left; margin-top:2%;">
<h3 style="display:block; float:left; width:auto;"><%# Container.ItemIndex+1 %>.<%# Eval("QuestGroup")%></h3>
<asp:Button CssClass="GroupLiButtonD" OnClick="RemoveGroup" CommandArgument='<%# Eval("QuestGroup") %>' ID="DeleteGroupBtn" runat="server"/>
<button type="button" onclick="ShowQuestArea('<%# Container.ItemIndex+1 %>_div')" class="GroupLiButtonA"></button>
</div>
<div id='<%# Container.ItemIndex+1 %>_div' style="width:100%; margin-left:3%; float:left; display:none;">
<div class="questarea">
<div style="width:100%; margin-top:1%;">
<h4 style="display:block; float:left; width:200px;">Add Fixed Question</h4>
<input name='check_<%# Container.ItemIndex+1 %>' id='fixcheck_<%# Container.ItemIndex+1 %>' onchange="FixedCheck('fixcheck_<%# Container.ItemIndex+1 %>','<%# Container.ItemIndex+1 %>')" type="radio" />
</div>
<div id="fixarea_<%# Container.ItemIndex+1 %>" class="subarea"> <%--fixedquestion view start tag--%>
</div> <%--fixedquestion view end tag--%>
<div style="width:100%; margin-top:1%;">
<h4 style="display:block; float:left; width:200px;">Add Random Question</h4>
<input name='check_<%# Container.ItemIndex+1 %>' id='randomcheck_<%# Container.ItemIndex+1 %>' onchange="RandomCheck('randomcheck_<%# Container.ItemIndex+1 %>','<%# Container.ItemIndex+1 %>')" type="radio" />
<div id="randomarea_<%# Container.ItemIndex+1 %>" class="subarea">
<div style="margin-top:1%;">
<p style="color:black; float:left;">Number of Random Questions:</p><input type="number" max="20" min="0" style="width:20px; float:left;" />
<button>Add</button>
</div>
</div>
</div>
</div>
</div>
</li>
</ItemTemplate>
</asp:Repeater>
</ul
My code might seem complicated. I added an image. So you can ignore my code for giving advice. Thank you.

Maybe a bit of jquery and some ajax calls will do the trick.
You can add same class and a data-groupid attribute to the "fixed answer" radio buttons.
Lets say the id of the group questions is resultlist and it is a ul element.
Then you will handle the click to load the questions with ajax
$(".yourclass").on"click", function (e) {
var groupid=$(this).data("groupid");
//get the questions
$.ajax({
type: 'POST',
contentType: "application/json; charset=iso-8859-7",
url: 'yourpage.aspx/yourmethod',
data: "{'group':'" + groupid +"'}",
async: false,
error: function (xhr) {console.log(xhr.responseText);},
success: function (response) {
//Query the jQuery object for the values
var items = response.d;
if (items == null) {
$('#resultlist').empty();
$('#resultlist').append("<li> no questions... </li>");
}
else {
var fragment = "";
$.each(items, function (index, val) {
var theQuestion = val.theQuestion;
var theCode = val.theCode;
fragment += "<li data-qustionid='"+theCode+"' class='question'>"+theQuestion+"</li>";});
$('#resultlist').empty();
$("#resultlist").append(fragment);
}
});
});
in your .cs file you will add a new web method that will get the group's questions
[WebMethod]
public static List<Results> yourmethod(string text, string phone, string type)
{
List<Results> result = new List<Results>();
DataTable question = getQuestions();
if(question!=null){
foreach (DataRow rw in autocomlete.Rows)
{
result.Add(new Results { theQuestion = rw[0].ToString(),
theCode = rw[3].ToString() });
}
}
return result;
}
and likewise you will handle the click of the class question which on click will get the data-questionid and update it to the database. You can add more fields that you need in the data- attributes (link here) Readmore for ajax here

Related

Why is the textbox in my ASP.NET webform always empty

This is my markup:
<%# Page Title="" Language="C#" MasterPageFile="~/User/Default.Master" AutoEventWireup="true" CodeBehind="Consulation.aspx.cs" Inherits="PetShop.User.Consulation" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<script>
window.onload = function () {
var second = 5;
setTimeout(function () {
document.getElementById("<%=lblMsg.ClientID%>").style.display = "none";
}, second * 1000)
}
</script>
<link href="../CSSandJS/StyleCss/consulation.css" rel="stylesheet" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<!-- Slider -->
<section id="Slider">
<div class="aspect-ratio-169">
<img src="../CSSandJS/images/bg_1.jpg" alt="">
<img src="../CSSandJS/images/bg_2.jpg" alt="">
<img src="../CSSandJS/images/bg_3.jpg" alt="">
<img src="../CSSandJS/images/bg_4.jpg" alt="">
</div>
<div class="dot-container">
<div class="dot active"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
</section>
<!-- End Slider -->
<!-- Free Consulation -->
<section class="contact">
<div class="container-contact">
<h1>Đặt lịch hẹn</h1>
<div class="row">
<div class="contact-img">
<img src="../CSSandJS/images/bg_1.jpg" alt="" width="400">
</div>
<div class="input-infor">
<div class="form">
<div class="dbl-field">
<asp:DropDownList ID="ddlCategory" runat="server" CssClass="form-control option field-mail listOp" DataSourceID="SqlDataSource1" DataTextField="TENDV" DataValueField="MADV" AppendDataBoundItems="true">
<asp:ListItem Value="0">Chọn danh mục</asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:cs %>" SelectCommand="SELECT [MADV], [TENDV] FROM [DICHVU]"></asp:SqlDataSource>
</div>
<div class="dbl-field">
<div class="field-mail">
<asp:TextBox ID="txtEmail" runat="server" CssClass="form-control input" placeholder="Nhập email" required></asp:TextBox>
<i class="ri-mail-line"></i>
</div>
</div>
<div class="dbl-field">
<div class="field">
<asp:TextBox ID="txtNameAcc" runat="server" CssClass="form-control input" placeholder="Nhập tên"></asp:TextBox>
<i class="ri-user-line"></i>
</div>
<div class="field">
<asp:TextBox ID="txtSDT" runat="server" CssClass="form-control input" placeholder="Nhập số điện thoại" MaxLength="11"></asp:TextBox>
<i class="ri-phone-line"></i>
</div>
</div>
<div class="dbl-field">
<div class="field">
<asp:TextBox ID="txtNgay" runat="server" CssClass="form-control input" TextMode="Date"></asp:TextBox>
<i class="ri-calendar-2-line"></i>
</div>
<div class="field">
<asp:TextBox ID="txtTime" runat="server" CssClass="form-control input" placeholder="Nhập giờ hẹn" MaxLength="5" TextMode="SingleLine"></asp:TextBox>
<i class="ri-time-line"></i>
</div>
</div>
<div class="message">
<asp:TextBox ID="txtDescription" runat="server" CssClass="form-control textarea" placeholder="Tin nhắn" TextMode="MultiLine"></asp:TextBox>
<i class="ri-message-2-line"></i>
</div>
<div class="button-area">
<asp:Button ID="Add" runat="server" Text="Gửi lịch hẹn" class="btn btn-primary button" OnClick="Add_Click"/>
<asp:Label ID="lblMsg" runat="server" Visible="false"></asp:Label>
<%--<asp:linkbutton id="submitcal" runat="server" cssclass="btn btn-primary button" OnClick="Add_Click">gửi lịch hẹn</asp:linkbutton>--%>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End Free Consulation -->
</asp:Content>
The textbox doesn't get any value when I debug the program.
I have tested the stored procedure in SQL Server and it works fine. But the data returned from the SQL code is empty.
My button submit code:
namespace PetShop.User
{
public partial class Consulation : System.Web.UI.Page
{
SqlConnection con;
SqlCommand cmd;
protected void Page_Load(object sender, EventArgs e)
{
}
private void clear()
{
txtEmail.Text = string.Empty;
txtDescription.Text = string.Empty;
txtNameAcc.Text = string.Empty;
txtSDT.Text = string.Empty;
txtNgay.Text = string.Empty;
txtTime.Text = string.Empty;
ddlCategory.ClearSelection();
}
protected void Add_Click(object sender, EventArgs e)
{
string actionName = string.Empty;
bool isValidToExcute = true;
con = new SqlConnection(Connection.GetConnectionString());
cmd = new SqlCommand("Add_KHaddLH", con);
cmd.Parameters.AddWithValue("#Action", "INSERT4KH");
cmd.Parameters.AddWithValue("#MaDv", ddlCategory.SelectedValue);
cmd.Parameters.AddWithValue("#EMail", txtEmail.Text.Trim());
cmd.Parameters.AddWithValue("#Ten", txtNameAcc.Text.Trim());
cmd.Parameters.AddWithValue("#Sdt", txtSDT.Text.Trim());
cmd.Parameters.AddWithValue("#NgayHen", txtNgay.Text.ToString());
cmd.Parameters.AddWithValue("#GioHen", txtTime.Text.Trim());
cmd.Parameters.AddWithValue("#GhiC", txtDescription.Text.Trim());
if (isValidToExcute)
{
cmd.CommandType = CommandType.StoredProcedure;
try
{
con.Open();
cmd.ExecuteNonQuery();
actionName = "gửi";
lblMsg.Visible = true;
lblMsg.Text = "Lịch hẹn " + actionName + " thành công!";
lblMsg.CssClass = "alert alert-success";
clear();
}
catch (Exception ex)
{
lblMsg.Visible = true;
lblMsg.Text = "Lỗi !!!" + ex.Message;
lblMsg.CssClass = "alert alert-danger";
}
finally
{
con.Close();
}
}
}
}
}
I think the error lies in the page reload, because when submitting it will delete all the data in the textbox and then enter.
I've tried adding some commands to the button but still can't handle that it keeps losing textbox data.
I update code behind and markup.
Support me,
Thank.
Ok, so that helps a boatload.
if we have this code:
protected void Add_Click(object sender, EventArgs e)
{
string actionName = string.Empty;
bool isValidToExcute = true;
Debug.Print(txtEmail.Text);
output:
So, you might want to put a break point in, or simple add some debug.prints, and see which text box controls are "empty". But, just looking at what you have, those text boxes should be ok.
And including page-load, shows that you not say running the "clear" routine you have. (so, having included the page load event eliminates about 100 possible issues here. This is VERY much why posting some of your code allows the public here to eliminate a 100 "back and forth" suggestions.) So, for example, had you included "clear" routine in page load, then of course page load fires each and every time BEFORE a button click event, so code in page load is VERY OFTEN suspect here. But, since you don't have code in page load event, we scratch that off the table.
So, far, the controls look to have values, but I suggest you add a break point, or some debug.prints as per above to be 100% sure that the controls in fact do not have values.
Also, just pasting in some of the markup, we see things like this:
So, you do have stray "garbage" in a number of places. (not good).
As it stands, with the posted markup, I MOST certainly do get/see/have/enjoy/observe that the text boxes are intact, do have values.
Given we can't re-produce your issue?
I suggest creating a blank new page, drop in some of those controls, and try a test button - (don't even bother with the database save code - we NOT gone that far down the debugging road just yet).
So, only thing so far?
Are you 100% sure the text boxes don't have values, and you tested this BEFORE any of the database save code runs?
and do remove the stray "required" markup in that txtEmail box, the editor even HONKS OUT AT YOU that the markup is bad as per above screen shot.
In fact, drop in another button on the form, and its only job would be to debug print out the text boxes - does that work?
As it stands now, you don't have a re-producable error, and the community in general here has not, does not see your error, nor are we the viewing public EVEN able to re-produce that these text boxes don't have values.
As a result, there information we don't have to re-produce the error.
I suggest building a page with just the txtEmail that is blank, and a simple button. if that works, then start adding markup from that other page until it stops working, since we here can't re-produce your issue with the provided code and markup you have provided.
And, since you using a master page, then check if page load in master page has any code that runs on page load.

Trying to apply bootstrap styles in ASP.net webform

I have a text box which has an asp:RegularExpressionValidator attached to it as so
<div class="form-group col-sm-6 <%= (revAlertValue.IsValid == false ? "has-error" : "") %>">
<label for="AlertValue" class="control-label col-sm-4">Alert Value</label>
<div class="col-sm-4 input-group">
<span class="input-group-btn">
<asp:Button ID="btnMediumValue" CssClass="btn btn-warning" runat="server" Text="Low" OnClientClick="btnMediumValue_Click" OnClick="btnMediumValue_Click" />
</span>
<asp:TextBox CssClass="form-control text-center" CausesValidation="true" ID="tbAlertValue" runat="server" MaxLength="4" />
<asp:RegularExpressionValidator ID="revAlertValue" runat="server"
ControlToValidate="tbAlertValue" ErrorMessage=""
ValidationExpression="^[1-9]\d*$" />
<asp:RequiredFieldValidator ID="rfvAlertValue" runat="server" ControlToValidate="tbAlertValue" />
<span class="input-group-btn">
<asp:Button ID="btnHighValue" CssClass="btn btn-danger" runat="server" Text="High" OnClientClick="btnHighValue_Click" OnClick="btnHighValue_Click" />
</span>
</div>
I'm basically trying to apply the has-error class to my form-group if the regular expression validator is not valid. However, when I go to test and input text that would fail the regex validator the class is not applied.
I've tried writing the expression in other ways:
<%= (revResendEvery.IsValid == false) ? "has-error" : "" %>
<%= (revAlertValue.IsValid == false ? "has-error" : "") %>
I've thought maybe it has to be triggered when the submit button is pressed, or more code has to be added to the .aspx.cs handling the class addition after submit is pressed but that doesn't do the trick either.
In order to do this client side you need to tap into the client side code rendered by ASP.NET. Here is an example of some script you might include on your page to do so.
(function () {
var originalRegularExpressionValidator = RegularExpressionValidatorEvaluateIsValid;
RegularExpressionValidatorEvaluateIsValid = function (val) {
var originalValidationResult = originalRegularExpressionValidator(val);
if (!originalValidationResult) {
var formGroup = $("#" + val.controltovalidate).closest(".form-group");
formGroup.addClass("has-error");
}
return originalValidationResult;
}
})();
This, of course, assumes you have jQuery on the page (for the closest and addClass methods), but you can replace that with whatever you want.
Additionally, you may want to look into overriding the Page_ClientValidate function ASP.NET renders. There are many questions on StackOverflow that address how to do that.

Can't refresh dropdownlist in asp mvc 4 with chosen 0.9.12

I have few dropdownlist created by using Html.DropDownListFor like:
<div class="control-group">
<label class="control-label" for="inputPropertySurname">
City
<span class="form-required" title="This field is required.">*</span>
</label>
<div class="controls">
#*<input type="text" id="inputPropertySurname">*#
#Html.DropDownListFor(m => m.CityId, vmpa.Cities)
</div>
<!-- /.controls -->
</div>
but it always create a div area after selectbox
<div id="CityId_chzn" class="chzn-containerchzn-container-single
chzn-container-single-nosearch" style="width: 220px;" title="">
<a href="javascript:void(0)" class="chzn-single" tabindex="-1">
<span>Hà Nội</span>
<div><b></b></div>
</a>
<div class="chzn-drop" style="left: -9000px;">
<div class="chzn-search"><input type="text" autocomplete="off">
</div>
<ul class="chzn-results">
<li id="CityId_chzn_o_0" class="active-resultresult-selected" style="">Hà Nội</li>
<li id="CityId_chzn_o_1" class="active-result" style="">Hồ Chí Minh</li>
</ul>
</div>
</div>
i use ajax to get json array and replace new option in json aray to dropdownlist. select box have new option but it still show old option in div id City_chzn. i try many ways jquery but can't refresh it to show new value.
my ajax
<script type="text/javascript">
$(document).ready(function () {
$("#CountryId").chosen().change(function () {
var id = $("#CountryId option:selected").val();
DDLCountryChange(id);
});
});
function DDLCountryChange(id) {
var ddl = $("#CityId");
ddl.chosen();
ddl.prop("disabled", true);
$.ajax({
url: "/Post/GetCityInfoByCountry/" + id,
type: "GET",
dataType: "JSON",
success: function (result) {
ddl.empty();
var str = '';
$.each(result, function (index, value) {
ddl.chosen().append("<option value='" + value['Value'] + "'>" + value['Text'] + "</option>");
ddl.chosen().trigger('listzt:updated');
});
//ddl.prop('disabled', false);
}
});
}
</script>
UPDATE
Now i know why my code create a div. because my template using chosen jquery so it is reason why a div created after select. my chosen ver 0.9.12. i'm using
ddl.trigger('listzt:updated');
but chosen doesn't update new value to display
UPDATE
I have solved my problem. trigger('liszt:updated') not listzt:updated. All my bad :(
Please take a look at this very descriptive and helpful tutorial on how to work with DropDownLists, in an MVC environment, using JQuery and JSON rest services.
http://www.c-sharpcorner.com/UploadFile/4b0136/working-with-dropdownlist-in-mvc-5/
Strangely, the example they are using to make the tutorial, is almost exactly what you're doing here (Country, City, etc)...
Hope this helps!

Error Object reference not set when using UpdatePanel

I had this error " Object reference not set .... " , I had checked my
code and I got that the error in UpdatePanel , when i removed it the
code worked well but I must use it to prevent all page reload .
<div>
<fieldset style="width: 498px; text-align: right; padding: 5px; direction: rtl;">
<legend>what do y think ? </legend>
<div class="add-post">
<textarea class="textarea" cols="3" rows="3" runat="server" id="txpost"></textarea>
<asp:RequiredFieldValidator ID="RVAddPost" runat="server" ForeColor="Red" ErrorMessage="*"
ControlToValidate="txpost" ValidationGroup="AddUserPost">*</asp:RequiredFieldValidator>
</div>
<asp:UpdatePanel ID="UPAddUserPost" runat="server">
<ContentTemplate>
<div class="add-post-control">
<div class="post">
<asp:Button Text="Submit" runat="server" ID="btAddPost" OnClick="btAddPost_Click" ValidationGroup="AddUserPost" />
</div>
<div class="fileUpload btn btn-primary">
<div class="fileUpload btn btn-primary">
<span>
<img src="res/images/img.png" width="38" height="27" /></span>
<input type="file" runat="server" class="upload" id="FUFile" />
</div>
</div>
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btAddPost" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</fieldset>
<script type="text/javascript">
$('.textarea').focus(function () {
$(this).animate({
height: "80px"
}, 500);
$('.add-post-control').fadeIn(200);
});
</script>
</div>
Method:
protected void btAddPost_Click(object sender, EventArgs e)
{
AddpostfromFront();
}
private void AddpostfromFront()
{
if (FUFile.PostedFile.ContentLength != 0)
{
string tempVar = "~/res/Posts/" + FUFile.Value.ToString();
FUFile.PostedFile.SaveAs(Server.MapPath(tempVar));
ftier.Addpostfromfront(LoggedUserID, "4", txpost.Value, tempVar, DateTime.Now, DateTime.Now, false, false);
}
}
I think what you need to do instead of check the length of the file is to use a method that is built into PostedFile to check if there is a file to begin with.
if you look on the Microsoft page for PostedFile your code would look more like this
Private void AddpostfromFront() //I don't like your naming on this, should be AddPostFromFront
{
if (FUFile.HasFile)
{
string tempVar = "~/res/Posts/" + FUFile.Value.ToString();
FUFile.SaveAs(tempVar);
}
}
to use these methods you may have to use the ASP control instead of the HTML tag, <asp:FileUpload></asp:FileUpload> you will have to adjust the attributes to fit your situation and naming scheme. This would replace your HTML tag <input type="file" runat="server" class="upload" id="FUFile" />
I think that you are meshing two processes into one and getting confused as to what your code should be doing.
no clue what ftier is and why it has the same method name with the same bad naming scheme, or what it is doing with that information.
you should do this in 3 steps
upload the file
save the file
if you need to display the file then do so with the file that is saved, not the file that is being uploaded.

How to use getElementId for tag in an asp:Repeater

I have a div inside an asp:Repeater:
<ItemTemplate>
<div id="myDiv" style="display:none" />
</ItemTemplate>
</asp:Repeater>
<script type="text/javascript">
window.onload = function() {
document.getElementById('myDiv').style.display = 'block';
</script>
This works great except my div elements occur within a repeater which means only the first div is found. Could some please explain to me how to get all the divs in the ItemTemplate?
It is invalid to use the same id more than once on a page. Instead you'll have to use some other means of finding your elements, such as css class. jQuery makes this task easy.
$(".someClass").show();
However, you may not even need to do that. If all you are trying to do is change some styles on a set of elements under a common parent, you can just change the class name of the parent. Consider the following repeater:
<div id="repeaterParent">
<asp:Repeater runat="server">
<ItemTemplate>
<div class="repeaterItemDiv"></div>
</ItemTemplate>
</asp:Repeater>
</div>
Set up your css like this:
#repeaterParent .repeaterItemDiv
{
display: none;
}
#repeaterParent.showDivs .repeaterItemDiv
{
display: block;
}
Then use this JavaScript:
document.getElementById("repeaterParent").className = "showDivs";
Or, this jQuery:
$("#repeaterItemParent").addClass("showDivs");
You can't have multiple elements with the same ID value on the page. Use classes instead:
<ItemTemplate>
<div class="myDiv" style="display:none" />
</ItemTemplate>
Selecting the DIVs:
document.getElementsByClassName('myDiv')
// or
document.querySelectorAll('.myDiv')
// or
$('.myDiv') // jQuery
If you want to do this in javascript, you can do something like the following:
<div id="repeaterParent">
<asp:Repeater runat="server">
<ItemTemplate>
<div id="myDiv" style="display:none" runat="server"/>
</ItemTemplate>
</asp:Repeater>
</div>
<script type="text/javascript">
window.onload = function(){
//get the parent element
var ParentEle=document.getElementById('repeaterParent');
//get all the div tags within parent element
var AllDivInParentEle=ParentEle.getElementsByTagname('DIV');
//loop div elements and do what is required
for(var i=AllDivInParentEle.length-1;i>=0;i--){
AllDivInParentEle[i].style.display = 'block';
}
}
</script>
Using runat="server" for the div will give it its own id.
But if the div does not need to have an id, the javascript method will still work as it relies on the parent elements id.
So you could replace
<div id="myDiv" style="display:none" runat="server"/>
with
<div style="display:none">

Categories