How can I filter some content added dynamically with jQuery? - dynamic

First of all, sorry for my english, I'm still learning :).
My problem is the next, I have added some HTML content dinamically with jQuery, specifically these inputs:
<td id="date"><input type="text" id="input_1" class="select" /></td>
<td id="date"><input type="text" id="input_2" class="select" /></td>
<td id="date"><input type="text" id="input_3" class="select" /></td>
<td id="date"><input type="text" id="input_4" class="select" /></td>
<td id="date"><input type="text" id="input_X" class="select" /></td>
The number of inputs depends how many register I have in my DB.
For the another hand, I have this code in jQuery that I used with the same content but it wasn't added dynamically. I tried to execute this script after add the content above:
$('input')
.filter(function() {
return this.id.match(/input_./);
})
.foo({
....
});
When I try to apply the same script with the dynamically content it doesn't work, it doesn't match anything.
I read about delegate() and live() method but I didn't understand how can use them in my situation because all the examples I saw it was for handlers events.
Anybody knows how can I solve this problem.
Thanks in advance.

$(document).on('change', 'input[id^=input_]', function() {
/* Do stuff */
});
So you could do something like this demo
// Wrap inside a document ready
// Read .on() docs (To ensure the elements...bla bla)
$(document).ready( function () {
input_index = 0;
setInterval(addInput, 1000);
$(document).on('change', 'input[id^=input_]', function() {
$(this).val($(this).attr('id'));
});
function addInput () {
$('<input type="text" id="input_'+input_index+'"/>')
.appendTo('#empty')
.change(); // <============================ Pay attention to this
input_index++;
}
});

Related

Vue js: How to add a class to the closest td on click of Button

