Knockout js string format index in template - asp.net-mvc

I am currently working on some Knockout js templating stuff. My requirement is I need to set the name of a field (input) with a combination of string and the index value of the row.
For example "xxx3".
I tried two options.
'xxx' + ko.utils.arrayIndexOf(viewModel.mycollection, $data)
and
'xxx' + $index
The first option always gives '-1' for my index value and the second option doesnt work
becasue seems like I can only use the $index value without any string concatenation.
Could someone let me know if I can concatenate a string value to $index value in knockout so that I can set that to the name property of an input field.
The final result I want should be like this.
<input class="text-box single-line" data-val="true"
data-val-required="The XXX field is required." id="XXX" type="text" name="XXX3">
Here is how my template looks like.
<table id ="editorRows" class="table">
<tbody data-bind='template: {name: "rowTemplate", foreach: Rules }'></tbody>
</table>
<script id="rowTemplate" type="text/html">
<tr data-bind="attr: { id: RuleKey }">
<td>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="The Name field is required." id="Name" type="text" data-bind="value: Name, attr: {name : 'Rules[' + $index + '].Name'}" />
<span class="field-validation-valid" data-bind="attr : { 'data-valmsg-for': 'Rules[' + $index + '].Name'}" data-valmsg-replace="true"></span>
</div>
</td>
</tr>
</script>

$index is an observable, so you would need to call it to retrieve the value. So assuming you are trying to set the values of the attributes to literally Rule[0].Name, you'd do this:
<input class="text-box single-line" data-val="true" data-val-required="The Name field is required." id="Name" type="text"
data-bind="value: Name, attr: {name : 'Rules[' + $index() + '].Name'}" />
<span class="field-validation-valid" data-valmsg-replace="true"
data-bind="attr : { 'data-valmsg-for': 'Rules[' + $index() + '].Name'}"></span>

Related

How to show password entered when checkbox is clicked?

in my form i have one checkbox so when i check the checkbox it should show password entered in password field.i am doing it using angular 7.
<div class="form-group">
<label for="Password" class="control-label">Password</label>
<div>
<input type="password" class="form-control" name="Password" ngModel
#pwd="ngModel" placeholder="Password" required pattern="^(?=.*[a-z])(?
=.*
[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]{8,}$">
<div *ngIf= pwd.invalid>
<small class="form-text text-danger" *ngIf=
pwd.errors.required>Password Required</small>
<small class="form-text text-danger"
*ngIf=pwd.errors.pattern>Minimum eight characters, at least one
uppercase letter, one lowercase letter, one number and one special
character.</small>
</div>
</div>
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input"
[disabled]="pwd.invalid">
<label class="form-check-label" id="show" for="exampleCheck1">Show
Password</label>
</div>
By checking the checkbox it should show password entered in the password field.
Hi and welcome on Stackoverflow!
Try to switch between type="password" and type="text" based on checkbox value.
Add #showPassword to your checkbox input, like that :
<input #showPassword type="checkbox" class="form-check-input" [disabled]="pwd.invalid">
Then on your password field :
<input type="showPassword.checked ? 'text' : 'password'" .... />
EDIT (in case you did not solve it yet, and for others) :
component.ts
// show/hide boolean variable
showPassword: boolean;
constructor() {
// init value in constructor
this.showPassword = false;
}
// click event, show/hide based on checkbox value
showHidePassword(e) {
this.showPassword = e.target.checked;
}
component.html
<input [type]="showPassword ? 'text' : 'password'" />
<input type="checkbox" (change)="showHidePassword($event)" > toggle view

Insert multiple check box values into multiple rows in one table?

