I have a small problem. This is my HTML code fragment:
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr th:each="boiler : ${boilers}">
<td th:text="${boiler.value[0].model}"></td>
<td th:text="${boiler.value[0].brand}">
<td th:text="${#lists.size(boiler.value)}"></td>
<td th:text="${boiler.value[0].price}"></td>
<td>
<form>
<input type="text" th:class="boiler_model" th:id="boiler_model"
th:value="${boiler.value[0].model}" style="width:75px;"/>
<input class="form-control" type="number" id="quantity" style="width: 80px"/>
</form>
<td>
<button type="submit" class="btn btn-primary btn_submit" th:text="Add">Add</button>
</td>
</tr>
</tbody>
</table>
this is my jQuery:
$(document).ready(function () {
$('.btn_submit').on("click", function (e) {
e.preventDefault();
var quantity = $("#quantity").val();
// var boilerModel = $(".boiler_model").val();
var boilerModel = document.getElementById('boiler_model').value;
if (quantity === 0) {
alert("You must fill the quantity");
}
else if ($.trim(boilerModel) === "") {
alert("You must choose the model");
}
else {
var productIds = [];
$.ajax({
type: "POST",
url: "/order",
data: {quantity: quantity, model: boilerModel},
success: function (data) {
window.reload();
}
});
}
});
My problem is when I click the button it does read the quantity, but only reads the first model, even though it is printed in input correctly. I even removed the "hidden" type so I could see it for myself.
As you can see - the input is printed correctly, but when I debug this the controller always receives a quantity that is null if clicked on 2nd or 3rd model, but correct for the first one and model that is always the same. It always is "Super Hot Premium".
Could you please help me modify the table so it reads input separately from each row and then sends it to my controller?
Thank you very much.
There are several issues with your code :
you are looping through your boilers collection and generating a row for each loop. Each row contains two input fields with the same ids : quantity and boiler_model
in your click event handler, you are not looping through each row to submit data.
To fix this :
Follow this example to keep track of your loop status
Use the row index to generate unique ids for both your input fields
Store the size of your boilers collection in some hidden field to be able to send data from all rows
In your event handler, retrieve the size of your boilers collection and retrieve/send data for each row.
Here is a suggestion for your template (please note that I haven't tested it) :
<tr th:each="boiler, iterStatus : ${boilers}">
<td th:text="${boiler.value[0].model}"></td>
<td th:text="${boiler.value[0].brand}">
<td th:text="${#lists.size(boiler.value)}"></td>
<td th:text="${boiler.value[0].price}"></td>
<td>
<form>
<input type="text" th:class="boiler_model" id="boiler_model_${iterStatus.index}"
th:value="${boiler.value[0].model}" style="width:75px;"/>
<input class="form-control" type="number" id="quantity_${iterStatus.index}" style="width: 80px"/>
</form>
<td>
<button type="submit" class="btn btn-primary btn_submit" th:text="Add">Add</button>
</td>
</tr>
<input type="hidden" id="boilersLength" th:value="${#lists.size(boilers)}"/>
And your event handler :
$(document).ready(function () {
$('.btn_submit').on("click", function (e) {
var quantity, boilerModel, boilersLength, i;
e.preventDefault();
// retrieving the length of the boilers collection
boilersLength = $("#boilersLength").val();
// looping and sending data for each row :
for (i=0;i<boilersLength;i++) {
// retrieving data from both inputs :
quantity = $("#quantity_" + i).val();
boilerModel = $("#boiler_model_" + i).val();
if (quantity === 0) {
alert("You must fill the quantity");
}
else if ($.trim(boilerModel) === "") {
alert("You must choose the model");
}
else {
var productIds = [];
$.ajax({
type: "POST",
url: "/order",
data: {quantity: quantity, model: boilerModel},
success: function (data) {
// I wouldn't reload the window here, or you may reload before all data is sent
// window.reload();
}
});
}
}
});
}
You need to send a unique-id to identify on which Row the button is clicked so that you could get those values on your controller on the basis of that 'unique-id'
For Example :--
<tr th:each="boiler : ${boilers}">
<td th:text="${boiler.uniqueID}"></td>
<td th:text="${boiler.value[0].model}"></td>
<td th:text="${boiler.value[0].brand}">
<td th:text="${#lists.size(boiler.value)}"></td>
<td th:text="${boiler.value[0].price}"></td>
//Rest of your Code
<td>
<button type="submit" th:onclick="'javascript:addFunction(\'' + ${boiler.uniqueID} +'\');'" >Add</button>
</td>
</tr>
Related
I have a column input field in <td> which is in the loop due to this each Row has input field I got a javascript from which it storing local storage for input field but the issue is this javascript is working only for one input For Example :
I have five rows and due to loop input field generated for 5 rows automatically
What I am looking for is to store different values for each row..due to this script its not implementing for each row individually
Code
<input type="text" id="txt_1" onkeyup='saveValue(this);'/>
Javascript
<script type="text/javascript">
document.getElementById("txt_1").value = getSavedValue("txt_1"); // set the value to this input
document.getElementById("txt_2").value = getSavedValue("txt_2"); // set the value to this input
/* Here you can add more inputs to set value. if it's saved */
//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e){
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val);// Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue (v){
if (!localStorage.getItem(v)) {
return "";// You can change this to your defualt value.
}
return localStorage.getItem(v);
}
</script>
Image Showing
COde
<table class="table table-hover table-striped table-bordered" id="input-group">
<thead ><tr >
<th class="text-right"><?php echo "Contact No."; ?></th>
<th><?php echo "Followup 1 Date"; ?>
</th></tr></thead>
<tbody>
<?php
if (empty($enquiry_list)) {
?>
<?php
} else {
foreach ($enquiry_list as $key => $value) {
$current_date = date("d/m/Y");
$next_date = $value["next_date"];
if (empty($next_date)) { $next_date = $value["follow_up_date"];
}if ($next_date < $current_date) {
$class = "class='danger'";} else {
$class = ""; } ?>
<td class="mailbox-name"><?php echo $value['contact']; ?> </td>
<td class="mailbox-name" >
<div style="width:200px" style="height:200px" >
<input id="txt_<?= $row[id] ?>" onkeyup='saveValue(this);'
autocomplete="off" type="text" class="form-control" /></div></td>
</tr> </tr>
<?php }}?> </tbody> </table>
var inputGroup = document.getElementById('input-group');
var inputs = inputGroup.getElementsByTagName('input');
for(i=0;i<inputs.length;i++)
{
var id = inputs[i].getAttribute('id');
inputs[i].value = getSavedValue(id);
}
//Save the value function - save it to localStorage as (ID, VALUE)
function saveValue(e){
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val);// Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue (v){
if (!localStorage.getItem(v)) {
return "";// You can change this to your defualt value.
}
return localStorage.getItem(v);
}
<table id="input-group">
<tr>
<th>Text 1</th>
<th><input type="text" id="txt_1" onkeyup='saveValue(this);'/> </th>
</tr>
<tr>
<th>Text 2</th>
<th><input type="text" id="txt_2" onkeyup='saveValue(this);'/> </th>
</tr>
<tr>
<th>Text 3</th>
<th><input type="text" id="txt_3" onkeyup='saveValue(this);'/> </th>
</tr>
<tr>
<th>Text 4</th>
<th><input type="text" id="txt_4" onkeyup='saveValue(this);'/> </th>
</tr>
<tr>
<th>Text 5</th>
<th><input type="text" id="txt_5" onkeyup='saveValue(this);'/> </th>
</tr>
</table>
First of all you need to pass the event listener to the function that you have implemented, so i've solved it adding the events on the js file.
So instead of this:
<input type="text" id="txt_1" onkeyup='saveValue(this);'/>
You need to add the event on the js:
<input type="text" id="txt_1"/>
<input type="text" id="txt_2"/>
document.getElementById("txt_1").onkeyup = saveValue;
document.getElementById("txt_2").onkeyup = saveValue;
After this you need to access the id and the value from the event.target like this:
function saveValue(e) {
var id = e.target.id; // get the sender's id to save it .
var val = e.target.value; // get the value.
localStorage.setItem(id, val); // Every time user writing something, the localStorage's value will override .
}
Look at this codesandbox and see if it helps you out
Html is not reliable. You can use pure javascript code for cleaner way. Here is the working sample. Slackblitz https://stackblitz.com/edit/js-xycijp
function saveValue({ target }, index) {
localStorage.setItem(target.id, target.value); // Every time user writing
// OR
localStorage.setItem("target.id"+index, target.value); // Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return ""; // You can change this to your defualt value.
}
return localStorage.getItem(v);
}
document.querySelectorAll(".textField").forEach((elm, index) => {
elm.addEventListener("input", (e) => saveValue(e, index), false);
});
// Can ignore
window.saveValue = saveValue;
window.getSavedValue = getSavedValue;
<input class='textField' type="text" id="txt_1" />
<input class='textField' type="text" id="txt_2" />
I m trying to make the default value for the input field from an array in the state..i could
put the values but after that i am not able to change the field any more ( it works wrong i can add only one letter which is strange )
(PS: there is only one input in my code ) :
when i change the value="" in the input it works but i need this table to contain the values from the state.
state ={
splitAmount : [ {
SplitAmount0: this.props.data.amount1
},
{
SplitAmount1: this.props.data.amount2
},
{
SplitAmount2: this.props.data.amount3
}
],
}
}
StopTyping = (event) => {
const self = this;
if (self.state.typingTimeout) {
clearTimeout(self.state.typingTimeout);
}
self.setState({
val : event.target.value,
name : event.target.name,
id : event.target.id,
typingTimeout: setTimeout(function () {
self.setAmount(self.state.name,self.state.id,self.state.val);
}, 1000)
});
}
setAmount=(name,id,val)=>{
this.removeSplitAmount(name);
let some=0;
for(var i=0;i<this.state.splitAmount.length;i++){
let splitAmountState=`SplitAmount${i}`;
some+=this.state.splitAmount[i][splitAmountState]
}
let newAmount=this.props.data.amount-(some+val);
if(some>0){
let newValues=[{[val]:val},{[`SplitAmount${id+1}`]:newAmount}]
let newSplitAmount=this.state.splitAmount.concat(newValues);
this.setState({splitAmount:newSplitAmount})
}
}
return(
<div>
{this.state.splitAmount.map((splitAmount,i)=>{
const splitAmountKey=i
return(
<table className="middle-table"key={i}>
<tbody>
<tr>
<th>DueDate</th>
<th>Status</th>
<th>Amount</th>
<th>VAT</th>
<th>Otherexpenses</th>
<th>SocialSecurity</th>
<th>Miscelaneous</th>
<th>TaxableAmount</th>
</tr>
<tr style={{height:40}}>
<td className="middle-table-
col">05.12.2018</td>
<td className="middle-table-colright-align">
{this.props.data.status}</td>
<td className="middle-table-colright-align">
<input className="tax-value" value=
{this.state.splitAmount[i][`SplitAmount ${i}`]} id={i} name=
{'SplitAmount'+i}
onChange=
{this.StopTyping}/>
</td>
<td className="middle-table-colright-align">
{this.props.data.vatAmount}</td>
<td className="middle-table-colright-align">
{this.props.data.otherExpenses}</td>
<td className="middle-table-colright-align">
{this.props.data.socialSecurityAmountIncluded}</td>
<td className="middle-table-colright-align">
{this.props.data.miscellaneousDeduction}</td>
<td className="middle-table-colright-
align"style={{backgroundColor:'#F4F6F8'}}>1000</td>
</tr>
</tbody>
</table>
)
})}
If you update state, never use the current state array or object: we always have to create a new structure and update the state with that. So, in your 'StopTyping' method (which should be renamed to 'taxValueChangeHandler', really!), say:
let newSplitAmount=[...this.state.splitAmount].concat(newValues);
It creates a new array with all values of splitAmount and concatenates that with the new values.
Then, in the input element, I'd always explicitly pass the event, if the event is needed in the method:
onChange={(e) => StopTyping(e)}
Hope this already helps!
I am newbie to Angular js.'this' operator will be helpful, but no idea how to use it.
On Each First Column, user will input the data, and corresponding that data should be fetched. Now data is fetched from php to Angular js, but how to push the data from angular js to that text box using "this" operator.
For eg: If 'Y' is entered then, X and Z should be push to textbox
If 'Q' is entered then, P and R should be push to textbox.
HTML:
<tr>
<td><input type="text" ng-model="bot.Wo_Id" /></td>
<td><input type="text" ng-click="acc1()" ng-value="b_code" /</td>
<td><input type="text" ng-value="Pre_req" /></td>
<td><a href ng-click="remove_bottle(bottle)">Remove</a></td>
</tr>
<tr>
<td><a href ng-click="add_bottle()">Add</a></td>
</tr>
Angular Js:
$scope.acc1 = function () {
$http.get("machin.php", {
params: {
"W_id": this.bot.Wo_Id,
"MC": "Machine"
}
})
.success(function (response) {
var values = response.split("#");
$scope.b_code = ?
$scope.Pre_req = ? // what should be code here
});
};
machin.php
echo X."#".Z //for input Y
echo P."#".R //for input Q
I am unable to sort this problem.Please help me.Thanks in advance.
This should do the trick:
Don't use this, use $scope.
Change ng-value to ng-model
HTML
<tr>
<td><input type="text" ng-model="bot.Wo_Id" /></td>
<td><input type="text" ng-click="acc1()" ng-model="b_code" /</td>
<td><input type="text" ng-model="Pre_req" /></td>
<td><a href ng-click="remove_bottle(bottle)">Remove</a></td>
</tr>
<tr>
<td><a href ng-click="add_bottle()">Add</a></td>
</tr>
Angular:
$scope.acc1 = function () {
$http.get("machin.php", {
params: {
"W_id": $scope.bot.Wo_Id,
"MC": "Machine"
}
})
.success(function (response) {
var values = response.split("#");
$scope.b_code = values[0];
$scope.Pre_req = values[1];
});
};
Here's a plunker with example. I can't do the http request so I just resolve the promise.
https://plnkr.co/edit/f6EzxBlaFInJghNwsXaU?p=preview
In my mvc application i'm appending jquery autocomplete to the searchbox. my problem is at first time autocomplete is working fine. it shows the related items when ever we type in the searchbox. after selecting one of the item it will redirect to another page. where the searchbox autocomplete is not working.
Here is my code:
View:
<div id="targetDiv">
#Html.TextBox("name", null, new { id = "SearchBox", #class = "SearchBox" })
</div>
Javascript code:
<script type="text/javascript">
function load() {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(getItems);
}
$(document).ready(function () {
//We have used keyup event to track the user enter value in the textbox.
$("#SearchBox").keyup(function () {
//Fetching the textbox value.
var query = $(this).val();
//Calling GetItems method.
getItems(query);
});
function getItems(query) {
//var path = '#Url.Action("Suggest", "Home")';
//Here we are using ajax get method to fetch data from the list based on the user entered value in the textbox.
//We are sending query i.e textbox as data.
$.ajax({
url: '#Url.Action( "RemoteData", "Home")',
data: { "query": query },
type: 'POST',
dataType: 'json',
success: function (response) {
if (response.Data != null) {
if ($("#targetUL") != undefined) {
//If the UL element is not null or undefined we are clearing it, so that the result is appended in new UL every next time.
$("#targetUL").remove();
}
//assigning json response data to local variable. It is basically list of values.
data = response.Data;
//appending an UL element to show the values.
$("#targetDiv").append($("<ul id='targetUL'></ul>"));
//Removing previously added li elements to the list.
$("#targetUL").find("li").remove();
//We are iterating over the list returned by the json and for each element we are creating a li element and appending the li element to ul element.
$.each(data, function (i, value) {
//On click of li element we are calling a method.
$("#targetUL").append($("<li class='targetLI' onclick='javascript:appendTextToTextBox(this)'>" + value + "</li>"));
});
}
else {
//If data is null the we are removing the li and ul elements.
$("#targetUL").find("li").remove();
$("#targetUL").remove();
}
},
error: function (xhr, status, error) {
}
});
}
});
//This method appends the text oc clicked li element to textbox.
function appendTextToTextBox(e) {
//Getting the text of selected li element.
var textToappend = e.innerText;
//setting the value attribute of textbox with selected li element.
$("#SearchBox").val(textToappend);
//Removing the ul element once selected element is set to textbox.
$("#targetUL").remove();
}
</script>
controller code:
[HttpPost]
public ActionResult RemoteData(string query)
{
ArrayList list = new ArrayList();
SearchModel searchmodel = new SearchModel();
DataTable dt = new DataTable();
dt = searchmodel.FilteredSearchProductDisplay(query, 5, 0);
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
list.Add(dr["ProductName"]);
}
}
return Json(new { Data = list });
}
Redirected-Page:
if (#Model.dtProduct.Rows.Count > 0)
{
<div style="width:100%; height:auto;">#Html.Raw(#Model.dtProduct.Rows[0]["ThumbnailFilename"])</div>
<br />
if (ViewBag.RedirectedFromPage == "Search" || ViewBag.RedirectedFromPage == "OfferProduct")
{
if (#Model.dtProduct.Rows[0]["Stock"].ToString().Length > 0)
{
<table id ="priceTable">
<tr>
#if(#offerPrice > 0)
{
<td style="width:10%" class="divSizehPrice"><label>#Html.Raw(#Model.dtcurrentCurrency.Rows[0]["HTMLENTITY"])#APrice.ToString("0.00")</label></td>
<td style="width:90%" class="divSizehPrice"><label>RRP </label><p>#Html.Raw(#Model.dtcurrentCurrency.Rows[0]["HTMLENTITY"])#Price.ToString("0.00")</p></td>
}
else
{
<td colspan=2 style="width:90%" class="divSizehPrice"><p>#Html.Raw(#Model.dtcurrentCurrency.Rows[0]["HTMLENTITY"])#APrice.ToString("0.00")</p></td>
}
</tr>
</table>
<div id="divPrice2"style="display:none">
<table>
<tr>
<td>#Html.Raw(#Model.dtcurrentCurrency.Rows[0]["HTMLENTITY"])</td>
<td><div id="PriceDiv2"></div></td>
</tr>
</table>
</div>
<br />
Change currency
<br />
Add to Shopping Cart
}
else
{
using (Html.BeginForm("SelectedProductDisplay", "Product", FormMethod.Post, new { ProductId = #Model.dtProduct.Rows[0]["ProductId"], ProductpriceId = #Model.dtProduct.Rows[0]["ProductPriceId"] }))
{
<b>Out of stock</b>
<br />
#*<p>Please enter your email address below and we will contact you when it comes back in to stock.</p>
<br />
<label>Email:</label> #Html.TextBoxFor(m => m.OutOfStockEmail, new { id = "emailid" })
<br />
<div id="erroremail" class="validationColor" style="width:100%; text-align:center"></div>
<label>#Model.OutOfStockStatus</label>
<input type="submit" value="Notify Me" onclick="return checkEmail()"/>*#
}
Continue Shopping
}
<br />
<div class="divSearchHeader">
<p>#Html.Raw(Model.dtProduct.Rows[0]["ProductName"])</p>
<br />
</div>
<div class="divSearchContent">
#Html.Raw(#Model.dtProduct.Rows[0]["ProductDescription"])
</div>
<div class="divSearchContent">
#Html.Raw(#Model.dtProduct.Rows[0]["Description"])
</div>
}
else
{
<table style="width:100%" id="priceTable1">
#if (offerPrice > 0)
{
<tr>
<td style="width:25%"><div class="divSizehPrice">#APrice.ToString("0.00")</div></td>
<td style="width:75%"><div class="divSizehPrice"><p><label>RRP </label>#Price.ToString("0.00")</p></div></td>
</tr>
}
else
{
<tr>
<td colspan=2 class="divSizehPrice"><p>#Html.Raw(#Model.dtcurrentCurrency.Rows[0]["HTMLENTITY"])#APrice.ToString("0.00")</p></td>
</tr>
}
</table>
<div id="divPrice1"style="display:none" class="divSizehPrice">
<table>
<tr>
<td>#Html.Raw(#Model.dtcurrentCurrency.Rows[0]["HTMLENTITY"])</td>
<td><div id="PriceDiv1"></div></td>
</tr>
</table>
</div>
<br />
Change currency
<br />
Add to Shopping Cart
<br />
<div class="divSearchHeader">
<p>#Html.Raw(Model.dtProduct.Rows[0]["Name"])</p>
<br />
</div>
<div class="divSearchContent">
#Html.Raw(#Model.dtProduct.Rows[0]["Description"])
</div>
}
}
else
{
<p>No records found.</p>
}
Please use live instead simple keyup:
$('selector').live('keyup',function(){
//your code
});
Try :
$('sel').on('keyup',function(){
//your code
});
Please try this
$("body").delegate("selector","keyup",function(e){//your code.})
Try this:
$('selector').on('input', function(){
// Do your stuff here
});
Check the 'input' event,
I have also used Jquery AutoComplete Search Box it is working fine the only difference is in Controller Code
public ActionResult Autocomplete(string term)
{
// Return the Result list store in searchResultList
return Json(searchResultList, JsonRequestBehavior.AllowGet);
}
Removed Httpost Attribute
While Returning Json, use the 2nd Overload Method JsonRequestBehavior.AllowGet
Hope it helps you, Please note I am using MVC4 VS 2010
i want to iterate through the table rows and get the id and name of each checkbox checked in each tr in the first td and save it in a new Object() called values ex: values.id, values.name
Thanks
<table>
<tr>
<td>
<input id="1" type="checkbox" name="name1" checked="checked">
</td>
<td>
Some input control 1
</td>
</tr>
<tr>
<td>
<input id="2" type="checkbox" name="name2">
</td>
<td>
Some input control 2
</td>
</tr>
</table>
Working example
aRecord is an array of objects with each object containing both the name and ID of each checked checkbox found in the table.
$(document).ready(function() {
var aRecord = [];
$('#your_table input:checkbox:checked').each(function() {
var oChkBox = {};
oChkBox.name = $(this).attr('name');
oChkBox.id = $(this).attr('id');
aRecord.push(oChkBox);
});
var i = aRecord.length;
while (i--) {
alert("Name: "+ aRecord[i].name + " ID: "+ aRecord[i].id);
}
});
http://jsfiddle.net/tracyfu/r6RMV/
var values = {};
$('tr input:checked').each(function(i) {
values[i] = [];
values[i].push($(this).attr('id'));
values[i].push($(this).attr('name'));
});
Will produce:
values = { [1, 'name1'] }
I'm leaving this solution as-is, since you specifically said you wanted to store the values in an object named values, but without knowing what you're going to do with the data, I would store the values in an array instead...