使用复选框实时更新用户界面 [英] Using checkboxes to update UI in realtime

查看:60
本文介绍了使用复选框实时更新用户界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试为我的一位客户开发更智能的UI。但是,我可以用来开发此功能的唯一代码是纯JS。我无权访问源HTML或CSS文件,唯一的访问权是能够通过外部.js文件注入JavaScript。
我不太熟悉JS,但是我可以围绕一两个基本脚本工作。



场景



我们正在做的是允许用户编辑PDF模板使用称为Core Create的软件在线进行。通过浏览器访问的UI非常混乱,我想提供一个选项,以通过使用复选框来隐藏和显示UI元素< textareas> /< inputs>


这是一个非常基本的



上图是我正在处理的页面的屏幕抓图,在左侧,您可以在检查元素工具的右侧看到UI及其组成。



我得出的结论是,我需要遍历突出显示的选择并将它们与七个复选框相应地链接起来。然后,结果将是一个复选框,这些复选框将隐藏/显示正确的UI元素。



The Caveat



意识到无法编辑或引入新的HTML时,我注意到缺少单击属性。因此,我对如何调用最终将要构建的JavaScript感到迷茫。


我的问题



以我对JS的有限了解,我不知道如何遍历div元素 editoraccvar-editoraccvar6 我需要操纵的那些。