I have multiple check box with the same input name like this
<input type="checkbox" name="pop[]" value="pop1">pop1<br>
<input type="checkbox" name="pop[]" value="pop2">pop2<br>
<input type="checkbox" name="pop[]" value="pop3">pop3<br>
<input type="checkbox" name="pop[]" value="pop4">pop4 <br>
<input type="checkbox" name="pop[]" value="pop5">pop5<br>
<input type="checkbox" name="pop[]" value="pop6">pop6 <br>
<input type="checkbox" name="pop[]" value="pop7">pop7<br>
<input type="checkbox" name="pop[]" value="pop8">pop8 <br>
The database table contains two columns (ID and POPNAME).
I need every pop checked to inserted into database in separate row but with the same ID so this is my PHP:
$pop = implode(',', $_POST['pop']);
mysql_query("INSERT INTO pops (id, popname) VALUES (LAST_INSERT_ID(), '$pop')");
But this not working. I tried to stick to this answer make explode then use for each but also not working. This is the foreach code:
$pop = implode(',', $_POST['pop']);
$pops = explode(',', $pop);
foreach ($pops as $pop )
{
mysql_query("INSERT INTO pops (id, popname) VALUES (LAST_INSERT_ID(), '$pop')");
}
Am I missing something!
It's solved.
Problem is $pop defined twice one as a var another one in foreach
So after rename the first var every thing ok
$popimp = implode(',', $_POST['pop']);
$pops = explode(',', $pop);
foreach ($pops as $pop )
{
mysql_query("INSERT INTO pops (id, popname) VALUES (LAST_INSERT_ID(), '$pop')");
}
PDO php:
Database connection code:
<?php
$dbhost = 'localhost';
$dbname = 'yourDB';
$dbuser = 'root';
$dbpass = '';
try {
$db = new PDO("mysql:host={$dbhost};dbname={$dbname}",$dbuser,$dbpass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo "Connection error: ".$e->getMessage();
}
?>
and php code:
$pop= implode(', ', $_POST['pop']);
$statement = $db->prepare("INSERT INTO popTable (pop) VALUES (?)");
$statement->execute(array($pop));
$success_message = "Order's has been inserted successfully.";
html:
<form action="pop_form">
<input type="checkbox" name="pop[]" value="pop1">pop1<br>
<input type="checkbox" name="pop[]" value="pop2">pop2<br>
<input type="checkbox" name="pop[]" value="pop3">pop3<br>
<input type="checkbox" name="pop[]" value="pop4">pop4 <br>
<input type="checkbox" name="pop[]" value="pop5">pop5<br>
<input type="checkbox" name="pop[]" value="pop6">pop6 <br>
<input type="checkbox" name="pop[]" value="pop7">pop7<br>
<input type="checkbox" name="pop[]" value="pop8">pop8 <br>
<input type="submit" value="Submit"/>
</form>

Editor template duplicated - applyBindings?

When I submit my form, foreach: integers is duplicating my Editor templates. Does anybody know why?
e.g. Suppose I submit 5 integers, when I click the add button, 5 editor templates will be added instead of 1.
Razor:
<div data-bind="foreach: integers">
#Html.EditorFor(model => model.Integers)
</div>
<input name="btn" type="button" data-bind="click: addInteger" value="+" />
<input name="btn" type="button" data-bind="click: removeInteger, enable: integers().length > 2" value="-" />
Editor Template:
#model IntegerSorter.Models.IntegerViewModel
<div class="input-group">
#Html.TextBoxFor(
m => m.IntegerValue,
new {
#class = "text-box single-line text-input large-input",
type = "number",
data_bind = "value: name,
uniqueName: true,
valueUpdate: 'afterkeydown',
attr:
{
id: 'Integers_' + $index() + '__IntegerValue',
name: 'Integers[' + $index() + '].IntegerValue'
}"
}
)
#Html.ValidationMessageFor(model => model.IntegerValue)
</div>
Knockout:
var viewModel = {
integers: ko.observableArray([
{ name: ko.observable(), value: "0" }
]),
addInteger: function () {
this.integers.push({
name: ko.observable()
});
},
removeInteger: function () {
this.integers.pop({
name: ko.observable()
});
},
save: function () {
ko.utils.postJson($("form")[0], integers);
}
};
ko.applyBindings(viewModel);
Edit:
HTML:
<div data-bind="foreach: integers">
<div class="input-group">
<input class="input-validation-error text-box single-line text-input large-input" data-bind="value: name, uniqueName: true, valueUpdate: 'afterkeydown', attr: { id: 'Integers_' + $index() + '__IntegerValue', name: 'Integers[' + $index() + '].IntegerValue' }" data-val="true" data-val-number="The field IntegerValue must be a number." data-val-regex="Enter an integer" data-val-regex-pattern="^-?\d+$" data-val-required="Enter an integer" id="Integers_0__IntegerValue" name="Integers[0].IntegerValue" type="number" value="">
<span class="field-validation-error" data-valmsg-for="Integers[0].IntegerValue" data-valmsg-replace="true">Enter an integer</span>
</div>
<div class="input-group">
<input class="input-validation-error text-box single-line text-input large-input" data-bind="value: name, uniqueName: true, valueUpdate: 'afterkeydown', attr: { id: 'Integers_' + $index() + '__IntegerValue', name: 'Integers[' + $index() + '].IntegerValue' }" data-val="true" data-val-number="The field IntegerValue must be a number." data-val-regex="Enter an integer" data-val-regex-pattern="^-?\d+$" data-val-required="Enter an integer" id="Integers_0__IntegerValue" name="Integers[0].IntegerValue" type="number" value="">
<span class="field-validation-error" data-valmsg-for="Integers[1].IntegerValue" data-valmsg-replace="true">Enter an integer</span>
</div>
<div class="input-group">
<input class="input-validation-error text-box single-line text-input large-input" data-bind="value: name, uniqueName: true, valueUpdate: 'afterkeydown', attr: { id: 'Integers_' + $index() + '__IntegerValue', name: 'Integers[' + $index() + '].IntegerValue' }" data-val="true" data-val-number="The field IntegerValue must be a number." data-val-regex="Enter an integer" data-val-regex-pattern="^-?\d+$" data-val-required="Enter an integer" id="Integers_0__IntegerValue" name="Integers[0].IntegerValue" type="number" value="">
<span class="field-validation-error" data-valmsg-for="Integers[2].IntegerValue" data-valmsg-replace="true">Enter an integer</span>
</div>
<div class="input-group">
<input class="input-validation-error text-box single-line text-input large-input" data-bind="value: name, uniqueName: true, valueUpdate: 'afterkeydown', attr: { id: 'Integers_' + $index() + '__IntegerValue', name: 'Integers[' + $index() + '].IntegerValue' }" data-val="true" data-val-number="The field IntegerValue must be a number." data-val-regex="Enter an integer" data-val-regex-pattern="^-?\d+$" data-val-required="Enter an integer" id="Integers_0__IntegerValue" name="Integers[0].IntegerValue" type="number" value="">
<span class="field-validation-error" data-valmsg-for="Integers[3].IntegerValue" data-valmsg-replace="true">Enter an integer</span>
</div>
<div class="input-group">
<input class="input-validation-error text-box single-line text-input large-input" data-bind="value: name, uniqueName: true, valueUpdate: 'afterkeydown', attr: { id: 'Integers_' + $index() + '__IntegerValue', name: 'Integers[' + $index() + '].IntegerValue' }" data-val="true" data-val-number="The field IntegerValue must be a number." data-val-regex="Enter an integer" data-val-regex-pattern="^-?\d+$" data-val-required="Enter an integer" id="Integers_0__IntegerValue" name="Integers[0].IntegerValue" type="number" value="">
<span class="field-validation-error" data-valmsg-for="Integers[4].IntegerValue" data-valmsg-replace="true">Enter an integer</span>
</div>
</div>
</div>