I am new to Vue coming off of JS/JQuery. I have a table, and each row has 2 possible buttons and two inputs, all wrapped in <td>. When I click a button I want the nearest input to have a class added. In JQuery I would have used the closest method in selecting the neighbouring <td> Here is my Vue template syntax. Many thanks!
<tbody>
<tr v-for="child in registeredChildren">
<td class="col-2"><a :href="'/getchild/'+ child.child_id">{{child.childFirstName}}</a>&nbsp &nbsp {{child.childLastName}}</td>
<!--========TIME IN===========-->
<td class="col-3 pb-2"}"><input style="text-align:center;" class="form-control editChild initial" type="text" v-model="child.timeIn" ></td>
<td><button v-on:click="updateTimeIn(child)" class="btn btn-outline-success">Reset</button></td>
<!-- //========TIME Out ===========//-->
<td class="col-3 pb-2" ><input style="text-align:center;" class="form-control editChild" type="text" v-model="child.timeOut" ></td>
<td><button v-on:click="updateTimeOut(child)" class="btn btn-outline-success">Reset</button></td>
</tr>
</tbody>
Methods: I was thinking if I could add some code to the UpdateTimeIn and TimeOut methods, this could be an approach?
methods:{
updateTimeIn(child){
this.updatedChild = child;
console.log(child.child_id,child.timeIn)
axios.post('http://kidsclub.test/upDateChildTimeIn', {
child_id: child.child_id,
timeIn: child.timeIn,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
},
**NB** I have the same for updateTimeOut
You are using Vue, which unlike jQuery, means the data should drive the DOM. In Vue, you don’t have to consider selecting certain dom nodes.
I used to switch from jQuery to Vue, too. I have provided a demo, hope you can find ideas in it.
<button #click="onClick">click me</button>
<div class="fixed-classes" :class="{'dynamic-class': isClick}"></div>
data() {
return {
isClick: false
};
},
methods: {
onClick() {
this.isClick = !this.isClick;
}
}
You can run it online through the code sandbox link: codesandbox
I updated the code based on the comments in the code sandbox.

dynamically add input as well as dropdown in vuejs

I m trying to add a dynamical input along with dropdown for that i m using vue-serach-select let me show my code then issue in detail
<template>
<button #click="addRow1"></button>
<table class="table table-striped">
<thead>
<tr style="font-size: 12px; text-align: center;">
<th class="span2" >Product Name</th>
<th class="span2" >Unit</th>
</tr>
</thead>
<tbody id="product_table_body">
<tr v-for="(row, index) in rows">
<td><model-list-select :list="productname"
option-value="product_name"
option-text="product_name"
v-model="row.selectproduct"
placeholder="Search Product Name"
#searchchange="searchprd3">
</model-list-select>
</td>
<td>
<input class="form-control-sm" type="text" v-model="row.new1" disabled="disabled" style="width: 100px;">
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data () {
return {
productname3:[],
rows:[],
}
},
methods:{
addRow1(){
this.rows.push({})
},
searchprd3(search,index){
},
}
}
</script>
now if i click on button one more row is added with dropdown now my problem is that how i can differentiate productname according to dynamic create row i had tried like :list="productname{index},:list="productname.index but none of them worked and last thing i want to pass index parameter in searchprd3 function so i tried like this searchprd3(search,index) in function I m getting index but it throw error for search and if only pass index then also throw error however it work none of parameter is passed from select like this #searchchange="searchprd3" but in function i m not getting index value or is there anyother way to achieve this thing
updated
<tr v-for="(row, index) in rows">
<td><model-list-select :list="row.productname"
option-value="product_name"
option-text="product_name"
v-model="row.selectproduct"
placeholder="Search Product Name"
#searchchange="searchprd3">
</model-list-select>
</td>
</tr>
<script>
searchprd3(searchText,index){
var _this=this
this.$http.get('/api/companyproducts?filter[where][product_name][ilike]=%'+searchText+'%').then(function (response) {
_this.rows.push({productname:response.data})
}).catch(function (error) {
console.log("error.response");
});
},
</script>
i want select option list seprate for every row but my code throw error like "Cannot read property 'map' of undefined"
that is why row push not working for dynamic row is I m missing Something
update2
found my mistake
addRow1(){
this.rows.push({
productnamex:[],
unit:'',
qty:'',
amt:'',
cgst:'',
sgst:'',
igst:''})
},
problem is that i haven't initialize my dropdown at rows click now another problem is that why my drop not get populated
try like this
<template>
<model-list-select :list="row.productnamex"
option-value="product_name"
option-text="product_name"
v-model="row.selectproduct"
placeholder="Search Product Name"
#searchchange="searchprd3($event,index,row)" >
</model-list-select>
</template>
<script>
addRow1(){
console.log(this.rows)
this.rows.push({ productnamex:[],unit:'', qty:'',amt:'', cgst:'', sgst:'', igst:''})
},
searchprd3(searchText,index,row){
console.log(index)
var _this=this
console.log(row)
this.$http.get('/api/companyproducts?filter[where][product_name][ilike]=%'+searchText+'%').then(function (response) {
console.log(response.data)
row.productnamex=response.data
}).catch(function (error) {
console.log("error.response");
});
},
</script>
hope this will help you as well as other enjoy :D
you should be able to do:
:list="productname+index"
You need to manually pass the index into the callback together with the searchtext in order for your searchprd3 method to receive both values.
This is where the inline $event variable in your event listener comes into the action. The $event variable contains the value that is supposedly passed to your callback by the event.
So if you want to pass additional data into the callback aside from the data that is passed by the event, you can manually call the callback function and pass the $event together with the data that you want to pass which in this case, the index variable.
Your event listener should look like this:
#searchchange="searchprd3($event, index)"

Vue.js doesn't render table

My template is:
<tbody id="deliveries-table">
<tr v-for="item in deliveries">
<td class="table-view-item__col"></td>
<td class="table-view-item__col" v-bind:class="{ table-view-item__col--extra-status: item.exclamation }"></td>
<td class="table-view-item__col">{{item.number}}</td>
<td class="table-view-item__col">{{item.sender_full_name}}</td>
<td class="table-view-item__col" v-if="item.courier_profile_url">{{item.courier_full_name}}</td>
<td class="table-view-item__col" v-if="item.delivery_provider_url">{{item.delivery_provider_name}}</td>
<td class="table-view-item__col">
<span style="font-weight: 900">{{item.get_status_display}}</span><br>
<span>{{item.date_state_updated}}</span>
</td>
</tr>
</tbody>
My javascript code for render a lot of prepared data is:
var monitorActiveDeliveries = new ActiveDeliveries();
monitorActiveDeliveries.fillTable(allDeliveries);
class ActiveDeliveries {
constructor() {
this.table = new Vue({
el: '#deliveries-table',
data: {
deliveries: []
}
});
}
fillTable (d) {
this.table.deliveries = d;
}
}
But after script starts any render into tbody, i have just empty place in HTML.
Where i got some wrong?
First, although you can instantiate your Vue app on the <table> tag, usually you want just a single Vue instance on the whole page, so it might be better to make the Vue instance on one main div/body tag.
Second, I think your code could work (I don't know what your deliveries objects should look like...), but your fillTable() method is probably not getting called, i.e. deliveries are empty.
I made this working example based on your code: http://jsfiddle.net/wmh29mds/
Life is easier than it seems.
I got a mistake into this directive:
v-bind:class="{ table-view-item__col--extra-status: item.exclamation }"
I just forgot single quotas into class name, next variant is working:
v-bind:class="{ 'table-view-item__col--extra-status': item.exclamation }"

How to handle variable number of process variables in Camunda

I'm new to Camunda and didn't find any tutorial or reference explaining how to achieve the following:
When starting a process I want the user to add as many items as he likes to an invoice. On the next user task all those items and their quantity should be printed to somebody approving the data.
I don't understand yet how to get this 1:n relationship between a process and its variables working. Do I need to start subprocesses for each item? Or do I have to use a custom Java object? If so, how can I map form elements to such an object from within the Tasklist?
I got it working with the help of the links provided by Thorben.
The trick is to use JSON process variables to store more complex data structures. I initialize such lists in my "Start Event". This can be done either in a form or in my case in a Listener:
execution.setVariable("items", Variables.objectValue(Arrays.asList(dummyItem)).serializationDataFormat("application/json").create());
Note that I added a dummyItem, as an empty list would lose its type information during serialization.
Next in my custom form I load this list and can add/remove items. Using the camForm callbacks one can persist the list.
<form role="form" name="form">
<script cam-script type="text/form-script">
/*<![CDATA[*/
$scope.items = [];
$scope.addItem = function() {
$scope.items.push({name: '', count: 0, price: 0.0});
};
$scope.removeItem = function(index) {
$scope.items.splice(index, 1);
};
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('items');
});
// variables-fetched is not working with "saved" forms, so we need to use variables-restored, which gets called after variables-fetched
camForm.on('variables-restored', function() {
$scope.items = camForm.variableManager.variableValue('items');
});
camForm.on('store', function() {
camForm.variableManager.variableValue('items', $scope.items);
});
/*]]>*/
</script>
<table class="table">
<thead>
<tr><th>Name</th><th>Count</th><th>Price</th><th></th></tr>
</thead>
<tbody>
<tr ng-repeat="i in items">
<td><input type="text" ng-model="i.name"/></td>
<td><input type="number" ng-model="i.count"/></td>
<td><input type="number" ng-model="i.price"/></td>
<td>
<button class="btn btn-default" ng-click="removeItem($index)">
<span class="glyphicon glyphicon-minus"></span>
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button class="btn btn-default" ng-click="addItem()">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
</tr>
</tfoot>
</table>
</form>
Two things aren't working yet:
Field validation, e.g. for number fields
The dirty flag used on the "save" button doesn't get updated, when adding/removing rows

Dynamically added rows to table does not the get the Dojo style

I am working in ASP.Net MVC4 with Dojo. I have a strange problem when I am adding new rows to html table. I need to have a table which supports adding and removing rows and textboxes inside should have dojo style. I referred the post http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ ad tried to create the same thing. Let me explain my code. Below is my view
#section scripts {
<script type="text/javascript">
require(["dojo/parser", "dijit/form/TextBox", "dijit/form/Button"]);
</script>
}
<table id="servicesTable">
<tr>
<th>
<label id="lblSelectService">
Select</label>
</th>
<th>
<label id="lblServiceName">
Name</label>
</th>
<th>
<label id="lblTitle">
AE Title</label>
</th>
</tr>
#for (int i = 0; i < Model.Services.Count; i++)
{
#Html.Partial("_ServiceRow", Model.Services[i])
}
</table>
My partial view for rendering each row is like below
#model WebUI.Models.RemDevServiceViewModel
<tr>
<td>
#Html.CheckBoxFor(x => x.IsMarked,
new { id = #String.Format("Service[{0}]IsMarked", #Model.ID) })
</td>
<td>
<input style="width: 100px; id="Service[#Model.ID]Name"
name="Service[#Model.ID].Name" type="text"
data-dojo-type="dijit/form/TextBox" value="#Model.Name"/>
</td>
<td>
<input style="width: 100px;" id="Service[#Model.ID]Title"
data-dojo-type="dijit/form/TextBox"
name="Service[#Model.ID].Title" type="text"
value="#Model.Title" />
</td>
</tr>
I have an add button which will add new row to the table. The problem that I am facing is, new row does not get the dojo style and they are rendered as normal textboxes. Initially loaded rows are rendered as dojo style text boxes, but the newly added are not like that. My jquery function to add new rows is like below
function addNewService() {
$.ajax({
url: rootPath + "MyController/AddNewService",
type: "get",
cache: false,
success: function (html) {
$("#servicesTable tbody").append(html);
},
error: function (ts) {
alert("Error while adding services");
}
});
}
Can any one tell me how to solve this? Please note that I am aware about the existence of Dojo grid. I want to take the advantage of model binding and hence following this style
Try running the parser over the added nodes. Are you seriously loading jquery on the page as well? Anyway, with the code you've got, it's kind of tricky to select the just added nodes, but if you put the following inside the success method it might work.
var newNodes = $(html).appendTo("#servicesTable tbody");
require(["dojo/parser"], function(parser){
newNodes.forEach(function(node){
parser.parse(node);
});
});
If you parse over nodes that were already parsed, the parser will throw an error. Also, if you need to support older browsers you'll want to replace the forEach with a standard for loop.
Thanks a lot David for your reply. Your code did not work exactly, but I got the idea and below code is working for me. Please dont feel that I am answering my own question. I want to format the code properly and hence using this view. Once again thanks a lot
success: function (html) {
var newNodes = $(html).appendTo("#servicesTable tbody");
require(["dojo/_base/array", "dojo/parser"], function (array, parser) {
array.forEach(newNodes, function (node, i) {
parser.parse(node);
});
});