I'm trying to show the parent child elements in dropdown select list.as the following image
i have the code as in foreach
#helper GetOption(List<Project_Cost_Management_System.Models.ChartOfAccount> model1, Guid? parentid)
{
foreach (var item3 in model1.Where(s => s.ParentAccountId.Equals(parentid)))
{
var zs3 = model1.Where(s => s.ParentAccountId == item3.Id);
int count3 = zs3.Count();
if (count3 >= 0)
{
if(#item3.ParentAccountId == null)
{
<option value="#item3.Id">#item3.Name</option>
}
else
{
var cout = model1.Count();
<option value="#item3.Id"> #item3.Name #model1.Where(s => s.dataid == #item3.dataparentid).Select(d => d.Name).First(). </option>
}
}
if (count3 > 0)
{
#GetOption(model1, item3.Id)
}
}
}
but it showed as
How can i display as the first picture.
You can sort of achieve what you're looking for using <optgroup>, so your rendered HTML would end up being something like:
<option value="...">Professional Fees</option>
<optgroup label="Property Related Expenses">
<option value="...">Maintenance Contribution</option>
...
</optgroup>
...
The only problem you might have with this, is that your actual groupings are not valid options themselves, i.e. you can't pick "Property Related Expenses", because it's just a grouping label. You also can't really control your right aligned descriptive text this way. In general, the HTML select element is pretty restrictive and doesn't allow a whole lot of customization.
When you need more advance functionality, you must move some sort of library that creates a "control" that mimics the functionality of a select list with more customizable HTML elements. There's a million and one different such libraries out on the interwebs, but I'm particular fond of Select2.js. In particular to your scenario, see the section there on "Templating".
I Got Answer.
Adding another field in model class as Hierarchy.
Adding space using the hierarchy. I add my code for refer.
#helper GetOption(List<Project_Cost_Management_System.Models.ChartOfAccount> model1, Guid? parentid)
{
foreach (var item3 in model1.Where(s => s.ParentAccountId.Equals(parentid)))
{
var zs3 = model1.Where(s => s.ParentAccountId == item3.Id);
int count3 = zs3.Count();
if (count3 >= 0)
{
if (#item3.ParentAccountId == null)
{
<option value="#item3.Id">#item3.Name</option>
}
else
{
int str = #item3.Hierarchy * 3;
string str1 = " ".ToString().PadRight(str);
str1 = str1.Replace(" ", "\u00a0");
<option value="#item3.Id">#str1 #item3.Name</option>
}
}
if (count3 > 0)
{
#GetOption(model1, item3.Id)
}
}
}
Related
Angular 6/7, Material Design.
Since I don't have access to the total number of items the item count is irrelevant (the box in the screen shot).
How do I remove the item count completely? Or alternatively show the page I'm currently on instead of the item count?
<mat-paginator
itemsPerPageLabel="Items per page"
(page)="changePage()"
[length]="resultsLength"
[pageSizeOptions]="[10, 100]">
</mat-paginator>
Remove the range label by inserting in global CSS
.mat-paginator-range-label {
display: none;
}
Insert page number instead (of course based on your API - you might not have the page info!) by inserting in your component
ngAfterViewChecked() {
const list = document.getElementsByClassName('mat-paginator-range-label');
list[0].innerHTML = 'Page: ' + this.page.toString();
}
and of course delete the CSS rule above!
Paginator now looks like this
I just modified Johan Faerch's solution to fit more to your question.
Create method which has two parameters, one for matpaginator and another for list of HTMLCollectionOf
paginatorList: HTMLCollectionOf<Element>;
onPaginateChange(paginator: MatPaginator, list: HTMLCollectionOf<Element>) {
setTimeout((idx) => {
let from = (paginator.pageSize * paginator.pageIndex) + 1;
let to = (paginator.length < paginator.pageSize * (paginator.pageIndex + 1))
? paginator.length
: paginator.pageSize * (paginator.pageIndex + 1);
let toFrom = (paginator.length == 0) ? 0 : `${from} - ${to}`;
let pageNumber = (paginator.length == 0) ? `0 of 0` : `${paginator.pageIndex + 1} of ${paginator.getNumberOfPages()}`;
let rows = `Page ${pageNumber} (${toFrom} of ${paginator.length})`;
if (list.length >= 1)
list[0].innerHTML = rows;
}, 0, paginator.pageIndex);
}
How to call this method? you can initialize this on ngAfterViewInit()
ngAfterViewInit(): void {
this.paginatorList = document.getElementsByClassName('mat-paginator-range-label');
this.onPaginateChange(this.paginator, this.paginatorList);
this.paginator.page.subscribe(() => { // this is page change event
onPaginateChange(this.paginator, this.paginatorList);
});
}
Include this method in your css file(note: do not include in the main styles.css file)
.mat-paginator-range-label {
display: none;
}
You can call onPaginateChange(this.paginator, this.paginatorList) functions wherever you need to change the page number details other than clicking on the navigation buttons on the mat paginator.
Result looks like this
I need to store both the name and the id of the option the user chooses in my SQL Database. Right now I am only storing the Id, by setting the value of the option to the current Id in the iteration.
#foreach (var item in selection)
{
if (item.Id.ToString() == contentId)
{
//dont mind this, just for displaying purposes
}
else
{
<option value="#item.Id" #(Request.Form["førstePrio"] != null && Request.Form["førstePrio"].ToString().Equals(item.Name.ToString()) ? " selected" : "")>#item.Name</option>
}
}
How can I store the #item.Name value as well in a separate Request.Form?
Edit:
#{
var selection = Model.Content.Site().FirstChild("Sprog").FirstChild("sommerhuse").Children()
.Where(x => x.IsVisible());
}
At the moment, the item.id is the value of the selection.
What you'd actually want to receive on the surface controller at this point would be the item / model itself
There's an example of such a controller here;
https://our.umbraco.org/documentation/Reference/Templating/Mvc/forms#creating-the-surfacecontroller-action
So you would want to post the whole object to this controller. From there you would be able to get whatever properties you needed from the model, in order to save them to the DB.
It would be something like
<option value="#item" #(Request.Form["førstePrio"] != null && Request.Form["førstePrio"].ToString().Equals(item.Name.ToString()) ? " selected" : "")>#item.Name</option>
I am not sure if Select tag is the best way to go, but here is what I have:
<select size="20" style="width:25%;">
<option>State 01</option>
<option>City 01</option>
<option>City 02</option>
<option>City 03</option>
<option>State 02</option>
<option>City 01</option>
<option>State 03</option>
<option>City 01</option>
<option>City 02</option>
</select>
Currently I am seeking advice and suggestions. Long story short, this box will be placed next to a map and when a specific state is selected, it will be shown on the map and I am hoping to show a list of cities for that state (only when the state is selected, not before). And then the user can select a city from the options to see on the map. If another state is selected, a new "dropdown" of cities will be shown for the newly selected state and the previously selected state's cities will go into hiding again.
I have seen code with select optgroup tag (https://stackoverflow.com/a/9892421/5003918), but I am wanting the hide-show functionality as well.
Should I just have two separate select boxes? One with states filled in, and another (initially empty) which will be filled in with cities when a state is selected? Or perhaps an unordered list? Zero or one state will be selected at any given time.
There are couple of ways to achieve what you're looking for. One way to have two separate drop-down menus , one for states and one for cities that got populated automatically based on the selected state.
Next thing will be , the data source , where would you get the list of states/cities with association (which cities belong to which state). Once again there are a lot of options here , In the example i am sharing , I chose a JSON ' s like structure but you can pick anything else.
I used pure JS code but you can easily use another library suck as JQuery and it will shorten the lines of code.
JS CODE
var States = [{
key: 13,
name: "State1",
cities: ["City1", "City2", "Silver Spring"]
}, {
key: 2,
name: "State2",
cities: ["City5", "City9", "City8","San Diego"]
}];
//populate states
for (var i = 0; i < States.length; i++) {
var opt = States[i];
var el = document.createElement("option");
el.textContent = opt.name;
el.value = opt.key;
StatesList.appendChild(el);
}
//Populate initial cities
populateCities();
//populate cities
function populateCities() {
//clear the cities list
document.getElementById('CitiesList').options.length = 0;
var e = document.getElementById("StatesList");
var selectedState = e.options[e.selectedIndex].value;
var listOfCities;
for (var i = 0; i < States.length; i++) {
if (States[i].key == selectedState) {
listOfCities = States[i].cities;
break;
}
}
//populate Cities DropDown menu
for (var i = 0; i < listOfCities.length; i++) {
var opt = listOfCities[i];
var el = document.createElement("option");
el.textContent = opt;
el.value = opt;
CitiesList.appendChild(el);
}
}
HTML
<div class="DDStyle" id="states" onChange="populateCities()">
States :
<select id="StatesList" class="DDStyle" >
</select>
</div>
<div id="Cities" class="DDStyle">
Cities :
<select id="CitiesList" class="DDStyle">
</select>
</div>
http://codepen.io/anon/pen/wKzqYG
When adding a derived column to a data flow with ezAPI, I get the following warnings
"Add stuff here.Inputs[Derived Column Input].Columns[ad_zip]" on "Add
stuff here" has usage type READONLY, but is not referenced by an
expression. Remove the column from the list of available input
columns, or reference it in an expression.
I've tried to delete the input columns, but either the method is not working or I'm doing it wrong:
foreach (Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSInputColumn100 col in derFull.Meta.InputCollection[0].InputColumnCollection)
{
Console.WriteLine(col.Name);
derFull.DeleteInputColumn(col.Name);
}
I have the following piece of code that fixes the problem.
I got it from a guy called Daniel Otykier. So he is propably the one that should be credited for it... Unlesss he got it from someone else :-)
static public void RemoveUnusedInputColumns(this EzDerivedColumn component)
{
var usedLineageIds = new HashSet<int>();
// Parse all expressions used in new output columns, to determine which input lineage ID's are being used:
foreach (IDTSOutputColumn100 column in component.GetOutputColumns())
{
AddLineageIdsFromExpression(column.CustomPropertyCollection, usedLineageIds);
}
// Parse all expressions in replaced input columns, to determine which input lineage ID's are being used:
foreach (IDTSInputColumn100 column in component.GetInputColumns())
{
AddLineageIdsFromExpression(column.CustomPropertyCollection, usedLineageIds);
}
var inputColumns = component.GetInputColumns();
// Remove all input columns not used in any expressions:
for (var i = inputColumns.Count - 1; i >= 0; i--)
{
if (!usedLineageIds.Contains(inputColumns[i].LineageID))
{
inputColumns.RemoveObjectByIndex(i);
}
}
}
static private void AddLineageIdsFromExpression(IDTSCustomPropertyCollection100 columnProperties, ICollection<int> lineageIds)
{
int lineageId = 1;
var expressionProperty = columnProperties.Cast<IDTSCustomProperty100>().FirstOrDefault(p => p.Name == "Expression");
if (expressionProperty != null)
{
// Input columns used in expressions are always referenced as "#xxx" where xxx is the integer lineage ID.
var expression = expressionProperty.Value.ToString();
var expressionTokens = expression.Split(new[] { ' ', ',', '(', ')' });
foreach (var c in expressionTokens.Where(t => t.Length > 1 && t.StartsWith("#") && int.TryParse(t.Substring(1), out lineageId)))
{
if (!lineageIds.Contains(lineageId)) lineageIds.Add(lineageId);
}
}
}
Simple but not 100% Guaranteed Method
Call ReinitializeMetaData on the base component that EzApi is extending:
dc.Comp.ReinitializeMetaData();
This doesn't always respect some of the customizations and logic checks that EzAPI has, so test it carefully. For most vanilla components, though, this should work fine.
100% Guaranteed Method But Requires A Strategy For Identifying Columns To Ignore
You can set the UsageType property of those VirtualInputColumns to the enumerated value DTSUsageType.UT_IGNORED using EzApi's SetUsageType wrapper method.
But! You have to do this after you're done modifying any of the other metadata of your component (attaching other components, adding new input or output columns, etc.) since each of these triggers the ReinitializeMetaData method on the component, which automatically sets (or resets) all UT_IGNORED VirtualInputColumn's UsageType to UT_READONLY.
So some sample code:
// define EzSourceComponent with SourceColumnToIgnore output column, SomeConnection for destination
EzDerivedColumn dc = new EzDerivedColumn(this);
dc.AttachTo(EzSourceComponent);
dc.Name = "Errors, Go Away";
dc.InsertOutputColumn("NewDerivedColumn");
dc.Expression["NewDerivedColumn"] = "I was inserted!";
// Right here, UsageType is UT_READONLY
Console.WriteLine(dc.VirtualInputCol("SourceColumnToIgnore").UsageType.ToString());
EzOleDbDestination d = new EzOleDbDestination(f);
d.Name = "Destination";
d.Connection = SomeConnection;
d.Table = "dbo.DestinationTable";
d.AccessMode = AccessMode.AM_OPENROWSET_FASTLOAD;
d.AttachTo(dc);
// Now we can set usage type on columns to remove them from the available inputs.
// Note the false boolean at the end.
// That's required to not trigger ReinitializeMetadata for usage type changes.
dc.SetUsageType(0, "SourceColumnToIgnore", DTSUsageType.UT_IGNORED, false);
// Now UsageType is UT_IGNORED and if you saved the package and viewed it,
// you'll see this column has been removed from the available input columns
// ... and the warning for it has gone away!
Console.WriteLine(dc.VirtualInputCol("SourceColumnToIgnore").UsageType.ToString());
I was having exactly your problem and found a way to solve it. The problem is that the EzDerivedColumn has not the PassThrough defined in it's class.
You just need to add this to the class:
private PassThroughIndexer m_passThrough;
public PassThroughIndexer PassThrough
{
get
{
if (m_passThrough == null)
m_passThrough = new PassThroughIndexer(this);
return m_passThrough;
}
}
And alter the ReinitializeMetadataNoCast() to this:
public override void ReinitializeMetaDataNoCast()
{
try
{
if (Meta.InputCollection[0].InputColumnCollection.Count == 0)
{
base.ReinitializeMetaDataNoCast();
LinkAllInputsToOutputs();
return;
}
Dictionary<string, bool> cols = new Dictionary<string, bool>();
foreach (IDTSInputColumn100 c in Meta.InputCollection[0].InputColumnCollection)
cols.Add(c.Name, PassThrough[c.Name]);
base.ReinitializeMetaDataNoCast();
foreach (IDTSInputColumn100 c in Meta.InputCollection[0].InputColumnCollection)
{
if (cols.ContainsKey(c.Name))
SetUsageType(0, c.Name, cols[c.Name] ? DTSUsageType.UT_READONLY : DTSUsageType.UT_IGNORED, false);
else
SetUsageType(0, c.Name, DTSUsageType.UT_IGNORED, false);
}
}
catch { }
}
That is the strategy used by other components. If you want to see all the code you can check my EzApi2016#GitHub. I'm updating the original code from Microsoft to SQL Server 2016.
So I have some code that dynamically creates an ASP.NET form based on an XML input file. I'm trying to add attributes to the controls at run time and I'm having some weird issues with list items.
My Server Side Code looks something like this:
Me.radioButtonList = New RadioButtonList()
Me.dropDownList = New DropDownList()
Me.listControl = Nothing
If controlType = "dropdown" Then
Me.listControl = Me.dropDownList
Else
Me.listControl = Me.radioButtonList
End If
For Each ansElement As Answer In strAnswers
Dim newListItem = New ListItem(ansElement.AnswerText, ansElement.AnswerText)
If ansElement.ActionID IsNot Nothing AndAlso ansElement.ActionID <> "" Then
newListItem.Attributes.Add("actionID", ansElement.ActionID)
End If
Me.listControl.Items.Add(newListItem)
Next
Me.listControl.ID = controlID
Me.Controls.Add(Me.listControl)
The problem is when I run the code and the page is render the attributes are being added to the proceeding span tag of the control not the input item itself. So the rendered HTML ends up looking like this.
<span actionID="1">
<input id="lst_dynamic_MedIllnesses_0" name="ctl00$MainContentPlaceHolder$FormGenerator1$lst_dynamic_MedIllnesses$lst_dynamic_MedIllnesses_0" value="None" type="checkbox">
<label for="lst_dynamic_MedIllnesses_0">None</label>
</span>
What do I have to do to get the actionID attribute to be added to the actual input control and not the span tag?
Thanks!
I suppose you are talking about RadioButtonList. The problem with it is that it uses RadioButton control, and it has 3 attributes properties - Attributes, InputAttributes and LabelAttributes. Each of them is used for specific html element.
The problem with RadioButtonList, is that it uses just Attributes property, and doesn't use InputAttributes. Here is code of RadioButtonList.RenderItem method:
protected virtual void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
{
if (repeatIndex == 0)
{
this._cachedIsEnabled = this.IsEnabled;
this._cachedRegisterEnabled = this.Page != null && !this.SaveSelectedIndicesViewState;
}
RadioButton controlToRepeat = this.ControlToRepeat;
int index1 = repeatIndex + this._offset;
ListItem listItem = this.Items[index1];
controlToRepeat.Attributes.Clear();
if (listItem.HasAttributes)
{
foreach (string index2 in (IEnumerable) listItem.Attributes.Keys)
controlToRepeat.Attributes[index2] = listItem.Attributes[index2];
}
if (!string.IsNullOrEmpty(controlToRepeat.CssClass))
controlToRepeat.CssClass = "";
ListControl.SetControlToRepeatID((Control) this, (Control) controlToRepeat, index1);
controlToRepeat.Text = listItem.Text;
controlToRepeat.Attributes["value"] = listItem.Value;
controlToRepeat.Checked = listItem.Selected;
controlToRepeat.Enabled = this._cachedIsEnabled && listItem.Enabled;
controlToRepeat.TextAlign = this.TextAlign;
controlToRepeat.RenderControl(writer);
if (!controlToRepeat.Enabled || !this._cachedRegisterEnabled || this.Page == null)
return;
this.Page.RegisterEnabledControl((Control) controlToRepeat);
}
controlToRepeat is that RadioButton, and it specifies only Attributes property and ignores InputAttributes.
I can suggest way to fix it - you can create new class that inherits RadioButtonList, and use it instead of default. Here is code of that class:
public class MyRadioButtonList : RadioButtonList
{
private bool isFirstItem = true;
protected override void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
{
if (isFirstItem)
{
// this.ControlToRepeat will be created during this first call, and then it will be placed into Controls[0], so we can get it from here and update for each item.
var writerStub = new HtmlTextWriter(new StringWriter());
base.RenderItem(itemType, repeatIndex, repeatInfo, writerStub);
isFirstItem = false;
}
var radioButton = this.Controls[0] as RadioButton;
radioButton.InputAttributes.Clear();
var item = Items[repeatIndex];
foreach (string attribute in item.Attributes.Keys)
{
radioButton.InputAttributes.Add(attribute, item.Attributes[attribute]);
}
// if you want to clear attributes for top element, in that case it's a span, then you need to call
item.Attributes.Clear();
base.RenderItem(itemType, repeatIndex, repeatInfo, writer);
}
}
A bit of description - it has isFirstItem property, as RadioButton control that used by it is created in runtime in the first access, so we need to call RenderItem before we can update InputAttrubutes property. So we call it once and send some stub HtmlTextWriter, so it won't be displayed twice. And then after that we just get this control as Controls[0], and for each ListItem we update InputAttributes values.
PS. Sorry, I didn't use VB.Net so control is written in C#