MVC view with two forms, why are both rendering to same action?

#using (Html.BeginForm("Unassign", "Terminals_DataGroups"))
{
#Html.HiddenFor(m => m.DeviceId)
#Html.HiddenFor(m => m.DataGroupId)
<input type="submit" value="Remove group from device" #(string.IsNullOrEmpty(Model.DataGroupName) ? "disabled=\"disabled\"" : "") />
}
#using (Html.BeginForm("Assign", "Terminals_DataGroups"))
{
#Html.HiddenFor(m => m.DeviceId)
<div class="editor-label">
#Html.LabelFor(model => model.DataGroups)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.DataGroupsSelectedItem, new SelectList(Model.DataGroups, "Value", "Text"))
#Html.ValidationMessageFor(model => model.DataGroupsSelectedItem)
</div>
<input type="submit" value="Assign Data Group" />
}
Yet the HTML renders as:
<form action="/Terminals_DataGroups/Assign" method="post">
<input data-val="true"
data-val-number="The field DeviceId must be a number."
data-val-required="The DeviceId field is required."
id="DeviceId"
name="DeviceId"
type="hidden"
value="15" />
<input data-val="true"
data-val-number="The field DataGroupId must be a number."
id="DataGroupId"
name="DataGroupId"
type="hidden"
value="1" />
<input type="submit" value="Remove group from device" />
</form>
<form action="/Terminals_DataGroups/Assign" method="post">
<input data-val="true"
data-val-number="The field DeviceId must be a number."
data-val-required="The DeviceId field is required."
id="DeviceId"
name="DeviceId"
type="hidden"
value="15" />
<div class="editor-label">
<label for="DataGroups">Data groups</label>
</div>
<div class="editor-field">
<select data-val="true"
data-val-number="The field DataGroupsSelectedItem must be a number."
id="DataGroupsSelectedItem"
name="DataGroupsSelectedItem">
<option value="2">DataGroup2</option>
<option value="3">DataGroup3</option>
<option value="5">New group</option>
</select>
<span class="field-validation-valid"
data-valmsg-for="DataGroupsSelectedItem"
data-valmsg-replace="true"></span>
</div>
<input type="submit" value="Assign Data Group" />
</form>
you must added ID tag and value
sory my english ;)

