As shown in the figure: The function to be realized is to click the add button at the top and dynamically add table rows at the bottom, and then the content in each row is traversed from the object.
Then I only have the lines written in the first html that have content and functions.
The row that comes out after clicking the button has no content and no function. (Note: The function refers to my first column and second column, which are the secondary linkage effects)
The following is the code: (I am a novice, and I am not very familiar with jq, so the writing is very messy, and it is a mixture of js and jq =-=, please give me some advice and guidance!)
<p class="clearfix" style="margin-left:200px;">
<button class="button2" style="border:1px solid #000">添加</button>
<form class="clearfix" style="float:left;margin-top:100px;">
<table id="b" border="1px solid #000">
<thead>
<tr class="zzz">
<th style="width:141px;">计算期类型</th>
<th style="width:281px;">期间</th>
<th style="width:141px;">征收方式</th>
</tr>
</thead>
<tbody id="zType_all">
<tr>
<td>
<select id="zType_time"></select>
</td>
<td>
<select id="zType_years" style="float:left;"></select>
<select id="month_quarter"></select>
</td>
<td>
<select id="zCollection">
<option value="chazhang">查账征收</option>
<option value="heding">核定征收</option>
</select>
</td>
</tr>
</tbody>
</table>
</form>
</p>
//点击按钮添加
$('.button2').on('click',function(){
var ccc = $('<tr><td><select id="zType_time"></select></td><td><select id="zType_years"></select><select id="month_quarter"></select></td><td><select id="zCollection"><option value="chazhang">查账征收</option><option value="heding">核定征收</option></select></td></tr>');
var ddd = $('#zType_all');
ddd.append(ccc);
$('#a').css({"background":"white","color":"#000"});
});
//下面是关于二级和三级联动的遍历
//这个是存储着option里信息的对象
var zType_chose = [
{
"name":"年终汇算","types":[
{"years":"2015年"},
{"years":"2016年"}
]
},
{
"name":"预缴-月度","types":[
{"years":"2015年","zType_time1":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]},
{"years":"2016年","zType_time1":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]}
]
},
{
"name":"预缴-季度","types":[
{"years":"2015年","zType_time1":["第一季度","第二季度","第三季度","第四季度"]},
{"years":"2016年","zType_time1":["第一季度","第二季度","第三季度","第四季度"]}
]
}
];
//下面是我实现联动的js代码
var zType_time = document.getElementById("zType_time");
var zType_years = document.getElementById("zType_years");
var month_quarter = document.getElementById("month_quarter");
var zType_all = document.getElementById("zType_all");
zType_time.options[0] = new Option("计算期类型");
zType_years.options[0] = new Option("请选择年");
month_quarter.options[0] = new Option("请选择月/季度");
// 循环第一步把计算期类型循环进select
for (var i = 0; i < zType_chose.length; i++) {
zType_time.options[zType_time.length] = new Option(zType_chose[i].name);
// 循环第二步,把第二列都循环进select
zType_time.onchange = function(){
zType_years.options.length = 0;
month_quarter.options.length = 0;
zType_years.options[zType_years.length] = new Option("请选择年");
month_quarter.options[month_quarter.length] = new Option("请选择月/季度");
for (var j = 0; j < zType_chose[zType_time.selectedIndex-1].types.length; j++) {
zType_years.options[zType_years.length] = new Option(zType_chose[zType_time.selectedIndex-1].types[j].years)
}
if(zType_time.options[zType_time.selectedIndex].text == "年终汇算"){
month_quarter.style.display = "none";
}else{
month_quarter.style.display = "inline-block";
}
}
zType_years.onchange = function(){
month_quarter.options.length = 0;
month_quarter.options[month_quarter.length] = new Option("请选择月/季度");
//循环另一个
for (var k = 0; k < zType_chose[zType_time.selectedIndex-1].types[zType_years.selectedIndex-1].zType_time1.length; k++) {
month_quarter.options[month_quarter.length] = new Option(zType_chose[zType_time.selectedIndex-1].types[zType_years.selectedIndex-1].zType_time1[k]);
};
}
};
I think maybe the content should be traversed when creating the rows of the table? But I don’t know how to do it, and what should I do with my function?
Waiting for a big guy online
tell me! Many thanks! urgent!
First of all, id can only appear once in a page and is unique. Only class can appear multiple times!
Statement
id
is the only attribute, that is, only one correspondingid
can appear in ahtml
file, and multipleclass
can be used;Requirement realization
The front-end part, from the framework to the functions, can all be solved using design patterns. To put it bluntly, they can all be solved using MVC, as in your example:
C -> Entire JS logic;
V -> Single line entry;
M -> filled data;
You can actually encapsulate this kind of thing with a closure, or make it into a processing class. Such as:
Continue to improve the script:
Explanation
Create a constructor to generate a structure with interactive encapsulation effect - component;
Add a series of methods to the component and create logic inside;
Closure encapsulation refers to only taking effect in
(function($){ /*code*/ })(jQuery);
;$.fn.remove
can ensure the security of the data on the page. Do not use$.fn.hide
;You can also use
AppRow.prototype.delete()
to extend delete operations, etc.;If you need to use
name
for data submission, you need to use the format ofname="row[index][name]"
, such as:name="row[1]['type']"
,name="row[1]['year']"
、name="row[1]['sub']"
;Final effect:
Online effect
https://jsfiddle.net/kxjyo7fp...
Put the code for traversing the data in the method where you click to add a row. The specific coordination is how to add a row and traverse one. You have to implement this yourself. I didn't look into it carefully. You are now a bit like a dynamically added element. You bind the event, and the result is bound in the HTML written, but the added element is not bound to the event
It is recommended to use the ui library directly. For jquery, you can choose easyui / bootstrap table
Event binding will be successfully bound after the page rendering is completed, and will not be automatically bound afterwards. That is, nodes added after the page is rendered cannot be bound. What we are talking about here is $('.a').click (...) This is a similar method because when it is compiled for the first time, an event will be bound to the class A on the page. If you dynamically condition several nodes with class a in JS, then adding them later will have no effect. , because the node added later does not exist when binding for the first time.
The solution is to use the on() method. For example, $('body').on('click','.a',fun(){}) This method is fine, because the body tag will exist no matter when. Therefore, there will be no situation where the node cannot be found and cannot be bound.
Of course, you can also write the function on the node yourself, but this is not recommended.
I rewrote part of the script to generate DOM using jQuery. For speed, I used some ES6 syntax. But the function is not completed yet
https://jsfiddle.net/jrhju549/1/
Then when I was thinking about cascading this part of things, I found a problem (about data):
From the data point of view, the optional data for monthly payment and quarter are the same no matter what year it is. Month is 12 months and quarter is 4 quarters. Then these data are actually fixed and can be written directly in HTML. In this way, when generating new rows, you only need to clone them first and then handle the details, which is much simpler.
However, another possibility cannot be ruled out, that is, your options are different every year. For example, 2015 is 12 months, 2016 is 8 months... (Of course, the possibility of this situation is very low), in this case, the select can be dynamically generated based on this data. Then before dynamically generating select, you need to use a findXxxx function to find the data that the corresponding option list needs to use - this process will of course be much more complicated.
Looking at the current progress, here are a few main points
Modular processing
Don’t think of doing everything in one function, split it up. For example, I initially split createRow and createSelect in the code. Among them, createSelect is highly reusable
Organize the data first
Because the DOM structure is generated based on data, the data is very important. The intuitive way is to search for the data at the same time, but this way the code looks messy. Therefore, it is generally recommended to organize and prepare the corresponding data first, and then generate DOM based on the organized data
For example,
types
is extracted fromzType_chose
firstWhen sorting list data, map, filter and reduce are basically standard (for more complex situations, you can consider RxJs)
You have changed id to class, which is good, clearing the way for later use
$.fn.close()
. Since I don't have much time to go further, I'll leave the question to you: consider defining select in HTML, and then handle the details (such as hiding) in code. If the select still needs to be defined based on data, you can fill in all the first select at the beginning to facilitate cloning later - of course in this case, the process of perfecting tr is encapsulated in a function, and you don't even need to clone. You can also create tr directly.