I am using c# and razor to produce a list of invoices. Each invoice is a table row and has a huge list of notes against it. To avoid a massive amount of space between rows, I want to hide the notes and allow a pop to view it. It is currently:
<td>
#foreach (var invoiceLine in invoice.InvoiceLines)
{
<p>
<strong>#invoiceLine.Date.ToShortDateString() #invoiceLine.Username</strong> <br />
#Html.Raw(invoiceLine.Notes.Replace(Environment.NewLine, "<br />"))
#Html.Raw((invoiceLine.DueDate.HasValue ? "<br /><strong>Follow up:</strong> " + invoiceLine.DueDate.Value.ToShortDateString() : ""))
#Html.Raw(invoiceLine.Completed ? "<br /><strong>Completed</strong>" : "")
</p>
}
So what I want to do is to add the popup using jquery:
$(function () {
$('#clickMe').click(function (event) {
var mytext = $('#myText').val();
$('<div id="dialog">' + mytext + '</div>').appendTo('body');
event.preventDefault();
$("#dialog").dialog({
width: 600,
modal: true,
close: function (event, ui) {
$("#dialog").hide();
}
});
}); //close click
});
Then modify my code:
<td>
<h3 id="clickMe">Open Notes</h3>
<textarea cols="1" rows="75" id="myText" style="display:none">
#foreach (var invoiceLine in invoice.InvoiceLines)
{
<p>
<strong>#invoiceLine.Date.ToShortDateString() #invoiceLine.Username</strong> <br />
#Html.Raw(invoiceLine.Notes.Replace(Environment.NewLine, "<br />"))
#Html.Raw((invoiceLine.DueDate.HasValue ? "<br /><strong>Follow up:</strong> " + invoiceLine.DueDate.Value.ToShortDateString() : ""))
#Html.Raw(invoiceLine.Completed ? "<br /><strong>Completed</strong>" : "")
</p>
}
</textarea>
</td>
First problem is, that only the first row appears. I presume because my id is the same all the way down?
How do I make the dialog open for each row?
I am a newb at c# and js btw :)
First: The textarea makes no sense at all.
Then change the parts like this. See it working in the jsfiddle.
HTML
<td>
#foreach (var invoiceLine in invoice.InvoiceLines)
{
<p>
<strong>#invoiceLine.Date.ToShortDateString() #invoiceLine.Username</strong> <br />
#Html.Raw((invoiceLine.DueDate.HasValue ? "<br /><strong>Follow up:</strong> " + invoiceLine.DueDate.Value.ToShortDateString() : ""))
#Html.Raw(invoiceLine.Completed ? "<br /><strong>Completed</strong>" : "")
<h3 class="notesClick">Open Notes</h3>
<div class="notesHtml" style="display:none">
#Html.Raw(invoiceLine.Notes.Replace(Environment.NewLine, "<br />"))
</div>
</p>
}
</td>
JS
$(function() {
$('.notesClick').click(function(event) {
var notes = $(event.currentTarget).next('.notesHtml');
$("<div>").html(notes.html()).dialog();
});
});
Related
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!
I am currently having problem retaining the bootstrap tab after my fileupload postback.
The code is as follow
<script type="text/javascript">
$('#myTab a[href="#image"]').click(function (e) {
e.preventDefault();
$("#myTab").removeClass("active");
$(this).addClass('active');
$(this).tab('show');
})
$('#myTab a[href="#information"]').click(function (e) {
e.preventDefault();
$("#myTab").removeClass("active");
$(this).addClass('active');
$(this).tab('show');
})
$('#myTab a[href="#password"]').click(function (e) {
e.preventDefault();
$("#myTab").removeClass("active");
$(this).addClass('active');
$(this).tab('show');
})
$('#myTab a[href="#account"]').click(function (e) {
e.preventDefault();
$("#myTab").removeClass("active");
$(this).addClass('active');
$(this).tab('show');
})
</script>
Can anyone enlighten me on how to retain this bootstrap after postback?
Well, I had this issue already and I solved it this way:
Include a new HiddenField on your page and set its value to the first tab that need to be shown:
<asp:HiddenField ID="hidTAB" runat="server" Value="image" />
On every click function you defined to alternate the tabs, set the HiddenField value to the actual tab clicked.
document.getElementById('<%=hidTAB.ClientID %>').value = "image";
On your jQuery document.ready function, use the HiddenField value to alternate to the last tab opened before the Postback.
$(document).ready( function(){
var tab = document.getElementById('<%= hidTAB.ClientID%>').value;
$( '#myTab a[href="' + tab + '"]' ).tab( 'show' );
});
Here's the Bootstrap Tab Documentation and here's the jQuery Ready documentation
With reference to the above ideas here is how I did it (full code included)
In your HTML Page, in the < Head > section put
<script type="text/javascript">
$(document).ready(function () {
var tab = document.getElementById('<%= hidTAB.ClientID%>').value;
$('#myTabs a[href="' + tab + '"]').tab('show');
});
</script>
in the < body > section put a hiddenfield
<asp:HiddenField ID="hidTAB" runat="server" Value="#tab1" />
and also in the < body > section have the Bootstrap 3.0 related code
<ul class="nav nav-tabs" id="myTabs">
<li>Home page</li>
<li>another page</li>
</ul>
Do not set any tab to active (this is set by the initial Value="#tab1" of the Hiddenfield).
Then add a button to the tab2 DIV
like so:
<div class="tab-pane" id="tab2">
<asp:FileUpload ID="FileUpload2" runat="server" /> (note this example is for uploading a file)
<asp:Button ID="FileUploadButton" runat="server" Text="Upload File" onclick="FileUploadButton_Click" />
</div>
Lastly add your c# code behind to set the value of the hiddenfield
protected void FileUploadButton_Click(object sender, EventArgs e)
{
hidTAB.Value = "#tab2";
}
on posting back the JQuery will read the new value in the hiddenfield and show tab2 :)
Hope this helps someone.
Trev.
Please try this
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<div class="panel panel-default" style="width: 500px; padding: 10px; margin: 10px">
<div id="Tabs" role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li><a href="#personal" aria-controls="personal" role="tab" data-toggle="tab">Personal
</a></li>
<li>Employment</li>
</ul>
<!-- Tab panes -->
<div class="tab-content" style="padding-top: 20px">
<div role="tabpanel" class="tab-pane active" id="personal">
This is Personal Information Tab
</div>
<div role="tabpanel" class="tab-pane" id="employment">
This is Employment Information Tab
</div>
</div>
</div>
<asp:Button ID="Button1" Text="Submit" runat="server" CssClass="btn btn-primary" />
<asp:HiddenField ID="TabName" runat="server" />
</div>
<script type="text/javascript">
$(function () {
var tabName = $("[id*=TabName]").val() != "" ? $("[id*=TabName]").val() : "personal";
$('#Tabs a[href="#' + tabName + '"]').tab('show');
$("#Tabs a").click(function () {
$("[id*=TabName]").val($(this).attr("href").replace("#", ""));
});
});
</script>
After quite a long time trying out the bootstrap tab.. i decided to change to jquery tab.
In the first place, jquery tab also give the same problem i encounter in this situation..
but after much effort in looking for solution and trying out codes after codes.
i managed to find a solution
I'm really thankful to the person who provide this solution.
In this solution, it uses sessionStorage (to me, its a new stuff that i never heard of)
& the codes are
$(document).ready(function () {
var currentTabIndex = "0";
$tab = $("#tabs").tabs({
activate : function (e, ui) {
currentTabIndex = ui.newTab.index().toString();
sessionStorage.setItem('tab-index', currentTabIndex);
}
});
if (sessionStorage.getItem('tab-index') != null) {
currentTabIndex = sessionStorage.getItem('tab-index');
console.log(currentTabIndex);
$tab.tabs('option', 'active', currentTabIndex);
}
$('#btn-sub').on('click', function () {
sessionStorage.setItem("tab-index", currentTabIndex);
//window.location = "/Home/Index/";
});
});
In the above answer : the document ready function must be modified as below
$(document).ready(function () {
var selectedTab = $("#<%=hidTAB.ClientID%>");
var tabId = selectedTab.val() != "" ? selectedTab.val() : "tab1";
$('#myTab a[href="#' + tabId + '"]').tab('show');
$("#myTab a").click(function () {
selectedTab.val($(this).attr("href").substring(1));
});
});
So I have a simple ASP.NET/ C# generated html form where I have a list of textboxes that I want to be able to add and/or delete on the fly. There are pre-existing textboxes that are generated from a SP that look like this, with an 'add another textbox' button below:
<tr>
<td id="lblRole" style="vertical-align:top;" ><strong>The Role *</strong><br />(2000 characters maximum each)</td>
<td id="rolesColumn">
<div id="roles-1" class="div_row">
<textarea name="ctl00$mainContent$uxRolesList$ctl01" rows="5" cols="100"
id="ctl00_mainContent_uxRolesList_ctl01">yuyuy</textarea>
<input type="button" style="vertical-align:top;" value="X" class="remove-roles-btn" /><br /><br />
</div>
<input type="hidden" name="ctl00$mainContent$uxTxtBoxRolesCount"
id="ctl00_mainContent_uxTxtBoxRolesCount" value="1" />
</td>
</tr>
<tr>
<td> </td>
<td>
<input type="submit" name="ctl00$mainContent$uxAddRoleBtn"
value="Add a new role requirement"
id="ctl00_mainContent_uxAddRoleBtn" class="btn" />
</td>
</tr>
My jQuery is this:
$("#ctl00_mainContent_uxAddRoleBtn").live("click", (function (e) {
var rolesCounter = $('#ctl00_mainContent_uxTxtBoxRolesCount').val();
rolesCounter++;
if (rolesCounter < 10) {
var rolesCounterText = "0" + rolesCounter;
} else {
var rolesCounterText = rolesCounter;
}
$('#rolesColumn').append("<div id='roles-" + rolesCounter + "' class='div_row'><textarea name='ctl00$mainContent$uxRolesList$ctl" + rolesCounterText + "' rows='5' cols='100' id='ctl00_mainContent_uxRolesList_ctl" + rolesCounterText + "'></textarea><input class='remove-roles-btn' type='button' value='X' style='vertical-align:top;' /><br /><br /></div>");
e.preventDefault();
$('#ctl00_mainContent_uxTxtBoxRolesCount').val(rolesCounter);
}));
$(".remove-roles-btn").on("click", (function (e) {
$(this).parents('.div_row').remove();
e.preventDefault();
var rolesCounter = $('#ctl00_mainContent_uxTxtBoxRolesCount').val();
rolesCounter--;
$('#ctl00_mainContent_uxTxtBoxRolesCount').val(rolesCounter);
}));
But when I click to add a new textbox, all the textboxes are deleted.
And when I click to delete a textbox, nothing happens.
Thank you.
You have a typo in your code:
$("#ctl00_mainContent_uxAddRoleBtn").live("click", (function (e) {
//-------------------------------------------^----here you can see a "("
and here:
$(".remove-roles-btn").on("click", (function (e) {
//------------------^-----------------here
but i suggest you to use .on() method:
$(document).on("click", "#ctl00_mainContent_uxAddRoleBtn", function (e) {
and this:
$(document).on("click", ".remove-roles-btn", function (e) {
NOTE, be sure to be using jQuery 1.8.3 or lower, otherwise it will NOT work. All you have to do is change 'on' to 'live'
$(".remove-roles-btn").live("click", (function (e) {
Here is a simple example with your code that shows it working.
For remove button you need to use event delegation
$(document).on("click", "#rolesColumn .remove-roles-btn", function (e) {
e.preventDefault();
$(this).closest('.div_row').remove();
var rolesCounter = $('#ctl00_mainContent_uxTxtBoxRolesCount').val();
$('#ctl00_mainContent_uxTxtBoxRolesCount').val(rolesCounter - 1);
});
$(document).on("click", "#ctl00_mainContent_uxAddRoleBtn", function (e) {
var rolesCounter = $('#ctl00_mainContent_uxTxtBoxRolesCount').val();
rolesCounter++;
if (rolesCounter < 10) {
var rolesCounterText = "0" + rolesCounter;
} else {
var rolesCounterText = rolesCounter;
}
$('#rolesColumn').append("<div id='roles-" + rolesCounter + "' class='div_row'><textarea name='ctl00$mainContent$uxRolesList$ctl" + rolesCounterText + "' rows='5' cols='100' id='ctl00_mainContent_uxRolesList_ctl" + rolesCounterText + "'></textarea><input class='remove-roles-btn' type='button' value='X' style='vertical-align:top;' /><br /><br /></div>");
e.preventDefault();
$('#ctl00_mainContent_uxTxtBoxRolesCount').val(rolesCounter);
});
Demo: Fiddle
i am using knockout to display items on page. I have a list of groups ex: Group 1, Group 2,... each group is in it's own div. When i click on one of the groups it will open and display the items in the group. Some of my groups don't have any items to display and instead of it not showing anything i would like to change that to display: "No items in group"
I am having trouble doing this in the view in javascript and thought i would be able to do it in my knockout/jquery script
View:
<div class="accordion-group elements-by-item">
<div class="accordion-heading">
<a class="ui_title accordion-toggle text_x-large item_accordion_toggle" data-toggle="collapse" data-parent="#ByTimeIndex"
data-bind="text: Title() != null ? Title() : Identity(), attr: { 'href': '#itemContent_' + Id(), 'data-item-id': Id() }">
</a>
</div>
<div class="accordion-body collapse state-loading" data-bind="attr: { 'id': 'itemContent_' + Id(), 'data-item-id': Id() }">
#Html.Partial("_itemElements")
</div>
</div>
**_itemElements Page:**
<div class="accordion-inner no_border" data-bind="foreach: Children">
<div class="element">
........
</div>
<div>
knockout/Jquery js
$idx.ItemsRetrieved = new Array();
$idx.GetItemContent = function (element) {
var _itemId = element.attr('data-item-id');
var _elementData = $idx.itemData;
this.GetElementContent({
groupId: _itemId,
groupData: _elementData.items,
elementData: _elementData,
apiUrl: _courseIndexOptions.GetitemUrlPrefix + _itemId,
accordionBodySelector: '.accordion-body[data-item-id="' + _itemId + '"]',
accordionBtnSelector: 'a[data-item-id="' + _itemId + '"]',
viewModel: $idx.TimeViewModel
});
}
$idx.GetElementContent = function (options) {
if (linq.From($idx.ItemsRetrieved).Any(function (x) { return x == options.groupId })) {
$(options.accordionBodySelector).removeClass(constants.StateClasses.Loading);
return;
}
return Ajax.Get({
Url: options.apiUrl,
OnSuccess: function (data) {
var _items = linq.From(options.groupData);
var _itemToUpdate = _items.Where(function (x) { return x.Id == options.groupId; });
if (_itemToUpdate.Any()) {
_itemToUpdate.First().Children = data.Items;
}
ko.mapping.fromJS(options.elementData, options.viewModel);
sections.ElementArray.AddRange(data.Items);
$(options.accordionBodySelector).removeClass(constants.StateClasses.Loading);
$idx.ItemsRetrieved.push(options.groupId);
$(options.accordionBtnSelector).click();
}
});
how can i check if the children ItemsRetrieved = 0 and to set a message "No Items" to show in the view page?
You can do that :
<div class="accordion-inner no_border" >
<div data-bind="foreach: Children">
<div class="element">
</div>
</div>
<span data-bind="if : Children().length == 0">No items in group</span>
<div>
I hope it helps.
I am bit new in the c# programming, so I got stuck at one place. Need your help.
Actually through javascript I am generating table(4 columns) rows(having textboxes so that user can give inputs) as per as the user button click. As the number of rows are not fixed and we dont have the exact name of the textboxes so now my problem is how should we insert these rows into the sqlserver table?
should I use simply the loop for generating the name of the Textboxes for every user button click? and once we got the name for all controls can we insert these all through a single insert statement by using loop?
warm regrads,
ammy
If you're using just a regular html table add 'runat="server"' Tag with JS as well as html form controls then just change TableRow to HtmlTableRow and TextBox to HtmlInputText. All of those controls are in the System.Web.UI.HtmlControls namespace.
Assuming you're using the Table server control then it's just:
foreach (TableRow row in table.Rows)
{
var col2 = (TextBox)row.Cells[1].Controls[0];
//Do DB inserting stuff here With col2
string stringToInsert= col2 .Text;
}
I'm asuming you're using MVC..
You can start by creating a model such as:
public class YourModel
{
public IEnumerable<Users> users { get; set; }
}
Than create a view and add the rows dynamically by script given below:
<script type="text/javascript">
var Rows = 1;
// We already got the 0 element as html so start from 1
function AddUser() {
$("#UserTable").append('<tr>' +
'<td><input type="text" name="users[' + Rows + '].Name" style="width:100px;" /></td>' +
'<td><input type="text" name="users[' + Rows + '].Surname" style="width:100px;" /></td>' +
'<td><input type="text" name="users[' + Rows + '].Age" style="width:50px;" /></td>' +
'<td><input type="text" name="users[' + Rows + '].Date" style="width:70px;" /></td>' +
'</tr>');
// Add datepicker (this is an optional jQueryUI stuff)
$('input[name="users[' + Rows + '].Date"]').datepicker({ dateFormat: 'yy.mm.dd' });
// Go to next row
Rows = Rows + 1;
}
$(document).ready(function(){
// Create an empty row on load
AddUser();
// Than on each click add another row
$('input[type=button]').click(function(){ AddUser(); });
});
</script>
<div>
<table id="UserTable">
<tr>
<td><input type="text" name="user[0].Name" style="width:100px;" value="Berker" /></td>
<td><input type="text" name="user[0].Surname" style="width:100px;" value="Yüceer" /></td>
<td><input type="text" name="user[0].Age" style="width:50px;" value="24" /></td>
<td><input type="text" name="user[0].Date" style="width:70px;" value="2012.12.11" /></td>
</tr>
</table>
<input type="button" id="add" value="Add" />
</div>
fiddle for the script: http://jsfiddle.net/BerkerYuceer/YFecD/
From your controller you can get the values as show below:
// Thanks to LinqToSql you can define ur Sql-DB this way
YourDBDataContext db = new YourDBDataContext();
//
// POST: /YourForm/Edit
[HttpPost]
public ActionResult Edit(YourModel model)
{
try
{
// if users not empty..
if (model.users != null)
{
// Each User in Users
foreach (var user in model.users)
{ // Save it to your Sql-DB
db.Users.InsertOnSubmit(user);
db.SubmitChanges();
}
}
// Return
return RedirectToAction("Index");
}
catch (Exception ex)
{
return RedirectToAction("Error", new { ErrorMessage = "Message[" + ex.Message + "] - Source[" + ex.Source + "] - StackTrace[" + ex.StackTrace + "] - Data[" + ex.Data + "]" });
}
}
//
// GET: /YourForm/Error
public ActionResult Error(String ErrorMessage)
{
ViewData["Error"] = ErrorMessage;
return View();
}
simple as this!