2 identical items in a list with the same id get id value modified in view

I have this view in which I need to display twice the same item. So I pass a list of my model and this list contains twice the same item.
Here's how I display them:
<p>
#using (Html.BeginForm("Confirm", "Inventory"))
{
<table>
<tr>
<th>Item Name</th>
(...)
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.DisplayFor(x => x[i].OtrObj.ObjName)</td>
(...)
#Html.HiddenFor(x => x[i].OtrObjID)
</tr>
}
</table>
<div class="float-right">
<input type="submit" value="Ready!"/>
</div>
}
</p>
I'm sure that it occurs in the view because just when I send the view each items in my list carries the right "ObjID".
But when the page is rendered, the result is like this:
item 1:
<input data-val="true" data-val-number="The field OtrObjID must be a number."
data-val-required="The OtrObjID field is required."
name="[0].OtrObjID" type="hidden" value="1" />
item 2:
<input data-val="true" data-val-number="The field OtrObjID must be a number."
data-val-required="The OtrObjID field is required."
name="[1].OtrObjID" type="hidden" value="2" />
Why? I really don't get it. Can anyone help me out on this?
Here is the HTML output for those items:
<p>
<form action="/Inventory/Confirm" method="post">
<table>
<tr>
<th>Item Name</th>
...
</tr>
<tr>
<td>Item one</td>
<td><input checked="checked" class="state1" name="[0].Destination" style="width: 50px" type="radio" value="State 1" /></td>
<td><input class="state2" name="[0].Destination" style="width: 50px" type="radio" value="State 2" /></td>
<td>
<input class="field1" data-val="true" data-val-number="The field m_Field1 must be a number." data-val-required="The m_Field1 field is required." name="[0].m_Field1" style="width:200px" type="text" value="0,99" />
<span class="field-validation-valid" data-valmsg-for="[0].m_Field1" data-valmsg-replace="false">Field 1 must be a number.</span>
</td>
<td>
<input class="field2" data-val="true" data-val-number="The field m_Field2 must be a number." data-val-required="The m_Field2 field is required." name="[0].m_Field2" style="width:200px" type="text" value="1,00" />
<span class="field-validation-valid" data-valmsg-for="[0].m_Field2" data-valmsg-replace="false">Field 2 must be a number.</span>
</td>
<td>
<input class="field3" data-val="true" data-val-number="The field m_Field3 must be a number." data-val-required="The m_Field3 field is required." name="[0].m_Field3" style="width:200px" type="text" value="1,00" />
<span class="field-validation-valid" data-valmsg-for="[0].m_Field3" data-valmsg-replace="false">Field 3 must be a number.</span>
</td>
<td>See other information</td>
<input data-val="true" data-val-number="The field OtrObjID must be a number." data-val-required="The OtrObjID field is required." name="[0].OtrObjID" type="hidden" value="1" />
<input data-val="true" data-val-number="The field ObjID must be a number." data-val-required="The ObjID field is required." name="[0].ObjID" type="hidden" value="1" />
<input name="[0].m_Field1" type="hidden" value="0,99" />
<input name="[0].m_Field2" type="hidden" value="1,00" />
<input name="[0].m_Field3" type="hidden" value="1,00" />
</tr>
<tr>
<td>Item 2</td>
<td><input checked="checked" class="state1" name="[1].Destination" style="width: 50px" type="radio" value="State 1" /></td>
<td><input class="state2" name="[1].Destination" style="width: 50px" type="radio" value="State 2" /></td>
<td>
<input class="field1" data-val="true" data-val-number="The field m_Field1 must be a number." data-val-required="The m_Field1 field is required." name="[1].m_Field1" style="width:200px" type="text" value="0,99" />
<span class="field-validation-valid" data-valmsg-for="[1].m_Field1" data-valmsg-replace="false">Field 1 must be a number.</span>
</td>
<td>
<input class="field2" data-val="true" data-val-number="The field m_Field2 must be a number." data-val-required="The m_Field2 field is required." name="[1].m_Field2" style="width:200px" type="text" value="1,00" />
<span class="field-validation-valid" data-valmsg-for="[1].m_Field2" data-valmsg-replace="false">Field2 must be a number.</span>
</td>
<td>
<input class="field3" data-val="true" data-val-number="The field m_Field3 must be a number." data-val-required="The m_Field3 field is required." name="[1].m_Field3" style="width:200px" type="text" value="1,00" />
<span class="field-validation-valid" data-valmsg-for="[1].m_Field3" data-valmsg-replace="false">Field 3 must be a number.</span>
</td>
<td>See other information</td>
<input data-val="true" data-val-number="The field OtrObjID must be a number." data-val-required="The OtrObjID field is required." name="[1].OtrObjID" type="hidden" value="2" />
<input data-val="true" data-val-number="The field ObjID must be a number." data-val-required="The ObjID field is required." name="[1].ObjID" type="hidden" value="2" />
<input name="[1].m_Field1" type="hidden" value="0,99" />
<input name="[1].m_Field2" type="hidden" value="1,00" />
<input name="[1].m_Field3" type="hidden" value="1,00" />
</tr>
</table>
<div class="float-right">
<input type="submit" value="Ready!"/>
</div>
</form>
</p>
The "problem" is that you have #model IEnumerable<Model> that'll force the [#] prefix.
One possible solution would be to wrap your Model inside a ViewModel.
public class ViewModel
{
public IEnumerable<Model> Models { get; set; }
}
And then use #model ViewModel
I'd also like to suggest the use of #foreach as it's cleaner.
#foreach (var item in Model.Models) {
<tr>
<td>
#Html.DisplayFor(x => item.ObjName)
(...)
#Html.HiddenFor(x => item.OtrObjID)
</td>
</tr>
}
Note: I put everything inside the <td> as it's not valid HTML to have anything other than <td> or <th> inside the <tr> tag. http://www.w3schools.com/tags/tag_tr.asp
You can use simple html hidden field control
<input type="hidden" value="x[i].OtrObjID" name="OtrObjID" />

Resources