由于缺少ID /名称(我认为必须使用父/子规则来完成,因为其余类使用了widley UI,我将不胜感激地举一个小例子,演示如何实现此目标,以便从中学到东西。


我应该澄清一下,我已经将复选框添加到页面中,我只需要在Checkbox和我要定位的UI元素之间构建JS链接即可。您可以找到链接到 JS小提琴



编辑//一个简化的示例;



由于一些困惑,我一起弗兰肯斯坦一些代码以显示最终的结果一个实际的结果示例需要针对7个复选框和7个分区。我将在下面列出它们的常见属性。



  //此脚本已就位并由系统构建。//写在脚本标签内,位于'editopt1之后'.// $(document).ready(function(){// $('#checkboxopt1')。click(function(){// if($('#checkboxopt1')。val()=='true '){// $('#opt1')。val('false'); // $('#checkboxopt1')。val('false'); // $('#checkboxopt1')。prop(' check',false); // $('#previewrefresh')。trigger('click'); //} else {// $('#opt1')。val('true'); // $(' #checkboxopt1')。val('true'); // $('#checkboxopt1')。prop('checked',true); // $('#previewrefresh')。trigger('click'); // }; //}); //}); function exFunction(){//检查函数名为console.log( 200:OK); //使用.field-summernote类获取所有元素var uiblocks = document.querySelectorAll(’。field-summernote’); for(var i = 0; i  

 。 editoraccvar1 {width:300px;背景:#0ff; padding:.5em;}。editoropt1 {width:300px;背景:#ff0; padding:.5em;} textarea {display:block;宽度:95%;调整大小:无; padding:.5em;}  

 < ;!-我正在试图隐藏&显示整个分区...->< div class = seq-box-form-field field-summernote editoraccvar1> < label for = accvar1> Ground Floor Info< / label> < div class = clearfix>< / div> < textarea id = richaccvar1 name = richaccvar1 class = summernote>< / textarea> <输入类型=隐藏 name = accvar1 id = accvar1 value = />< / div><!-仅使用系统提供的内容。 ->< div class = seq-box-form-field editoropt1> < label for = opt1>< span style = padding-right:10px; vertical-align:1px;> Ground Floor< / span> <输入type = checkbox name = checkboxopt1 id = checkboxopt1 value = true已选中= true /> <输入type = hidden name = opt1 id = opt1 value = true /> < / label>< / div>  


部门< div class =>< / div>
* editoraccvar,
editoraccvar1,
editoraccvar2 ,
editoraccvar3,
editoraccvar4,
editoraccvar5,
editoraccvar6 *



复选框< input id =>< / input>
* checkboxopt,
checkboxopt1,
checkboxopt2,
checkboxopt3,
checkboxopt4,
checkboxopt5,
checkboxopt6,*



解决方案

看到,您的问题归结为将复选框(似乎已经以某种方式生成)链接到要隐藏的html部分的划分部分。另外,您必须在页面中注入javascript代码(因此我猜代码越少越好)。



一种方法可能如下:

  //将代码包装在匿名函数中,以避免集群全局空间。 
(function(domElements){
//这是单击复选框时将触发的回调。
function clickCallback(){
//此回调的上下文是
//提取元素类的checkNumber。这个数字是我们要隐藏/显示的部门的链接。
var checkNumber =((/ editoropt(\d *)/).exec(this.className))[1],
checkBox = document.getElementById('checkboxopt'+ checkNumber),
除法=文档。 querySelectorAll('。editoraccvar'+ checkNumber)[0];

//隐藏/显示分区,更新复选框状态。
toggleElements(division,checkBox,window.getComputedStyle(division).display ==='none');
}

函数toggleElements(division,checkBox,isShown){
//相应地切换分区(显示/隐藏)。 b division.style.display = isShown吗? ‘封锁’:‘无’;
//由于事件侦听器已附加到复选框的父级,因此我们需要手动维护一致性。
checkBox.checked = isShown;
}

//从DOMElements数组中删除那些不是复选框的复选框,并为每个复选框添加一个click事件监听器。
domElements
.filter(function(el){
return el.className.indexOf('editoropt')!== -1;
})
.forEach (函数(el){
el.addEventListener('click',clickCallback,false);
});

//调用以seq-box-form-field类作为参数传递dom元素的函数。复选框包含在其中。另外,将节点列表
//转换为适当的数组,以便可以使用Array.prototype中定义的方法。
})([[。slice.call(document.querySelectorAll(’。seq-box-form-field’))));

该代码已注释,并且(我认为)很不言而喻。但是,如果您有任何疑问或希望我进一步阐述一点,请告诉我。



最后,这是工作中的小提琴



更新



具有相同的功能(或多或少),但现在它接受的值将对应于复选框的初始状态:

 (function(domElements,cbState){
function clickCallback(){
toggleElements(this.className);
}

函数toggleElements(className,initialShow){
var checkNumber =((/ editoropt(\d *)/).exec(className))[1],
checkBox = document.getElementById('checkboxopt '+ checkNumber),
部门= document.querySelectorAll('。editoraccvar'+ checkNumber)[0],
isShown = initialShow ===未定义?window.getComputedStyle(division).display ===' none':initialShow;

division.style.display = isShown? ‘封锁’:‘无’;
checkBox.checked = isShown;
}

domElements
.filter(function(el){
return el.className.indexOf('editoropt')!== -1;
})
.forEach(函数(el,index){
el.addEventListener('click',clickCallback,false);
toggleElements(el.className,cbState [index]);
});

//复选框的初始状态进入第二个参数。数组中的索引对应于页面中复选框的位置。
})([]。slice.call(document.querySelectorAll(’。seq-box-form-field’)),[false,false]);

这是提琴一起玩。希望对您有所帮助。


I'm currently in the process of trying to develop a smarter UI for one of my clients. However the only code I can use to develop this 'feature', is pure JS. I have no access to the source HTML or CSS files the only access I have is the ability to inject JavaScript through an external .js file. I'm not too familiar with JS, but I can work my way around a basic script or two.

Scenario

What we're doing is allowing users to edit PDF Templates online using a software called Core Create. The UI accessed through the browser is quite cluttered and I would like to provide an option to hide and show UI elements <textareas>/<inputs> through the use of checkboxes.

Here is a very basic JS Fiddle that I have built with the intention of hiding and displaying UI.

The page in question

Above is a screen grab of the page I am working with, on the left you can see the UI and its composition on the right within the 'Inspect Element' tool.

I have come to the conclusion that I need to iterate through the highlighted selection and link them accordingly with seven checkboxes. The result would then be a selection of checkboxes that would hide / display the correct UI element.

The Caveat

In realizing I cannot edit or introduce new HTML I noticed the lack of on-click attributes. So I'm a bit lost on how to invoke the JavaScript I will eventually build.

My Question

With my limited knowledge of JS I don't know how I would iterate though div elements editoraccvar - editoraccvar6 picking out the ones I need to manipulate.

Due to the lack of ID's / Names (I assume it would have to be done using Parent/Child rules somehow, as the classes are widley used by the rest of the UI. I would appreciate a small example demonstrating how I could achieve this, so I can learn from it.

I should clarify, I have already added the checkboxes to the page, I just need to build the JS link between the Checkbox and the UI element I'm attempting to target. You can find all attributes linking to these checkboxes included in the JS Fiddle.

EDIT // A Working Simplified Example;

Due to some confusion I have 'frankensteined' some code together to show the final result I am after. A working example of sorts. The actual result needs to target 7 Checkboxes and 7 Divisions. I'll list thier common properties below.

// This script is already in place and constructed by the system.
// Written inside script tags and located straight after 'editopt1'.
//    $(document).ready(function() {
//      $('#checkboxopt1').click(function() {
//        if ($('#checkboxopt1').val() == 'true') {
//          $('#opt1').val('false');
//          $('#checkboxopt1').val('false');
//          $('#checkboxopt1').prop('checked', false);
//          $('#previewrefresh').trigger('click');
//        } else {
//          $('#opt1').val('true');
//          $('#checkboxopt1').val('true');
//          $('#checkboxopt1').prop('checked', true);
//          $('#previewrefresh').trigger('click');
//        };
//      });
//    });

function exFunction() {

  // Check the function is called
  console.log("200 : OK");

  // grab all elements with the class, .field-summernote
  var uiblocks = document.querySelectorAll('.field-summernote');

  for (var i = 0; i < uiblocks.length; i++) {

    var current = uiblocks[i];
    if (current.className.indexOf('editoraccvar') < 0) //not found: -1
      return;

    // check elements in the array
    console.log(current);

    // control the elemets in the array.
    if (document.getElementById('checkboxopt1').checked) {
      uiblocks[0].style.display = 'block'; // display the element
    } else {
      uiblocks[0].style.display = 'none'; // hide the element
    }
  }
};

// Trigger the collection the check, and the control.
var x = document.getElementById("checkboxopt1");
x.addEventListener("click", function() {
  console.log("Opt");
  exFunction();
});

.editoraccvar1 {
  width: 300px;
  background: #0ff;
  padding: .5em;
}
.editoropt1 {
  width: 300px;
  background: #ff0;
  padding: .5em;
}
textarea {
  display: block;
  width: 95%;
  resize: none;
  padding: .5em;
}

<!-- I'm trying to hide & show this entire division... -->
<div class="seq-box-form-field  field-summernote editoraccvar1  ">
  <label for="accvar1">Ground Floor Info</label>
  <div class="clearfix"></div>
  <textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
  <input type="hidden" name="accvar1" id="accvar1" value="" />
</div>

<!-- Using only what the system has supplied. -->
<div class="seq-box-form-field  editoropt1  ">
  <label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">Ground Floor </span>
    <input type="checkbox" name="checkboxopt1" id="checkboxopt1" value="true" checked="true" />
    <input type="hidden" name="opt1" id="opt1" value="true" />
  </label>
</div>

Divisions <div class=""></div> * editoraccvar, editoraccvar1, editoraccvar2, editoraccvar3, editoraccvar4, editoraccvar5, editoraccvar6*

Checkboxes <input id=""></input> * checkboxopt, checkboxopt1, checkboxopt2, checkboxopt3, checkboxopt4, checkboxopt5, checkboxopt6,*

解决方案

As far as I can see, your problem boils down to link checkboxes (that seem to have been generated in some way) to "division" parts of your html that you want to hide. Plus, you have to inject javascript code in the page (so I guess the less code the better).

One approach could be as follows:

// Wrap the code in an anonymus function, to avoid clustering the global space.
(function (domElements) {
    // This is the callback that will fire when a checkbox is clicked.
    function clickCallback() {
        // the context of this callback is the DOM element thus we can access its attributes through this.
        // extract the checkNumber of the class of the element. This number is the link to the division that we want to hide/show.
        var checkNumber = ((/ editoropt(\d*) /).exec(this.className))[1],
            checkBox = document.getElementById('checkboxopt' + checkNumber),
            division = document.querySelectorAll('.editoraccvar' + checkNumber)[0];

        // Hide/show division, update checkBox state.
        toggleElements(division, checkBox, window.getComputedStyle(division).display === 'none');
    }

    function toggleElements(division, checkBox, isShown) {
        // Toggle the division (show/hide) accordingly.
        division.style.display = isShown ? 'block' : 'none';
        // Due to the fact that the event listener is attached to the parent of the checkBox, we need to maintain consistency manually.
        checkBox.checked = isShown;
    }

    // Remove from the array of DOMElements those that aren't checkboxes and add a click event listener to each of them.
    domElements
            .filter(function (el) {
                return el.className.indexOf('editoropt') !== -1;
            })
            .forEach(function (el) {
                el.addEventListener('click', clickCallback, false);
            });

// Call the function passing the dom elements with class '.seq-box-form-field' as argument. Checkboxes are contained within them. Also, transform the nodelist
// into a proper array so that methods defined in Array.prototype can be used.
})([].slice.call(document.querySelectorAll('.seq-box-form-field')));

The code is commented and (I think) quite self-explanatory. However, if you have any doubt or want me to elaborate any point further, please, let me know.

Finally, here's the working fiddle.

UPDATE

Same function (more or less) but now it accepts an array of values that will correspond to the initial state of the checkboxes:

(function (domElements, cbState) {
    function clickCallback() {
        toggleElements(this.className);
    }

    function toggleElements(className, initialShow) {
        var checkNumber = ((/ editoropt(\d*) /).exec(className))[1],
            checkBox = document.getElementById('checkboxopt' + checkNumber),
            division = document.querySelectorAll('.editoraccvar' + checkNumber)[0],
            isShown = initialShow === undefined ? window.getComputedStyle(division).display === 'none' : initialShow;

        division.style.display = isShown ? 'block' : 'none';
        checkBox.checked = isShown;
    }

    domElements
            .filter(function (el) {
                return el.className.indexOf('editoropt') !== -1;
            })
            .forEach(function (el, index) {
                el.addEventListener('click', clickCallback, false);
                toggleElements(el.className, cbState[index]);
            });

// Initial state of the checkboxes goes in the second parameter. The index in the array correspond to the checkbox position in the page.
})([].slice.call(document.querySelectorAll('.seq-box-form-field')), [false, false]);

Here's the Fiddle to play with. Hope it helps.

这篇关于使用复选框实时更新用户界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